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

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

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

3831 {
3832  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3833  {
3834  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3835  {
3836  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3837  }
3838  return ( 1.0);
3839  }
3840  else
3841  {
3842  if ( days_after_emergence[_p->slot] < 0)
3843  {
3844  return 0.0;
3845  }
3846  else
3847  {
3848  if ( cbm::flt_less( _p->dvsFlush, 0.95))
3849  {
3850  return ( 1.0);
3851  }
3852  else
3853  {
3854  return cbm::bound_min( 0.0, (1.0 - _p->dvsFlush) / 0.05);
3855  }
3856  }
3857  }
3858 }
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().

3792 {
3793  if ( m_veg->is_family( _vt, ":wheat:"))
3794  {
3795  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3796  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3797 
3798  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3799  cbm::flt_greater( _vt->dw_lst, lst_opt))
3800  {
3801  return lst_opt / _vt->dw_lst;
3802  }
3803  }
3804 
3805  return 1.0;
3806 }
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().

3563 {
3564  double const t_min( (*_vt)->TLIMIT() - 2.0);
3565  double const t_max( (*_vt)->TLIMIT());
3566 
3567  if ( cbm::flt_less( _temp, t_min))
3568  {
3569  return 0.0;
3570  }
3571  else if ( cbm::flt_less( _temp, t_max))
3572  {
3573  return (_temp - t_min) / (t_max - t_min);
3574  }
3575  else
3576  {
3577  return 1.0;
3578  }
3579 }
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().

3759 {
3760 // if ( m_veg->is_family( _vt, ":winterwheat:"))
3761 // {
3762 // double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3763 // (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3764 // double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3765 // _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3766 // double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3767 // double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3768 //
3769 // return cbm::bound( 0.01,
3770 // vc / vc_max,
3771 // 1.0);
3772 // }
3773 // else
3774  {
3775  double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3776  if ( n_ratio < 1.0)
3777  {
3778  return cbm::bound( 0.01,
3779  pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3780  1.0);
3781  }
3782  else
3783  {
3784  return 1.0;
3785  }
3786  }
3787 }
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().

3488 {
3489  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3490  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3491  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3492  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3493 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3869
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.

2090 {
2091  DroughtStress droughtstress;
2092  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
2093  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
2094  double const fact_a( PlaMox_get_age_factor( _vt));
2095  double const fact_t( PlaMox_get_frost_factor( _vt, *mc_temp));
2096  double const fact_h( PlaMox_get_heat_factor( _vt));
2097  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
2098  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
2099  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
2100 
2101  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
2102 
2103  /* update activity of photosynthesis apparat */
2104  if ( cbm::flt_greater_zero( fact_all))
2105  {
2106  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2107  {
2108  //rubisco activity
2109  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
2110 
2111  //electron transport under standard conditions
2112  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
2113 
2114  //photorespiration under standard conditions
2115  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2116  }
2117  }
2118 
2119  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2120  {
2121  m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
2122  m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2123  m_photo.temp_fl[fl] = mc_.temp_fl[fl];
2124  m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
2125  m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
2126  m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
2127  m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2128  m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2129  }
2130  m_photo.nd_airpressure = mc_.nd_airpressure;
2131  m_photo.set_vegetation_base_state( _vt);
2132  m_photo.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
2133 
2134  m_photo.solve();
2135 
2136  m_photo.get_vegetation_state( _vt);
2137 
2138  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2139 
2140  if ( cbm::flt_greater_zero( carbonuptake_sum))
2141  {
2142  timestep_c_assi += carbonuptake_sum;
2143  double const dw_assi( carbonuptake_sum / cbm::CCDM);
2144 
2145  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2146  // the root length for mass from photosynthesis gets adapted in update root system
2147  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2148  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2149  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2150 
2151  dcFru[_vt->slot] = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2152  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2153  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2154  dcLst[_vt->slot] = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2155 
2161  }
2162 
2163  return LDNDC_ERR_OK;
2164 }
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3758
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3583
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:3741
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3561
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3830
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3791
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:3503
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.

3340 {
3341  size_t const fl_cnt( _vt->nb_foliagelayers());
3342 
3343  double sla_cum( 0.0);
3344  for (size_t fl = 0; fl < fl_cnt; ++fl)
3345  {
3346  sla_cum += _vt->sla_fl[fl];
3347  }
3348 
3349  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3350  double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3351  _vt->mFol));
3352  lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3353  lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3354  if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3355  {
3356  mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3357  }
3358 
3359  if ( cbm::flt_greater_zero( sla_cum))
3360  {
3361  DroughtStress droughtstress;
3362  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3363 
3364  for (size_t fl = 0; fl < fl_cnt; ++fl)
3365  {
3366  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3367  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3368  //_vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3369  }
3370  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3371  {
3372  _vt->fFol_fl[fl] = 0.0;
3373  _vt->lai_fl[fl] = 0.0;
3374  _vt->sla_fl[fl] = 0.0;
3375  }
3376  }
3377  else
3378  {
3379  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3380  {
3381  _vt->fFol_fl[fl] = 0.0;
3382  _vt->lai_fl[fl] = 0.0;
3383  _vt->sla_fl[fl] = 0.0;
3384  }
3385  }
3386 }
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.

3288 {
3289  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3290  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3291  if ( _vt->group() == "crop")
3292  {
3293  //height evegrowth starts with stem elongation
3294  //minimum of 1% development until start of height growth required: dvs_of_start_height !> 0.0
3295  double const dvs_of_start_height( cbm::bound_min( 0.01, (*_vt)->GDD_STEM_ELONGATION() / (*_vt)->GDD_MATURITY()));
3296  //minimum of 2% development until end of height growth required: dvs_of_end_height !> dvs_of_start_height
3297  double const dvs_of_max_height( cbm::bound_min( 0.02, gdd_grain_filling[_vt->slot] / (*_vt)->GDD_MATURITY()));
3298 
3299  //until start of stem elongation, height modeled with plant development
3300  //10% of final height is always reached until start of stem elongation
3301  double const height_fraction_at_stem_elongation( 0.1);
3302  double height_fraction( cbm::bound_max( _vt->dvsFlush / dvs_of_start_height, 1.0) * height_fraction_at_stem_elongation);
3303  if ( cbm::flt_greater( _vt->dvsFlush, dvs_of_start_height))
3304  {
3305  double const biomass_fraction( cbm::bound_max( cbm::sqrt((_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt)), 1.0));
3306  //bound biomass-depending height by plant development
3307  //max should not be reached before start of grain filling (end of phase of stem elongation)
3308  height_fraction = cbm::bound( height_fraction,
3309  biomass_fraction,
3310  height_fraction_at_stem_elongation +
3311  (1.0 - height_fraction_at_stem_elongation) *
3312  (_vt->dvsFlush - dvs_of_start_height)/ (dvs_of_max_height- dvs_of_start_height));
3313  }
3314  _vt->height_max = cbm::bound_min( _vt->height_max, height_fraction * (*_vt)->HEIGHT_MAX());
3315  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3316  }
3317  else
3318  {
3319  _vt->height_max = cbm::bound_max( (_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt) * (*_vt)->HEIGHT_MAX(), (*_vt)->HEIGHT_MAX());
3320  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3321  }
3322 
3323  // update height of canopy layers (m)
3324  ph_.update_canopy_layers_height( m_veg);
3325 }
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().

3504 {
3505  double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3506  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);
3507 
3508 // double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3509 
3510  double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3511  cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3512  _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3513  + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3514  _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3515  double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3516  cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3517  _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3518  + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3519  _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3520  double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3521  cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3522  _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3523  + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3524  _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3525  double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3526  cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3527  _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3528  + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3529  _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3530 
3531  double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3532  if ( cbm::flt_greater_zero( n_tot_opt))
3533  {
3534  // CB: fraction of available N to optimum N
3535  double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3536  // CB: N gets distributed evenly over all compartments regarding their optimum N content
3537  _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3538  (*_vt)->NC_FOLIAGE_MAX();
3539  _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3540  0.0;
3541  _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3542  (*_vt)->NC_FRUIT_MAX();
3543  _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3544  (*_vt)->NC_FINEROOTS_MAX();
3545  }
3546 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3869
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3487
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

3403 {
3404  size_t const fl_cnt( _vt->nb_foliagelayers());
3405 
3416  if ( IS_SPECIE( _vt->cname(), "mungbean"))
3417  {
3418  double slamax( 26.0);
3419  if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3420  {
3421  slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3422  }
3423  else
3424  {
3425  slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3426  }
3427 
3428  for (size_t fl = 0; fl < fl_cnt; ++fl)
3429  {
3430  _vt->sla_fl[fl] = slamax;
3431  }
3432  }
3433  else if ( m_veg->is_family( _vt, ":rice:"))
3434  {
3435  double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3436  cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3437  _vt->dvsMort);
3438 
3439  double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3440  for (size_t fl = 0; fl < fl_cnt; ++fl)
3441  {
3442  _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3443  }
3444  }
3445  else
3446  {
3447  // reduction of specific leaf area with crop age
3448  double sla_red( 1.0);
3449  if (_vt->groupId() == SPECIES_GROUP_GRASS)
3450  {
3451  if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3452  {
3453  sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3454  }
3455  }
3456  else
3457  {
3458  sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3459  }
3460 
3461  for (size_t fl = 0; fl < fl_cnt; ++fl)
3462  {
3463  _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3464  }
3465  }
3466 
3467  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3468  {
3469  _vt->sla_fl[fl] = 0.0;
3470  }
3471 }

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