LandscapeDNDC 1.37.0
Loading...
Searching...
No Matches
ldndc::PhysiologyPlaMox Class Reference

Vegetation model PlaMox. More...

#include <models/physiology/plamox/plamox.h>

Public Member Functions

 ~PhysiologyPlaMox ()
 Delete allocated classes.
 

Private Member Functions

lerr_t PlaMox_step_init ()
 pre-run initialization each time step
 
lerr_t PlaMox_step_resize ()
 resize plant species vector
 
lerr_t PlaMox_management ()
 Applies grazing and cutting.
 
lerr_t PlaMox_event_plant (MoBiLE_Plant *, EventAttributes const &)
 handle plant event
 
lerr_t PlaMox_event_harvest (MoBiLE_Plant *, EventAttributes const &)
 handle harvest event
 
lerr_t PlaMox_photosynthesis (MoBiLE_Plant *)
 Update of information needed by photofarquhar.
 
void PlaMox_vernalization (MoBiLE_Plant *)
 Determines the growing degree days and the plant development stage based on if vernalization requirements are fullfilled or not.
 
void PlaMox_growing_degree_days (MoBiLE_Plant *)
 Calculates growing degree days depending on daily average temperature.
 
void PlaMox_heat_stress_limitation (MoBiLE_Plant *_vt)
 Limits pod filling due to heat stress around anthesis.
 
lerr_t PlaMox_allocation_grass (MoBiLE_Plant *)
 Allocation metrics for grass species.
 
lerr_t PlaMox_bud_burst (MoBiLE_Plant *)
 Burst of buds.
 
lerr_t PlaMox_redistribution (MoBiLE_Plant *)
 Redistribution of reserves.
 
void PlaMox_respiration (MoBiLE_Plant *)
 Calculates maintenance/residual and growth respiration.
 
void PlaMox_exsudation (MoBiLE_Plant *)
 Determines root exsudation as fraction of root growth respiration.
 
void PlaMox_nitrogen_uptake (MoBiLE_Plant *)
 Calculates plant nitrogen uptake based on daily demand.
 
lerr_t PlaMox_nitrogen_fixation (MoBiLE_Plant *)
 Calculates plant nitrogen fixation.
 
lerr_t PlaMox_senescence (MoBiLE_Plant *)
 Calculates aboveground and belowground plant senecsence.
 
void PlaMox_drought (MoBiLE_Plant *)
 Calculates drought stress.
 
void PlaMox_transpiration (MoBiLE_Plant *)
 Calculates potential transpiration.
 
void PlaMox_update_root_structure (MoBiLE_Plant *, double)
 Updates all relevant root structural matters.
 
void PlaMox_update_height (MoBiLE_Plant *)
 
void PlaMox_update_ground_cover (MoBiLE_Plant *)
 
void PlaMox_update_foliage_structure (MoBiLE_Plant *)
 Calculation of canopy layer properties:
 
void PlaMox_update_specific_leaf_area (MoBiLE_Plant *)
 Calculates specific leaf area (sla) in each canopy layer.
 
void PlaMox_update_nitrogen_concentrations (MoBiLE_Plant *)
 
double PlaMox_get_nitrogen_deficiency (MoBiLE_Plant *)
 
double PlaMox_get_biomass_induced_downregulation (MoBiLE_Plant *)
 
double PlaMox_get_age_factor (MoBiLE_Plant *)
 Calculates an age factor.
 
double PlaMox_get_frost_factor (MoBiLE_Plant *, double)
 Calculates a temperature factor.
 
double PlaMox_get_hypoxia_factor (MoBiLE_Plant *)
 Calculates a temperature factor.
 
double PlaMox_get_heat_factor (MoBiLE_Plant *)
 Calculates a temperature factor.
 
double PlaMox_get_foliage_nitrogen_concentration (MoBiLE_Plant *)
 Calculates optimum foliage nitrogen concentration.
 
double PlaMox_n_opt (MoBiLE_Plant *)
 Determines optimum nitrogen concentration.
 

Private Attributes

BerryBall plamox_berryball
 Photosynthesis.
 
NitrogenFixation * plamox_nitrogen_fixation
 Nitrogen fixation.
 
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
 Root system.
 
LD_PlantFunctions m_pf
 All kind of plant related functions.
 
bool have_drought_stress
 Consider drought stress yes/no.
 
bool have_heat_stress
 Consider heat stress yes/no.
 
cbm::string_t droughtstress_method
 Transpiration method used by PlaMox.
 
cbm::string_t::cbmstring_array_t plantfamilies
 Plant families that are considered by PlaMox.
 
double const FTS_TOT_
 Time resolution factor: \( \text{FTS_TOT_} = \frac{1.0}{\text{time resolution}} \).
 
lvector_t< double > allocation_factor_leafs
 Allocation factor of daily assimilated carbon to leaf growth [-].
 
lvector_t< double > allocation_factor_stems
 Allocation factor of daily assimilated carbon to stem growth [-].
 
lvector_t< double > allocation_factor_fruit
 Allocation factor of daily assimilated carbon to fruit growth [-].
 
lvector_t< double > allocation_factor_roots
 Allocation factor of daily assimilated carbon to root growth [-].
 
lvector_t< double > lai_min
 Minimum value of üplamt leaf area index (m^2:m^-2). For crops, this value is fixed until between sowing and emergence.
 
lvector_t< double > fractional_cover
 Density of seeded plants with regard to optimum (full area) seeding (-).
 
lvector_t< double > chill_units
 Accumulated chilling units for vernalization;.
 
lvector_t< unsigned int > root_q_vt_
 Largest soil layer index where roots exist [-].
 
lvector_t< double > daytime_temperatures
 store daytime temperature for heat stress analysis
 
lvector_t< double > influence_heat_daily
 store daily impact factor of heat stress on grain yield;
 
double influence_heat_reduction_grainfilling
 Resulting impact factor of the heat stress influence on grain yield.
 
double day_of_flowering
 day after emergence where flowering is onset
 
double Tcrit
 the timing of the episode of high temperatures relative to flowering
 
double Tzero
 The temperature at which there is zero pod-set (°C)
 

Detailed Description

Vegetation model PlaMox.

Author
David Kraus

Constructor & Destructor Documentation

◆ ~PhysiologyPlaMox()

ldndc::PhysiologyPlaMox::~PhysiologyPlaMox ( )

Delete allocated classes.

Delete:

  • roots system
  • nitrogen fixation
187{
188 for ( size_t r = 0; r < plamox_root_system.size(); ++r)
189 {
190 if ( plamox_root_system[r])
191 {
192 LD_Allocator->destroy( plamox_root_system[r]);
193 }
194 }
195
197}
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
Root system.
Definition plamox.h:145
NitrogenFixation * plamox_nitrogen_fixation
Nitrogen fixation.
Definition plamox.h:137

References plamox_nitrogen_fixation, plamox_root_system, and ~PhysiologyPlaMox().

Referenced by ~PhysiologyPlaMox().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ PlaMox_event_harvest()

lerr_t ldndc::PhysiologyPlaMox::PlaMox_event_harvest ( MoBiLE_Plant * _vt,
EventAttributes const & _attributes )
private

handle harvest event

Parameters
species
Returns
LDNDC_ERR_OK if no harvest event is pending or everything went well.

...

777{
778 if ( plamox_root_system[_vt->slot] == NULL)
779 {
780 KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
781 return LDNDC_ERR_RUNTIME_ERROR;
782 }
783
784 bool const mulching = _attributes.get( "/mulching", false);
785
786 double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
787 double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
788 double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
789 double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
790 double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
791
792 double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
793 double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
794
795 double const fru_c( _vt->mBud * cbm::CCDM);
796 double const fru_n( _vt->n_bud());
797
798 double fru_c_export( 0.0);
799 double fru_n_export( 0.0);
800
801 double straw_c_export( 0.0);
802 double straw_n_export( 0.0);
803
804 double mulching_c( 0.0);
805 double mulching_n( 0.0);
806
807 double stubble_c( 0.0);
808 double stubble_n( 0.0);
809
810 double gdd_sum( _vt->growing_degree_days );
811 double dvs_flush( _vt->dvsFlush );
812
813 double const height( _attributes.get( "/height", invalid_flt));
814 double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
815 double remains_absolute( _attributes.get( "/remains_absolute", invalid_flt));
816 if( cbm::is_valid( remains_absolute))
817 {
818 remains_absolute *= cbm::HA_IN_M2;
819 }
820
821 if ( !cbm::flt_greater_equal_zero( remains_relative)
822 && !cbm::flt_greater_equal_zero( remains_absolute)
823 && !cbm::flt_greater_equal_zero( height))
824 {
825 if ( _vt->is_covercrop)
826 {
827 remains_relative = 1.0;
828 }
829 else
830 {
831 KLOGWARN( "harvest event attribute \"remains_relative\" and \"remains_absolute\" and \"height\" not set;",
832 " \"remains_relative\" set to zero and used [species=", _vt->name(),"]");
833 }
834 }
835 else if ( (cbm::flt_greater_equal_zero( remains_relative) ||
836 cbm::flt_greater_equal_zero( remains_absolute))
837 && cbm::flt_greater_equal_zero( height))
838 {
839 KLOGWARN( "harvest event attribute \"remains_(relative/absolute)\" and \"height\" both set;"
840 " attribute \"remains_relative\" used [species=", _vt->name(),"]");
841 }
842
843 if ( cbm::flt_greater_equal_zero( remains_relative))
844 {
845 /* no op */
846 }
847 else if ( cbm::flt_greater_equal_zero( remains_absolute))
848 {
849 remains_relative = cbm::bound( 0.0,
850 remains_absolute / (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst),
851 1.0);
852 }
853 else if ( cbm::flt_equal_zero( height))
854 {
855 remains_relative = 0.0;
856 }
857 else if ( cbm::flt_greater_zero( height))
858 {
859 double h_cum( 0.0);
860 double remains_relative_fol = 0.0;
861 for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
862 {
863 remains_relative_fol += _vt->fFol_fl[fl];
864 h_cum += ph_.h_fl[fl];
865 if ( cbm::flt_greater_equal( h_cum, height))
866 {
867 break;
868 }
869 }
870
871 h_cum = 0.0;
872 double remains_relative_lst = 0.0;
873 double remains_relative_lst_total = 0.0;
874 for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
875 {
876 //lst decreases with height
877 remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
878 if ( cbm::flt_less_equal( h_cum, height))
879 {
880 remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
881 }
882 h_cum += ph_.h_fl[fl];
883 }
884 remains_relative_lst /= remains_relative_lst_total;
885
886 remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
887 remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
888 (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
889 }
890 else
891 {
892 KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
893 return LDNDC_ERR_FAIL;
894 }
895
896 stubble_c += remains_relative * straw_c;
897 stubble_n += remains_relative * straw_n;
898 if ( mulching)
899 {
900 mulching_c += (1.0-remains_relative) * straw_c;
901 mulching_n += (1.0-remains_relative) * straw_n;
902 }
903 else
904 {
905 straw_c_export += (1.0-remains_relative) * straw_c;
906 straw_n_export += (1.0-remains_relative) * straw_n;
907 }
908
909 if ( _vt->is_covercrop)
910 {
911 stubble_c += remains_relative * fru_c;
912 stubble_n += remains_relative * fru_n;
913 if ( mulching)
914 {
915 mulching_c += (1.0-remains_relative) * fru_c;
916 mulching_n += (1.0-remains_relative) * fru_n;
917 }
918 else
919 {
920 stubble_c += (1.0-remains_relative) * fru_c;
921 stubble_n += (1.0-remains_relative) * fru_n;
922 }
923 }
924 else
925 {
926 fru_c_export = fru_c;
927 fru_n_export = fru_n;
928 }
929
930 //export
931 c_total_exported += straw_c_export + fru_c_export;
932 c_fruit_exported += fru_c_export;
933 n_total_exported += straw_n_export + fru_n_export;
934 n_fruit_exported += fru_n_export;
935
936 ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
937 ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
938
939 ph_.accumulated_c_fru_export_harvest += fru_c_export;
940 ph_.accumulated_n_fru_export_harvest += fru_n_export;
941
942 //stubble litter
943 sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
944 sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
945 sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
946 sc_.accumulated_c_litter_stubble += stubble_c;
947
948 sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
949 sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
950 sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
951 sc_.accumulated_n_litter_stubble += stubble_n;
952
953 //raw litter
954 sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
955 sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
956 sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
957 sc_.accumulated_c_litter_above += mulching_c;
958
959 sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
960 sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
961 sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
962 sc_.accumulated_n_litter_above += mulching_n;
963
964 //root litter
965 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
966 {
967 double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
968 double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
969
970 sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
971 sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
972 sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
973 sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
974
975 sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
976 sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
977 sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
978 sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
979 }
980
981 cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
982 std::string mcom_key;
983
984 char const * species_name = _attributes.get( "/name", "?");
985
986 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
987 mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
988
989 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
990 mcom->set( mcom_key.c_str(), gdd_sum);
991
992 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
993 mcom->set( mcom_key.c_str(), dvs_flush);
994
995 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
996 mcom->set( mcom_key.c_str(), fru_c);
997
998 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
999 mcom->set( mcom_key.c_str(), fru_c_export);
1000
1001 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
1002 mcom->set( mcom_key.c_str(), fru_n);
1003
1004 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
1005 mcom->set( mcom_key.c_str(), fru_n_export);
1006
1007 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
1008 mcom->set( mcom_key.c_str(), straw_c);
1009
1010 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
1011 mcom->set( mcom_key.c_str(), straw_c_export);
1012
1013 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
1014 mcom->set( mcom_key.c_str(), straw_n);
1015
1016 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
1017 mcom->set( mcom_key.c_str(), straw_n_export);
1018
1019 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
1020 mcom->set( mcom_key.c_str(), stubble_c);
1021
1022 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1023 mcom->set( mcom_key.c_str(), stubble_n);
1024
1025 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1026 mcom->set( mcom_key.c_str(), rootlitter_c);
1027
1028 cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1029 mcom->set( mcom_key.c_str(), rootlitter_n);
1030
1031 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1032 {
1033 _vt->fFrt_sl[sl] = 0.0;
1034 }
1035
1036 cbm::invalidate( root_q_vt_[_vt->slot]);
1037 _vt->rooting_depth = 0.0;
1038
1039 days_after_emergence[_vt->slot] = -1;
1040
1041 dw_retranslocation_stem[_vt->slot] = 0.0;
1042 dw_retranslocation_foliage[_vt->slot] = 0.0;
1043
1044 dw_fol_old[_vt->slot] = 0.0;
1045 lai_dynamic[_vt->slot] = 0.0;
1046
1047 _vt->mFol = 0.0;
1048 _vt->dw_dfol = 0.0;
1049 _vt->ncFol = 0.0;
1050 _vt->n_dfol = 0.0;
1051
1052 _vt->dw_lst = 0.0;
1053 _vt->n_lst = 0.0;
1054
1055 _vt->dw_dst = 0.0;
1056 _vt->n_dst = 0.0;
1057
1058 _vt->mBud = 0.0;
1059 _vt->mBudStart = 0.0;
1060 _vt->ncBud = 0.0;
1061
1062 _vt->mFrt = 0.0;
1063 _vt->ncFrt = 0.0;
1064
1065 _vt->dEmerg = -1;
1066 _vt->growing_degree_days = 0.0;
1067 _vt->dvsMort = 0.0;
1068 _vt->dvsFlush = 0.0;
1069 _vt->dvsFlushOld = 0.0;
1070
1071 n_plant[_vt->slot] = 0.0;
1072 _vt->a_fix_n = 0.0;
1073
1074 _vt->height_max = 0.0;
1075 _vt->height_at_canopy_start = 0.0;
1076
1077 _vt->f_area = 0.0;
1078 for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1079 {
1080 _vt->fFol_fl[fl] = 0.0;
1081 _vt->lai_fl[fl] = 0.0;
1082 }
1083
1084 _vt->f_fac = 0.0;
1085 chill_units[_vt->slot] = 0.0;
1086 _vt->chill_factor = 1.0;
1087
1088 yearly_cuts[_vt->slot] = 0;
1089
1090 allocation_factor_leafs[_vt->slot] = 0.0;
1091 allocation_factor_stems[_vt->slot] = 0.0;
1092 allocation_factor_fruit[_vt->slot] = 0.0;
1093 allocation_factor_roots[_vt->slot] = 0.0;
1094
1095 m_fruit_maximum[_vt->slot] = -1.0;
1096 spikelets_sterility[_vt->slot] = 0.0;
1097 hypoxia[_vt->slot] = 0.0;
1098
1099 LD_Allocator->destroy( plamox_root_system[_vt->slot]);
1100 plamox_root_system[_vt->slot] = NULL;
1101
1102 return LDNDC_ERR_OK;
1103}
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition plamox.h:271
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition plamox.h:277
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition plamox.h:283
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition plamox.h:265
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition plamox.h:327
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition plamox.h:303

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_units, plamox_root_system, and root_q_vt_.

◆ PlaMox_event_plant()

lerr_t ldndc::PhysiologyPlaMox::PlaMox_event_plant ( MoBiLE_Plant * _vt,
EventAttributes const & _attributes )
private

handle plant event

Parameters
species
Returns
LDNDC_ERR_OK if no plant event is pending or everything went well.

...

464{
465 species_t const * sp = NULL;
466 if ( m_species)
467 {
468 sp = m_species->get_species( _vt->cname());
469 }
470
472
473 seconds_crop_planting[_vt->slot] = lclock()->seconds();
474 fractional_cover[_vt->slot] = _attributes.get( "/fractional-cover", 1.0);
475
476 //Scale growing degree days
477 //Currently only used by FarmSystem to dynamically adjust species
478 //over larger regions and/or time periods
479 double gdd_maturity_target( _attributes.get( "/gdd-maturity-target", -1.0));
480 if ( cbm::flt_less( gdd_maturity_target, 0.0) &&
481 (std::strstr( _vt->cname(), "GDD-MATURITY-TARGET") != NULL) &&
482 gdd_target.find( _vt->cname()) != gdd_target.end())
483 {
484 gdd_maturity_target = gdd_target[_vt->cname()];
485 }
486
487 if ( cbm::flt_greater_zero( gdd_maturity_target) &&
488 cbm::flt_greater_zero( (*_vt)->GDD_MATURITY()))
489 {
490 double const scale_gdd( gdd_maturity_target / (*_vt)->GDD_MATURITY());
491 MoBiLE_PlantParameters p_parameters = (*m_speciesparameters)[_vt->ctype()];
492 p_parameters.GDD_EMERGENCE_UPDATE( (*_vt)->GDD_EMERGENCE() * scale_gdd);
493 p_parameters.GDD_STEM_ELONGATION_UPDATE( (*_vt)->GDD_STEM_ELONGATION() * scale_gdd);
494 p_parameters.GDD_FLOWERING_UPDATE( (*_vt)->GDD_FLOWERING() * scale_gdd);
495 p_parameters.GDD_GRAIN_FILLING_UPDATE( (*_vt)->GDD_GRAIN_FILLING() * scale_gdd);
496 p_parameters.GDD_ROOTS_GROWN_UPDATE( (*_vt)->GDD_ROOTS_GROWN() * scale_gdd);
497 p_parameters.GDD_MATURITY_UPDATE( gdd_maturity_target);
498 _vt->switchparameters( p_parameters);
499 }
500
501 _vt->is_covercrop = _attributes.get( "/cover-crop", false);
502 //_vt->f_fac = (*_vt)->FFACMAX();
503
504 //amount of seeds
505 double const initial_biomass( cbm::bound_min( 10.0,
506 cbm::flt_greater_zero( _attributes.get( "/initial-biomass", 0.0)) ?
507 _attributes.get( "/initial-biomass", 0.0) :
508 (*_vt)->SEED_RATE()) * cbm::HA_IN_M2);
509
510 location[_vt->slot] = _attributes.get( "/location", "?");
511
512 dw_retranslocation_stem[_vt->slot] = 0.0;
513 dw_retranslocation_foliage[_vt->slot] = 0.0;
514
515 dw_fol_old[_vt->slot] = 0.0;
516 lai_dynamic[_vt->slot] = 0.0;
517
518 //plant gets biomass by species initializer
519 //store and substract later according amounts of C and N
520 //for balance check at day of planting
521 double const plant_n_old( _vt->total_nitrogen());
522 double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
523
524 _vt->height_max = 0.0;
525 _vt->height_at_canopy_start = 0.0;
526
527 chill_units[_vt->slot] = 0.0;
528 _vt->chill_factor = 1.0;
529
530 _vt->f_heat_daily = 1.0;
531
532 if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
533 {
534 m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
535 }
536 else
537 {
538 m_fruit_maximum[_vt->slot] = -1.0;
539 }
540 spikelets_sterility[_vt->slot] = 0.0;
541
542 if ( m_veg->is_family( _vt, ":rice:"))
543 {
544 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
545 }
546 else if ( m_veg->is_family( _vt, ":wheat:"))
547 {
548 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
549 }
550 else
551 {
552 nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
553 }
554
555 gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
556
557 hypoxia[_vt->slot] = 0.0;
558 transplanting_shock_vt[_vt->slot] = 0.0;
559
560 PlaMox_reset_phenology( _vt);
561
562 if ( cbm::is_equal( _vt->group().c_str(), "crop"))
563 {
564 lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
565 if ( rc_plant)
566 {
567 return LDNDC_ERR_OK;
568 }
569
570 /* only considered for rice so far */
571 int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
572 if ( seedbedduration > 0)
573 {
574 double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
575 _vt->growing_degree_days = seedbedduration * mean_gdd;
576 _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
577 transplanting_shock_vt[_vt->slot] = 1.0;
578 days_after_emergence[_vt->slot] = 0;
579 }
580 else
581 {
582 _vt->growing_degree_days = 0.0;
583 _vt->dvsFlush = 0.0;
584 }
585
586 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
587 allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
588 allocation_factor_stems[_vt->slot] = 0.0;
589 allocation_factor_fruit[_vt->slot] = 0.0;
590
591 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
592 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
593 _vt->n_lst = 0.0;
594 _vt->ncBud = 0.0;
595 _vt->ncSap = 0.0;
596 _vt->ncCor = 0.0;
597
598 if ( cbm::flt_greater_zero( (*_vt)->GDD_AUTOTROPHY()))
599 {
600 _vt->mFol = 0.01 * initial_biomass;
601 _vt->mFrt = initial_biomass - _vt->mFol;
602 _vt->dw_lst = 0.0;
603 _vt->mBud = 0.0;
604 _vt->mSap = 0.0;
605 _vt->mCor = 0.0;
606
607 //assuming a constant value of 50% of seeds being respired and 50% being allocated to leaves
608 double const leaves_from_seed( 0.5 * 0.5);;
609 lai_min[_vt->slot] = 0.001;
610 lai_min_at_tillering[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
611 leaves_from_seed * initial_biomass * (*_vt)->SLAMAX());
612 }
613 else
614 {
615 double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
616 (*_vt)->FRACTION_ROOT_START() :
617 (*_vt)->FRACTION_ROOT());
618 double const initial_foliage_biomass_max( 0.02);
619 _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
620 initial_foliage_biomass_max);
621
622 _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
623 _vt->dw_lst = 0.0;
624 _vt->mBud = 0.0;
625 _vt->mSap = 0.0;
626 _vt->mCor = 0.0;
627
628 lai_min[_vt->slot] = 0.01;
629 lai_min_at_tillering[_vt->slot] = 0.01;
630 }
631
632 n_plant[_vt->slot] = _vt->total_nitrogen();
634
635 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
636 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
637 }
638 else if ( cbm::is_equal( _vt->cgroup(), "grass"))
639 {
640 lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
641 if ( rc_plant)
642 {
643 return LDNDC_ERR_OK;
644 }
645
646 if ( lclock()->seconds() > cbm::SEC_IN_DAY)
647 {
648 PlaMox_reset_phenology( _vt);
649 }
650
651 /* set to fixed value */
652 lai_min[_vt->slot] = 0.1;
653 lai_min_at_tillering[_vt->slot] = 0.1;
654
655 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
656 allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
657 allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
658 allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
659
660 _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
661 _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
662 _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
663 _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
664
665 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
666 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
667 _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
668 _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
669
670 n_plant[_vt->slot] = _vt->total_nitrogen();
671
673
674 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
675 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
676 }
677 else
678 {
679 KLOGERROR( "I do not handle this group of species ",
680 "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
681 return LDNDC_ERR_RUNTIME_ERROR;
682 }
683
684 // currently no concept for free available carbon
685 _vt->f_fac = 0.0;
686
687 // initialize root system
688 if (plamox_root_system.size() <= _vt->slot)
689 {
690 plamox_root_system.resize(_vt->slot+1);
691 }
692
693 ldndc_kassert( plamox_root_system[_vt->slot] == NULL);
694 plamox_root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
695 if ( !plamox_root_system[_vt->slot])
696 {
697 KLOGERROR( "Failed to allocate root-system object");
698 return LDNDC_ERR_NOMEM;
699 }
700
701 double const seed_depth = _attributes.get( "/seed-depth", 0.05);
702 root_q_vt_[_vt->slot] = 0; // no rooted layers yet
703 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
704 {
705 if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
706 {
707 break;
708 }
709 root_q_vt_[_vt->slot] = sl; // no rooted layers yet
710 }
711
712 PlaMox_update_root_structure( _vt, _vt->mFrt);
713
714 return LDNDC_ERR_OK;
715}
void PlaMox_update_root_structure(MoBiLE_Plant *, double)
Updates all relevant root structural matters.
lvector_t< double > daytime_temperatures
store daytime temperature for heat stress analysis
Definition plamox.h:333
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition plamox.cpp:3317
LD_PlantFunctions m_pf
All kind of plant related functions.
Definition plamox.h:151
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition plamox.h:297
lvector_t< double > lai_min
Minimum value of üplamt leaf area index (m^2:m^-2). For crops, this value is fixed until between sowi...
Definition plamox.h:290

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_units, daytime_temperatures, fractional_cover, lai_min, m_pf, plamox_root_system, PlaMox_update_nitrogen_concentrations(), PlaMox_update_root_structure(), and root_q_vt_.

Here is the call graph for this function:

◆ PlaMox_get_age_factor()

double ldndc::PhysiologyPlaMox::PlaMox_get_age_factor ( MoBiLE_Plant * )
private

Calculates an age factor.

Parameters
[in]_vtPlant species

References PlaMox_get_foliage_nitrogen_concentration(), PlaMox_get_frost_factor(), PlaMox_get_heat_factor(), PlaMox_get_hypoxia_factor(), PlaMox_n_opt(), and plantfamilies.

Referenced by PlaMox_photosynthesis().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlaMox_get_biomass_induced_downregulation()

double ldndc::PhysiologyPlaMox::PlaMox_get_biomass_induced_downregulation ( MoBiLE_Plant * _vt)
private
Parameters
[in]_vtPlant species
3624{
3625 if ( m_veg->is_family( _vt, ":wheat:"))
3626 {
3627 double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3628 double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3629
3630 if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3631 cbm::flt_greater( _vt->dw_lst, lst_opt))
3632 {
3633 return lst_opt / _vt->dw_lst;
3634 }
3635 }
3636
3637 return 1.0;
3638}

References fractional_cover.

Referenced by PlaMox_photosynthesis(), and PlaMox_update_ground_cover().

Here is the caller graph for this function:

◆ PlaMox_get_frost_factor()

double ldndc::PhysiologyPlaMox::PlaMox_get_frost_factor ( MoBiLE_Plant * _vt,
double _temp )
private

Calculates a temperature factor.

Parameters
[in]_vtPlant species
[in]_tempTemperature
Returns
Temperature factor
3377{
3378 double const t_min( (*_vt)->TLIMIT() - 2.0);
3379 double const t_max( (*_vt)->TLIMIT());
3380
3381 if ( cbm::flt_less( _temp, t_min))
3382 {
3383 return 0.0;
3384 }
3385 else if ( cbm::flt_less( _temp, t_max))
3386 {
3387 return (_temp - t_min) / (t_max - t_min);
3388 }
3389 else
3390 {
3391 return 1.0;
3392 }
3393}

Referenced by PlaMox_get_age_factor(), and PlaMox_photosynthesis().

Here is the caller graph for this function:

◆ PlaMox_get_nitrogen_deficiency()

double ldndc::PhysiologyPlaMox::PlaMox_get_nitrogen_deficiency ( MoBiLE_Plant * _vt)
private
Parameters
[in]_vtPlant species
3591{
3592// if ( m_veg->is_family( _vt, ":winterwheat:"))
3593// {
3594// double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3595// (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3596// double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3597// _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3598// double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3599// double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3600//
3601// return cbm::bound( 0.01,
3602// vc / vc_max,
3603// 1.0);
3604// }
3605// else
3606 {
3607 double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3608 if ( n_ratio < 1.0)
3609 {
3610 return cbm::bound( 0.01,
3611 pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3612 1.0);
3613 }
3614 else
3615 {
3616 return 1.0;
3617 }
3618 }
3619}

Referenced by PlaMox_photosynthesis(), and PlaMox_update_ground_cover().

Here is the caller graph for this function:

◆ PlaMox_n_opt()

double ldndc::PhysiologyPlaMox::PlaMox_n_opt ( MoBiLE_Plant * _vt)
private

Determines optimum nitrogen concentration.

Adding the optimum concentrations of foliage, sapwood, fine roots and buds.

Returns
Optimum nitrogen concentration of the whole plant
  • Optimum concentration for foliage is calculated by: get_foliage_nitrogen_concentration()
  • For sapwood by Sapwood Biomass \( * \) NC_STRUCTURAL_TISSUE
  • For fine roots by Fine Root Biomass \( * \) NC_FINE_ROOTS
  • For buds by: \( \frac{BudBiomass * CarbonContent}{BudC:N} \)
3302{
3303 return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3304 + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3305 + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3306 + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3307}
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition plamox.cpp:3723

References PlaMox_get_foliage_nitrogen_concentration().

Referenced by PlaMox_get_age_factor(), and PlaMox_update_nitrogen_concentrations().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlaMox_photosynthesis()

lerr_t ldndc::PhysiologyPlaMox::PlaMox_photosynthesis ( MoBiLE_Plant * _vt)
private

Update of information needed by photofarquhar.

Nitrogen concentration:
Nitrogen concentrations are updated in each compartment update_nitrogen_concentrations()

1976{
1977 DroughtStress droughtstress;
1978 droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
1979 double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
1980 double const fact_a( PlaMox_get_age_factor( _vt));
1981 double const fact_t( PlaMox_get_frost_factor( _vt, mc_.ts_airtemperature));
1982 double const fact_h( PlaMox_get_heat_factor( _vt));
1983 double const fact_o( PlaMox_get_hypoxia_factor( _vt));
1984 double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
1985 double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
1986
1987 double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
1988
1989 /* update activity of photosynthesis apparat */
1990 if ( cbm::flt_greater_zero( fact_all))
1991 {
1992 for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
1993 {
1994 //rubisco activity
1995 _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
1996
1997 //electron transport under standard conditions
1998 _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
1999
2000 //photorespiration under standard conditions
2001 _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2002 }
2003 }
2004
2005 for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2006 {
2007 plamox_berryball.vpd_fl[fl] = mc_.vpd_fl[fl];
2008 plamox_berryball.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2009 plamox_berryball.temp_fl[fl] = mc_.temp_fl[fl];
2010 plamox_berryball.parsun_fl[fl] = mc_.parsun_fl[fl];
2011 plamox_berryball.parshd_fl[fl] = mc_.parshd_fl[fl];
2012 plamox_berryball.tFol_fl[fl] = mc_.tFol_fl[fl];
2013 plamox_berryball.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2014 plamox_berryball.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2015 }
2016 plamox_berryball.nd_airpressure = mc_.nd_airpressure;
2017 plamox_berryball.set_vegetation_base_state( _vt);
2018 plamox_berryball.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
2019
2020 plamox_berryball.solve();
2021
2022 plamox_berryball.get_vegetation_state( _vt);
2023
2024 double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2025
2026 if ( cbm::flt_greater_zero( carbonuptake_sum))
2027 {
2028 timestep_c_assi += carbonuptake_sum;
2029 double const dw_assi( carbonuptake_sum / cbm::CCDM);
2030
2031 _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2032 _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2033 _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2034 _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2035
2036 _vt->dcBud = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2037 _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2038 _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2039 _vt->dcSap = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2040
2046 }
2047
2048 return LDNDC_ERR_OK;
2049}
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition plamox.cpp:3556
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
BerryBall plamox_berryball
Photosynthesis.
Definition plamox.h:131
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition plamox.cpp:3623
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition plamox.cpp:3397
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition plamox.cpp:3590
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition plamox.cpp:3375

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, plamox_berryball, PlaMox_get_age_factor(), PlaMox_get_biomass_induced_downregulation(), PlaMox_get_frost_factor(), PlaMox_get_heat_factor(), PlaMox_get_hypoxia_factor(), PlaMox_get_nitrogen_deficiency(), and PlaMox_update_nitrogen_concentrations().

Here is the call graph for this function:

◆ PlaMox_update_foliage_structure()

void ldndc::PhysiologyPlaMox::PlaMox_update_foliage_structure ( MoBiLE_Plant * _vt)
private

Calculation of canopy layer properties:

  • foliage biomass
  • foliage biomass fraction
  • leaf area index
Parameters
[in]_vtPlant species
  • foliage biomass
  • foliage biomass fraction
  • leaf area index By these means, germination and growth of very small biomasses depend less on early lai development, which is not well represented by lai<->photosynthesis feedbacks.
3133{
3134 size_t const fl_cnt( _vt->nb_foliagelayers());
3135
3136 double sla_cum( 0.0);
3137 for (size_t fl = 0; fl < fl_cnt; ++fl)
3138 {
3139 sla_cum += _vt->sla_fl[fl];
3140 }
3141
3142 /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3143 double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3144 _vt->mFol));
3145
3146 if ( rm_ && cbm::is_valid( rm_->lai_subday( lclock_ref())))
3147 {
3148 lai_dynamic[_vt->slot] = rm_->lai_subday( lclock_ref());
3149 }
3150 else
3151 {
3152 lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3153 lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3154 }
3155
3156 if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3157 {
3158 mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3159 }
3160
3161 if ( cbm::flt_greater_zero( sla_cum))
3162 {
3163 DroughtStress droughtstress;
3164 droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3165
3166 //use dynamic lai only if remote sensing input is available
3167 if ( rm_)
3168 {
3169 for (size_t fl = 0; fl < fl_cnt; ++fl)
3170 {
3171 _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3172 _vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3173 }
3174 }
3175 else
3176 {
3177 for (size_t fl = 0; fl < fl_cnt; ++fl)
3178 {
3179 _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3180 _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3181 }
3182 }
3183
3184 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3185 {
3186 _vt->fFol_fl[fl] = 0.0;
3187 _vt->lai_fl[fl] = 0.0;
3188 _vt->sla_fl[fl] = 0.0;
3189 }
3190 }
3191 else
3192 {
3193 for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3194 {
3195 _vt->fFol_fl[fl] = 0.0;
3196 _vt->lai_fl[fl] = 0.0;
3197 _vt->sla_fl[fl] = 0.0;
3198 }
3199 }
3200}

References lai_min.

Referenced by PlaMox_update_ground_cover().

Here is the caller graph for this function:

◆ PlaMox_update_ground_cover()

void ldndc::PhysiologyPlaMox::PlaMox_update_ground_cover ( MoBiLE_Plant * )
private

◆ PlaMox_update_height()

void ldndc::PhysiologyPlaMox::PlaMox_update_height ( MoBiLE_Plant * )
private
Parameters
[in]_vtPlant species

◆ PlaMox_update_nitrogen_concentrations()

void ldndc::PhysiologyPlaMox::PlaMox_update_nitrogen_concentrations ( MoBiLE_Plant * _vt)
private
Parameters
[in]_vtPlant species

Distribution of total plant nitrogen throughout complete plant assumed to occur instantaneously.

3318{
3319 double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3320 double const nitrogen_satisfaction( cbm::flt_greater_zero( PlaMox_n_opt( _vt)) ? cbm::bound(0.0, n_living_plant / PlaMox_n_opt( _vt), 1.0) : 1.0);
3321
3322// double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3323
3324 double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3325 cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3326 _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3327 + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3328 _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3329 double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3330 cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3331 _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3332 + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3333 _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3334 double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3335 cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3336 _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3337 + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3338 _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3339 double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3340 cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3341 _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3342 + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3343 _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3344
3345 double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3346 if ( cbm::flt_greater_zero( n_tot_opt))
3347 {
3348 // CB: fraction of available N to optimum N
3349 double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3350 // CB: N gets distributed evenly over all compartments regarding their optimum N content
3351 _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3352 (*_vt)->NC_FOLIAGE_MAX();
3353 _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3354 0.0;
3355 _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3356 (*_vt)->NC_FRUIT_MAX();
3357 _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3358 (*_vt)->NC_FINEROOTS_MAX();
3359 }
3360}
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition plamox.cpp:3301

References PlaMox_get_foliage_nitrogen_concentration(), and PlaMox_n_opt().

Referenced by PlaMox_bud_burst(), PlaMox_event_plant(), PlaMox_exsudation(), PlaMox_photosynthesis(), and PlaMox_update_ground_cover().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlaMox_update_root_structure()

void ldndc::PhysiologyPlaMox::PlaMox_update_root_structure ( MoBiLE_Plant * ,
double  )
private

Updates all relevant root structural matters.

Parameters
[in]_vtPlant species
[in]_deltamassFrtFine root mass development

Referenced by PlaMox_event_plant().

Here is the caller graph for this function:

◆ PlaMox_update_specific_leaf_area()

void ldndc::PhysiologyPlaMox::PlaMox_update_specific_leaf_area ( MoBiLE_Plant * _vt)
private

Calculates specific leaf area (sla) in each canopy layer.

Parameters
[in]_vtPlant species

For mungbean, the species parameter SLAMAX is neglected and sla is calculated based on the following table taken from the WOFOST model parametrisation.

dvs sla 0.0 26.0 1.0 33.0 2.0 16.0

3217{
3218 size_t const fl_cnt( _vt->nb_foliagelayers());
3219
3230 if ( IS_SPECIE( _vt->cname(), "mungbean"))
3231 {
3232 double slamax( 26.0);
3233 if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3234 {
3235 slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3236 }
3237 else
3238 {
3239 slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3240 }
3241
3242 for (size_t fl = 0; fl < fl_cnt; ++fl)
3243 {
3244 _vt->sla_fl[fl] = slamax;
3245 }
3246 }
3247 else if ( m_veg->is_family( _vt, ":rice:"))
3248 {
3249 double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3250 cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3251 _vt->dvsMort);
3252
3253 double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3254 for (size_t fl = 0; fl < fl_cnt; ++fl)
3255 {
3256 _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3257 }
3258 }
3259 else
3260 {
3261 // reduction of specific leaf area with crop age
3262 double sla_red( 1.0);
3263 if (_vt->groupId() == SPECIES_GROUP_GRASS)
3264 {
3265 if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3266 {
3267 sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3268 }
3269 }
3270 else
3271 {
3272 sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3273 }
3274
3275 for (size_t fl = 0; fl < fl_cnt; ++fl)
3276 {
3277 _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3278 }
3279 }
3280
3281 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3282 {
3283 _vt->sla_fl[fl] = 0.0;
3284 }
3285}

Referenced by PlaMox_update_ground_cover().

Here is the caller graph for this function:

Member Data Documentation

◆ plamox_root_system

ldndc::growable_array< BaseRootSystemDNDC*, 1000, 1 > ldndc::PhysiologyPlaMox::plamox_root_system
private

Root system.

  • rooting depth
  • root distribution

Referenced by PlaMox_event_harvest(), PlaMox_event_plant(), PlaMox_exsudation(), and ~PhysiologyPlaMox().

◆ Tcrit

double ldndc::PhysiologyPlaMox::Tcrit
private

the timing of the episode of high temperatures relative to flowering

the duration of the episode of high temperatures relative to flowering

The critical temperature at which temperatuer affects pod-set, dependent on timing and duration of the heatshock (°C)

Referenced by PlaMox_heat_stress_limitation().