knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(airGRiwrm)
The aim of this vignette is to add reservoir connections to the Seine River model previously set up. A complete description of the reservoir system of the Seine River can be found in @dehayEtudeImpactChangement2012
Because of the airGR SD model structure, the topology of the network will differ between the physical one and the modeled one. In the following, we provide details for each of the 4 lakes, and then we present the complete SD network.
First, the physical topology of the Aube lake is represented below:
plot.mermaid("graph LR TRANN_01 -->|1.5km| AUBE_P2 AUBE_P2 -->|22km| AUBE_R3 AUBE_P2 --> AUBE(AUBE) AUBE --> AUBE_R3 AUBE_R3 -->|44.5km| ARCIS_24 style AUBE_P2 fill:#fcc style AUBE_R3 fill:#fcc style AUBE fill:#ccf ")
In the SD model, we do not simulate intermediate flows as well as the reservoir in the catchment. As a result, an equivalent topology compatible with airGR will be the one below:
plot.mermaid(" graph LR TRANN_01 -->|68km| ARCIS_24 AUBE_P2 -->|66.5km| ARCIS_24 AUBE_R3 -->|44.5km| ARCIS_24 style AUBE_P2 fill:#fcc style AUBE_R3 fill:#fcc ")
AUBE_P2
will propagate negative flows downstream (reservoir inflows) while
AUBE_R3
will propagate positive flows downstream (reservoir releases).
The configuration on the lake Seine is similar:
plot.mermaid(" graph LR BAR-S_06 -->|6km| SEINE_P7 SEINE_P7 -->|32km| SEINE_R8 SEINE_P7 --> SEINE(SEINE) SEINE--> SEINE_R8 SEINE_R8 -->|41.7km| MERY-_22 style SEINE_P7 fill:#fcc style SEINE_R8 fill:#fcc style SEINE fill:#ccf ")
which can be translated as:
plot.mermaid(" graph LR BAR-S_06 -->|79.7km| MERY-_22 SEINE_P7 -->|73.7km| MERY-_22 SEINE_R8 -->|41.7km| MERY-_22 style SEINE_P7 fill:#fcc style SEINE_R8 fill:#fcc ")
The Pannecière lake is an inline reservoir:
plot.mermaid(" graph LR P(PANNECIERE) CHAUM_07 -->|0km| P P --> |153km| GURGY_02 style P fill:#ccf ")
We can keep the same structure to model it. PANNEC_R
corresponds to the flow
released by the Pannecière lake, it is acting as an upstream node which means
that the flow simulated at CHAUM_07
is no longer routed to downstream.
plot.mermaid(" graph LR CHAUM_07 --> |0km| PANNEC_R PANNEC_R --> |153km| GURGY_02 style PANNEC_R fill:#fcc ")
The Marne lake can be mapped as:
plot.mermaid(" graph LR LOUVE_19 -->|0.5km| MARNE_P28 MARNE_P23 -->|3km| STDIZ_04 MARNE_P23 --> M(MARNE) MARNE_P28 --> M MARNE_P28 -->|25.6km| MARNE_R25 M --> MARNE_R25 STDIZ_04 -->|28.7km| MARNE_R25 MARNE_R25 -->|56.9km| CHALO_21 style MARNE_P28 fill:#fcc style MARNE_P23 fill:#fcc style MARNE_R25 fill:#fcc style M fill:#ccf ")
And can be modeled as:
plot.mermaid(" graph LR MARNE_P23 -->|3km| STDIZ_04 LOUVE_19 -->|83km| CHALO_21 MARNE_P28 -->|82.5km| CHALO_21 STDIZ_04 -->|85.6km| CHALO_21 MARNE_R25 -->|56.9km| CHALO_21 style MARNE_P28 fill:#fcc style MARNE_P23 fill:#fcc style MARNE_R25 fill:#fcc ")
Hence the topological connection to the reservoirs is described in the model as below:
reservoir_connections <- read.table( file = system.file("seine_data", "network_reservoir_connections.txt", package = "seinebasin"), sep = ";", header = TRUE ) reservoir_connections
Reservoir connections are added to the GRiwrm object:
reservoir_connections$length <- reservoir_connections$length / 1000 reservoir_connections$model <- NA reservoir_connections$area <- NA load("_cache/V01.RData") seine_nodes <- seine_nodes[, c("id_sgl", "distance_aval", "id_aval", "model", "area")] names(seine_nodes)[1:3] <- names(reservoir_connections)[1:3] seine_nodes2 <- rbind(seine_nodes, reservoir_connections) # Insert PANNEC_R between CHAUM_07 and GURGY_02 seine_nodes2$down[seine_nodes2$id == "CHAUM_07"] <- "PANNEC_R" seine_nodes2$length[seine_nodes2$id == "CHAUM_07"] <- 0 griwrm2 <- CreateGRiwrm(seine_nodes2) plot(griwrm2)
Description of the files, the columns and the type of connection (inlet / outlet) are defined in the list below:
lCfgReservoirs <- jsonlite::read_json(system.file("seine_data", "config_reservoirs.json", package = "seinebasin")) str(lCfgReservoirs)
Then, we load observation data for each reservoir and each connection:
library(seinebasin) data(QNAT) data(Qreservoirs)
InputsModel2 <- CreateInputsModel(griwrm2, DatesR, Precip, PotEvap, Qreservoirs)
# Load RunOptions load("_cache/V02.RData") # Load calibrated parameters with Michel's method load("_cache/V03.RData")
A lag parameter is now mandatory for these sub-basins. As no calibration is possible at that stage an arbitrary one will be used (1 m/s).
ParamMichel$STDIZ_04 <- c(1, ParamMichel$STDIZ_04)
We can now run the model, using the parameters previously obtained:
RunOptions <- CreateRunOptions( InputsModel2, IndPeriod_Run = IndPeriod_Run ) OutputsModels2 <- RunModel( InputsModel2, RunOptions = RunOptions, Param = ParamMichel )
data(QOBS)
We can compare these simulated flows with influenced discharge measurements:
ReduceOutputsModel <- function(OutputsModels, IndPeriod) { items <- names(OutputsModels) OutputsModelsOut <- sapply(items, function(x) { OutputsModels[[x]] <- OutputsModels[[x]][IndPeriod] }) OutputsModelsOut$StateEnd <- OutputsModels$StateEnd class(OutputsModelsOut) <- class(OutputsModels) return(OutputsModelsOut) } IndPeriod <- RunOptions[[1]]$IndPeriod_Run IndPeriod <- IndPeriod[IndPeriod <= nrow(Qobs)] htmltools::tagList(lapply( colnames(Qobs), function(x) { Q2 <- Qobs[IndPeriod, x] IndPeriod_Obs <- which(!is.na(Q2)) OutputsModels <- ReduceOutputsModel(OutputsModels2[[x]], IndPeriod_Obs) plot(OutputsModels, Qobs = Q2[IndPeriod_Obs], main = x, which = c("Regime")) } ))
save(griwrm2, ReduceOutputsModel, file = "_cache/V04.RData")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.