Skip to content

Commit

Permalink
Vectorization of snow model; snow related SGS fix
Browse files Browse the repository at this point in the history
  • Loading branch information
kuadrat committed Aug 21, 2024
1 parent ad04bf6 commit 5eec56f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 22 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: growR
Type: Package
Version: 1.3.0.9004
Version: 1.3.0.9005
Date: 2024-05-23
Authors@R: person(
given = "Kevin",
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
* autocut accepts 'medium' as alias for 'middle' and applies a single cut
according to phenology.
* Performance improvements to ModvegeSite$un() in the order of 25%.
* Small performance improvement of `WeatherData` initialization through
vectorization of snow model.

## Fixed

* `ModvegeParameters$set_parameters()` can now handle empty lists.
* Fix in determination of start of growing season for cases with no snow in
first half-year.

## Removed

Expand Down
8 changes: 5 additions & 3 deletions R/modvegesite.R
Original file line number Diff line number Diff line change
Expand Up @@ -665,11 +665,13 @@ ModvegeSite = R6Class(
W = self$get_weather()
# Find the last day of the first half of the year that still had snow
# cover. Assume that growth can only start after that day.
j_snow = 1
if (consider_snow) {
# Go one day beyond the last day with too much snow
j_snow = max(which(W[["snow"]][1:180] > critical_snow)) + 1
} else {
j_snow = 1
snow_days = which(W[["snow"]][1:180] > critical_snow)
if (length(snow_days) > 0) {
j_snow = max(snow_days) + 1
}
}

if (private$SGS_method == "MTD") {
Expand Down
37 changes: 19 additions & 18 deletions R/weather.R
Original file line number Diff line number Diff line change
Expand Up @@ -157,27 +157,28 @@ WeatherData = R6Class(
liquidP_vec = (1./(1. + exp(-1.5*(Ta_vec - 2.)))) * PP_vec
solidP_vec = PP_vec - liquidP_vec

melt_vec = numeric(vec_size)
freeze_vec = numeric(vec_size)
snow_vec = numeric(vec_size)
melt_vec[1] = 0.
freeze_vec[1] = 0.
snow_vec[1] = 0.
# Calculate as much as possible vectorially.
dT_melt = Ta_vec - T_melt
T_above_melting = dT_melt >= 0
freeze_vec = pmin(liquidP_vec, -C_freeze*dT_melt)
freeze_vec[T_above_melting] = 0
melt0 = C_melt * dT_melt
dsnow0 = solidP_vec + freeze_vec

snow_vec = numeric(vec_size)
melt_vec = numeric(vec_size)
snow_vec[1] = 0.
melt_vec[1] = 0.
for (j in 2:vec_size) {
# :TODO: Is time_step needed here?
time_step = 1
melt_vec[j] = ifelse(snow_vec[j - 1] > 0. & Ta_vec[j] >= T_melt,
min(snow_vec[j - 1]/time_step,
C_melt * (Ta_vec[j] - T_melt)),
0.)
freeze_vec[j] = ifelse(Ta_vec[j] < T_melt,
min(liquidP_vec[j],
C_freeze * (T_melt - Ta_vec[j])),
0.)
dsnow_dt = solidP_vec[j] + freeze_vec[j] - melt_vec[j]
snow_vec[j] = max(0., snow_vec[j - 1] + dsnow_dt * time_step)
if (snow_vec[j-1] > 0. & T_above_melting[j]) {
melt_vec[j] = min(snow_vec[j-1], melt0[j])
} else {
melt_vec[j] = 0
}
dsnow = dsnow0[j] - melt_vec[j]
snow_vec[j] = snow_vec[j-1] + dsnow
}

self[["liquidP_vec"]] = liquidP_vec
self[["melt_vec"]] = melt_vec
self[["snow_vec"]] = snow_vec
Expand Down

0 comments on commit 5eec56f

Please sign in to comment.