library(airGRiwrm)
#> Loading required package: airGR
#> 
#> Attaching package: 'airGRiwrm'
#> The following objects are masked from 'package:airGR':
#> 
#>     Calibration, CreateCalibOptions, CreateInputsCrit,
#>     CreateInputsModel, CreateRunOptions, RunModel

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 Dehay (2012)

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:

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:

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:

which can be translated as:

The Pannecière lake is an inline reservoir:

It can be modeled as:

With \(Q_{PANNEC\_P} = - Q_{CHAUM\_07}\) as all the upstream flows fill the reservoir.

The Marne lake can be mapped as:

And can be modeled as:

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
#>          id length     down
#> 1  AUBE-_P2  66500 ARCIS_24
#> 2  AUBE-_R3  44500 ARCIS_24
#> 3 MARNE_P23   3000 STDIZ_04
#> 4 MARNE_P28  82420 CHALO_21
#> 5 MARNE_R25  56870 CHALO_21
#> 6  PANNEC_P 153074 GURGY_02
#> 7  PANNEC_R 153074 GURGY_02
#> 8  SEINE_P7  73766 MERY-_22
#> 9  SEINE_R8  41766 MERY-_22

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")
griwrm2 <- rbind(griwrm, reservoir_connections[, names(griwrm)])
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)
#> List of 4
#>  $ Aube      :List of 2
#>   ..$ file       : chr "Obs_Aube_1987-2008.txt"
#>   ..$ connections:List of 2
#>   .. ..$ AUBE-_P2:List of 2
#>   .. .. ..$ col : chr "Q_prise_m3s"
#>   .. .. ..$ type: chr "in"
#>   .. ..$ AUBE-_R3:List of 2
#>   .. .. ..$ col : chr "Q_restitution_total_m3s"
#>   .. .. ..$ type: chr "out"
#>  $ Marne     :List of 2
#>   ..$ file       : chr "Obs_Marne_1973-2008.txt"
#>   ..$ connections:List of 3
#>   .. ..$ MARNE_P23:List of 2
#>   .. .. ..$ col : chr "Q_prise_Marne_m3s"
#>   .. .. ..$ type: chr "in"
#>   .. ..$ MARNE_P28:List of 2
#>   .. .. ..$ col : chr "Q_prise_Blaise_m3s"
#>   .. .. ..$ type: chr "in"
#>   .. ..$ MARNE_R25:List of 2
#>   .. .. ..$ col : chr "Q_restitution_total_m3s"
#>   .. .. ..$ type: chr "out"
#>  $ Panneciere:List of 2
#>   ..$ file       : chr "Obs_Panneciere_1949-2008.txt"
#>   ..$ connections:List of 1
#>   .. ..$ PANNEC_R:List of 2
#>   .. .. ..$ col : chr "Q_aval_bassin_m3s"
#>   .. .. ..$ type: chr "out"
#>  $ Seine     :List of 2
#>   ..$ file       : chr "Obs_Seine_1965-2008.txt"
#>   ..$ connections:List of 2
#>   .. ..$ SEINE_P7:List of 2
#>   .. .. ..$ col : chr "Q_prise_m3s"
#>   .. .. ..$ type: chr "in"
#>   .. ..$ SEINE_R8:List of 2
#>   .. .. ..$ col : chr "Q_restitution_total_m3s"
#>   .. .. ..$ type: chr "out"

Then, we load observation data for each reservoir and each connection:

library(seinebasin)
data(QNAT)
data(Qreservoirs)

How to handle an inline reservoir? The Pannecière lake case.

There are two possibilities:

  • truncate the system and only simulate the release of the reservoir if we only care about downstream flows
  • add a fictive inlet to the reservoir that will store all upstream discharge into the reservoir

If we know in advance the flows released by the reservoir, upstream flow informations is not useful for the simulation. However, reservoir management simulation would require upstream flow informations for simulating the reservoir state during simulation. The second alternative will therefore be useful for the next phases.

Qreservoirs <- cbind(
  Qreservoirs,
  -Qnat[, "CHAUM_07"] * griwrm2$area[griwrm2$id == "CHAUM_07"] * 1e3
)
colnames(Qreservoirs)[ncol(Qreservoirs)] <- "PANNEC_P"

Create the InputsModel object

InputsModel2 <- CreateInputsModel(griwrm2, DatesR, Precip, PotEvap, Qreservoirs)
#> CreateInputsModel.GRiwrm: Treating sub-basin TRANN_01...
#> CreateInputsModel.GRiwrm: Treating sub-basin STDIZ_04...
#> CreateInputsModel.GRiwrm: Treating sub-basin BAR-S_06...
#> CreateInputsModel.GRiwrm: Treating sub-basin CHAUM_07...
#> CreateInputsModel.GRiwrm: Treating sub-basin CUSSY_08...
#> CreateInputsModel.GRiwrm: Treating sub-basin STGER_09...
#> CreateInputsModel.GRiwrm: Treating sub-basin GUILL_10...
#> CreateInputsModel.GRiwrm: Treating sub-basin AISY-_11...
#> CreateInputsModel.GRiwrm: Treating sub-basin EPISY_14...
#> CreateInputsModel.GRiwrm: Treating sub-basin MONTR_18...
#> CreateInputsModel.GRiwrm: Treating sub-basin LOUVE_19...
#> CreateInputsModel.GRiwrm: Treating sub-basin LASSI_20...
#> CreateInputsModel.GRiwrm: Treating sub-basin VITRY_25...
#> CreateInputsModel.GRiwrm: Treating sub-basin MERY-_22...
#> CreateInputsModel.GRiwrm: Treating sub-basin GURGY_02...
#> Warning in airGR::CreateInputsModel(FUN_MOD = x, ...): 'Qupstream' contains NA
#> values: model outputs will contain NAs
#> CreateInputsModel.GRiwrm: Treating sub-basin CHABL_12...
#> CreateInputsModel.GRiwrm: Treating sub-basin BRIEN_03...
#> CreateInputsModel.GRiwrm: Treating sub-basin ARCIS_24...
#> CreateInputsModel.GRiwrm: Treating sub-basin CHALO_21...
#> CreateInputsModel.GRiwrm: Treating sub-basin COURL_23...
#> CreateInputsModel.GRiwrm: Treating sub-basin NOISI_17...
#> CreateInputsModel.GRiwrm: Treating sub-basin NOGEN_13...
#> CreateInputsModel.GRiwrm: Treating sub-basin MONTE_15...
#> CreateInputsModel.GRiwrm: Treating sub-basin ALFOR_16...
#> CreateInputsModel.GRiwrm: Treating sub-basin PARIS_05...

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
)
#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used

#> Warning in airGR::CreateRunOptions(FUN_MOD = x$FUN_MOD, InputsModel = x, : model warm up period not defined: default configuration used
#>   the year preceding the run period is used
OutputsModels2 <- RunModel(
  InputsModel2,
  RunOptions = RunOptions,
  Param = ParamMichel
)
#> RunModel.GRiwrmInputsModel: Treating sub-basin TRANN_01...
#> RunModel.GRiwrmInputsModel: Treating sub-basin STDIZ_04...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 139
#> time steps with negative flow, set to zero.
#> RunModel.GRiwrmInputsModel: Treating sub-basin BAR-S_06...
#> RunModel.GRiwrmInputsModel: Treating sub-basin CHAUM_07...
#> RunModel.GRiwrmInputsModel: Treating sub-basin CUSSY_08...
#> RunModel.GRiwrmInputsModel: Treating sub-basin STGER_09...
#> RunModel.GRiwrmInputsModel: Treating sub-basin GUILL_10...
#> RunModel.GRiwrmInputsModel: Treating sub-basin AISY-_11...
#> RunModel.GRiwrmInputsModel: Treating sub-basin EPISY_14...
#> RunModel.GRiwrmInputsModel: Treating sub-basin MONTR_18...
#> RunModel.GRiwrmInputsModel: Treating sub-basin LOUVE_19...
#> RunModel.GRiwrmInputsModel: Treating sub-basin LASSI_20...
#> RunModel.GRiwrmInputsModel: Treating sub-basin VITRY_25...
#> RunModel.GRiwrmInputsModel: Treating sub-basin MERY-_22...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 16
#> time steps with negative flow, set to zero.
#> RunModel.GRiwrmInputsModel: Treating sub-basin GURGY_02...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 230
#> time steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin CHABL_12...
#> RunModel.GRiwrmInputsModel: Treating sub-basin BRIEN_03...
#> RunModel.GRiwrmInputsModel: Treating sub-basin ARCIS_24...
#> RunModel.GRiwrmInputsModel: Treating sub-basin CHALO_21...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 1 time
#> steps with negative flow, set to zero.
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 3 time
#> steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin COURL_23...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 240
#> time steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin NOISI_17...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 8 time
#> steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin NOGEN_13...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 4 time
#> steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin MONTE_15...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 255
#> time steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin ALFOR_16...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 265
#> time steps with NA values
#> RunModel.GRiwrmInputsModel: Treating sub-basin PARIS_05...
#> Warning in RunModel_Lag(InputsModel, RunOptions, Param[1], OutputsModel): 275
#> time steps with NA values

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"))
  }
))

#> Warning in plot.OutputsModel(OutputsModels, Qobs = Q2[IndPeriod_Obs], main =
#> x, : zeroes detected in 'Qsim': some plots in the log space will not be created
#> using all time-steps

#> Warning in plot.OutputsModel(OutputsModels, Qobs = Q2[IndPeriod_Obs], main =
#> x, : zeroes detected in 'Qsim': some plots in the log space will not be created
#> using all time-steps

Save data for next vignettes

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

References

Dehay, F. 2012. “Etude de l’impact du changement climatique sur la gestion des lacs-réservoirs de la Seine.” Other, Diplôme d’ingénieur de l’ENGEES ,Strasbourg. https://hal.inrae.fr/hal-02597326.