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_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
 
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

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.

...

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

...

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 lai_min[_vt->slot] = 0.01;
511
512 location[_vt->slot] = _attributes.get( "/location", "?");
513
514 dw_retranslocation_stem[_vt->slot] = 0.0;
515 dw_retranslocation_foliage[_vt->slot] = 0.0;
516
517 dw_fol_old[_vt->slot] = 0.0;
518 lai_dynamic[_vt->slot] = 0.0;
519
520 //plant gets biomass by species initializer
521 //store and substract later according amounts of C and N
522 //for balance check at day of planting
523 double const plant_n_old( _vt->total_nitrogen());
524 double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
525
526 _vt->height_max = 0.0;
527 _vt->height_at_canopy_start = 0.0;
528
529 chill_units[_vt->slot] = 0.0;
530 chill_factor[_vt->slot] = 1.0;
531
532 _vt->f_heat_daily = 1.0;
533
534 if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
535 {
536 m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
537 }
538 else
539 {
540 m_fruit_maximum[_vt->slot] = -1.0;
541 }
542 spikelets_sterility[_vt->slot] = 0.0;
543
544 if ( m_veg->is_family( _vt, ":rice:"))
545 {
546 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
547 }
548 else if ( m_veg->is_family( _vt, ":wheat:"))
549 {
550 nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
551 }
552 else
553 {
554 nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
555 }
556
557 gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
558
559 hypoxia[_vt->slot] = 0.0;
560 transplanting_shock_vt[_vt->slot] = 0.0;
561
562 PlaMox_reset_phenology( _vt);
563
564 if ( cbm::is_equal( _vt->group().c_str(), "crop"))
565 {
566 lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
567 if ( rc_plant)
568 {
569 return LDNDC_ERR_OK;
570 }
571
572 /* only considered for rice so far */
573 int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
574 if ( seedbedduration > 0)
575 {
576 double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
577 _vt->growing_degree_days = seedbedduration * mean_gdd;
578 _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
579 transplanting_shock_vt[_vt->slot] = 1.0;
580 days_after_emergence[_vt->slot] = 0;
581 }
582 else
583 {
584 _vt->growing_degree_days = 0.0;
585 _vt->dvsFlush = 0.0;
586 }
587
588 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
589 allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
590 allocation_factor_stems[_vt->slot] = 0.0;
591 allocation_factor_fruit[_vt->slot] = 0.0;
592
593 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
594 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
595 _vt->n_lst = 0.0;
596 _vt->ncBud = 0.0;
597 _vt->ncSap = 0.0;
598 _vt->ncCor = 0.0;
599
600 double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
601 (*_vt)->FRACTION_ROOT_START() :
602 (*_vt)->FRACTION_ROOT());
603 double const initial_foliage_biomass_max( 0.02);
604 _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
605 initial_foliage_biomass_max );
606
607 _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
608 _vt->dw_lst = 0.0;
609 _vt->mBud = 0.0;
610 _vt->mSap = 0.0;
611 _vt->mCor = 0.0;
612
613 lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
614 n_plant[_vt->slot] = _vt->total_nitrogen();
616
617 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
618 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
619 }
620 else if ( cbm::is_equal( _vt->cgroup(), "grass"))
621 {
622 lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
623 if ( rc_plant)
624 {
625 return LDNDC_ERR_OK;
626 }
627
628 if ( lclock()->seconds() > cbm::SEC_IN_DAY)
629 {
630 PlaMox_reset_phenology( _vt);
631 }
632
633 /* set to fixed value */
634 lai_min[_vt->slot] = 0.1;
635
636 allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
637 allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
638 allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
639 allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
640
641 _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
642 _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
643 _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
644 _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
645
646 _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
647 _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
648 _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
649 _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
650
651 n_plant[_vt->slot] = _vt->total_nitrogen();
652
654
655 n_at_planting += (n_plant[_vt->slot] - plant_n_old);
656 timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
657 }
658 else
659 {
660 KLOGERROR( "I do not handle this group of species ",
661 "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
662 return LDNDC_ERR_RUNTIME_ERROR;
663 }
664
665 // currently no concept for free available carbon
666 _vt->f_fac = 0.0;
667
668 // initialize root system
669 if (plamox_root_system.size() <= _vt->slot)
670 {
671 plamox_root_system.resize(_vt->slot+1);
672 }
673
674 ldndc_kassert( plamox_root_system[_vt->slot] == NULL);
675 plamox_root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
676 if ( !plamox_root_system[_vt->slot])
677 {
678 KLOGERROR( "Failed to allocate root-system object");
679 return LDNDC_ERR_NOMEM;
680 }
681
682 double const seed_depth = _attributes.get( "/seed-depth", 0.05);
683 root_q_vt_[_vt->slot] = 0; // no rooted layers yet
684 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
685 {
686 if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
687 {
688 break;
689 }
690 root_q_vt_[_vt->slot] = sl; // no rooted layers yet
691 }
692
693 PlaMox_update_root_structure( _vt, _vt->mFrt);
694
695 return LDNDC_ERR_OK;
696}
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:3256
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
3601{
3602 if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3603 {
3604 if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3605 {
3606 return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3607 }
3608 return ( 1.0);
3609 }
3610 else
3611 {
3612 if ( days_after_emergence[_p->slot] < 0)
3613 {
3614 return 0.0;
3615 }
3616 else
3617 {
3618 if ( cbm::flt_less_equal( _p->growing_degree_days, (*_p)->GDD_MATURITY()))
3619 {
3620 return ( 1.0);
3621 }
3622 else
3623 {
3624 return 1.0 / std::exp( 0.01 * (_p->growing_degree_days - (*_p)->GDD_MATURITY()));
3625 }
3626 }
3627 }
3628}

Referenced by PlaMox_photosynthesis(), and PlaMox_update_ground_cover().

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
3562{
3563 if ( m_veg->is_family( _vt, ":wheat:"))
3564 {
3565 double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3566 double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3567
3568 if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3569 cbm::flt_greater( _vt->dw_lst, lst_opt))
3570 {
3571 return lst_opt / _vt->dw_lst;
3572 }
3573 }
3574
3575 return 1.0;
3576}

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
3316{
3317 double const t_min( (*_vt)->TLIMIT() - 2.0);
3318 double const t_max( (*_vt)->TLIMIT());
3319
3320 if ( cbm::flt_less( _temp, t_min))
3321 {
3322 return 0.0;
3323 }
3324 else if ( cbm::flt_less( _temp, t_max))
3325 {
3326 return (_temp - t_min) / (t_max - t_min);
3327 }
3328 else
3329 {
3330 return 1.0;
3331 }
3332}

Referenced by PlaMox_photosynthesis(), and PlaMox_update_ground_cover().

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
3529{
3530// if ( m_veg->is_family( _vt, ":winterwheat:"))
3531// {
3532// double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3533// (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3534// double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3535// _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3536// double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3537// double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3538//
3539// return cbm::bound( 0.01,
3540// vc / vc_max,
3541// 1.0);
3542// }
3543// else
3544 {
3545 double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3546 if ( n_ratio < 1.0)
3547 {
3548 return cbm::bound( 0.01,
3549 pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3550 1.0);
3551 }
3552 else
3553 {
3554 return 1.0;
3555 }
3556 }
3557}

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} \)
3241{
3242 return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3243 + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3244 + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3245 + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3246}
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition plamox.cpp:3639

References PlaMox_get_foliage_nitrogen_concentration().

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

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

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.
3093{
3094 size_t const fl_cnt( _vt->nb_foliagelayers());
3095
3096 double sla_cum( 0.0);
3097 for (size_t fl = 0; fl < fl_cnt; ++fl)
3098 {
3099 sla_cum += _vt->sla_fl[fl];
3100 }
3101
3102 /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3103 double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3104 _vt->mFol));
3105 lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3106 lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3107 if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3108 {
3109 mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3110 }
3111
3112 if ( cbm::flt_greater_zero( sla_cum))
3113 {
3114 DroughtStress droughtstress;
3115 droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3116
3117 for (size_t fl = 0; fl < fl_cnt; ++fl)
3118 {
3119 _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3120 _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3121 //_vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3122 }
3123 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3124 {
3125 _vt->fFol_fl[fl] = 0.0;
3126 _vt->lai_fl[fl] = 0.0;
3127 _vt->sla_fl[fl] = 0.0;
3128 }
3129 }
3130 else
3131 {
3132 for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3133 {
3134 _vt->fFol_fl[fl] = 0.0;
3135 _vt->lai_fl[fl] = 0.0;
3136 _vt->sla_fl[fl] = 0.0;
3137 }
3138 }
3139}

References lai_min.

Referenced by PlaMox_update_ground_cover().

Here is the caller graph for this function:

◆ PlaMox_update_ground_cover()

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

3257{
3258 double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3259 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);
3260
3261// double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3262
3263 double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3264 cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3265 _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3266 + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3267 _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3268 double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3269 cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3270 _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3271 + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3272 _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3273 double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3274 cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3275 _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3276 + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3277 _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3278 double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3279 cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3280 _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3281 + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3282 _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3283
3284 double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3285 if ( cbm::flt_greater_zero( n_tot_opt))
3286 {
3287 // CB: fraction of available N to optimum N
3288 double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3289 // CB: N gets distributed evenly over all compartments regarding their optimum N content
3290 _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3291 (*_vt)->NC_FOLIAGE_MAX();
3292 _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3293 0.0;
3294 _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3295 (*_vt)->NC_FRUIT_MAX();
3296 _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3297 (*_vt)->NC_FINEROOTS_MAX();
3298 }
3299}
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition plamox.cpp:3240

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

3156{
3157 size_t const fl_cnt( _vt->nb_foliagelayers());
3158
3169 if ( IS_SPECIE( _vt->cname(), "mungbean"))
3170 {
3171 double slamax( 26.0);
3172 if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3173 {
3174 slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3175 }
3176 else
3177 {
3178 slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3179 }
3180
3181 for (size_t fl = 0; fl < fl_cnt; ++fl)
3182 {
3183 _vt->sla_fl[fl] = slamax;
3184 }
3185 }
3186 else if ( m_veg->is_family( _vt, ":rice:"))
3187 {
3188 double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3189 cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3190 _vt->dvsMort);
3191
3192 double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3193 for (size_t fl = 0; fl < fl_cnt; ++fl)
3194 {
3195 _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3196 }
3197 }
3198 else
3199 {
3200 // reduction of specific leaf area with crop age
3201 double sla_red( 1.0);
3202 if (_vt->groupId() == SPECIES_GROUP_GRASS)
3203 {
3204 if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3205 {
3206 sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3207 }
3208 }
3209 else
3210 {
3211 sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3212 }
3213
3214 for (size_t fl = 0; fl < fl_cnt; ++fl)
3215 {
3216 _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3217 }
3218 }
3219
3220 for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3221 {
3222 _vt->sla_fl[fl] = 0.0;
3223 }
3224}

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