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:146
NitrogenFixation * NitrogenFixation_
Nitrogen fixation.
Definition: plamox.h:128

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

869 {
870  if ( root_system[_vt->slot] == NULL)
871  {
872  KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
873  return LDNDC_ERR_RUNTIME_ERROR;
874  }
875 
876  bool const mulching = _attributes.get( "/mulching", false);
877 
878  double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
879  double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
880  double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
881  double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
882  double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
883 
884  double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
885  double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
886 
887  double const fru_c( _vt->mBud * cbm::CCDM);
888  double const fru_n( _vt->n_bud());
889 
890  double fru_c_export( 0.0);
891  double fru_n_export( 0.0);
892 
893  double straw_c_export( 0.0);
894  double straw_n_export( 0.0);
895 
896  double mulching_c( 0.0);
897  double mulching_n( 0.0);
898 
899  double stubble_c( 0.0);
900  double stubble_n( 0.0);
901 
902  double gdd_sum( _vt->growing_degree_days );
903  double dvs_flush( _vt->dvsFlush );
904 
905  double const height( _attributes.get( "/height", invalid_flt));
906  double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
907  double remains_absolute( _attributes.get( "/remains_absolute", invalid_flt));
908  if( cbm::is_valid( remains_absolute))
909  {
910  remains_absolute *= cbm::HA_IN_M2;
911  }
912 
913  if ( !cbm::flt_greater_equal_zero( remains_relative)
914  && !cbm::flt_greater_equal_zero( remains_absolute)
915  && !cbm::flt_greater_equal_zero( height))
916  {
917  if ( _vt->is_covercrop)
918  {
919  remains_relative = 1.0;
920  }
921  else
922  {
923  KLOGWARN( "harvest event attribute \"remains_relative\" and \"remains_absolute\" and \"height\" not set;",
924  " \"remains_relative\" set to zero and used [species=", _vt->name(),"]");
925  }
926  }
927  else if ( (cbm::flt_greater_equal_zero( remains_relative) ||
928  cbm::flt_greater_equal_zero( remains_absolute))
929  && cbm::flt_greater_equal_zero( height))
930  {
931  KLOGWARN( "harvest event attribute \"remains_(relative/absolute)\" and \"height\" both set;"
932  " attribute \"remains_relative\" used [species=", _vt->name(),"]");
933  }
934 
935  if ( cbm::flt_greater_equal_zero( remains_relative))
936  {
937  /* no op */
938  }
939  else if ( cbm::flt_greater_equal_zero( remains_absolute))
940  {
941  remains_relative = cbm::bound( 0.0,
942  remains_absolute / (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst),
943  1.0);
944  }
945  else if ( cbm::flt_equal_zero( height))
946  {
947  remains_relative = 0.0;
948  }
949  else if ( cbm::flt_greater_zero( height))
950  {
951  double h_cum( 0.0);
952  double remains_relative_fol = 0.0;
953  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
954  {
955  remains_relative_fol += _vt->fFol_fl[fl];
956  h_cum += ph_.h_fl[fl];
957  if ( cbm::flt_greater_equal( h_cum, height))
958  {
959  break;
960  }
961  }
962 
963  h_cum = 0.0;
964  double remains_relative_lst = 0.0;
965  double remains_relative_lst_total = 0.0;
966  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
967  {
968  //lst decreases with height
969  remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
970  if ( cbm::flt_less_equal( h_cum, height))
971  {
972  remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
973  }
974  h_cum += ph_.h_fl[fl];
975  }
976  remains_relative_lst /= remains_relative_lst_total;
977 
978  remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
979  remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
980  (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
981  }
982  else
983  {
984  KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
985  return LDNDC_ERR_FAIL;
986  }
987 
988  stubble_c += remains_relative * straw_c;
989  stubble_n += remains_relative * straw_n;
990  if ( mulching)
991  {
992  mulching_c += (1.0-remains_relative) * straw_c;
993  mulching_n += (1.0-remains_relative) * straw_n;
994  }
995  else
996  {
997  straw_c_export += (1.0-remains_relative) * straw_c;
998  straw_n_export += (1.0-remains_relative) * straw_n;
999  }
1000 
1001  if ( _vt->is_covercrop)
1002  {
1003  stubble_c += remains_relative * fru_c;
1004  stubble_n += remains_relative * fru_n;
1005  if ( mulching)
1006  {
1007  mulching_c += (1.0-remains_relative) * fru_c;
1008  mulching_n += (1.0-remains_relative) * fru_n;
1009  }
1010  else
1011  {
1012  stubble_c += (1.0-remains_relative) * fru_c;
1013  stubble_n += (1.0-remains_relative) * fru_n;
1014  }
1015  }
1016  else
1017  {
1018  fru_c_export = fru_c;
1019  fru_n_export = fru_n;
1020  }
1021 
1022  //export
1023  c_total_exported += straw_c_export + fru_c_export;
1024  c_fruit_exported += fru_c_export;
1025  n_total_exported += straw_n_export + fru_n_export;
1026  n_fruit_exported += fru_n_export;
1027 
1028  ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
1029  ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
1030 
1031  ph_.accumulated_c_fru_export_harvest += fru_c_export;
1032  ph_.accumulated_n_fru_export_harvest += fru_n_export;
1033 
1034  //stubble litter
1035  sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
1036  sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
1037  sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1038  sc_.accumulated_c_litter_stubble += stubble_c;
1039 
1040  sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
1041  sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
1042  sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1043  sc_.accumulated_n_litter_stubble += stubble_n;
1044 
1045  //raw litter
1046  sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1047  sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
1048  sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
1049  sc_.accumulated_c_litter_above += mulching_c;
1050 
1051  sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1052  sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
1053  sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
1054  sc_.accumulated_n_litter_above += mulching_n;
1055 
1056  //root litter
1057  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1058  {
1059  double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
1060  double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
1061 
1062  sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
1063  sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
1064  sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
1065  sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
1066 
1067  sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1068  sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
1069  sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
1070  sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
1071  }
1072 
1073  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
1074  std::string mcom_key;
1075 
1076  char const * species_name = _attributes.get( "/name", "?");
1077 
1078  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
1079  mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
1080 
1081  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
1082  mcom->set( mcom_key.c_str(), gdd_sum);
1083 
1084  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
1085  mcom->set( mcom_key.c_str(), dvs_flush);
1086 
1087  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
1088  mcom->set( mcom_key.c_str(), fru_c);
1089 
1090  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
1091  mcom->set( mcom_key.c_str(), fru_c_export);
1092 
1093  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
1094  mcom->set( mcom_key.c_str(), fru_n);
1095 
1096  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
1097  mcom->set( mcom_key.c_str(), fru_n_export);
1098 
1099  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
1100  mcom->set( mcom_key.c_str(), straw_c);
1101 
1102  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
1103  mcom->set( mcom_key.c_str(), straw_c_export);
1104 
1105  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
1106  mcom->set( mcom_key.c_str(), straw_n);
1107 
1108  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
1109  mcom->set( mcom_key.c_str(), straw_n_export);
1110 
1111  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
1112  mcom->set( mcom_key.c_str(), stubble_c);
1113 
1114  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1115  mcom->set( mcom_key.c_str(), stubble_n);
1116 
1117  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1118  mcom->set( mcom_key.c_str(), rootlitter_c);
1119 
1120  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1121  mcom->set( mcom_key.c_str(), rootlitter_n);
1122 
1123  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1124  {
1125  _vt->fFrt_sl[sl] = 0.0;
1126  }
1127 
1128  cbm::invalidate( root_q_vt_[_vt->slot]);
1129  _vt->rooting_depth = 0.0;
1130 
1131  days_after_emergence[_vt->slot] = -1;
1132 
1133  dw_retranslocation_stem[_vt->slot] = 0.0;
1134  dw_retranslocation_foliage[_vt->slot] = 0.0;
1135 
1136  _vt->mFol = 0.0;
1137  _vt->dw_dfol = 0.0;
1138  _vt->ncFol = 0.0;
1139  _vt->n_dfol = 0.0;
1140 
1141  _vt->dw_lst = 0.0;
1142  _vt->n_lst = 0.0;
1143 
1144  _vt->dw_dst = 0.0;
1145  _vt->n_dst = 0.0;
1146 
1147  _vt->mBud = 0.0;
1148  _vt->mBudStart = 0.0;
1149  _vt->ncBud = 0.0;
1150 
1151  _vt->mFrt = 0.0;
1152  _vt->ncFrt = 0.0;
1153 
1154  _vt->dEmerg = -1;
1155  _vt->growing_degree_days = 0.0;
1156  _vt->dvsMort = 0.0;
1157  _vt->dvsFlush = 0.0;
1158  _vt->dvsFlushOld = 0.0;
1159 
1160  n_plant[_vt->slot] = 0.0;
1161  _vt->a_fix_n = 0.0;
1162 
1163  _vt->height_max = 0.0;
1164  _vt->height_at_canopy_start = 0.0;
1165 
1166  _vt->f_area = 0.0;
1167  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1168  {
1169  _vt->fFol_fl[fl] = 0.0;
1170  _vt->lai_fl[fl] = 0.0;
1171  }
1172 
1173  _vt->f_fac = 0.0;
1174  chill_units[_vt->slot] = 0.0;
1175  chill_factor[_vt->slot] = 1.0;
1176 
1177  yearly_cuts[_vt->slot] = 0;
1178 
1179  allocation_factor_leafs[_vt->slot] = 0.0;
1180  allocation_factor_stems[_vt->slot] = 0.0;
1181  allocation_factor_fruit[_vt->slot] = 0.0;
1182  allocation_factor_roots[_vt->slot] = 0.0;
1183 
1184  m_fruit_maximum[_vt->slot] = -1.0;
1185  spikelets_sterility[_vt->slot] = 0.0;
1186  hypoxia[_vt->slot] = 0.0;
1187 
1188  LD_Allocator->destroy( root_system[_vt->slot]);
1189  root_system[_vt->slot] = NULL;
1190 
1191  return LDNDC_ERR_OK;
1192 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:333
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:272
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:278
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:303
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:284
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:309
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:266
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:146
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 const gdd_maturity_target( _attributes.get( "/gdd-maturity-target", -1.0));
603  if ( cbm::flt_greater_zero( gdd_maturity_target) &&
604  cbm::flt_greater_zero( (*_vt)->GDD_MATURITY()))
605  {
606  double const scale_gdd( gdd_maturity_target / (*_vt)->GDD_MATURITY());
607  MoBiLE_PlantParameters p_parameters = (*m_speciesparameters)[_vt->ctype()];
608  p_parameters.GDD_EMERGENCE_UPDATE( (*_vt)->GDD_EMERGENCE() * scale_gdd);
609  p_parameters.GDD_STEM_ELONGATION_UPDATE( (*_vt)->GDD_STEM_ELONGATION() * scale_gdd);
610  p_parameters.GDD_FLOWERING_UPDATE( (*_vt)->GDD_FLOWERING() * scale_gdd);
611  p_parameters.GDD_GRAIN_FILLING_UPDATE( (*_vt)->GDD_GRAIN_FILLING() * scale_gdd);
612  p_parameters.GDD_ROOTS_GROWN_UPDATE( (*_vt)->GDD_ROOTS_GROWN() * scale_gdd);
613  p_parameters.GDD_MATURITY_UPDATE( gdd_maturity_target);
614  _vt->switchparameters( p_parameters);
615  }
616 
617  _vt->is_covercrop = _attributes.get( "/cover-crop", false);
618  //_vt->f_fac = (*_vt)->FFACMAX();
619 
620  //amount of seeds
621  double initial_biomass = _attributes.get( "/initial-biomass", 0.0);
622  if ( cbm::flt_equal( initial_biomass, 0.0))
623  {
624  if ( m_veg->is_family( _vt, ":rice:"))
625  {
626  initial_biomass = 200.0;
627  }
628  else if ( m_veg->is_family( _vt, ":wheat:"))
629  {
630  initial_biomass = 150.0;
631  }
632  else if ( m_veg->is_family( _vt, ":corn:"))
633  {
634  initial_biomass = 50.0;
635  }
636  else if ( m_veg->is_family( _vt, ":rapeseed:"))
637  {
638  initial_biomass = 10.0;
639  }
640  }
641 
642  initial_biomass = cbm::bound_min( 0.0001, initial_biomass * cbm::HA_IN_M2);
643  lai_min[_vt->slot] = 0.01;
644 
645  location[_vt->slot] = _attributes.get( "/location", "?");
646 
647  dw_retranslocation_stem[_vt->slot] = 0.0;
648  dw_retranslocation_foliage[_vt->slot] = 0.0;
649 
650  //plant gets biomass by species initializer
651  //store and substract later according amounts of C and N
652  //for balance check at day of planting
653  double const plant_n_old( _vt->total_nitrogen());
654  double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
655 
656  _vt->height_max = 0.0;
657  _vt->height_at_canopy_start = 0.0;
658 
659  chill_units[_vt->slot] = 0.0;
660  chill_factor[_vt->slot] = 1.0;
661 
662  if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
663  {
664  m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
665  }
666  else
667  {
668  m_fruit_maximum[_vt->slot] = -1.0;
669  }
670  spikelets_sterility[_vt->slot] = 0.0;
671 
672  if ( m_veg->is_family( _vt, ":rice:"))
673  {
674  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
675  }
676  else if ( m_veg->is_family( _vt, ":wheat:"))
677  {
678  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
679  }
680  else
681  {
682  nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
683  }
684 
685  gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
686 
687  hypoxia[_vt->slot] = 0.0;
688  transplanting_shock_vt[_vt->slot] = 0.0;
689 
690  PlaMox_reset_phenology( _vt);
691 
692  if ( cbm::is_equal( _vt->group().c_str(), "crop"))
693  {
694  lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
695  if ( rc_plant)
696  {
697  return LDNDC_ERR_OK;
698  }
699 
700  /* only considered for rice so far */
701  int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
702  if ( seedbedduration > 0)
703  {
704  double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
705  _vt->growing_degree_days = seedbedduration * mean_gdd;
706  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
707  transplanting_shock_vt[_vt->slot] = 1.0;
708  days_after_emergence[_vt->slot] = 0;
709  }
710  else
711  {
712  _vt->growing_degree_days = 0.0;
713  _vt->dvsFlush = 0.0;
714  }
715 
716  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
717  allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
718  allocation_factor_stems[_vt->slot] = 0.0;
719  allocation_factor_fruit[_vt->slot] = 0.0;
720 
721  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
722  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
723  _vt->n_lst = 0.0;
724  _vt->ncBud = 0.0;
725  _vt->ncSap = 0.0;
726  _vt->ncCor = 0.0;
727 
728  double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
729  (*_vt)->FRACTION_ROOT_START() :
730  (*_vt)->FRACTION_ROOT());
731  double const initial_foliage_biomass_max( 0.02);
732  _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
733  initial_foliage_biomass_max );
734 
735  _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
736  _vt->dw_lst = 0.0;
737  _vt->mBud = 0.0;
738  _vt->mSap = 0.0;
739  _vt->mCor = 0.0;
740 
741  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
742  n_plant[_vt->slot] = _vt->total_nitrogen();
744 
745  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
746  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
747  }
748  else if ( cbm::is_equal( _vt->cgroup(), "grass"))
749  {
750  lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
751  if ( rc_plant)
752  {
753  return LDNDC_ERR_OK;
754  }
755 
756  /* set to fixed value */
757  lai_min[_vt->slot] = 0.1;
758 
759  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
760  allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
761  allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
762  allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
763 
764  _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
765  _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
766  _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
767  _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
768 
769  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
770  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
771  _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
772  _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
773 
774  n_plant[_vt->slot] = _vt->total_nitrogen();
775 
777 
778  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
779  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
780  }
781  else
782  {
783  KLOGERROR( "I do not handle this group of species ",
784  "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
785  return LDNDC_ERR_RUNTIME_ERROR;
786  }
787 
788  // currently no concept for free available carbon
789  _vt->f_fac = 0.0;
790 
791  // initialize root system
792  if (root_system.size() <= _vt->slot)
793  {
794  root_system.resize(_vt->slot+1);
795  }
796 
797  ldndc_kassert( root_system[_vt->slot] == NULL);
798  root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
799  if ( !root_system[_vt->slot])
800  {
801  KLOGERROR( "Failed to allocate root-system object");
802  return LDNDC_ERR_NOMEM;
803  }
804 
805  double const seed_depth = _attributes.get( "/seed-depth", 0.05);
806  root_q_vt_[_vt->slot] = 0; // no rooted layers yet
807  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
808  {
809  if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
810  {
811  break;
812  }
813  root_q_vt_[_vt->slot] = sl; // no rooted layers yet
814  }
815 
816  PlaMox_update_root_structure( _vt, _vt->mFrt);
817 
818  return LDNDC_ERR_OK;
819 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:333
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:272
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:339
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:278
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:303
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3448
LD_PlantFunctions m_pf
All kind of plant related functions.
Definition: plamox.h:134
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:284
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:309
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:297
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:266
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:291
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:146
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().

3776 {
3777  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3778  {
3779  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3780  {
3781  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3782  }
3783  return ( 1.0);
3784  }
3785  else
3786  {
3787  if ( days_after_emergence[_p->slot] < 0)
3788  {
3789  return 0.0;
3790  }
3791  else
3792  {
3793  if ( cbm::flt_less( _p->dvsFlush, 0.95))
3794  {
3795  return ( 1.0);
3796  }
3797  else
3798  {
3799  return cbm::bound_min( 0.0, (1.0 - _p->dvsFlush) / 0.05);
3800  }
3801  }
3802  }
3803 }
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().

3737 {
3738  if ( m_veg->is_family( _vt, ":wheat:"))
3739  {
3740  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3741  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3742 
3743  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3744  cbm::flt_greater( _vt->dw_lst, lst_opt))
3745  {
3746  return lst_opt / _vt->dw_lst;
3747  }
3748  }
3749 
3750  return 1.0;
3751 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:297
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().

3508 {
3509  double const t_min( (*_vt)->TLIMIT() - 2.0);
3510  double const t_max( (*_vt)->TLIMIT());
3511 
3512  if ( cbm::flt_less( _temp, t_min))
3513  {
3514  return 0.0;
3515  }
3516  else if ( cbm::flt_less( _temp, t_max))
3517  {
3518  return (_temp - t_min) / (t_max - t_min);
3519  }
3520  else
3521  {
3522  return 1.0;
3523  }
3524 }
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().

3704 {
3705 // if ( m_veg->is_family( _vt, ":winterwheat:"))
3706 // {
3707 // double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3708 // (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3709 // double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3710 // _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3711 // double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3712 // double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3713 //
3714 // return cbm::bound( 0.01,
3715 // vc / vc_max,
3716 // 1.0);
3717 // }
3718 // else
3719  {
3720  double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3721  if ( n_ratio < 1.0)
3722  {
3723  return cbm::bound( 0.01,
3724  pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3725  1.0);
3726  }
3727  else
3728  {
3729  return 1.0;
3730  }
3731  }
3732 }
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().

3433 {
3434  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3435  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3436  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3437  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3438 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3814
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.

2039 {
2040  DroughtStress droughtstress;
2041  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
2042  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
2043  double const fact_a( PlaMox_get_age_factor( _vt));
2044  double const fact_t( PlaMox_get_frost_factor( _vt, *mc_temp));
2045  double const fact_h( PlaMox_get_heat_factor( _vt));
2046  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
2047  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
2048  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
2049 
2050  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
2051 
2052  /* update activity of photosynthesis apparat */
2053  if ( cbm::flt_greater_zero( fact_all))
2054  {
2055  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2056  {
2057  //rubisco activity
2058  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
2059 
2060  //electron transport under standard conditions
2061  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
2062 
2063  //photorespiration under standard conditions
2064  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2065  }
2066  }
2067 
2068  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2069  {
2070  m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
2071  m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2072  m_photo.temp_fl[fl] = mc_.temp_fl[fl];
2073  m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
2074  m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
2075  m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
2076  m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2077  m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2078  }
2079  m_photo.nd_airpressure = mc_.nd_airpressure;
2080  m_photo.set_vegetation_base_state( _vt);
2081  m_photo.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
2082 
2083  m_photo.solve();
2084 
2085  m_photo.get_vegetation_state( _vt);
2086 
2087  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2088 
2089  if ( cbm::flt_greater_zero( carbonuptake_sum))
2090  {
2091  timestep_c_assi += carbonuptake_sum;
2092  double const dw_assi( carbonuptake_sum / cbm::CCDM);
2093 
2094  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2095  // the root length for mass from photosynthesis gets adapted in update root system
2096  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2097  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2098  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2099 
2100  dcFru[_vt->slot] = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2101  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2102  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2103  dcLst[_vt->slot] = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2104 
2110  }
2111 
2112  return LDNDC_ERR_OK;
2113 }
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3703
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3528
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:272
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3686
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3506
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3775
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3736
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:278
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3448
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:284
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:266
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.

3288 {
3289  size_t const fl_cnt( _vt->nb_foliagelayers());
3290 
3291  double sla_cum( 0.0);
3292  for (size_t fl = 0; fl < fl_cnt; ++fl)
3293  {
3294  sla_cum += _vt->sla_fl[fl];
3295  }
3296 
3297  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3298  double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3299  _vt->mFol));
3300  if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3301  {
3302  mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3303  }
3304 
3305  if ( cbm::flt_greater_zero( sla_cum))
3306  {
3307  DroughtStress droughtstress;
3308  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3309 
3310  for (size_t fl = 0; fl < fl_cnt; ++fl)
3311  {
3312  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3313  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3314  }
3315  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3316  {
3317  _vt->fFol_fl[fl] = 0.0;
3318  _vt->lai_fl[fl] = 0.0;
3319  _vt->sla_fl[fl] = 0.0;
3320  }
3321  }
3322  else
3323  {
3324  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3325  {
3326  _vt->fFol_fl[fl] = 0.0;
3327  _vt->lai_fl[fl] = 0.0;
3328  _vt->sla_fl[fl] = 0.0;
3329  }
3330  }
3331 }
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:291

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

3236 {
3237  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3238  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3239  if ( _vt->group() == "crop")
3240  {
3241  //height evegrowth starts with stem elongation
3242  //minimum of 1% development until start of height growth required: dvs_of_start_height !> 0.0
3243  double const dvs_of_start_height( cbm::bound_min( 0.01, (*_vt)->GDD_STEM_ELONGATION() / (*_vt)->GDD_MATURITY()));
3244  //minimum of 2% development until end of height growth required: dvs_of_end_height !> dvs_of_start_height
3245  double const dvs_of_max_height( cbm::bound_min( 0.02, gdd_grain_filling[_vt->slot] / (*_vt)->GDD_MATURITY()));
3246 
3247  //until start of stem elongation, height modeled with plant development
3248  //10% of final height is always reached until start of stem elongation
3249  double const height_fraction_at_stem_elongation( 0.1);
3250  double height_fraction( cbm::bound_max( _vt->dvsFlush / dvs_of_start_height, 1.0) * height_fraction_at_stem_elongation);
3251  if ( cbm::flt_greater( _vt->dvsFlush, dvs_of_start_height))
3252  {
3253  double const biomass_fraction( cbm::bound_max( cbm::sqrt((_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt)), 1.0));
3254  //bound biomass-depending height by plant development
3255  //max should not be reached before start of grain filling (end of phase of stem elongation)
3256  height_fraction = cbm::bound( height_fraction,
3257  biomass_fraction,
3258  height_fraction_at_stem_elongation +
3259  (1.0 - height_fraction_at_stem_elongation) *
3260  (_vt->dvsFlush - dvs_of_start_height)/ (dvs_of_max_height- dvs_of_start_height));
3261  }
3262  _vt->height_max = cbm::bound_min( _vt->height_max, height_fraction * (*_vt)->HEIGHT_MAX());
3263  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3264  }
3265  else
3266  {
3267  _vt->height_max = cbm::bound_max( (_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt) * (*_vt)->HEIGHT_MAX(), (*_vt)->HEIGHT_MAX());
3268  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3269  }
3270 
3271  // update height of canopy layers (m)
3272  ph_.update_canopy_layers_height( m_veg);
3273 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:297

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

3449 {
3450  double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3451  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);
3452 
3453 // double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3454 
3455  double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3456  cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3457  _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3458  + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3459  _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3460  double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3461  cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3462  _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3463  + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3464  _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3465  double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3466  cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3467  _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3468  + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3469  _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3470  double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3471  cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3472  _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3473  + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3474  _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3475 
3476  double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3477  if ( cbm::flt_greater_zero( n_tot_opt))
3478  {
3479  // CB: fraction of available N to optimum N
3480  double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3481  // CB: N gets distributed evenly over all compartments regarding their optimum N content
3482  _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3483  (*_vt)->NC_FOLIAGE_MAX();
3484  _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3485  0.0;
3486  _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3487  (*_vt)->NC_FRUIT_MAX();
3488  _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3489  (*_vt)->NC_FINEROOTS_MAX();
3490  }
3491 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3814
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3432
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

3348 {
3349  size_t const fl_cnt( _vt->nb_foliagelayers());
3350 
3361  if ( IS_SPECIE( _vt->cname(), "mungbean"))
3362  {
3363  double slamax( 26.0);
3364  if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3365  {
3366  slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3367  }
3368  else
3369  {
3370  slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3371  }
3372 
3373  for (size_t fl = 0; fl < fl_cnt; ++fl)
3374  {
3375  _vt->sla_fl[fl] = slamax;
3376  }
3377  }
3378  else if ( m_veg->is_family( _vt, ":rice:"))
3379  {
3380  double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3381  cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3382  _vt->dvsMort);
3383 
3384  double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3385  for (size_t fl = 0; fl < fl_cnt; ++fl)
3386  {
3387  _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3388  }
3389  }
3390  else
3391  {
3392  // reduction of specific leaf area with crop age
3393  double sla_red( 1.0);
3394  if (_vt->groupId() == SPECIES_GROUP_GRASS)
3395  {
3396  if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3397  {
3398  sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3399  }
3400  }
3401  else
3402  {
3403  sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3404  }
3405 
3406  for (size_t fl = 0; fl < fl_cnt; ++fl)
3407  {
3408  _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3409  }
3410  }
3411 
3412  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3413  {
3414  _vt->sla_fl[fl] = 0.0;
3415  }
3416 }

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