1#ifndef MULTILAYER_CANOPY_PHOTOSYNTHESIS_H
2#define MULTILAYER_CANOPY_PHOTOSYNTHESIS_H
5#include "../framework/module.h"
6#include "../framework/state_map.h"
15template <
typename leaf_module_type>
18 string_vector leaf_inputs = leaf_module_type::get_inputs();
19 string_vector result_vector;
20 for (std::string
const& name : reference_names) {
21 if (std::find(leaf_inputs.begin(),
23 name) != leaf_inputs.end()) {
24 result_vector.push_back(name);
35template <
typename canopy_module_type,
typename leaf_module_type>
38 return get_leaf_input_subset<leaf_module_type>(
39 canopy_module_type::define_multiclass_multilayer_outputs());
47template <
typename canopy_module_type,
typename leaf_module_type>
50 return get_leaf_input_subset<leaf_module_type>(
51 canopy_module_type::define_pure_multilayer_outputs());
66template <
typename canopy_module_type,
typename leaf_module_type>
69 string_vector layered_canopy_outputs;
71 std::vector<string_vector> quantities_that_change =
72 {canopy_module_type::define_multiclass_multilayer_outputs(),
73 canopy_module_type::define_pure_multilayer_outputs()};
75 for (string_vector
const& sv : quantities_that_change) {
76 for (std::string
const& name : sv) {
77 layered_canopy_outputs.push_back(name);
81 string_vector leaf_inputs_constant_through_canopy;
83 string_vector all_leaf_inputs = leaf_module_type::get_inputs();
85 for (std::string
const& name : all_leaf_inputs) {
86 if (std::find(layered_canopy_outputs.begin(),
87 layered_canopy_outputs.end(),
88 name) == layered_canopy_outputs.end()) {
89 leaf_inputs_constant_through_canopy.push_back(name);
93 return leaf_inputs_constant_through_canopy;
155template <
typename canopy_module_type,
typename leaf_module_type>
161 state_map
const& input_quantities,
162 state_map* output_quantities);
169 state_map leaf_module_quantities;
170 state_map leaf_module_output_map;
171 std::unique_ptr<module> leaf_module;
174 std::vector<std::vector<std::pair<double*, const double*>>> leaf_input_ptr_pairs;
177 std::vector<std::vector<std::pair<double*, const double*>>> leaf_output_ptr_pairs;
190template <
typename canopy_module_type,
typename leaf_module_type>
193 state_map
const& input_quantities,
194 state_map* output_quantities)
199 auto make_quantity_map = [](string_vector input_names, string_vector output_names) -> state_map {
201 for (string_vector
const& sv : {input_names, output_names}) {
202 for (std::string
const& quantity_name : sv) {
203 result[quantity_name] = 0.0;
210 leaf_module_quantities =
212 leaf_module_type::get_inputs(),
213 leaf_module_type::get_outputs());
215 leaf_module_output_map = leaf_module_quantities;
219 std::unique_ptr<module>(
new leaf_module_type(
220 leaf_module_quantities,
221 &leaf_module_output_map));
224 string_vector multiclass_multilayer_leaf_inputs =
225 MLCP::get_multiclass_multilayer_leaf_inputs<canopy_module_type, leaf_module_type>();
227 string_vector multilayer_leaf_inputs =
228 MLCP::get_pure_multilayer_leaf_inputs<canopy_module_type, leaf_module_type>();
230 string_vector other_leaf_inputs =
231 MLCP::get_other_leaf_inputs<canopy_module_type, leaf_module_type>();
235 for (std::string
const& class_name : canopy_module_type::define_leaf_classes()) {
236 for (
int i = 0; i < nlayers; ++i) {
238 std::vector<std::pair<double*, const double*>> input_ptr_pairs;
240 for (std::string
const& name : multiclass_multilayer_leaf_inputs) {
241 std::string specific_name =
242 add_class_prefix_to_quantity_name(
244 add_layer_suffix_to_quantity_name(nlayers, i, name));
246 std::pair<double*, const double*> temporary(
247 get_op(&leaf_module_quantities, name),
248 get_ip(input_quantities, specific_name));
250 input_ptr_pairs.push_back(temporary);
253 for (std::string
const& name : multilayer_leaf_inputs) {
254 std::string specific_name =
255 add_layer_suffix_to_quantity_name(nlayers, i, name);
257 std::pair<double*, const double*> temporary(
258 get_op(&leaf_module_quantities, name),
259 get_ip(input_quantities, specific_name));
261 input_ptr_pairs.push_back(temporary);
264 for (std::string
const& name : other_leaf_inputs) {
265 std::pair<double*, const double*> temporary(
266 get_op(&leaf_module_quantities, name),
267 get_ip(input_quantities, name));
269 input_ptr_pairs.push_back(temporary);
272 leaf_input_ptr_pairs.push_back(input_ptr_pairs);
275 std::vector<std::pair<double*, const double*>> output_ptr_pairs;
277 for (std::string
const& name : leaf_module_type::get_outputs()) {
278 std::string specific_name =
279 add_class_prefix_to_quantity_name(
281 add_layer_suffix_to_quantity_name(nlayers, i, name));
283 std::pair<double*, const double*> temporary(
284 get_op(output_quantities, specific_name),
285 get_ip(leaf_module_output_map, name));
287 output_ptr_pairs.push_back(temporary);
290 leaf_output_ptr_pairs.push_back(output_ptr_pairs);
295template <
typename canopy_module_type,
typename leaf_module_type>
299 string_vector multiclass_multilayer_leaf_inputs =
300 MLCP::get_multiclass_multilayer_leaf_inputs<canopy_module_type, leaf_module_type>();
302 string_vector multilayer_leaf_inputs =
303 MLCP::get_pure_multilayer_leaf_inputs<canopy_module_type, leaf_module_type>();
305 string_vector other_leaf_inputs =
306 MLCP::get_other_leaf_inputs<canopy_module_type, leaf_module_type>();
309 string_vector multilayer_inputs = generate_multiclass_quantity_names(
310 canopy_module_type::define_leaf_classes(),
311 multiclass_multilayer_leaf_inputs);
313 for (std::string
const& name : multilayer_leaf_inputs) {
314 multilayer_inputs.push_back(name);
317 string_vector inputs = generate_multilayer_quantity_names(nlayers, multilayer_inputs);
319 for (std::string
const& name : other_leaf_inputs) {
320 inputs.push_back(name);
326template <
typename canopy_module_type,
typename leaf_module_type>
330 return generate_multilayer_quantity_names(
332 generate_multiclass_quantity_names(
333 canopy_module_type::define_leaf_classes(),
334 leaf_module_type::get_outputs()));
337template <
typename canopy_module_type,
typename leaf_module_type>
341 for (
size_t i = 0; i < leaf_input_ptr_pairs.size(); ++i) {
343 for (
auto const& x : leaf_input_ptr_pairs[i]) {
344 *x.first = *x.second;
351 for (
auto const& x : leaf_output_ptr_pairs[i]) {
352 *x.first = *x.second;
Applies a leaf photosynthesis module to each layer and leaf class of a multilayer canopy.
multilayer_canopy_photosynthesis(const int &nlayers, state_map const &input_quantities, state_map *output_quantities)
Constructor for a multilayer canopy photosynthesis module, which initializes the leaf module and prep...
static string_vector generate_outputs(int nlayers)
static string_vector generate_inputs(int nlayers)
string_vector get_pure_multilayer_leaf_inputs()
A helping function for the multlayer canopy photosynthesis module that returns inputs to the leaf mod...
string_vector get_leaf_input_subset(string_vector reference_names)
A helping function for the multilayer canopy photosynthesis module that returns inputs to the leaf mo...
string_vector get_multiclass_multilayer_leaf_inputs()
A helping function for the multlayer canopy photosynthesis module that returns inputs to the leaf mod...
string_vector get_other_leaf_inputs()
A helping function for the multlayer canopy photosynthesis module that returns inputs to the leaf mod...
This is the standard BioCro module library; it includes the essential modules used in typical BioCro ...