LandscapeDNDC 1.37.0
ldndc::PhysiologyPlaMox Class Reference

Vegetation model PlaMox. More...

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

Inherits ldndc::MBE_LegacyModel.

Public Member Functions

 ~PhysiologyPlaMox ()
 Delete allocated classes. More...
 

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 More...
 
lerr_t PlaMox_event_harvest (MoBiLE_Plant *, EventAttributes const &)
 handle harvest event More...
 
lerr_t PlaMox_photosynthesis (MoBiLE_Plant *)
 Update of information needed by photofarquhar. More...
 
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. More...
 
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: More...
 
void PlaMox_update_specific_leaf_area (MoBiLE_Plant *)
 Calculates specific leaf area (sla) in each canopy layer. More...
 
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. More...
 
double PlaMox_get_frost_factor (MoBiLE_Plant *, double)
 Calculates a temperature factor. More...
 
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. More...
 

Private Attributes

BerryBall plamox_berryball
 Photosynthesis.
 
NitrogenFixation * plamox_nitrogen_fixation
 Nitrogen fixation.
 
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
 Root system. More...
 
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_factor
 Factor that retards plant development if vernalization requirement is not fullfilled.
 
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 More...
 
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
188{
189 for ( size_t r = 0; r < plamox_root_system.size(); ++r)
190 {
191 if ( plamox_root_system[r])
192 {
193 LD_Allocator->destroy( plamox_root_system[r]);
194 }
195 }
196
198}
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

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.

...

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

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_factor, 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.

...

462{
463 species_t const * sp = NULL;
464 if ( m_species)
465 {
466 sp = m_species->get_species( _vt->cname());
467 }
468
470
471 seconds_crop_planting[_vt->slot] = lclock()->seconds();
472 fractional_cover[_vt->slot] = _attributes.get( "/fractional-cover", 1.0);
473
474 //Scale growing degree days
475 //Currently only used by FarmSystem to dynamically adjust species
476 //over larger regions and/or time periods
477 double gdd_maturity_target( _attributes.get( "/gdd-maturity-target", -1.0));
478 if ( cbm::flt_less( gdd_maturity_target, 0.0) &&
479 (std::strstr( _vt->cname(), "GDD-MATURITY-TARGET") != NULL) &&
480 gdd_target.find( _vt->cname()) != gdd_target.end())
481 {
482 gdd_maturity_target = gdd_target[_vt->cname()];
483 }
484
485 if ( cbm::flt_greater_zero( gdd_maturity_target) &&
486 cbm::flt_greater_zero( (*_vt)->GDD_MATURITY()))
487 {
488 double const scale_gdd( gdd_maturity_target / (*_vt)->GDD_MATURITY());
489 MoBiLE_PlantParameters p_parameters = (*m_speciesparameters)[_vt->ctype()];
490 p_parameters.GDD_EMERGENCE_UPDATE( (*_vt)->GDD_EMERGENCE() * scale_gdd);
491 p_parameters.GDD_STEM_ELONGATION_UPDATE( (*_vt)->GDD_STEM_ELONGATION() * scale_gdd);
492 p_parameters.GDD_FLOWERING_UPDATE( (*_vt)->GDD_FLOWERING() * scale_gdd);
493 p_parameters.GDD_GRAIN_FILLING_UPDATE( (*_vt)->GDD_GRAIN_FILLING() * scale_gdd);
494 p_parameters.GDD_ROOTS_GROWN_UPDATE( (*_vt)->GDD_ROOTS_GROWN() * scale_gdd);
495 p_parameters.GDD_MATURITY_UPDATE( gdd_maturity_target);
496 _vt->switchparameters( p_parameters);
497 }
498
499 _vt->is_covercrop = _attributes.get( "/cover-crop", false);
500 //_vt->f_fac = (*_vt)->FFACMAX();
501
502 //amount of seeds
503 double const initial_biomass( cbm::bound_min( 10.0,
504 cbm::flt_greater_zero( _attributes.get( "/initial-biomass", 0.0)) ?
505 _attributes.get( "/initial-biomass", 0.0) :
506 (*_vt)->SEED_RATE()) * cbm::HA_IN_M2);
507
508 lai_min[_vt->slot] = 0.01;
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 chill_factor[_vt->slot] = 1.0;
529
530 if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
531 {
532 m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
533 }
534 else
535 {
536 m_fruit_maximum[_vt->slot] = -1.0;
537 }
538 spikelets_sterility[_vt->slot] = 0.0;
539
540 if ( m_veg->is_family( _vt, ":rice:"))
541 {
542 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
543 }
544 else if ( m_veg->is_family( _vt, ":wheat:"))
545 {
546 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
547 }
548 else
549 {
550 nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
551 }
552
553 gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
554
555 hypoxia[_vt->slot] = 0.0;
556 transplanting_shock_vt[_vt->slot] = 0.0;
557
558 PlaMox_reset_phenology( _vt);
559
560 if ( cbm::is_equal( _vt->group().c_str(), "crop"))
561 {
562 lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
563 if ( rc_plant)
564 {
565 return LDNDC_ERR_OK;
566 }
567
568 /* only considered for rice so far */
569 int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
570 if ( seedbedduration > 0)
571 {
572 double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
573 _vt->growing_degree_days = seedbedduration * mean_gdd;
574 _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
575 transplanting_shock_vt[_vt->slot] = 1.0;
576 days_after_emergence[_vt->slot] = 0;
577 }
578 else
579 {
580 _vt->growing_degree_days = 0.0;
581 _vt->dvsFlush = 0.0;
582 }
583
584 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
585 allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
586 allocation_factor_stems[_vt->slot] = 0.0;
587 allocation_factor_fruit[_vt->slot] = 0.0;
588
589 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
590 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
591 _vt->n_lst = 0.0;
592 _vt->ncBud = 0.0;
593 _vt->ncSap = 0.0;
594 _vt->ncCor = 0.0;
595
596 double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
597 (*_vt)->FRACTION_ROOT_START() :
598 (*_vt)->FRACTION_ROOT());
599 double const initial_foliage_biomass_max( 0.02);
600 _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
601 initial_foliage_biomass_max );
602
603 _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
604 _vt->dw_lst = 0.0;
605 _vt->mBud = 0.0;
606 _vt->mSap = 0.0;
607 _vt->mCor = 0.0;
608
609 lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
610 n_plant[_vt->slot] = _vt->total_nitrogen();
612
613 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
614 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
615 }
616 else if ( cbm::is_equal( _vt->cgroup(), "grass"))
617 {
618 lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
619 if ( rc_plant)
620 {
621 return LDNDC_ERR_OK;
622 }
623
624 if ( lclock()->seconds() > cbm::SEC_IN_DAY)
625 {
626 PlaMox_reset_phenology( _vt);
627 }
628
629 /* set to fixed value */
630 lai_min[_vt->slot] = 0.1;
631
632 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
633 allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
634 allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
635 allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
636
637 _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
638 _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
639 _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
640 _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
641
642 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
643 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
644 _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
645 _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
646
647 n_plant[_vt->slot] = _vt->total_nitrogen();
648
650
651 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
652 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
653 }
654 else
655 {
656 KLOGERROR( "I do not handle this group of species ",
657 "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
658 return LDNDC_ERR_RUNTIME_ERROR;
659 }
660
661 // currently no concept for free available carbon
662 _vt->f_fac = 0.0;
663
664 // initialize root system
665 if (plamox_root_system.size() <= _vt->slot)
666 {
667 plamox_root_system.resize(_vt->slot+1);
668 }
669
670 ldndc_kassert( plamox_root_system[_vt->slot] == NULL);
671 plamox_root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
672 if ( !plamox_root_system[_vt->slot])
673 {
674 KLOGERROR( "Failed to allocate root-system object");
675 return LDNDC_ERR_NOMEM;
676 }
677
678 double const seed_depth = _attributes.get( "/seed-depth", 0.05);
679 root_q_vt_[_vt->slot] = 0; // no rooted layers yet
680 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
681 {
682 if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
683 {
684 break;
685 }
686 root_q_vt_[_vt->slot] = sl; // no rooted layers yet
687 }
688
689 PlaMox_update_root_structure( _vt, _vt->mFrt);
690
691 return LDNDC_ERR_OK;
692}
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:338
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3338
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:296
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_factor, 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 *  _p)
private

Calculates an age factor.

Parameters
[in]_vtPlant species
3672{
3673 if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3674 {
3675 if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3676 {
3677 return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3678 }
3679 return ( 1.0);
3680 }
3681 else
3682 {
3683 if ( days_after_emergence[_p->slot] < 0)
3684 {
3685 return 0.0;
3686 }
3687 else
3688 {
3689 if ( cbm::flt_less_equal( _p->growing_degree_days, (*_p)->GDD_MATURITY()))
3690 {
3691 return ( 1.0);
3692 }
3693 else
3694 {
3695 return 1.0 / std::exp( 0.01 * (_p->growing_degree_days - (*_p)->GDD_MATURITY()));
3696 }
3697 }
3698 }
3699}

Referenced by PlaMox_photosynthesis().

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
3633{
3634 if ( m_veg->is_family( _vt, ":wheat:"))
3635 {
3636 double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3637 double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3638
3639 if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3640 cbm::flt_greater( _vt->dw_lst, lst_opt))
3641 {
3642 return lst_opt / _vt->dw_lst;
3643 }
3644 }
3645
3646 return 1.0;
3647}

References fractional_cover.

Referenced by PlaMox_photosynthesis().

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
3398{
3399 double const t_min( (*_vt)->TLIMIT() - 2.0);
3400 double const t_max( (*_vt)->TLIMIT());
3401
3402 if ( cbm::flt_less( _temp, t_min))
3403 {
3404 return 0.0;
3405 }
3406 else if ( cbm::flt_less( _temp, t_max))
3407 {
3408 return (_temp - t_min) / (t_max - t_min);
3409 }
3410 else
3411 {
3412 return 1.0;
3413 }
3414}

Referenced by 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
3600{
3601// if ( m_veg->is_family( _vt, ":winterwheat:"))
3602// {
3603// double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3604// (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3605// double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3606// _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3607// double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3608// double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3609//
3610// return cbm::bound( 0.01,
3611// vc / vc_max,
3612// 1.0);
3613// }
3614// else
3615 {
3616 double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3617 if ( n_ratio < 1.0)
3618 {
3619 return cbm::bound( 0.01,
3620 pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3621 1.0);
3622 }
3623 else
3624 {
3625 return 1.0;
3626 }
3627 }
3628}

Referenced by PlaMox_photosynthesis().

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} \)
3323{
3324 return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3325 + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3326 + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3327 + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3328}
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3710

References PlaMox_get_foliage_nitrogen_concentration().

Referenced by 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()

1932{
1933 DroughtStress droughtstress;
1934 droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
1935 double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
1936 double const fact_a( PlaMox_get_age_factor( _vt));
1937 double const fact_t( PlaMox_get_frost_factor( _vt, mc_.ts_airtemperature));
1938 double const fact_h( PlaMox_get_heat_factor( _vt));
1939 double const fact_o( PlaMox_get_hypoxia_factor( _vt));
1940 double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
1941 double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
1942
1943 double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
1944
1945 /* update activity of photosynthesis apparat */
1946 if ( cbm::flt_greater_zero( fact_all))
1947 {
1948 for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
1949 {
1950 //rubisco activity
1951 _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
1952
1953 //electron transport under standard conditions
1954 _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
1955
1956 //photorespiration under standard conditions
1957 _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
1958 }
1959 }
1960
1961 for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
1962 {
1963 plamox_berryball.vpd_fl[fl] = mc_.vpd_fl[fl];
1964 plamox_berryball.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
1965 plamox_berryball.temp_fl[fl] = mc_.temp_fl[fl];
1966 plamox_berryball.parsun_fl[fl] = mc_.parsun_fl[fl];
1967 plamox_berryball.parshd_fl[fl] = mc_.parshd_fl[fl];
1968 plamox_berryball.tFol_fl[fl] = mc_.tFol_fl[fl];
1969 plamox_berryball.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
1970 plamox_berryball.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
1971 }
1972 plamox_berryball.nd_airpressure = mc_.nd_airpressure;
1973 plamox_berryball.set_vegetation_base_state( _vt);
1974 plamox_berryball.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
1975
1976 plamox_berryball.solve();
1977
1978 plamox_berryball.get_vegetation_state( _vt);
1979
1980 double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
1981
1982 if ( cbm::flt_greater_zero( carbonuptake_sum))
1983 {
1984 timestep_c_assi += carbonuptake_sum;
1985 double const dw_assi( carbonuptake_sum / cbm::CCDM);
1986
1987 _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
1988 // the root length for mass from photosynthesis gets adapted in update root system
1989 _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
1990 _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
1991 _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
1992
1993 _vt->dcBud = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
1994 _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
1995 _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
1996 _vt->dcSap = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
1997
2003 }
2004
2005 return LDNDC_ERR_OK;
2006}
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3576
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3671
BerryBall plamox_berryball
Photosynthesis.
Definition: plamox.h:131
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3632
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3418
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3599
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3396

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.
3175{
3176 size_t const fl_cnt( _vt->nb_foliagelayers());
3177
3178 double sla_cum( 0.0);
3179 for (size_t fl = 0; fl < fl_cnt; ++fl)
3180 {
3181 sla_cum += _vt->sla_fl[fl];
3182 }
3183
3184 /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3185 double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3186 _vt->mFol));
3187 lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3188 lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3189 if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3190 {
3191 mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3192 }
3193
3194 if ( cbm::flt_greater_zero( sla_cum))
3195 {
3196 DroughtStress droughtstress;
3197 droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3198
3199 for (size_t fl = 0; fl < fl_cnt; ++fl)
3200 {
3201 _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3202 _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3203 //_vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3204 }
3205 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3206 {
3207 _vt->fFol_fl[fl] = 0.0;
3208 _vt->lai_fl[fl] = 0.0;
3209 _vt->sla_fl[fl] = 0.0;
3210 }
3211 }
3212 else
3213 {
3214 for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3215 {
3216 _vt->fFol_fl[fl] = 0.0;
3217 _vt->lai_fl[fl] = 0.0;
3218 _vt->sla_fl[fl] = 0.0;
3219 }
3220 }
3221}

References lai_min.

◆ PlaMox_update_ground_cover()

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

◆ 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.

3339{
3340 double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3341 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);
3342
3343// double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3344
3345 double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3346 cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3347 _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3348 + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3349 _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3350 double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3351 cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3352 _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3353 + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3354 _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3355 double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3356 cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3357 _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3358 + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3359 _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3360 double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3361 cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3362 _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3363 + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3364 _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3365
3366 double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3367 if ( cbm::flt_greater_zero( n_tot_opt))
3368 {
3369 // CB: fraction of available N to optimum N
3370 double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3371 // CB: N gets distributed evenly over all compartments regarding their optimum N content
3372 _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3373 (*_vt)->NC_FOLIAGE_MAX();
3374 _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3375 0.0;
3376 _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3377 (*_vt)->NC_FRUIT_MAX();
3378 _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3379 (*_vt)->NC_FINEROOTS_MAX();
3380 }
3381}
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3322

References PlaMox_get_foliage_nitrogen_concentration(), and PlaMox_n_opt().

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

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

3238{
3239 size_t const fl_cnt( _vt->nb_foliagelayers());
3240
3251 if ( IS_SPECIE( _vt->cname(), "mungbean"))
3252 {
3253 double slamax( 26.0);
3254 if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3255 {
3256 slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3257 }
3258 else
3259 {
3260 slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3261 }
3262
3263 for (size_t fl = 0; fl < fl_cnt; ++fl)
3264 {
3265 _vt->sla_fl[fl] = slamax;
3266 }
3267 }
3268 else if ( m_veg->is_family( _vt, ":rice:"))
3269 {
3270 double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3271 cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3272 _vt->dvsMort);
3273
3274 double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3275 for (size_t fl = 0; fl < fl_cnt; ++fl)
3276 {
3277 _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3278 }
3279 }
3280 else
3281 {
3282 // reduction of specific leaf area with crop age
3283 double sla_red( 1.0);
3284 if (_vt->groupId() == SPECIES_GROUP_GRASS)
3285 {
3286 if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3287 {
3288 sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3289 }
3290 }
3291 else
3292 {
3293 sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3294 }
3295
3296 for (size_t fl = 0; fl < fl_cnt; ++fl)
3297 {
3298 _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3299 }
3300 }
3301
3302 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3303 {
3304 _vt->sla_fl[fl] = 0.0;
3305 }
3306}

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(), and PlaMox_exsudation().

◆ 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().