knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(airGRiwrm)

Integration of the reservoir connections into the model

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

Add connections to the reservoirs in the gauging station network

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)

Loading reservoir observation time series

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)

Create the InputsModel object

InputsModel2 <- CreateInputsModel(griwrm2, DatesR, Precip, PotEvap, Qreservoirs)

Run simulation with naturalized flow parameters

Load calibration parameters

# Load RunOptions
load("_cache/V02.RData")
# Load calibrated parameters with Michel's method
load("_cache/V03.RData")

How to handle former upstream sub-basins with upstream flows ?

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)

Run simulation

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
)

Compare modeled flows with observed flows

Load observed flows

data(QOBS)

Comparison with simulated flows

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 data for next vignettes

save(griwrm2, ReduceOutputsModel, file = "_cache/V04.RData")

References



inrae/airGRiwrm documentation built on Sept. 27, 2024, 6:08 p.m.