Implementation
implementation
This page overviews the numerical methods used in plant and serves as the index for the Implementation section, linking out to detailed pages for each method.
Characteristic method
System of ODEs, IVPs.
See more detail in the characteristic method.
ODE stepping
See more detail in ODE stepping and control.
Adaptive node spacing
See more details in the node spacing algorithm.
TK splines
Gauss-Kronrod quadrature
To numerically integrate functions, we use the Gauss-Kronrod quadrature method. This is implemented in the QK and QAG classes.
- General background on the method is available at: https://en.wikipedia.org/wiki/Gaussian_quadrature
- The
QKclass is used to numerically integrate functions using Gauss-Kronrod quadrature.- The number of points used when numerically integrating the function is defined by the control variable
function_integration_rule. The integration has several “rules”, including QK15, QK21, QK31, QK41, QK51, defined inqk_rules.cpp. These determine the numbers of points in the integration. The default number of points is 21. - The
QKcode was ported from GSL by Rich FitzJohn.
- The number of points used when numerically integrating the function is defined by the control variable
- The
QAGclass uses theQKclass, for adaptive integration using Gauss-Kronrod quadrature. In the adaptive method, the difference between a Gauss quadrature rule and its Kronrod extension is used as an estimate of the approximation error, from which the need for more points is determined.- The QAG routine is adapted from the “QAG” algorithm in QUADPACK.
- The
QAGclass calls classQK, which does the actual integration.
Numerical derivatives
node introduction
Trapezium integration
trapezium(xx, yy).
Pre-compute step
Approximating the light environment with a spline
Creating the light environment
The patch calls compute_environment,
- which calls
environment.compute_environment(f, height_max()), wheref = compute_competitioncompute_competitionpasses through species- in species,
compute_competitionintegrates density over nodes- in node,
compute_competition = density * individual.compute_competition(height_);- individual passes straight through to strategy
- strategy calculates fraction of
leaf above = k_I * area_leaf(height) * Q(z, height);
- strategy calculates fraction of
- individual passes straight through to strategy
- in node,
- in species,
environment.compute_environmentcreates a spline of light availability, as a function of height- to do this, it uses the
ResourceSplineclass.ResourceSplineclass uses an adaptive routine to sample across the height range to approximate the function- the function is ultimately approximated with a spline, using the
tkclass
- the function is ultimately approximated with a spline, using the
- creating the spline is achieved through calls to
compute_competition, as described above
- to do this, it uses the
For more on light environments, see canopy models.
Using the light environment
- In
compute_rates, environment gets passed from Patch -> Species -> Node -> Individual -> Strategy- FF16_strategy
net_mass_production_dtcallsassimilation- assimilation uses the object
quadrature::QK function_integratorto integrate the functionassimilation_leaf(environment.get_environment_at_height(z)) * q(z, height)over z, where z is depth in the plant. The function is integrated using Gauss-Kronrod quadrature. The number of points used when numerically integrating the function is defined by the argumentfunction_integration_rule(see above), the default number of points is 21.- Previously, we used the QAG (instead of QK) class, to enable adaptive integration of the function. The QAG class uses QK, but includes an extra layer to refine the number of points. However, this is slower and isn’t noticeably changing the results. The adaptive routine may take twice as long.
- assimilation uses the object
- FF16_strategy