The BioCro C++ Library
multilayer_canopy_properties.cpp
Go to the documentation of this file.
1#include <vector>
3#include "BioCro.h" // for WINDprof
4#include "AuxBioCro.h" // for LNprof
5#include "sunML.h" // for sunML
6
9using std::vector;
10
14string_vector multilayer_canopy_properties::get_inputs(int /*nlayers*/)
15{
16 return {
17 "par_incident_direct", // J / (m^2 beam) / s [area perpendicular to beam]
18 "par_incident_diffuse", // J / m^2 / s [through any plane]
19 "lai", // dimensionless from (m^2 leaf) / (m^2 ground). LAI of entire canopy.
20 "cosine_zenith_angle", // dimensionless
21 "k_diffuse", // (m^2 ground) / (m^2 leaf)
22 "chil", // dimensionless from m^2 / m^2
23 "heightf", // m^-1 from (m^2 / m^2) / m. Leaf area density; LAI per height of canopy.
24 "windspeed", // m / s
25 "LeafN", // mmol / m^2 (?)
26 "kpLN", // dimensionless
27 "lnfun", // a dimensionless switch
28 "par_energy_content", // J / micromol
29 "par_energy_fraction", // dimensionless
30 "leaf_transmittance_nir", // dimensionless
31 "leaf_transmittance_par", // dimensionless
32 "leaf_reflectance_nir", // dimensionless
33 "leaf_reflectance_par" // dimensionless
34 };
35}
36
41{
42 return {
43 "sunlit", // these leaves receive diffuse, scattered, and direct solar radiation
44 "shaded" // these leaves receive diffuse and scattered solar radiation
45 };
46}
47
53{
54 return {
55 "incident_ppfd", // micromol / (m^2 leaf) / s
56 "incident_nir", // micromol / (m^2 leaf) / s
57 "absorbed_ppfd", // micromol / (m^2 leaf) / s
58 "absorbed_shortwave", // J / (m^2 leaf) / s
59 "fraction" // dimensionless
60 };
61}
62
68{
69 return {
70 "height", // m
71 "windspeed", // m / s
72 "LeafN", // mmol / m^2 (?)
73 };
74}
75
82{
83 // Add leaf_class prefixes to the multiclass_multilayer outputs
84 string_vector multilayer_outputs = generate_multiclass_quantity_names(
87
88 // Add other multilayer outputs
89 for (std::string const& name : multilayer_canopy_properties::define_pure_multilayer_outputs()) {
90 multilayer_outputs.push_back(name);
91 }
92
93 // Add layer number suffixes to all multilayer outputs
94 multilayer_outputs = generate_multilayer_quantity_names(nlayers, multilayer_outputs);
95
96 // Include outputs that do not depend on leaf class or number of layers.
97 multilayer_outputs.push_back("canopy_direct_transmission_fraction");
98
99 // Return the full list
100 return multilayer_outputs;
101}
102
104{
105 // Calculate values of incident photosynthetically active photon flux
106 // density (PPFD) and absorbed shortwave energy throughout the canopy. Note
107 // that the `sunML` function expects input expects PPFD values, so we must
108 // convert photosynthetically active radiation (PAR) to PPFD using the
109 // energy content of light in the PAR band
110 struct Light_profile light_profile = sunML(
111 par_incident_direct / par_energy_content, // micromol / (m^2 beam) / s
112 par_incident_diffuse / par_energy_content, // micromol / m^2 / s
113 chil,
114 cosine_zenith_angle,
115 heightf,
116 k_diffuse,
117 lai,
118 leaf_reflectance_nir,
119 leaf_reflectance_par,
120 leaf_transmittance_nir,
121 leaf_transmittance_par,
122 par_energy_content,
123 par_energy_fraction,
124 nlayers);
125
126 // Calculate windspeed throughout the canopy
127 vector<double> wind_speed_profile(nlayers);
128 WINDprof(windspeed, lai, wind_speed_profile); // Modifies wind_speed_profile
129
130 // Calculate leaf nitrogen throughout the canopy
131 vector<double> leafN_profile(nlayers);
132 LNprof(LeafN, lai, kpLN, leafN_profile); // Modifies leafN_profile
133
134 // Don't calculate anything based on the nitrogen profile
135 if (lnfun != 0) {
136 throw std::logic_error("Thrown by the multilayer_canopy_properties module: lnfun != 0 is not yet supported.");
137 }
138
139 // Update layer-dependent outputs
140 for (int i = 0; i < nlayers; ++i) {
141 update(sunlit_fraction_ops[i], light_profile.sunlit_fraction[i]);
142 update(sunlit_incident_nir_ops[i], light_profile.sunlit_incident_nir[i]);
143 update(sunlit_incident_ppfd_ops[i], light_profile.sunlit_incident_ppfd[i]);
144 update(sunlit_absorbed_ppfd_ops[i], light_profile.sunlit_absorbed_ppfd[i]);
145 update(sunlit_absorbed_shortwave_ops[i], light_profile.sunlit_absorbed_shortwave[i]);
146
147 update(shaded_fraction_ops[i], light_profile.shaded_fraction[i]);
148 update(shaded_incident_nir_ops[i], light_profile.shaded_incident_nir[i]);
149 update(shaded_incident_ppfd_ops[i], light_profile.shaded_incident_ppfd[i]);
150 update(shaded_absorbed_ppfd_ops[i], light_profile.shaded_absorbed_ppfd[i]);
151 update(shaded_absorbed_shortwave_ops[i], light_profile.shaded_absorbed_shortwave[i]);
152
153 update(height_ops[i], light_profile.height[i]);
154 update(windspeed_ops[i], wind_speed_profile[i]);
155 update(LeafN_ops[i], leafN_profile[i]);
156 }
157
158 // Update other outputs
159 update(canopy_direct_transmission_fraction_op, light_profile.canopy_direct_transmission_fraction);
160}
161
163// TEN LAYER CANOPY PROPERTIES MODULE //
165
166int const ten_layer_canopy_properties::nlayers = 10;
167
169{
170 return multilayer_canopy_properties::get_inputs(ten_layer_canopy_properties::nlayers);
171}
172
174{
176}
177
179{
180 // Just call the parent class's multilayer output function
182}
183
185{
186 // Just call the parent class's multilayer output function
188}
189
191{
192 return multilayer_canopy_properties::get_outputs(ten_layer_canopy_properties::nlayers);
193}
194
195void ten_layer_canopy_properties::do_operation() const
196{
198}
void LNprof(double LeafN, double LAI, double kpLN, vector< double > &leafN_profile)
Definition: AuxBioCro.cpp:184
void WINDprof(double WindSpeed, double LAI, vector< double > &wind_speed_profile)
Wind profile function.
Definition: AuxBioCro.cpp:66
Calculates environmental properties for sunlit and shaded leaves in each layer of a multilayer canopy...
static string_vector define_pure_multilayer_outputs()
Define all outputs that have different values for each layer, not including outputs that also depend ...
static string_vector define_multiclass_multilayer_outputs()
Define all outputs that have different values for each leaf class and layer.
static string_vector get_inputs(int nlayers)
Define all inputs required by the module.
static string_vector get_outputs(int nlayers)
Define all output names by appending leaf class prefixes and layer number suffixes....
static string_vector define_leaf_classes()
Define the different leaf classes included by the module.
A child class of multilayer_canopy_properties where the number of layers has been defined....
double shaded_fraction[MAXLAY]
Definition: sunML.h:11
double sunlit_incident_nir[MAXLAY]
Definition: sunML.h:17
double shaded_incident_nir[MAXLAY]
Definition: sunML.h:12
double sunlit_absorbed_ppfd[MAXLAY]
Definition: sunML.h:14
double sunlit_fraction[MAXLAY]
Definition: sunML.h:16
double shaded_incident_ppfd[MAXLAY]
Definition: sunML.h:13
double height[MAXLAY]
Definition: sunML.h:8
double sunlit_incident_ppfd[MAXLAY]
Definition: sunML.h:18
double shaded_absorbed_shortwave[MAXLAY]
Definition: sunML.h:10
double sunlit_absorbed_shortwave[MAXLAY]
Definition: sunML.h:15
double canopy_direct_transmission_fraction
Definition: sunML.h:7
double shaded_absorbed_ppfd[MAXLAY]
Definition: sunML.h:9
Light_profile sunML(double ambient_ppfd_beam, double ambient_ppfd_diffuse, double chil, double cosine_zenith_angle, double heightf, double k_diffuse, double lai, double leaf_reflectance_nir, double leaf_reflectance_par, double leaf_transmittance_nir, double leaf_transmittance_par, double par_energy_content, double par_energy_fraction, int nlayers)
Computes an n-layered light profile from the direct light, diffuse light, leaf area index,...
Definition: sunML.cpp:408