Commit f8a06071 authored by Dorchies David's avatar Dorchies David
Browse files

feat(RunModel_LLR): add parameter transformation due to distances to upstream stations

Version from Enola 09/06/2022

Refs HYCAR-Hydro/airgr#152, HYCAR-Hydro/airgr#153
parent 057d235c
No related merge requests found
Showing with 67 additions and 19 deletions
+67 -19
......@@ -69,7 +69,10 @@ RunModel_LLR <- function(InputsModel, RunOptions, Param, QcontribDown) {
KParam <- Param[2L]
## propagation time from upstream meshes to outlet
PT <- floor(InputsModel$LengthHydro * 1e3 / TParam / RunOptions$FeatFUN_MOD$TimeStep)
PT <- ifelse(InputsModel$LengthHydro == 0, 0, InputsModel$LengthHydro/max(InputsModel$LengthHydro)) *
(TParam + KParam) - ifelse(InputsModel$LengthHydro == 0, 0,
sqrt(InputsModel$LengthHydro/max(InputsModel$LengthHydro))) * KParam
PT[PT < 0] <- 0
PK <- ifelse(InputsModel$LengthHydro == 0,
0,
sqrt(InputsModel$LengthHydro/max(InputsModel$LengthHydro)) * KParam)
......@@ -77,13 +80,51 @@ RunModel_LLR <- function(InputsModel, RunOptions, Param, QcontribDown) {
C0 <- ifelse(PK ==0, 0, exp(-1/PK))
C1 <- ((PK/1) * (1-C0))-C0
C2 <- 1 - (PK/1) * (1-C0)
## Lag model computation
## set up initial states
IniSD <- RunOptions$IniStates[grep("SD", names(RunOptions$IniStates))]
if (length(IniSD) > 0) {
if (sum(floor(PT)) + NbUpBasins != length(IniSD)) {
stop(
sprintf(
"SD initial states has a length of %i and a length of %i is required",
length(IniSD),
sum(floor(PT)) + NbUpBasins
)
)
}
IniStates <- lapply(seq_len(NbUpBasins), function(x) {
iStart <- 1
if (x > 1) {
iStart <- iStart + sum(floor(PT[1:x - 1]) + 1)
}
as.vector(IniSD[iStart:(iStart + PT[x])])
})
} else {
IniStates <- lapply(
seq_len(NbUpBasins),
function(iUpBasins) {
iWarmUp <- seq.int(
from = max(1, IndPeriod1[1] - floor(PT[iUpBasins]) - 1),
to = max(1, IndPeriod1[1] - 1)
)
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(as.vector(ini))
}
)
}
## Lag & route model computation
Qsim_m3 <- matrix(0
, nrow = length(IndPeriod1), ncol = NbUpBasins)
QsimDown_input <- matrix(QsimDown *
InputsModel$BasinAreas[length(InputsModel$BasinAreas)] * 1e3, ncol = 1)
for (upstream_basin in seq_len(NbUpBasins)) {
Qupstream_m3 <- InputsModel$Qupstream[IndPeriod1, upstream_basin]
Qupstream_m3 <- c(IniStates[[upstream_basin]],
InputsModel$Qupstream[IndPeriod1, upstream_basin])
Qroute <- Qllr <- Qupstream_m3
if (is.na(Qroute[1])){
Qroute[1] <- 0
......@@ -98,6 +139,7 @@ RunModel_LLR <- function(InputsModel, RunOptions, Param, QcontribDown) {
}
Qsim_m3[, upstream_basin] <- Qllr[(1 +length(Qllr) - length(IndPeriod1)) :
(length(IndPeriod1) + (length(Qllr) - length(IndPeriod1)))]
}
Qsim_m3 <- cbind(QsimDown_input, Qsim_m3)
Qsim_m3 <- rowSums(Qsim_m3)
......@@ -136,7 +178,7 @@ RunModel_LLR <- function(InputsModel, RunOptions, Param, QcontribDown) {
InputsModel$Qupstream[(lastTS - floor(PT[x])):lastTS, x]
})
if (is.null(OutputsModel$StateEnd)) {
OutputsModel$StateEnd <- CreateIniStates(RunModel_Lag, InputsModel, SD = SD)
OutputsModel$StateEnd <- CreateIniStates(RunModel_LLR, InputsModel, SD = SD)
} else {
OutputsModel$StateEnd$SD <- SD
}
......
......@@ -322,7 +322,6 @@ test_that("Warm start should give same result as warmed model", {
expect_equal(OutputsModel2$Qsim, OutputsModel$Qsim[366:730])
})
## cette erreur marche pas non plus
test_that("Error on Wrong length of iniState$SD", {
OutputsModel1$StateEnd$SD[[1]] <- c(1,1)
RunOptions2 <- CreateRunOptions(FUN_MOD = RunModel_GR4J,
......@@ -334,17 +333,24 @@ test_that("Error on Wrong length of iniState$SD", {
FUN_SD = RunModel_LLR)
)
})
## ce test ne marche pas
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, FUN_SD = RunModel_LLR)
OM2 <- RunModel(InputsModel = IM2,
RunOptions = RunOptions2,
Param = PSDini,
FUN_MOD = RunModel_GR4J, FUN_SD = RunModel_LLR)
expect_equal(OM2$Qsim_m3[1:3], rep(2,3))
})
## pour que ce test marche il faut que Qsim_m3 soit de la taille de IndPeriod1 + max(PT)
## mais pour cela, il faut que les colonnes soient remplies par le bas.
#PSDini[2] <- 0
#IM <- InputsModel
#IM$BasinAreas <- rep(BasinInfo$BasinArea, 2)
#IM$LengthHydro <- c(1)
#test_that("First Qupstream time steps must be repeated if warm-up period is too short", {
# IM2 <- IM[2558:3557]
# IM2$BasinAreas[2] <- 0
# IM2$Qupstream <- matrix(seq(1:1000), ncol = 1)
# RunOptions2 <- CreateRunOptions(FUN_MOD = RunModel_GR4J,
# InputsModel = IM2, IndPeriod_Run = seq_len(1000),
# IndPeriod_WarmUp = 0L, FUN_SD = RunModel_LLR)
# OM2 <- RunModel(InputsModel = IM2,
# RunOptions = RunOptions2,
# Param = PSDini,
# FUN_MOD = RunModel_GR4J, FUN_SD = RunModel_LLR)
# expect_equal(OM2$Qsim_m3[1:3], rep(2,3))
#})
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment