traitecoevo / plant

Trait-Driven Models of Ecology and Evolution :evergreen_tree:
https://traitecoevo.github.io/plant
53 stars 20 forks source link

FF16w drawdown through evapotranspiration #328

Closed aornugent closed 2 years ago

aornugent commented 2 years ago

This attempts to provide some measure of cohort impact on shared, extractable resources that are represented as state variables in the environment. It's clunky ~and doesn't yet work~ - I can already see a few ways to improve the general approach, but posting it here for review in case there is a more streamlined approach that absolves the need for clunky-ness all together.

In short; we expose a strategy specific consumption method that is called from the patch during compute rates to provide the integrated impact of all cohorts for a given species across all resource pools (e.g. soil layers). The consumption totals are then passed into environment the rate of change is updated to reflect the impact of all species on a given resource pool.

aornugent commented 2 years ago

A smattering of print statements led me to the observation that water_exfiltration is negative, but I'm not sure why.

p0 <- scm_base_parameters("FF16w")
p1 <- expand_parameters(trait_matrix(0.0825, "lma"), p0, FF16w_hyperpar,FALSE)
env <- make_environment("FF16w")
ctrl <- scm_base_control()

out <- run_scm(p1, env, ctrl)
out$patch$environment$soil$states
devmitch commented 2 years ago

water_exfiltration was negative as the order of heights in the cohort vector is descending, and thus were being added to the vector of x-coordinates for trapezium integration in descending order - trapezium integration requires ascending order:

double trapezium(const ContainerX& x, const ContainerY& y) {
  // ...
  // x1 is ahead of x0, so if descending order ie x0 > x1, then x1 - x0 < 0 => negative result
  while (x1 != x.end()) {
    tot += (*x1++ - *x0++) * (*y1++ + *y0++);
  }
  return tot * 0.5;
}

Adding them in ascending order yields a positive result:

for(auto it = cohorts.rbegin(); it != cohorts.rend(); ++it) {
  heights.push_back(it->height());
  consumption.push_back(it->compute_consumption(i));
}

This may be pointing towards a need for an extra check in util::trapezium for ascending x-coordinates, similar to how the check is done in Interpolator::initialise(). If we are using the same check in multiple places it may be better to offload the function to util - for example, util::check_ascending()

if (not std::is_sorted(x.begin(), x.end(), std::less_equal<double>())) {
  util::stop("spline control points must be unique and in ascending order");
}
aornugent commented 2 years ago

Closing in favour of #329