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, ":corns:"))
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:3497
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().

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

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

3557 {
3558  double const t_min( (*_vt)->TLIMIT() - 2.0);
3559  double const t_max( (*_vt)->TLIMIT());
3560 
3561  if ( cbm::flt_less( _temp, t_min))
3562  {
3563  return 0.0;
3564  }
3565  else if ( cbm::flt_less( _temp, t_max))
3566  {
3567  return (_temp - t_min) / (t_max - t_min);
3568  }
3569  else
3570  {
3571  return 1.0;
3572  }
3573 }
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().

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

3482 {
3483  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3484  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3485  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3486  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3487 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3863
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.

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

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

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

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

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

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