The BioCro C++ Library
thermal_time_senescence.h
Go to the documentation of this file.
1#ifndef THERMAL_TIME_SENESCENCE_H
2#define THERMAL_TIME_SENESCENCE_H
3
4#include "../framework/module.h"
5#include "../framework/state_map.h"
6
7namespace standardBML
8{
91class thermal_time_senescence : public differential_module
92{
93 public:
95 state_map const& input_quantities,
96 state_map* output_quantities)
97 : // Indicate that this module requires a fixed step size Euler ODE solver
98 differential_module(true),
99
100 // Get pointers to input quantities
101 TTc{get_input(input_quantities, "TTc")},
102 seneLeaf{get_input(input_quantities, "seneLeaf")},
103 seneStem{get_input(input_quantities, "seneStem")},
104 seneRoot{get_input(input_quantities, "seneRoot")},
105 seneRhizome{get_input(input_quantities, "seneRhizome")},
106 leaf_senescence_index{get_input(input_quantities, "leaf_senescence_index")},
107 stem_senescence_index{get_input(input_quantities, "stem_senescence_index")},
108 root_senescence_index{get_input(input_quantities, "root_senescence_index")},
109 rhizome_senescence_index{get_input(input_quantities, "rhizome_senescence_index")},
110 kStem{get_input(input_quantities, "kStem")},
111 kRoot{get_input(input_quantities, "kRoot")},
112 kRhizome{get_input(input_quantities, "kRhizome")},
113 kGrain{get_input(input_quantities, "kGrain")},
114 remobilization_fraction{get_input(input_quantities, "remobilization_fraction")},
115 net_assimilation_rate_leaf{get_input(input_quantities, "net_assimilation_rate_leaf")},
116 net_assimilation_rate_stem{get_input(input_quantities, "net_assimilation_rate_stem")},
117 net_assimilation_rate_root{get_input(input_quantities, "net_assimilation_rate_root")},
118 net_assimilation_rate_rhizome{get_input(input_quantities, "net_assimilation_rate_rhizome")},
119
120 // Get pointers to output quantities
121 Leaf_op{get_op(output_quantities, "Leaf")},
122 LeafLitter_op{get_op(output_quantities, "LeafLitter")},
123 leaf_senescence_index_op{get_op(output_quantities, "leaf_senescence_index")},
124 Stem_op{get_op(output_quantities, "Stem")},
125 StemLitter_op{get_op(output_quantities, "StemLitter")},
126 stem_senescence_index_op{get_op(output_quantities, "stem_senescence_index")},
127 Root_op{get_op(output_quantities, "Root")},
128 RootLitter_op{get_op(output_quantities, "RootLitter")},
129 root_senescence_index_op{get_op(output_quantities, "root_senescence_index")},
130 Rhizome_op{get_op(output_quantities, "Rhizome")},
131 RhizomeLitter_op{get_op(output_quantities, "RhizomeLitter")},
132 rhizome_senescence_index_op{get_op(output_quantities, "rhizome_senescence_index")},
133 Grain_op{get_op(output_quantities, "Grain")}
134 {
135 }
136 static string_vector get_inputs();
137 static string_vector get_outputs();
138 static std::string get_name() { return "thermal_time_senescence"; }
139
140 private:
141 // Vectors for storing information about growth history
142 // Note: this feature is peculiar to this module
143 // and should be avoided in general since it
144 // precludes the use of any integration method
145 // except fixed-step Euler
146 std::vector<double> mutable assim_rate_leaf_vec;
147 std::vector<double> mutable assim_rate_stem_vec;
148 std::vector<double> mutable assim_rate_root_vec;
149 std::vector<double> mutable assim_rate_rhizome_vec;
150
151 // Pointers to input quantities
152 double const& TTc;
153 double const& seneLeaf;
154 double const& seneStem;
155 double const& seneRoot;
156 double const& seneRhizome;
157 double const& leaf_senescence_index;
158 double const& stem_senescence_index;
159 double const& root_senescence_index;
160 double const& rhizome_senescence_index;
161 double const& kStem;
162 double const& kRoot;
163 double const& kRhizome;
164 double const& kGrain;
165 const double& remobilization_fraction;
166 double const& net_assimilation_rate_leaf;
167 double const& net_assimilation_rate_stem;
168 double const& net_assimilation_rate_root;
169 double const& net_assimilation_rate_rhizome;
170
171 // Pointers to output quantities
172 double* Leaf_op;
173 double* LeafLitter_op;
174 double* leaf_senescence_index_op;
175 double* Stem_op;
176 double* StemLitter_op;
177 double* stem_senescence_index_op;
178 double* Root_op;
179 double* RootLitter_op;
180 double* root_senescence_index_op;
181 double* Rhizome_op;
182 double* RhizomeLitter_op;
183 double* rhizome_senescence_index_op;
184 double* Grain_op;
185
186 // Main operation
187 void do_operation() const;
188};
189
191{
192 return {
193 "TTc", // degree C * day
194 "seneLeaf", // degree C * day
195 "seneStem", // degree C * day
196 "seneRoot", // degree C * day
197 "seneRhizome", // degree C * day
198 "leaf_senescence_index", // dimensionless
199 "stem_senescence_index", // dimensionless
200 "root_senescence_index", // dimensionless
201 "rhizome_senescence_index", // dimensionless
202 "kStem", // dimensionless
203 "kRoot", // dimensionless
204 "kRhizome", // dimensionless
205 "kGrain", // dimensionless
206 "remobilization_fraction", // dimensionless
207 "net_assimilation_rate_leaf", // Mg / ha / hour
208 "net_assimilation_rate_stem", // Mg / ha / hour
209 "net_assimilation_rate_root", // Mg / ha / hour
210 "net_assimilation_rate_rhizome" // Mg / ha / hour
211 };
212}
213
215{
216 return {
217 "Leaf", // Mg / ha / hour
218 "LeafLitter", // Mg / ha / hour
219 "leaf_senescence_index", // hour^-1
220 "Stem", // Mg / ha / hour
221 "StemLitter", // Mg / ha / hour
222 "stem_senescence_index", // hour^-1
223 "Root", // Mg / ha / hour
224 "RootLitter", // Mg / ha / hour
225 "root_senescence_index", // hour^-1
226 "Rhizome", // Mg / ha / hour
227 "RhizomeLitter", // Mg / ha / hour
228 "rhizome_senescence_index", // hour^-1
229 "Grain" // Mg / ha / hour
230 };
231}
232
233void thermal_time_senescence::do_operation() const
234{
235 // Add the new tissue growth to the history vectors
236 assim_rate_leaf_vec.push_back(net_assimilation_rate_leaf);
237 assim_rate_stem_vec.push_back(net_assimilation_rate_stem);
238 assim_rate_root_vec.push_back(net_assimilation_rate_root);
239 assim_rate_rhizome_vec.push_back(net_assimilation_rate_rhizome);
240
241 // Initialize variables
242 double dLeaf{0.0};
243 double dStem{0.0};
244 double dRoot{0.0};
245 double dRhizome{0.0};
246 double dGrain{0.0};
247 double dLeafLitter{0.0};
248 double dStemLitter{0.0};
249 double dRootLitter{0.0};
250 double dRhizomeLitter{0.0};
251 double dleaf_senescence_index{0.0};
252 double dstem_senescence_index{0.0};
253 double droot_senescence_index{0.0};
254 double drhizome_senescence_index{0.0};
255
256 if (TTc >= seneLeaf) {
257 // Look back in time to find out how much the tissue grew in the past
258 double change = assim_rate_leaf_vec.at(leaf_senescence_index);
259
260 // Subtract the rate of new growth that occurred in the past from the
261 // derivative
262 dLeaf -= change;
263
264 // Remobilize some of the lost tissue and send the rest to the litter
265 dLeafLitter += change * (1.0 - remobilization_fraction);
266 dRhizome += kRhizome * change * remobilization_fraction;
267 dStem += kStem * change * remobilization_fraction;
268 dRoot += kRoot * change * remobilization_fraction;
269 dGrain += kGrain * change * remobilization_fraction;
270
271 // Increment the tissue senescence index
272 dleaf_senescence_index++;
273 }
274
275 if (TTc >= seneStem) {
276 // Look back in time to find out how much the tissue grew in the past
277 double change = assim_rate_stem_vec.at(stem_senescence_index);
278
279 // Subtract the rate of new growth that occurred in the past from the
280 // derivative
281 dStem -= change;
282
283 // Send the lost tissue to the litter
284 dStemLitter += change;
285
286 // Increment the tissue senescence index
287 dstem_senescence_index++;
288 }
289
290 if (TTc >= seneRoot) {
291 // Look back in time to find out how much the tissue grew in the past
292 double change = assim_rate_root_vec.at(root_senescence_index);
293
294 // Subtract the rate of new growth that occurred in the past from the
295 // derivative
296 dRoot -= change;
297
298 // Send the lost tissue to the litter
299 dRootLitter += change;
300
301 // Increment the tissue senescence index
302 droot_senescence_index++;
303 }
304
305 if (kRhizome < 0) {
306 // Increment the rhizome senescence index if it is acting as a source
307 drhizome_senescence_index++;
308 }
309
310 if (TTc >= seneRhizome) {
311 // Look back in time to find out how much the tissue grew in the past
312 double change = assim_rate_rhizome_vec.at(rhizome_senescence_index);
313
314 // Subtract the rate of new growth that occurred in the past from the
315 // derivative
316 dRhizome -= change;
317
318 // Send the lost tissue to the litter
319 dRhizomeLitter += change;
320
321 // Increment the tissue senescence index
322 drhizome_senescence_index++;
323 }
324
325 // Update the output quantity list
326 update(Leaf_op, dLeaf);
327 update(Stem_op, dStem);
328 update(Root_op, dRoot);
329 update(Rhizome_op, dRhizome);
330 update(Grain_op, dGrain);
331
332 update(LeafLitter_op, dLeafLitter);
333 update(StemLitter_op, dStemLitter);
334 update(RootLitter_op, dRootLitter);
335 update(RhizomeLitter_op, dRhizomeLitter);
336
337 update(leaf_senescence_index_op, dleaf_senescence_index);
338 update(stem_senescence_index_op, dstem_senescence_index);
339 update(root_senescence_index_op, droot_senescence_index);
340 update(rhizome_senescence_index_op, drhizome_senescence_index);
341}
342
343} // namespace standardBML
344#endif
Determines senescence rates for several plant organs based on thermal time thresholds and magical tim...
thermal_time_senescence(state_map const &input_quantities, state_map *output_quantities)
This is the standard BioCro module library; it includes the essential modules used in typical BioCro ...
Definition: aba_decay.h:8