LandscapeDNDC  1.36.0
ldndc::PhysiologyPlaMox Class Reference

Plamox. More...

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 *)
 calculates new height of plant depending on the ratio of current to optimum aboveground biomass More...
 
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

NitrogenFixation * NitrogenFixation_
 Nitrogen fixation.
 
LD_PlantFunctions m_pf
 All kind of plant related functions.
 
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
 Root system. More...
 
cbm::string_t transpiration_method
 Transpiration method used by PlaMox.
 
bool have_drought_stress
 Consider drought 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

Plamox.

Author
David Kraus

Constructor & Destructor Documentation

◆ ~PhysiologyPlaMox()

ldndc::PhysiologyPlaMox::~PhysiologyPlaMox ( )

Delete allocated classes.

Delete:

  • roots system
  • nitrogen fixation

References droughtstress_method, have_drought_stress, m_pf, NitrogenFixation_, plantfamilies, root_system, and transpiration_method.

203 {
204  for ( size_t r = 0; r < root_system.size(); ++r)
205  {
206  if ( root_system[r])
207  {
208  LD_Allocator->destroy( root_system[r]);
209  }
210  }
211 
212  delete NitrogenFixation_;
213 }
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:147
NitrogenFixation * NitrogenFixation_
Nitrogen fixation.
Definition: plamox.h:129

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.

...

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_factor, chill_units, root_q_vt_, and root_system.

Referenced by PlaMox_event_plant().

896 {
897  if ( root_system[_vt->slot] == NULL)
898  {
899  KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
900  return LDNDC_ERR_RUNTIME_ERROR;
901  }
902 
903  bool const mulching = _attributes.get( "/mulching", false);
904 
905  double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
906  double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
907  double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
908  double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
909  double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
910 
911  double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
912  double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
913 
914  double const fru_c( _vt->mBud * cbm::CCDM);
915  double const fru_n( _vt->n_bud());
916 
917  double fru_c_export( 0.0);
918  double fru_n_export( 0.0);
919 
920  double straw_c_export( 0.0);
921  double straw_n_export( 0.0);
922 
923  double mulching_c( 0.0);
924  double mulching_n( 0.0);
925 
926  double stubble_c( 0.0);
927  double stubble_n( 0.0);
928 
929  double gdd_sum( _vt->growing_degree_days );
930  double dvs_flush( _vt->dvsFlush );
931 
932  double const height( _attributes.get( "/height", invalid_flt));
933  double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
934  double remains_absolute( _attributes.get( "/remains_absolute", invalid_flt));
935  if( cbm::is_valid( remains_absolute))
936  {
937  remains_absolute *= cbm::HA_IN_M2;
938  }
939 
940  if ( !cbm::flt_greater_equal_zero( remains_relative)
941  && !cbm::flt_greater_equal_zero( remains_absolute)
942  && !cbm::flt_greater_equal_zero( height))
943  {
944  if ( _vt->is_covercrop)
945  {
946  remains_relative = 1.0;
947  }
948  else
949  {
950  KLOGWARN( "harvest event attribute \"remains_relative\" and \"remains_absolute\" and \"height\" not set;",
951  " \"remains_relative\" set to zero and used [species=", _vt->name(),"]");
952  }
953  }
954  else if ( (cbm::flt_greater_equal_zero( remains_relative) ||
955  cbm::flt_greater_equal_zero( remains_absolute))
956  && cbm::flt_greater_equal_zero( height))
957  {
958  KLOGWARN( "harvest event attribute \"remains_(relative/absolute)\" and \"height\" both set;"
959  " attribute \"remains_relative\" used [species=", _vt->name(),"]");
960  }
961 
962  if ( cbm::flt_greater_equal_zero( remains_relative))
963  {
964  /* no op */
965  }
966  else if ( cbm::flt_greater_equal_zero( remains_absolute))
967  {
968  remains_relative = cbm::bound( 0.0,
969  remains_absolute / (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst),
970  1.0);
971  }
972  else if ( cbm::flt_equal_zero( height))
973  {
974  remains_relative = 0.0;
975  }
976  else if ( cbm::flt_greater_zero( height))
977  {
978  double h_cum( 0.0);
979  double remains_relative_fol = 0.0;
980  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
981  {
982  remains_relative_fol += _vt->fFol_fl[fl];
983  h_cum += ph_.h_fl[fl];
984  if ( cbm::flt_greater_equal( h_cum, height))
985  {
986  break;
987  }
988  }
989 
990  h_cum = 0.0;
991  double remains_relative_lst = 0.0;
992  double remains_relative_lst_total = 0.0;
993  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
994  {
995  //lst decreases with height
996  remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
997  if ( cbm::flt_less_equal( h_cum, height))
998  {
999  remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
1000  }
1001  h_cum += ph_.h_fl[fl];
1002  }
1003  remains_relative_lst /= remains_relative_lst_total;
1004 
1005  remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
1006  remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
1007  (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
1008  }
1009  else
1010  {
1011  KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
1012  return LDNDC_ERR_FAIL;
1013  }
1014 
1015  stubble_c += remains_relative * straw_c;
1016  stubble_n += remains_relative * straw_n;
1017  if ( mulching)
1018  {
1019  mulching_c += (1.0-remains_relative) * straw_c;
1020  mulching_n += (1.0-remains_relative) * straw_n;
1021  }
1022  else
1023  {
1024  straw_c_export += (1.0-remains_relative) * straw_c;
1025  straw_n_export += (1.0-remains_relative) * straw_n;
1026  }
1027 
1028  if ( _vt->is_covercrop)
1029  {
1030  stubble_c += remains_relative * fru_c;
1031  stubble_n += remains_relative * fru_n;
1032  if ( mulching)
1033  {
1034  mulching_c += (1.0-remains_relative) * fru_c;
1035  mulching_n += (1.0-remains_relative) * fru_n;
1036  }
1037  else
1038  {
1039  stubble_c += (1.0-remains_relative) * fru_c;
1040  stubble_n += (1.0-remains_relative) * fru_n;
1041  }
1042  }
1043  else
1044  {
1045  fru_c_export = fru_c;
1046  fru_n_export = fru_n;
1047  }
1048 
1049  //export
1050  c_total_exported += straw_c_export + fru_c_export;
1051  c_fruit_exported += fru_c_export;
1052  n_total_exported += straw_n_export + fru_n_export;
1053  n_fruit_exported += fru_n_export;
1054 
1055  ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
1056  ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
1057 
1058  ph_.accumulated_c_fru_export_harvest += fru_c_export;
1059  ph_.accumulated_n_fru_export_harvest += fru_n_export;
1060 
1061  //stubble litter
1062  sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
1063  sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
1064  sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1065  sc_.accumulated_c_litter_stubble += stubble_c;
1066 
1067  sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
1068  sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
1069  sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1070  sc_.accumulated_n_litter_stubble += stubble_n;
1071 
1072  //raw litter
1073  sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1074  sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
1075  sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
1076  sc_.accumulated_c_litter_above += mulching_c;
1077 
1078  sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1079  sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
1080  sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
1081  sc_.accumulated_n_litter_above += mulching_n;
1082 
1083  //root litter
1084  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1085  {
1086  double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
1087  double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
1088 
1089  sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
1090  sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
1091  sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
1092  sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
1093 
1094  sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1095  sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
1096  sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
1097  sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
1098  }
1099 
1100  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
1101  std::string mcom_key;
1102 
1103  char const * species_name = _attributes.get( "/name", "?");
1104 
1105  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
1106  mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
1107 
1108  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
1109  mcom->set( mcom_key.c_str(), gdd_sum);
1110 
1111  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
1112  mcom->set( mcom_key.c_str(), dvs_flush);
1113 
1114  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
1115  mcom->set( mcom_key.c_str(), fru_c);
1116 
1117  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
1118  mcom->set( mcom_key.c_str(), fru_c_export);
1119 
1120  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
1121  mcom->set( mcom_key.c_str(), fru_n);
1122 
1123  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
1124  mcom->set( mcom_key.c_str(), fru_n_export);
1125 
1126  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
1127  mcom->set( mcom_key.c_str(), straw_c);
1128 
1129  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
1130  mcom->set( mcom_key.c_str(), straw_c_export);
1131 
1132  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
1133  mcom->set( mcom_key.c_str(), straw_n);
1134 
1135  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
1136  mcom->set( mcom_key.c_str(), straw_n_export);
1137 
1138  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
1139  mcom->set( mcom_key.c_str(), stubble_c);
1140 
1141  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1142  mcom->set( mcom_key.c_str(), stubble_n);
1143 
1144  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1145  mcom->set( mcom_key.c_str(), rootlitter_c);
1146 
1147  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1148  mcom->set( mcom_key.c_str(), rootlitter_n);
1149 
1150  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1151  {
1152  _vt->fFrt_sl[sl] = 0.0;
1153  }
1154 
1155  cbm::invalidate( root_q_vt_[_vt->slot]);
1156  _vt->rooting_depth = 0.0;
1157 
1158  days_after_emergence[_vt->slot] = -1;
1159 
1160  dw_retranslocation_stem[_vt->slot] = 0.0;
1161  dw_retranslocation_foliage[_vt->slot] = 0.0;
1162 
1163  dw_fol_old[_vt->slot] = 0.0;
1164  lai_dynamic[_vt->slot] = 0.0;
1165 
1166  _vt->mFol = 0.0;
1167  _vt->dw_dfol = 0.0;
1168  _vt->ncFol = 0.0;
1169  _vt->n_dfol = 0.0;
1170 
1171  _vt->dw_lst = 0.0;
1172  _vt->n_lst = 0.0;
1173 
1174  _vt->dw_dst = 0.0;
1175  _vt->n_dst = 0.0;
1176 
1177  _vt->mBud = 0.0;
1178  _vt->mBudStart = 0.0;
1179  _vt->ncBud = 0.0;
1180 
1181  _vt->mFrt = 0.0;
1182  _vt->ncFrt = 0.0;
1183 
1184  _vt->dEmerg = -1;
1185  _vt->growing_degree_days = 0.0;
1186  _vt->dvsMort = 0.0;
1187  _vt->dvsFlush = 0.0;
1188  _vt->dvsFlushOld = 0.0;
1189 
1190  n_plant[_vt->slot] = 0.0;
1191  _vt->a_fix_n = 0.0;
1192 
1193  _vt->height_max = 0.0;
1194  _vt->height_at_canopy_start = 0.0;
1195 
1196  _vt->f_area = 0.0;
1197  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1198  {
1199  _vt->fFol_fl[fl] = 0.0;
1200  _vt->lai_fl[fl] = 0.0;
1201  }
1202 
1203  _vt->f_fac = 0.0;
1204  chill_units[_vt->slot] = 0.0;
1205  chill_factor[_vt->slot] = 1.0;
1206 
1207  yearly_cuts[_vt->slot] = 0;
1208 
1209  allocation_factor_leafs[_vt->slot] = 0.0;
1210  allocation_factor_stems[_vt->slot] = 0.0;
1211  allocation_factor_fruit[_vt->slot] = 0.0;
1212  allocation_factor_roots[_vt->slot] = 0.0;
1213 
1214  m_fruit_maximum[_vt->slot] = -1.0;
1215  spikelets_sterility[_vt->slot] = 0.0;
1216  hypoxia[_vt->slot] = 0.0;
1217 
1218  LD_Allocator->destroy( root_system[_vt->slot]);
1219  root_system[_vt->slot] = NULL;
1220 
1221  return LDNDC_ERR_OK;
1222 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:336
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:275
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:281
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:306
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:287
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:312
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:269
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:147
Here is the caller graph for this function:

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

...

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_event_harvest(), PlaMox_update_nitrogen_concentrations(), PlaMox_update_root_structure(), plantfamilies, root_q_vt_, and root_system.

Referenced by PlaMox_step_init().

587 {
588  species_t const * sp = NULL;
589  if ( m_species)
590  {
591  sp = m_species->get_species( _vt->cname());
592  }
593 
595 
596  seconds_crop_planting[_vt->slot] = lclock()->seconds();
597  fractional_cover[_vt->slot] = _attributes.get( "/fractional-cover", 1.0);
598 
599  //Scale growing degree days
600  //Currently only used by FarmSystem to dynamically adjust species
601  //over larger regions and/or time periods
602  double gdd_maturity_target( _attributes.get( "/gdd-maturity-target", -1.0));
603  if ( cbm::flt_less( gdd_maturity_target, 0.0) &&
604  (std::strstr( _vt->cname(), "GDD-MATURITY-TARGET") != NULL) &&
605  gdd_target.find( _vt->cname()) != gdd_target.end())
606  {
607  gdd_maturity_target = gdd_target[_vt->cname()];
608  }
609 
610  if ( cbm::flt_greater_zero( gdd_maturity_target) &&
611  cbm::flt_greater_zero( (*_vt)->GDD_MATURITY()))
612  {
613  double const scale_gdd( gdd_maturity_target / (*_vt)->GDD_MATURITY());
614  MoBiLE_PlantParameters p_parameters = (*m_speciesparameters)[_vt->ctype()];
615  p_parameters.GDD_EMERGENCE_UPDATE( (*_vt)->GDD_EMERGENCE() * scale_gdd);
616  p_parameters.GDD_STEM_ELONGATION_UPDATE( (*_vt)->GDD_STEM_ELONGATION() * scale_gdd);
617  p_parameters.GDD_FLOWERING_UPDATE( (*_vt)->GDD_FLOWERING() * scale_gdd);
618  p_parameters.GDD_GRAIN_FILLING_UPDATE( (*_vt)->GDD_GRAIN_FILLING() * scale_gdd);
619  p_parameters.GDD_ROOTS_GROWN_UPDATE( (*_vt)->GDD_ROOTS_GROWN() * scale_gdd);
620  p_parameters.GDD_MATURITY_UPDATE( gdd_maturity_target);
621  _vt->switchparameters( p_parameters);
622  }
623 
624  _vt->is_covercrop = _attributes.get( "/cover-crop", false);
625  //_vt->f_fac = (*_vt)->FFACMAX();
626 
627  //amount of seeds
628  double initial_biomass = _attributes.get( "/initial-biomass", 0.0);
629  if ( cbm::flt_equal( initial_biomass, 0.0))
630  {
631  if ( m_veg->is_family( _vt, ":rice:"))
632  {
633  initial_biomass = 200.0;
634  }
635  else if ( m_veg->is_family( _vt, ":wheat:"))
636  {
637  initial_biomass = 150.0;
638  }
639  else if ( m_veg->is_family( _vt, ":corn:"))
640  {
641  initial_biomass = 50.0;
642  }
643  else if ( m_veg->is_family( _vt, ":rapeseed:"))
644  {
645  initial_biomass = 10.0;
646  }
647  }
648 
649  initial_biomass = cbm::bound_min( 0.0001, initial_biomass * cbm::HA_IN_M2);
650  lai_min[_vt->slot] = 0.01;
651 
652  location[_vt->slot] = _attributes.get( "/location", "?");
653 
654  dw_retranslocation_stem[_vt->slot] = 0.0;
655  dw_retranslocation_foliage[_vt->slot] = 0.0;
656 
657  dw_fol_old[_vt->slot] = 0.0;
658  lai_dynamic[_vt->slot] = 0.0;
659 
660  //plant gets biomass by species initializer
661  //store and substract later according amounts of C and N
662  //for balance check at day of planting
663  double const plant_n_old( _vt->total_nitrogen());
664  double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
665 
666  _vt->height_max = 0.0;
667  _vt->height_at_canopy_start = 0.0;
668 
669  chill_units[_vt->slot] = 0.0;
670  chill_factor[_vt->slot] = 1.0;
671 
672  if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
673  {
674  m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
675  }
676  else
677  {
678  m_fruit_maximum[_vt->slot] = -1.0;
679  }
680  spikelets_sterility[_vt->slot] = 0.0;
681 
682  if ( m_veg->is_family( _vt, ":rice:"))
683  {
684  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
685  }
686  else if ( m_veg->is_family( _vt, ":wheat:"))
687  {
688  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
689  }
690  else
691  {
692  nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
693  }
694 
695  gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
696 
697  hypoxia[_vt->slot] = 0.0;
698  transplanting_shock_vt[_vt->slot] = 0.0;
699 
700  PlaMox_reset_phenology( _vt);
701 
702  if ( cbm::is_equal( _vt->group().c_str(), "crop"))
703  {
704  lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
705  if ( rc_plant)
706  {
707  return LDNDC_ERR_OK;
708  }
709 
710  /* only considered for rice so far */
711  int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
712  if ( seedbedduration > 0)
713  {
714  double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
715  _vt->growing_degree_days = seedbedduration * mean_gdd;
716  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
717  transplanting_shock_vt[_vt->slot] = 1.0;
718  days_after_emergence[_vt->slot] = 0;
719  }
720  else
721  {
722  _vt->growing_degree_days = 0.0;
723  _vt->dvsFlush = 0.0;
724  }
725 
726  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
727  allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
728  allocation_factor_stems[_vt->slot] = 0.0;
729  allocation_factor_fruit[_vt->slot] = 0.0;
730 
731  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
732  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
733  _vt->n_lst = 0.0;
734  _vt->ncBud = 0.0;
735  _vt->ncSap = 0.0;
736  _vt->ncCor = 0.0;
737 
738  double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
739  (*_vt)->FRACTION_ROOT_START() :
740  (*_vt)->FRACTION_ROOT());
741  double const initial_foliage_biomass_max( 0.02);
742  _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
743  initial_foliage_biomass_max );
744 
745  _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
746  _vt->dw_lst = 0.0;
747  _vt->mBud = 0.0;
748  _vt->mSap = 0.0;
749  _vt->mCor = 0.0;
750 
751  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
752  n_plant[_vt->slot] = _vt->total_nitrogen();
754 
755  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
756  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
757  }
758  else if ( cbm::is_equal( _vt->cgroup(), "grass"))
759  {
760  lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
761  if ( rc_plant)
762  {
763  return LDNDC_ERR_OK;
764  }
765 
766  if ( lclock()->seconds() > cbm::SEC_IN_DAY)
767  {
768  PlaMox_reset_phenology( _vt);
769  }
770 
771  /* set to fixed value */
772  lai_min[_vt->slot] = 0.1;
773 
774  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
775  allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
776  allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
777  allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
778 
779  _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
780  _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
781  _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
782  _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
783 
784  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
785  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
786  _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
787  _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
788 
789  n_plant[_vt->slot] = _vt->total_nitrogen();
790 
792 
793  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
794  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
795  }
796  else
797  {
798  KLOGERROR( "I do not handle this group of species ",
799  "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
800  return LDNDC_ERR_RUNTIME_ERROR;
801  }
802 
803  // currently no concept for free available carbon
804  _vt->f_fac = 0.0;
805 
806  // initialize root system
807  if (root_system.size() <= _vt->slot)
808  {
809  root_system.resize(_vt->slot+1);
810  }
811 
812  ldndc_kassert( root_system[_vt->slot] == NULL);
813  root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
814  if ( !root_system[_vt->slot])
815  {
816  KLOGERROR( "Failed to allocate root-system object");
817  return LDNDC_ERR_NOMEM;
818  }
819 
820  double const seed_depth = _attributes.get( "/seed-depth", 0.05);
821  root_q_vt_[_vt->slot] = 0; // no rooted layers yet
822  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
823  {
824  if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
825  {
826  break;
827  }
828  root_q_vt_[_vt->slot] = sl; // no rooted layers yet
829  }
830 
831  PlaMox_update_root_structure( _vt, _vt->mFrt);
832 
833  return LDNDC_ERR_OK;
834 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:336
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:275
speciesparameters::speciesparameters_set_t MoBiLE_PlantParameters
Definition: mbe_plant.h:25
lvector_t< double > daytime_temperatures
store daytime temperature for heat stress analysis
Definition: plamox.h:342
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:281
void PlaMox_update_root_structure(MoBiLE_Plant *, double)
Updates all relevant root structural matters.
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:306
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3482
LD_PlantFunctions m_pf
All kind of plant related functions.
Definition: plamox.h:135
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:287
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:312
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:300
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:269
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:294
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:147
Here is the call graph for this function:
Here is the caller 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

Referenced by PlaMox_photosynthesis().

3810 {
3811  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3812  {
3813  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3814  {
3815  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3816  }
3817  return ( 1.0);
3818  }
3819  else
3820  {
3821  if ( days_after_emergence[_p->slot] < 0)
3822  {
3823  return 0.0;
3824  }
3825  else
3826  {
3827  if ( cbm::flt_less( _p->dvsFlush, 0.95))
3828  {
3829  return ( 1.0);
3830  }
3831  else
3832  {
3833  return cbm::bound_min( 0.0, (1.0 - _p->dvsFlush) / 0.05);
3834  }
3835  }
3836  }
3837 }
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

References fractional_cover.

Referenced by PlaMox_photosynthesis().

3771 {
3772  if ( m_veg->is_family( _vt, ":wheat:"))
3773  {
3774  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3775  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3776 
3777  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3778  cbm::flt_greater( _vt->dw_lst, lst_opt))
3779  {
3780  return lst_opt / _vt->dw_lst;
3781  }
3782  }
3783 
3784  return 1.0;
3785 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:300
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

Referenced by PlaMox_exsudation(), and PlaMox_photosynthesis().

3542 {
3543  double const t_min( (*_vt)->TLIMIT() - 2.0);
3544  double const t_max( (*_vt)->TLIMIT());
3545 
3546  if ( cbm::flt_less( _temp, t_min))
3547  {
3548  return 0.0;
3549  }
3550  else if ( cbm::flt_less( _temp, t_max))
3551  {
3552  return (_temp - t_min) / (t_max - t_min);
3553  }
3554  else
3555  {
3556  return 1.0;
3557  }
3558 }
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

Referenced by PlaMox_photosynthesis().

3738 {
3739 // if ( m_veg->is_family( _vt, ":winterwheat:"))
3740 // {
3741 // double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3742 // (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3743 // double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3744 // _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3745 // double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3746 // double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3747 //
3748 // return cbm::bound( 0.01,
3749 // vc / vc_max,
3750 // 1.0);
3751 // }
3752 // else
3753  {
3754  double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3755  if ( n_ratio < 1.0)
3756  {
3757  return cbm::bound( 0.01,
3758  pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3759  1.0);
3760  }
3761  else
3762  {
3763  return 1.0;
3764  }
3765  }
3766 }
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} \)

References PlaMox_get_foliage_nitrogen_concentration().

Referenced by PlaMox_photosynthesis(), and PlaMox_update_nitrogen_concentrations().

3467 {
3468  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3469  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3470  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3471  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3472 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3848
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()

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_factor, fractional_cover, FTS_TOT_, have_drought_stress, m_pf, NitrogenFixation_, 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(), PlaMox_n_opt(), PlaMox_nitrogen_fixation(), PlaMox_nitrogen_uptake(), PlaMox_respiration(), PlaMox_update_nitrogen_concentrations(), root_q_vt_, and root_system.

2069 {
2070  DroughtStress droughtstress;
2071  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
2072  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
2073  double const fact_a( PlaMox_get_age_factor( _vt));
2074  double const fact_t( PlaMox_get_frost_factor( _vt, *mc_temp));
2075  double const fact_h( PlaMox_get_heat_factor( _vt));
2076  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
2077  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
2078  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
2079 
2080  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
2081 
2082  /* update activity of photosynthesis apparat */
2083  if ( cbm::flt_greater_zero( fact_all))
2084  {
2085  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2086  {
2087  //rubisco activity
2088  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
2089 
2090  //electron transport under standard conditions
2091  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
2092 
2093  //photorespiration under standard conditions
2094  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2095  }
2096  }
2097 
2098  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2099  {
2100  m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
2101  m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2102  m_photo.temp_fl[fl] = mc_.temp_fl[fl];
2103  m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
2104  m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
2105  m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
2106  m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2107  m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2108  }
2109  m_photo.nd_airpressure = mc_.nd_airpressure;
2110  m_photo.set_vegetation_base_state( _vt);
2111  m_photo.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
2112 
2113  m_photo.solve();
2114 
2115  m_photo.get_vegetation_state( _vt);
2116 
2117  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2118 
2119  if ( cbm::flt_greater_zero( carbonuptake_sum))
2120  {
2121  timestep_c_assi += carbonuptake_sum;
2122  double const dw_assi( carbonuptake_sum / cbm::CCDM);
2123 
2124  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2125  // the root length for mass from photosynthesis gets adapted in update root system
2126  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2127  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2128  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2129 
2130  dcFru[_vt->slot] = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2131  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2132  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2133  dcLst[_vt->slot] = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2134 
2140  }
2141 
2142  return LDNDC_ERR_OK;
2143 }
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3737
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3562
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:275
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3720
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3540
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3809
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3770
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:281
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3482
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:287
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:269
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.

References lai_min.

3319 {
3320  size_t const fl_cnt( _vt->nb_foliagelayers());
3321 
3322  double sla_cum( 0.0);
3323  for (size_t fl = 0; fl < fl_cnt; ++fl)
3324  {
3325  sla_cum += _vt->sla_fl[fl];
3326  }
3327 
3328  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3329  double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3330  _vt->mFol));
3331  lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3332  lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3333  if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3334  {
3335  mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3336  }
3337 
3338  if ( cbm::flt_greater_zero( sla_cum))
3339  {
3340  DroughtStress droughtstress;
3341  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3342 
3343  for (size_t fl = 0; fl < fl_cnt; ++fl)
3344  {
3345  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3346  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3347  //_vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3348  }
3349  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3350  {
3351  _vt->fFol_fl[fl] = 0.0;
3352  _vt->lai_fl[fl] = 0.0;
3353  _vt->sla_fl[fl] = 0.0;
3354  }
3355  }
3356  else
3357  {
3358  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3359  {
3360  _vt->fFol_fl[fl] = 0.0;
3361  _vt->lai_fl[fl] = 0.0;
3362  _vt->sla_fl[fl] = 0.0;
3363  }
3364  }
3365 }
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:294

◆ PlaMox_update_ground_cover()

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

Referenced by PlaMox_transpiration().

Here is the caller graph for this function:

◆ PlaMox_update_height()

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

calculates new height of plant depending on the ratio of current to optimum aboveground biomass

Parameters
[in]_vtPlant species

References fractional_cover.

3267 {
3268  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3269  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3270  if ( _vt->group() == "crop")
3271  {
3272  //height evegrowth starts with stem elongation
3273  //minimum of 1% development until start of height growth required: dvs_of_start_height !> 0.0
3274  double const dvs_of_start_height( cbm::bound_min( 0.01, (*_vt)->GDD_STEM_ELONGATION() / (*_vt)->GDD_MATURITY()));
3275  //minimum of 2% development until end of height growth required: dvs_of_end_height !> dvs_of_start_height
3276  double const dvs_of_max_height( cbm::bound_min( 0.02, gdd_grain_filling[_vt->slot] / (*_vt)->GDD_MATURITY()));
3277 
3278  //until start of stem elongation, height modeled with plant development
3279  //10% of final height is always reached until start of stem elongation
3280  double const height_fraction_at_stem_elongation( 0.1);
3281  double height_fraction( cbm::bound_max( _vt->dvsFlush / dvs_of_start_height, 1.0) * height_fraction_at_stem_elongation);
3282  if ( cbm::flt_greater( _vt->dvsFlush, dvs_of_start_height))
3283  {
3284  double const biomass_fraction( cbm::bound_max( cbm::sqrt((_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt)), 1.0));
3285  //bound biomass-depending height by plant development
3286  //max should not be reached before start of grain filling (end of phase of stem elongation)
3287  height_fraction = cbm::bound( height_fraction,
3288  biomass_fraction,
3289  height_fraction_at_stem_elongation +
3290  (1.0 - height_fraction_at_stem_elongation) *
3291  (_vt->dvsFlush - dvs_of_start_height)/ (dvs_of_max_height- dvs_of_start_height));
3292  }
3293  _vt->height_max = cbm::bound_min( _vt->height_max, height_fraction * (*_vt)->HEIGHT_MAX());
3294  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3295  }
3296  else
3297  {
3298  _vt->height_max = cbm::bound_max( (_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt) * (*_vt)->HEIGHT_MAX(), (*_vt)->HEIGHT_MAX());
3299  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3300  }
3301 
3302  // update height of canopy layers (m)
3303  ph_.update_canopy_layers_height( m_veg);
3304 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:300

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

References PlaMox_get_foliage_nitrogen_concentration(), and PlaMox_n_opt().

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

3483 {
3484  double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3485  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);
3486 
3487 // double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3488 
3489  double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3490  cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3491  _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3492  + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3493  _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3494  double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3495  cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3496  _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3497  + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3498  _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3499  double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3500  cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3501  _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3502  + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3503  _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3504  double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3505  cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3506  _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3507  + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3508  _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3509 
3510  double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3511  if ( cbm::flt_greater_zero( n_tot_opt))
3512  {
3513  // CB: fraction of available N to optimum N
3514  double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3515  // CB: N gets distributed evenly over all compartments regarding their optimum N content
3516  _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3517  (*_vt)->NC_FOLIAGE_MAX();
3518  _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3519  0.0;
3520  _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3521  (*_vt)->NC_FRUIT_MAX();
3522  _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3523  (*_vt)->NC_FINEROOTS_MAX();
3524  }
3525 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3848
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3466
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(), and PlaMox_transpiration().

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

3382 {
3383  size_t const fl_cnt( _vt->nb_foliagelayers());
3384 
3395  if ( IS_SPECIE( _vt->cname(), "mungbean"))
3396  {
3397  double slamax( 26.0);
3398  if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3399  {
3400  slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3401  }
3402  else
3403  {
3404  slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3405  }
3406 
3407  for (size_t fl = 0; fl < fl_cnt; ++fl)
3408  {
3409  _vt->sla_fl[fl] = slamax;
3410  }
3411  }
3412  else if ( m_veg->is_family( _vt, ":rice:"))
3413  {
3414  double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3415  cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3416  _vt->dvsMort);
3417 
3418  double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3419  for (size_t fl = 0; fl < fl_cnt; ++fl)
3420  {
3421  _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3422  }
3423  }
3424  else
3425  {
3426  // reduction of specific leaf area with crop age
3427  double sla_red( 1.0);
3428  if (_vt->groupId() == SPECIES_GROUP_GRASS)
3429  {
3430  if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3431  {
3432  sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3433  }
3434  }
3435  else
3436  {
3437  sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3438  }
3439 
3440  for (size_t fl = 0; fl < fl_cnt; ++fl)
3441  {
3442  _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3443  }
3444  }
3445 
3446  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3447  {
3448  _vt->sla_fl[fl] = 0.0;
3449  }
3450 }

Member Data Documentation

◆ root_system

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

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