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

feat: handle multi time step supervision and debug multi variable controller

Refs #19
Showing with 249 additions and 153 deletions
+249 -153
#' Create a Supervisor for handling regulation in a model #' Create a Supervisor for handling regulation in a model
#' #'
#' @param InputsModel `GRiwrmInputsModel` The inputs of the basin model #' @param InputsModel `GRiwrmInputsModel` The inputs of the basin model
#' @param TimeStep [integer] The number of time steps between each supervision
#' #'
#' @return `Supervisor` object #' @return `Supervisor` object
#' @export #' @export
...@@ -23,8 +24,12 @@ ...@@ -23,8 +24,12 @@
#' PotEvap <- ConvertMeteoSD(griwrm, PotEvapTot) #' PotEvap <- ConvertMeteoSD(griwrm, PotEvapTot)
#' InputsModel <- CreateInputsModel(griwrm, DatesR, Precip, PotEvap, Qobs) #' InputsModel <- CreateInputsModel(griwrm, DatesR, Precip, PotEvap, Qobs)
#' sv <- CreateSupervisor(InputsModel) #' sv <- CreateSupervisor(InputsModel)
CreateSupervisor <- function(InputsModel) { CreateSupervisor <- function(InputsModel, TimeStep = 1L) {
if(!inherits(InputsModel, "GRiwrmInputsModel")) stop("`InputsModel` parameter must of class 'GRiwrmInputsModel' (See ?CreateInputsModel.GRiwrm)") if(!inherits(InputsModel, "GRiwrmInputsModel")) {
stop("`InputsModel` parameter must of class 'GRiwrmInputsModel' (See ?CreateInputsModel.GRiwrm)")
}
if(!is.integer(TimeStep)) stop("`TimeStep` parameter must be an integer")
# Create Supervisor environment from the parent of GlobalEnv # Create Supervisor environment from the parent of GlobalEnv
e <- new.env(parent = parent.env(globalenv())) e <- new.env(parent = parent.env(globalenv()))
class(e) <- c("Supervisor", class(e)) class(e) <- c("Supervisor", class(e))
...@@ -39,14 +44,15 @@ CreateSupervisor <- function(InputsModel) { ...@@ -39,14 +44,15 @@ CreateSupervisor <- function(InputsModel) {
e$InputsModel <- InputsModel e$InputsModel <- InputsModel
e$griwrm <- attr(InputsModel, "GRiwrm") e$griwrm <- attr(InputsModel, "GRiwrm")
e$OutputsModel <- list() e$OutputsModel <- list()
e$.TimeStep <- TimeStep
# Controller list # Controller list
e$controllers <- list() e$controllers <- list()
class(e$controllers) <- c("Controllers", class(e$controllers)) class(e$controllers) <- c("Controllers", class(e$controllers))
# Copy functions to be used enclosed in the Supervisor environment # Copy functions to be used enclosed in the Supervisor environment
e$createController <- createController e$CreateController <- CreateController
environment(e$createController) <- e environment(e$CreateController) <- e
# Time steps handling: these data are provided by RunModel # Time steps handling: these data are provided by RunModel
# Index of the current time steps in the modelled time series between 1 and length(RunOptions$Ind_Period) # Index of the current time steps in the modelled time series between 1 and length(RunOptions$Ind_Period)
......
...@@ -42,7 +42,6 @@ GRiwrm <- function(db, ...@@ -42,7 +42,6 @@ GRiwrm <- function(db,
length = "double", length = "double",
model = "character", model = "character",
area = "double")) area = "double"))
rownames(db) <- db$id
class(db) <- c("GRiwrm", class(db)) class(db) <- c("GRiwrm", class(db))
db db
} }
......
...@@ -9,7 +9,18 @@ ...@@ -9,7 +9,18 @@
#' @export #' @export
RunModel.Supervisor <- function(x, RunOptions, Param, ...) { RunModel.Supervisor <- function(x, RunOptions, Param, ...) {
# Time steps handling
x$ts.index0 <- RunOptions[[1]]$IndPeriod_Run[1] - 1 x$ts.index0 <- RunOptions[[1]]$IndPeriod_Run[1] - 1
ts.start <- RunOptions[[1]]$IndPeriod_Run[1]
ts.end <- RunOptions[[1]]$IndPeriod_Run[length(RunOptions[[1]]$IndPeriod_Run)]
superTSstarts <- seq(ts.start, ts.end, x$.TimeStep)
lSuperTS <- lapply(
superTSstarts, function(x, TS, xMax) {
seq(x, min(x + TS - 1, xMax))
},
TS = x$.TimeStep,
xMax = ts.end
)
# Run runoff model for each sub-basin # Run runoff model for each sub-basin
x$OutputsModel <- lapply(X = x$InputsModel, FUN = function(IM) { x$OutputsModel <- lapply(X = x$InputsModel, FUN = function(IM) {
...@@ -36,19 +47,18 @@ RunModel.Supervisor <- function(x, RunOptions, Param, ...) { ...@@ -36,19 +47,18 @@ RunModel.Supervisor <- function(x, RunOptions, Param, ...) {
RunOptions[[id]]$Outputs_Sim <- "StateEnd" RunOptions[[id]]$Outputs_Sim <- "StateEnd"
} }
# Loop over time steps # Loop over time steps with a step equal to the supervision time step
for(iTS in RunOptions[[1]]$IndPeriod_Run) { for(iTS in lSuperTS) {
# Run regulation on the whole basin for the current time step # Run regulation on the whole basin for the current time step
x$ts.index <- iTS - x$ts.index0 x$ts.index <- iTS - x$ts.index0
x$ts.date <- x$InputsModel[[1]]$DatesR[iTS] x$ts.date <- x$InputsModel[[1]]$DatesR[iTS]
# Regulation occurs from second time step # Regulation occurs from second time step
if(iTS > RunOptions[[1]]$IndPeriod_Run[1]) { if(iTS[1] > ts.start) {
doSupervision(x) doSupervision(x)
} }
# Loop over sub-basin using SD model # Loop over sub-basin using SD model
for(id in getSD_Ids(x$InputsModel)) { for(id in getSD_Ids(x$InputsModel)) {
# Run the SD model for the sub-basin and one time step # Run the SD model for the sub-basin and one time step
RunOptions[[id]]$IndPeriod_Run <- iTS RunOptions[[id]]$IndPeriod_Run <- iTS
RunOptions[[id]]$IniStates <- unlist(x$OutputsModel[[id]]$StateEnd) RunOptions[[id]]$IniStates <- unlist(x$OutputsModel[[id]]$StateEnd)
...@@ -70,6 +80,6 @@ RunModel.Supervisor <- function(x, RunOptions, Param, ...) { ...@@ -70,6 +80,6 @@ RunModel.Supervisor <- function(x, RunOptions, Param, ...) {
for(id in getSD_Ids(x$InputsModel)) { for(id in getSD_Ids(x$InputsModel)) {
x$OutputsModel[[id]]$Qsim <- Qsim[[id]] x$OutputsModel[[id]]$Qsim <- Qsim[[id]]
} }
attr(x$OutputsModel, "Qm3s") <- OutputsModelQsim(x$InputsModel, x$OutputsModel) attr(x$OutputsModel, "Qm3s") <- OutputsModelQsim(x$InputsModel, x$OutputsModel, RunOptions[[1]]$IndPeriod_Run)
return(x$OutputsModel) return(x$OutputsModel)
} }
#' Create a controller #' Create and add a controller in a supervisor
#' #'
#' @details #' @details
#' `ctrl.id` parameter is a unique id for finding the controller in the supervisor. #' `ctrl.id` parameter is a unique id for finding the controller in the supervisor.
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
#' # A controller which usually releases 0.1 m3/s and provides #' # A controller which usually releases 0.1 m3/s and provides
#' # extra release if the downstream flow is below 0.5 m3/s #' # extra release if the downstream flow is below 0.5 m3/s
#' logicDamRelease <- function(Y) max(0.5 - Y[1], 0.1) #' logicDamRelease <- function(Y) max(0.5 - Y[1], 0.1)
#' createController(sv, "DamRelease", Y = c("54001"), U = c("54095"), FUN = logicDamRelease) #' CreateController(sv, "DamRelease", Y = c("54001"), U = c("54095"), FUN = logicDamRelease)
createController <- function(supervisor, ctrl.id, Y, U, FUN){ CreateController <- function(supervisor, ctrl.id, Y, U, FUN){
if(!is.character(ctrl.id)) stop("Parameter `ctrl.id` should be character") if(!is.character(ctrl.id)) stop("Parameter `ctrl.id` should be character")
...@@ -34,7 +34,9 @@ createController <- function(supervisor, ctrl.id, Y, U, FUN){ ...@@ -34,7 +34,9 @@ createController <- function(supervisor, ctrl.id, Y, U, FUN){
ctrlr <- list( ctrlr <- list(
id = ctrl.id, id = ctrl.id,
U = createControl(U), U = createControl(U),
Unames = U,
Y = createControl(Y), Y = createControl(Y),
Ynames = Y,
FUN = FUN FUN = FUN
) )
class(ctrlr) <- c("Controller", class(ctrlr)) class(ctrlr) <- c("Controller", class(ctrlr))
...@@ -53,9 +55,8 @@ createController <- function(supervisor, ctrl.id, Y, U, FUN){ ...@@ -53,9 +55,8 @@ createController <- function(supervisor, ctrl.id, Y, U, FUN){
#' #'
#' @param locations vector of [character] containing the location of the variable in the model (see details) #' @param locations vector of [character] containing the location of the variable in the model (see details)
#' #'
#' @return [data.frame] of two columns: #' @return a [matrix] with each column is the location of the variables and the rows
#' - 'loc' [character]: the locations of the variables #' the values of the variable for the current time steps (empty by default)
#' - 'v' [numeric]: the value of the variable for the current time step which is [NA] at its creation
#' @export #' @export
#' #'
#' @examples #' @examples
...@@ -65,5 +66,6 @@ createControl <- function(locations) { ...@@ -65,5 +66,6 @@ createControl <- function(locations) {
if(!is.character(locations)) { if(!is.character(locations)) {
stop("Parameter `locations` should be character") stop("Parameter `locations` should be character")
} }
data.frame(loc = locations, v = rep(NA, length(locations))) m <- matrix(NA, ncol = length(locations), nrow = 0)
return(m)
} }
...@@ -50,15 +50,16 @@ getDataFromLocation <- function(loc, sv) { ...@@ -50,15 +50,16 @@ getDataFromLocation <- function(loc, sv) {
#' Write data to model input for the current time step #' Write data to model input for the current time step
#' #'
#' @param control [vector] A row of the `U` [data.frame] from a `Controller` #' @param ctrlr a `Controller` object (See [CreateController])
#' @param sv `Supervisor` (See [CreateSupervisor]) #' @param sv `Supervisor` (See [CreateSupervisor])
#' #'
#' @return [NULL] #' @return [NULL]
setDataToLocation <- function(control, sv) { setDataToLocation <- function(ctrlr, sv) {
node <- sv$griwrm$down[sv$griwrm$id == control[1]] l <- lapply(seq(length(ctrlr$Unames)), function(i) {
# ! Qupstream contains warm up period and run period => the index is shifted node <- sv$griwrm$down[sv$griwrm$id == ctrlr$Unames[i]]
sv$InputsModel[[node]]$Qupstream[sv$ts.index0 + sv$ts.index, control[1]] <- # ! Qupstream contains warm up period and run period => the index is shifted
as.numeric(control[2]) sv$InputsModel[[node]]$Qupstream[sv$ts.index0 + sv$ts.index, ctrlr$Unames[i]] <- ctrlr$U[,i]
})
} }
...@@ -66,21 +67,22 @@ setDataToLocation <- function(control, sv) { ...@@ -66,21 +67,22 @@ setDataToLocation <- function(control, sv) {
#' #'
#' @param supervisor `Supervisor` (See [CreateSupervisor]) #' @param supervisor `Supervisor` (See [CreateSupervisor])
#' #'
#' @return [NULL]
doSupervision <- function(supervisor) { doSupervision <- function(supervisor) {
for (id in names(supervisor$controllers)) { for (id in names(supervisor$controllers)) {
# Read Y from locations in the model # Read Y from locations in the model
supervisor$controllers[[id]]$Y$v <- supervisor$controllers[[id]]$Y <- do.call(
sapply(supervisor$controllers[[id]]$Y$loc, getDataFromLocation, sv = supervisor) cbind,
lapply(supervisor$controllers[[id]]$Ynames, getDataFromLocation, sv = supervisor)
)
# Run logic # Run logic
supervisor$controllers[[id]]$U$v <- supervisor$controllers[[id]]$U <-
sapply(supervisor$controllers[[id]]$Y$v, supervisor$controllers[[id]]$FUN) supervisor$controllers[[id]]$FUN(supervisor$controllers[[id]]$Y)
# Write U to locations in the model # Write U to locations in the model
apply(supervisor$controllers[[id]]$U, 1, setDataToLocation, sv = supervisor) setDataToLocation(supervisor$controllers[[id]], sv = supervisor)
} }
return()
} }
#' Check the parameters of RunModel methods #' Check the parameters of RunModel methods
#' #'
#' Stop the execution if an error is detected. #' Stop the execution if an error is detected.
...@@ -89,13 +91,10 @@ doSupervision <- function(supervisor) { ...@@ -89,13 +91,10 @@ doSupervision <- function(supervisor) {
#' @param RunOptions a `GRiwrmRunOptions` object (See [CreateRunOptions.GRiwrmInputsModel]) #' @param RunOptions a `GRiwrmRunOptions` object (See [CreateRunOptions.GRiwrmInputsModel])
#' @param Param a [list] of [numeric] containing model parameters of each node of the network #' @param Param a [list] of [numeric] containing model parameters of each node of the network
#' #'
#' @return [NULL]
#'
checkRunModelParameters <- function(InputsModel, RunOptions, Param) { checkRunModelParameters <- function(InputsModel, RunOptions, Param) {
if(!inherits(InputsModel, "GRiwrmInputsModel")) stop("`InputsModel` parameter must of class 'GRiwrmRunoptions' (See ?CreateRunOptions.GRiwrmInputsModel)") if(!inherits(InputsModel, "GRiwrmInputsModel")) stop("`InputsModel` parameter must of class 'GRiwrmRunoptions' (See ?CreateRunOptions.GRiwrmInputsModel)")
if(!inherits(RunOptions, "GRiwrmRunOptions")) stop("Argument `RunOptions` parameter must of class 'GRiwrmRunOptions' (See ?CreateRunOptions.GRiwrmInputsModel)") if(!inherits(RunOptions, "GRiwrmRunOptions")) stop("Argument `RunOptions` parameter must of class 'GRiwrmRunOptions' (See ?CreateRunOptions.GRiwrmInputsModel)")
if(!is.list(Param) || !all(names(InputsModel) %in% names(Param))) stop("Argument `Param` must be a list with names equal to nodes IDs") if(!is.list(Param) || !all(names(InputsModel) %in% names(Param))) stop("Argument `Param` must be a list with names equal to nodes IDs")
return()
} }
......
...@@ -50,29 +50,32 @@ test_that("RunModelSupervisor with no regulation should returns same results as ...@@ -50,29 +50,32 @@ test_that("RunModelSupervisor with no regulation should returns same results as
expect_equal(OM_Supervisor[["54057"]]$Qsim, OM_GriwrmInputs[["54057"]]$Qsim) expect_equal(OM_Supervisor[["54057"]]$Qsim, OM_GriwrmInputs[["54057"]]$Qsim)
}) })
# Add 2 nodes to the network
griwrm2 <- rbind(griwrm,
data.frame(
id = c("R1", "R2"),
down = "54057",
length = 100000,
area = NA,
model = NA
))
# Add Qobs for the 2 new nodes and create InputsModel
Qobs2 <- cbind(Qobs, matrix(data = rep(0, 2*nrow(Qobs)), ncol = 2))
colnames(Qobs2) <- c(colnames(Qobs2)[1:6], "R1", "R2")
InputsModel <- CreateInputsModel(griwrm2, DatesR, Precip, PotEvap, Qobs2)
test_that("RunModelSupervisor with two regulations that cancel each other out should returns same results as RunModel.GRiwrmInputsModel", { test_that("RunModelSupervisor with two regulations that cancel each other out should returns same results as RunModel.GRiwrmInputsModel", {
# Add 2 nodes to the network # Create Supervisor
griwrm2 <- rbind(griwrm,
data.frame(
id = c("R1", "R2"),
down = "54057",
length = 100000,
area = NA,
model = NA
))
# Add Qobs for the 2 new nodes
Qobs2 <- cbind(Qobs, matrix(data = rep(0, 2*nrow(Qobs)), ncol = 2))
colnames(Qobs2) <- c(colnames(Qobs2)[1:6], "R1", "R2")
InputsModel <- CreateInputsModel(griwrm2, DatesR, Precip, PotEvap, Qobs2)
sv <- CreateSupervisor(InputsModel) sv <- CreateSupervisor(InputsModel)
# Function to withdraw half of the measured flow # Function to withdraw half of the measured flow
fWithdrawal <- function(y) { -y/2 } fWithdrawal <- function(y) { -y/2 }
# Function to release half of the the measured flow # Function to release half of the the measured flow
fRelease <- function(y) { y/2 } fRelease <- function(y) { y/2 }
# Controller that withdraw half of the flow measured at node "54002" at location "R1" # Controller that withdraw half of the flow measured at node "54002" at location "R1"
createController(sv, "Withdrawal", Y = c("54002"), U = c("R1"), FUN = fWithdrawal) CreateController(sv, "Withdrawal", Y = c("54002"), U = c("R1"), FUN = fWithdrawal)
# Controller that release half of the flow measured at node "54002" at location "R2" # Controller that release half of the flow measured at node "54002" at location "R2"
createController(sv, "Release", Y = c("54002"), U = c("R2"), FUN = fRelease) CreateController(sv, "Release", Y = c("54002"), U = c("R2"), FUN = fRelease)
OM_Supervisor <- RunModel( OM_Supervisor <- RunModel(
sv, sv,
RunOptions = RunOptions, RunOptions = RunOptions,
...@@ -81,3 +84,16 @@ test_that("RunModelSupervisor with two regulations that cancel each other out sh ...@@ -81,3 +84,16 @@ test_that("RunModelSupervisor with two regulations that cancel each other out sh
expect_equal(OM_Supervisor[["54057"]]$Qsim, OM_GriwrmInputs[["54057"]]$Qsim) expect_equal(OM_Supervisor[["54057"]]$Qsim, OM_GriwrmInputs[["54057"]]$Qsim)
}) })
test_that("RunModelSupervisor with multi time steps controller, two regulations in 1 centralised controller that cancel each other out should returns same results as RunModel.GRiwrmInputsModel", {
sv <- CreateSupervisor(InputsModel, TimeStep = 10L)
fEverything <- function(y) {
matrix(c(y[,1]/2, -y[,1]/2), ncol = 2)
}
CreateController(sv, "Everything", Y = c("54002", "54032"), U = c("R1", "R2"), FUN = fEverything)
OM_Supervisor <- RunModel(
sv,
RunOptions = RunOptions,
Param = Param
)
expect_equal(OM_Supervisor[["54057"]]$Qsim, OM_GriwrmInputs[["54057"]]$Qsim)
})
...@@ -16,7 +16,7 @@ knitr::opts_chunk$set(echo = TRUE) ...@@ -16,7 +16,7 @@ knitr::opts_chunk$set(echo = TRUE)
library(airGRiwrm) library(airGRiwrm)
``` ```
The package **airGRiwrm** is a modeling tool for integrated water resource management based on the package **airGR** package [See @coron_airgr_2020]. The package **airGRiwrm** is a modeling tool for integrated water resource management based on the package **airGR** package [See @coronSuiteLumpedGR2017].
In a semi-distributive model, the catchment is divided into several sub-catchments. Each sub-catchment is an hydrological entity where a runfall-runoff model produces a flow time series at the outlet of the sub-catchment. Then a hydraulic link is set between sub-catchment outlets to model the flow at the outlet of the whole catchment. The aim of **airGRiwrm** is to organise the structure and schedule the execution of the hydrological and hydraulic sub-models contained in the semi-distributive model. In a semi-distributive model, the catchment is divided into several sub-catchments. Each sub-catchment is an hydrological entity where a runfall-runoff model produces a flow time series at the outlet of the sub-catchment. Then a hydraulic link is set between sub-catchment outlets to model the flow at the outlet of the whole catchment. The aim of **airGRiwrm** is to organise the structure and schedule the execution of the hydrological and hydraulic sub-models contained in the semi-distributive model.
...@@ -24,7 +24,7 @@ In this vignette, we show how to prepare observation data for the model. ...@@ -24,7 +24,7 @@ In this vignette, we show how to prepare observation data for the model.
## Description of the example used in this tutorial ## Description of the example used in this tutorial
The example of this tutorial takes place on the Severn River in United Kingdom. The data set comes from the CAMEL GB database [See @coxon_catchment_2020]. The example of this tutorial takes place on the Severn River in United Kingdom. The data set comes from the CAMEL GB database [See @coxonCatchmentAttributesHydrometeorological2020].
```{r} ```{r}
data(Severn) data(Severn)
......
...@@ -23,7 +23,7 @@ library(airGRiwrm) ...@@ -23,7 +23,7 @@ library(airGRiwrm)
We can see in vignette 'V02_Calibration_SD_model' that calibration result for the flow simulated on the Avon at Evesham (Gauging station '54002') and on the Severn at Buildwas (Gauging station '54095') is not satisfactory. These upper basins are heavily influenced by impoundments and inter-basin transfers [@higgs_hydrological_1988]. We can see in vignette 'V02_Calibration_SD_model' that calibration result for the flow simulated on the Avon at Evesham (Gauging station '54002') and on the Severn at Buildwas (Gauging station '54095') is not satisfactory. These upper basins are heavily influenced by impoundments and inter-basin transfers [@higgsHydrologicalChangesRiver1988].
To cope with this influenced flow, we won't try to simulate it with a hydrological model and we will directly inject in the model the observed flow at these nodes. To cope with this influenced flow, we won't try to simulate it with a hydrological model and we will directly inject in the model the observed flow at these nodes.
...@@ -42,10 +42,10 @@ load("_cache/V01.RData") ...@@ -42,10 +42,10 @@ load("_cache/V01.RData")
To notify the SD model that the provided flow on a node should be directly used instead of an hydrological model, you only need to declare its model as `NA`: To notify the SD model that the provided flow on a node should be directly used instead of an hydrological model, you only need to declare its model as `NA`:
```{r} ```{r}
griwrm_OL <- griwrm griwrmV03 <- griwrm
griwrm_OL$model[griwrm$id == "54002"] <- NA griwrmV03$model[griwrm$id == "54002"] <- NA
griwrm_OL$model[griwrm$id == "54095"] <- NA griwrmV03$model[griwrm$id == "54095"] <- NA
griwrm_OL griwrmV03
``` ```
Here, we keep the area of this basin which means that the discharge will be provided in mm per time step. If the discharge is provided in m<sup>3</sup>/s, then the area should be set to `NA` and downstream basin areas should be modified subsequently. Here, we keep the area of this basin which means that the discharge will be provided in mm per time step. If the discharge is provided in m<sup>3</sup>/s, then the area should be set to `NA` and downstream basin areas should be modified subsequently.
...@@ -57,7 +57,7 @@ The diagram of the network structure is represented below with: ...@@ -57,7 +57,7 @@ The diagram of the network structure is represented below with:
* in red the node with direct flow injection (no hydrological model) * in red the node with direct flow injection (no hydrological model)
```{r diagram} ```{r diagram}
DiagramGRiwrm(griwrm_OL) DiagramGRiwrm(griwrmV03)
``` ```
### Generate the GRiwrmInputsModel object ### Generate the GRiwrmInputsModel object
...@@ -66,7 +66,7 @@ Since the network description has changed, the `GRiwrmInputsModel` should be gen ...@@ -66,7 +66,7 @@ Since the network description has changed, the `GRiwrmInputsModel` should be gen
```{r} ```{r}
load("_cache/V01b.RData") load("_cache/V01b.RData")
IM_OL <- CreateInputsModel(griwrm_OL, DatesR, Precip, PotEvap, Qobs) IM_OL <- CreateInputsModel(griwrmV03, DatesR, Precip, PotEvap, Qobs)
``` ```
## Calibration of the new model ## Calibration of the new model
...@@ -82,16 +82,21 @@ The **airGR** calibration process is applied on each hydrological node of the `G ...@@ -82,16 +82,21 @@ The **airGR** calibration process is applied on each hydrological node of the `G
```{r Calibration} ```{r Calibration}
OC_OL <- suppressWarnings( OC_OL <- suppressWarnings(
Calibration(IM_OL, RunOptions, InputsCrit, CalibOptions)) Calibration(IM_OL, RunOptions, InputsCrit, CalibOptions))
Param_OL <- sapply(griwrm$id, function(x) {OC_OL[[x]]$Param}) ParamV03 <- sapply(griwrm$id, function(x) {OC_OL[[x]]$Param})
``` ```
```{r}
save(griwrmV03, ParamV03, file = "_cache/V03.RData")
```
## Run model with this newly calibrated parameters ## Run model with this newly calibrated parameters
```{r RunModel} ```{r RunModel}
OM_OL <- RunModel( OM_OL <- RunModel(
IM_OL, IM_OL,
RunOptions = RunOptions, RunOptions = RunOptions,
Param = Param_OL Param = ParamV03
) )
``` ```
......
This diff is collapsed.
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