From cb8b0be58bbb39079ea3355876117318ab2144f8 Mon Sep 17 00:00:00 2001 From: Dorchies David <david.dorchies@inrae.fr> Date: Thu, 17 Jun 2021 14:39:56 +0200 Subject: [PATCH] feat(RunModel_Lag): handling of warm-up simulated flows - Implementation and tests Refs #123 --- R/RunModel_Lag.R | 18 +++++++++++++++--- tests/testthat/test-RunModel_Lag.R | 25 ++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/R/RunModel_Lag.R b/R/RunModel_Lag.R index 473e7758..29712446 100644 --- a/R/RunModel_Lag.R +++ b/R/RunModel_Lag.R @@ -69,9 +69,21 @@ RunModel_Lag <- function(InputsModel, RunOptions, Param, QcontribDown) { IniSD[iStart:(iStart + PT[x])] }) } else { - IniStates <- lapply(seq_len(NbUpBasins), function(x) { - rep(0, floor(PT[x] + 1)) - }) + IniStates <- lapply( + seq_len(NbUpBasins), + function(iUpBasins) { + iWarmUp <- seq.int( + max(1, RunOptions$IndPeriod_WarmUp[length(RunOptions$IndPeriod_WarmUp)] - floor(PT[iUpBasins])), + max(1, RunOptions$IndPeriod_WarmUp[length(RunOptions$IndPeriod_WarmUp)]) + ) + ini <- InputsModel$Qupstream[iWarmUp, iUpBasins] + if(length(ini) != floor(PT[iUpBasins] + 1)) { + # If warm-up period is not enough long complete beginning with first value + ini <- c(rep(ini[1], floor(PT[iUpBasins] + 1) - length(ini)), ini) + } + return(ini) + } + ) } # message("Initstates: ", paste(IniStates, collapse = ", ")) diff --git a/tests/testthat/test-RunModel_Lag.R b/tests/testthat/test-RunModel_Lag.R index c7cc53ec..d71189c1 100644 --- a/tests/testthat/test-RunModel_Lag.R +++ b/tests/testthat/test-RunModel_Lag.R @@ -165,7 +165,7 @@ Qm3GR4Only <- OutputsGR4JOnly$Qsim * InputsModel$BasinAreas[2L] * 1e3 test_that("1 input with lag of 1 time step delay out gives an output delayed of one time step", { OutputsSD <- RunModel(InputsModel, RunOptions, Param = ParamSD, FUN_MOD = RunModel_GR4J) Qm3SdSim <- OutputsSD$Qsim_m3 - Qm3UpstLagObs <- c(0, Qupstream[Ind_Run[1:(length(Ind_Run) - 1)]]) * InputsModel$BasinAreas[1] * 1e3 + Qm3UpstLagObs <- Qupstream[Ind_Run - 1] * InputsModel$BasinAreas[1] * 1e3 expect_equal(Qm3SdSim - Qm3GR4Only, Qm3UpstLagObs) }) @@ -174,7 +174,7 @@ test_that("1 input with lag of 0.5 time step delay out gives an output delayed o Param = c(InputsModel$LengthHydro * 1e3 / (12 * 3600), Param), FUN_MOD = RunModel_GR4J) Qm3SdSim <- OutputsSD$Qsim_m3 - Qm3UpstLagObs <- (Qupstream[Ind_Run] + c(0, Qupstream[Ind_Run[1:(length(Ind_Run) - 1)]])) / 2 * InputsModel$BasinAreas[1] * 1e3 + Qm3UpstLagObs <- (Qupstream[Ind_Run] + Qupstream[Ind_Run - 1]) / 2 * InputsModel$BasinAreas[1] * 1e3 expect_equal(Qm3SdSim - Qm3GR4Only, Qm3UpstLagObs) }) @@ -233,7 +233,7 @@ InputsCrit <- CreateInputsCrit( InputsModel = InputsModel, RunOptions = RunOptions, VarObs = "Q", - Obs = (c(0, Qupstream[Ind_Run[1:(length(Ind_Run) - 1)]]) * BasinAreas[1L] + + Obs = (Qupstream[Ind_Run - 1] * BasinAreas[1L] + BasinObs$Qmm[Ind_Run] * BasinAreas[2L]) / sum(BasinAreas) ) @@ -283,7 +283,7 @@ test_that("1 no area input with lag of 1 time step delay out gives an output del expect_false(any(is.na(OutputsSD$Qsim))) Qm3SdSim <- OutputsSD$Qsim_m3 - Qm3UpstLagObs <- c(0, InputsModel$Qupstream[Ind_Run[1:(length(Ind_Run) - 1)]]) + Qm3UpstLagObs <- InputsModel$Qupstream[Ind_Run - 1] expect_equal(Qm3SdSim - Qm3GR4Only, Qm3UpstLagObs) }) @@ -338,6 +338,21 @@ test_that("Error on Wrong length of iniState$SD", { InputsModel = IM, IndPeriod_Run = Ind_Run2, IndPeriod_WarmUp = 0L, IniStates = OutputsModel1$StateEnd) - expect_error(RunModel(InputsModel = IM, RunOptions = RunOptions2, Param = PSDini, FUN_MOD = RunModel_GR4J) + expect_error( + RunModel(InputsModel = IM, RunOptions = RunOptions2, Param = PSDini, FUN_MOD = RunModel_GR4J) ) }) + +test_that("First Qupstream time steps must be repeated if warm-up period is too short", { + IM2 <- IM[2558:3557] + IM2$BasinAreas[3] <- 0 + IM2$Qupstream <- matrix(rep(1:1000, 2), ncol = 2) + RunOptions2 <- CreateRunOptions(FUN_MOD = RunModel_GR4J, + InputsModel = IM2, IndPeriod_Run = seq_len(1000), + IndPeriod_WarmUp = 0L) + OM2 <- RunModel(InputsModel = IM2, + RunOptions = RunOptions2, + Param = PSDini, + FUN_MOD = RunModel_GR4J) + expect_equal(OM2$Qsim_m3[1:3], rep(2,3)) +}) -- GitLab