Nothing
library(tinytest)
###########################################
# Bare Soil Water Balance Model Test Example
###########################################
# Rain and ETo forcings derived from NASA POWER data for 2020-09-01 to 2021-08-31
ETo <- c(9.4974498, 8.7488478, 14.3757234, 13.76894025, 14.2566156,
14.5291725, 13.872384, 10.5480225, 2.6586549, 4.2959646, 3.928311,
9.4031928, 10.87665165, 7.941888, 9.0801999, 11.550276, 10.3571325,
8.60881095, 9.270612, 9.5191524, 10.3721472, 3.0451869, 6.2345052,
10.6671384, 10.3474665, 10.9330722, 2.29770405, 9.2637, 8.93646,
10.5232203, 9.520038, 8.866773, 6.3407799, 8.3558952, 9.2137824,
8.3862243, 9.6835743, 9.418032, 7.3353843, 7.18265475, 10.1679057,
9.2375397, 9.2385414, 9.4345182, 7.3101555, 7.0712946, 8.02905075,
1.3342644, 2.00933055, 2.32925895, 6.314679, 8.9583975, 2.46699945,
2.4019254, 1.5285348, 0.5253255, 0.5941188, 0.578664, 4.314141,
5.5606041, 5.739552, 6.0035985, 5.27877405, 6.61921875, 5.08605075,
6.3830025, 6.3343215, 6.380451, 5.24585025, 3.7125297, 4.71982275,
4.9949865, 5.153085, 3.2174415, 4.36689225, 5.2881012, 5.3133975,
5.413716, 5.438637, 5.849496, 3.87735255, 1.06374465, 2.5337232,
2.5450443, 0.588033, 3.76529445, 4.1406174, 4.05330345, 2.4521103,
1.5598791, 3.2430672, 3.5451108, 0.51533415, 0.85169475, 3.2351022,
3.3356502, 3.488751, 3.558762, 3.8234268, 4.1745375, 4.2744753,
1.8696906, 1.40797035, 0.6775191, 2.2370904, 0.64118655, 1.29448935,
2.8501875, 2.9580714, 3.396222, 3.4659495, 3.5732745, 3.7638216,
3.60229545, 2.0335536, 2.906064, 3.8495709, 3.8478564, 1.642113,
1.06731, 1.3578084, 1.248912, 0.897777, 1.4824269, 2.5912197,
3.3654258, 3.3797547, 0.77362425, 0.8013168, 1.5080904, 2.4696711,
1.7364375, 3.15141435, 3.26806515, 3.379644, 3.6391761, 1.7243928,
2.89603755, 3.7200681, 2.0856528, 2.19607875, 1.432809, 2.3390694,
3.9650796, 2.0590308, 1.17585, 1.27413, 0.97548165, 1.5540525,
3.07725075, 3.1432401, 2.1549969, 2.22507, 3.751839, 4.7844513,
4.8935124, 4.28141025, 4.0134042, 1.3414302, 0.821205, 0.71772075,
0.591273, 0.649512, 0.661581, 0.8499087, 1.682694, 0.3191346,
0.3645972, 0.7452, 1.7549136, 2.7069984, 3.4281225, 4.41663435,
4.1763384, 6.12888255, 7.0395885, 6.37117245, 4.50289125, 2.1120075,
4.3775721, 3.9670452, 6.32784285, 6.9159285, 5.9859486, 7.51829175,
3.46518, 6.9812685, 7.8985179, 7.7438025, 7.37933085, 8.5621536,
2.5750332, 1.9699875, 3.4180272, 5.23375425, 8.1117504, 7.0178724,
2.0018502, 3.9236886, 8.01595575, 8.6635359, 8.4498417, 2.2010103,
2.9370816, 5.8949748, 3.5130132, 9.7547085, 8.6699808, 9.7684542,
11.1700539, 8.3928474, 8.83218735, 9.3686544, 9.147114, 10.8554985,
11.13912, 10.8806571, 5.6310876, 5.3757594, 11.8212507, 5.8080861,
8.6037066, 11.5956441, 7.5685077, 8.9971479, 6.06620475, 4.7986992,
2.3699871, 4.509189, 8.7417063, 11.537883, 4.70000475, 8.9617725,
5.3824176, 3.863403, 10.4963148, 13.14301275, 10.4765859, 5.29308,
5.62197375, 11.024964, 14.46786495, 7.8588387, 5.8285548, 8.0631774,
8.3391363, 11.56248, 13.57763175, 10.9188135, 13.6791828, 7.1709975,
7.6381191, 3.5690868, 9.5276412, 13.21624215, 10.7424009, 8.4150927,
5.3104329, 8.8988328, 6.9227784, 5.3697573, 3.6170118, 8.34337395,
5.9805135, 4.7754252, 5.20040925, 7.07090715, 11.8728315, 3.95082765,
12.974094, 12.089493, 8.588349, 2.6772768, 5.29195005, 8.4237165,
14.08645485, 15.3659916, 11.9078208, 10.647774, 10.6170318, 12.9541734,
13.1839245, 16.69537575, 14.05755, 16.0327512, 16.9199685, 18.3867138,
18.592119, 18.4959558, 18.0592632, 18.32748525, 17.8471755, 18.078309,
9.4400208, 16.9857621, 15.8388048, 17.215335, 15.9527394, 11.0113938,
7.0428501, 6.15845835, 8.4061989, 9.7281675, 5.217534, 13.6407456,
16.0090371, 14.60971485, 16.3940112, 16.0579746, 11.2431564,
17.4784176, 16.357221, 11.66319, 11.3187942, 16.0283826, 16.6098357,
15.93108, 9.8532315, 13.8172797, 12.1522356, 11.40831, 15.1159338,
13.5246456, 13.3892946, 14.599305, 16.5191508, 17.44472565, 15.18477435,
13.5944055, 16.8596802, 17.15459715, 17.34196095, 16.8826599,
16.8710985, 10.92615075, 13.3638417, 14.060196, 13.50351405,
8.33555475, 14.73787845, 15.6401658, 11.214801, 15.7549293, 17.0717544,
14.6874546, 16.024635, 9.2452725, 13.5340308, 13.7106594, 11.13837885,
11.9559726, 12.5817624, 8.625528, 12.996126, 11.725938, 15.04051875,
16.8381504, 16.6380723, 16.7152302, 16.2983259, 15.4354059, 14.85610875,
13.3843833, 13.051233, 14.4270504)
rain <- c(16.92, 5.77, 0.14, 0, 0, 0, 0, 9.47, 25.85, 4.45, 5.1, 0.04,
0.01, 0, 0, 0.01, 0, 0, 0.03, 0, 0.13, 13.81, 0.1, 0, 0.02, 0,
3.9, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0.05, 0, 0, 0.1, 0.07, 0,
0, 0, 0, 0, 0, 0.48, 0.05, 0.04, 0, 0.11, 0.43, 0, 0.82, 36.84,
20.46, 18.02, 9.89, 0, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.45,
0, 0, 0.44, 0.83, 0, 0, 0, 0, 0, 0, 3.73, 3.35, 0.04, 16.91,
0.09, 0, 0, 0.09, 1.41, 0, 0.01, 10.71, 0.57, 0, 0.11, 0.04,
0, 0.02, 0, 0, 1.06, 0, 8.67, 0.85, 1.1, 1.11, 2.87, 0.38, 0.11,
0, 0, 0, 0, 0, 0, 0, 0, 0.02, 17.81, 16.04, 11.63, 11.86, 2.24,
2.11, 0, 0.02, 5, 0.49, 0.01, 0, 0.04, 0, 0.01, 0.01, 0, 0, 0,
0, 0, 0, 0.06, 0.19, 0, 0, 0.99, 26.16, 0, 0.01, 0, 0.18, 11.23,
0.01, 0.26, 0, 0, 0, 0, 0.66, 0.09, 0.64, 0, 0.02, 0, 0, 0.06,
1.36, 0.02, 0.95, 1.39, 0.01, 0, 0, 0, 0, 0, 0, 0.8, 0.06, 0.27,
0.08, 0, 0, 0, 2.42, 5.36, 0, 0, 0, 0, 0.07, 0.59, 7.39, 5.01,
6.91, 0, 0.49, 15.62, 0.01, 0, 0, 0, 32.69, 0.84, 2.04, 0.42,
0, 0, 0, 0, 0, 0, 0, 0.01, 0, 0, 0, 0.03, 0.06, 0, 7.59, 0, 0,
0.16, 9.8, 10.45, 1.66, 10.9, 0.01, 0, 0, 0.03, 0, 0.49, 18.17,
14.16, 0, 0, 6.51, 16.31, 0.04, 0, 0, 0, 12.05, 4.98, 0.76, 0,
0.04, 0.1, 0.05, 0.36, 9.3, 0.06, 0, 0.08, 0.26, 15.98, 1.67,
3.46, 4.99, 9, 3.34, 1.8, 2.88, 9.91, 1.49, 0.1, 30.48, 0, 0.01,
0.31, 20.17, 0.71, 0.72, 0, 0, 0.45, 1.97, 6.86, 7.49, 0, 0,
15.75, 4.15, 0.29, 0, 0, 0, 0, 0, 0, 0.67, 7.23, 0, 0.01, 0,
23.02, 59.37, 30.18, 23.39, 16.31, 3.3, 22.27, 3.07, 0.01, 0,
0, 0, 2.68, 0.62, 0.04, 19.24, 1.16, 0, 0, 0, 0.09, 1.02, 1.6,
0.72, 0.04, 0, 0, 0, 0.12, 0.55, 0.41, 9.11, 2.68, 0.01, 0, 0,
2.79, 10.57, 0.03, 0, 0, 1.78, 0.16, 3.73, 7.04, 0.1, 0.08, 0.03,
0, 6.78, 2.05, 0.23, 3.26, 0.74, 1.39, 1.23, 1.91, 14.31, 1.34,
0.04, 0, 0, 0.01, 0, 0, 0.03, 1.95, 0.07)
time <- (1:length(ETo)) - 1
wth <-
matrix(c(
time,
ETo,
rain),
byrow = FALSE,
ncol = 3)
colnames(wth) <- c("time", "ETo", "P")
# Generate soil input data
profile_depth_mm <- 100
soil <-
c(# soil water at field capacity
sw_fc = 0.36*profile_depth_mm,
# soil water at permanent wilting point
sw_pwp = 0.22*profile_depth_mm,
# soil water at limit of readily extractable water
sw_rew = (0.36 + 0.22*3)/4*profile_depth_mm,
# soil water at limit of total extractable water
sw_tew = 0.22/2*profile_depth_mm)
# Initial conditions
state <- c(sw = unname(soil[1]))
# parameters
parameters <-
c(Ke = 0.15)
# Rate equation function
dsw_dt <- function(t, state, parms, wth, soil){
with(as.list(c(state, parms)), {
ETo_t <- csmbuilder::csm_get_at_t(wth[, "ETo"], wth[, "time"], t, "linear")
P_t <- csmbuilder::csm_get_at_t(wth[, "P"], wth[, "time"], t, "linear")
fi <- 1 - 1/(1+exp(-log(99)/(soil["sw_fc"] - (soil["sw_fc"]*3 + soil["sw_pwp"])/4)*(sw - (soil["sw_fc"]*7/8+soil["sw_pwp"]/8))))
fe <- 1/(1+exp(-log(99)/(soil["sw_rew"] - soil["sw_tew"])*(sw - soil["sw_rew"])))
list(
unname(P_t*fi-ETo_t*Ke*fe)
)
})
}
# Check dsw_dt()
expect_equal(
dsw_dt(0,
state = state,
parms = parameters,
wth = wth,
soil = soil),
with(as.list(parameters), {
fi <- unname(1 - 1/(1+exp(-log(99)/(soil["sw_fc"] - (soil["sw_fc"]*3 + soil["sw_pwp"])/4)*(state["sw"] - (soil["sw_fc"]*7/8+soil["sw_pwp"]/8)))))
fe <- unname(1/(1+exp(-log(99)/(soil["sw_rew"] - soil["sw_tew"])*(state["sw"] - soil["sw_rew"]))))
list(
unname(wth[1,"P"]*fi-wth[1,"ETo"]*Ke*fe)
)
}),
info = "dsw_dt(); t=0"
)
# Specify times at which to report output
times <- csmbuilder::csm_time_vector(0, nrow(wth)-1, dt = 0.01)
# Create list of integration methods to test:
integ_list <- c("euler", "rk4")
# Run integration
sw_ref_out <-
integ_list |>
(\(.x) setNames(.x, .x))() |>
lapply(\(.method){
deSolve::ode(
y = state,
times = times,
func = dsw_dt,
parms = parameters,
method = .method,
wth = wth,
soil = soil
)
})
##########################################################
# Create Simple Soil Water Balance Model with csmbuilder
##########################################################
# Define state variables
sw_state <- csmbuilder::csm_create_state(
"sw",
definition = "soil water",
units = "mm",
expression(~P_t*fi-ETo_t*Ke*fe))
# Define parameters
sw_parameters <- csmbuilder::csm_create_parameter(
"Ke",
definition = "soil evaporation coefficient",
units = "unitless")
# Define soil inputs
sw_soil_vars <- c(
csmbuilder::csm_create_variable(
"sw_fc",
definition = "soil water at field capacity",
units = "mm"),
csmbuilder::csm_create_variable(
"sw_pwp",
definition = "soil water at permanent wilting point",
units = "mm"),
csmbuilder::csm_create_variable(
"sw_rew",
definition = "soil water at limit of readily extractable water",
units = "mm"),
csmbuilder::csm_create_variable(
"sw_tew",
definition = "soil water at limit of total extractable water",
units = "mm")
)
# Define weather variables
sw_wth_vars <- c(
csmbuilder::csm_create_variable(
"wtime",
definition = "time of observation",
units = "days after planting"),
csmbuilder::csm_create_variable(
"ETo",
definition = "reference evapotranspiration",
units = "mm"),
csmbuilder::csm_create_variable(
"P",
definition = "precipitation",
units = "mm")
)
# Define input data structures
sw_inputs <- c(
csmbuilder::csm_create_data_structure(
"soil_data",
definition = "soil data",
variables = sw_soil_vars
),
csmbuilder::csm_create_data_structure(
"wth_data",
definition = "weather data",
variables = sw_wth_vars,
n_dim = 2
)
)
sw_wth_t <- c(
csmbuilder::csm_create_transform(
"ETo_t",
definition = "reference evapotranspiration at t",
units = "mm",
equation = ~csm_get_at_t(ETo, wtime, t, "linear")),
csmbuilder::csm_create_transform(
"P_t",
definition = "precipitation at t",
units = "mm",
equation = ~csm_get_at_t(P, wtime, t, "linear"))
)
# Define intermediate factors
sw_factors <- c(
csmbuilder::csm_create_transform(
"fi",
definition = "infiltration factor",
units = "unitless",
equation = ~1 - 1/(1+exp(-log(99)/(sw_fc - (sw_fc*3 + sw_pwp)/4)*(sw - (sw_fc*7/8+sw_pwp/8))))),
csmbuilder::csm_create_transform(
"fe",
definition = "evaporation factor",
units = "unitless",
equation = ~1/(1+exp(-log(99)/(sw_rew - sw_tew)*(sw - sw_rew))))
)
# Create model object
sw_model <-
csmbuilder::csm_create_model(sw_state,
sw_parameters,
sw_factors,
sw_inputs,
sw_wth_t)
# Create function for calculating rates
sw_dydt <-
csmbuilder::csm_render_model(
name = "sw",
model = sw_model,
arg_alias = c(state_variables = "state",
soil_data = "soil",
wth_data = "wth"),
output_type = "function",
language = "R")
# Run integration
sw_dydt_out <-
integ_list |>
(\(.x) setNames(.x, .x))() |>
lapply(\(.method){
csmbuilder::csm_run_sim(
model_function = sw_dydt,
y_init = state,
t = times,
parms = parameters,
wth = wth,
soil = soil,
method = .method
)
})
for(integ_method in integ_list){
expect_equal(
current = sw_dydt_out[[integ_method]],
target = sw_ref_out[[integ_method]],
info = integ_method
)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.