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.

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

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

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

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

3768 {
3769  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3770  {
3771  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3772  {
3773  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3774  }
3775  return ( 1.0);
3776  }
3777  else
3778  {
3779  if ( days_after_emergence[_p->slot] < 0)
3780  {
3781  return 0.0;
3782  }
3783  else
3784  {
3785  if ( cbm::flt_less( _p->dvsFlush, 0.95))
3786  {
3787  return ( 1.0);
3788  }
3789  else
3790  {
3791  return cbm::bound_min( 0.0, (1.0 - _p->dvsFlush) / 0.05);
3792  }
3793  }
3794  }
3795 }
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().

3729 {
3730  if ( m_veg->is_family( _vt, ":wheat:"))
3731  {
3732  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3733  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3734 
3735  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3736  cbm::flt_greater( _vt->dw_lst, lst_opt))
3737  {
3738  return lst_opt / _vt->dw_lst;
3739  }
3740  }
3741 
3742  return 1.0;
3743 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:296
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().

3500 {
3501  double const t_min( (*_vt)->TLIMIT() - 2.0);
3502  double const t_max( (*_vt)->TLIMIT());
3503 
3504  if ( cbm::flt_less( _temp, t_min))
3505  {
3506  return 0.0;
3507  }
3508  else if ( cbm::flt_less( _temp, t_max))
3509  {
3510  return (_temp - t_min) / (t_max - t_min);
3511  }
3512  else
3513  {
3514  return 1.0;
3515  }
3516 }
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().

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

3425 {
3426  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3427  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3428  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3429  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3430 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3806
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_, 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.

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

3284 {
3285  size_t const fl_cnt( _vt->nb_foliagelayers());
3286 
3287  double sla_cum( 0.0);
3288  for (size_t fl = 0; fl < fl_cnt; ++fl)
3289  {
3290  sla_cum += _vt->sla_fl[fl];
3291  }
3292 
3293  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3294  double const mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3295  _vt->mFol));
3296 
3297  if ( cbm::flt_greater_zero( sla_cum))
3298  {
3299  DroughtStress droughtstress;
3300  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3301 
3302  for (size_t fl = 0; fl < fl_cnt; ++fl)
3303  {
3304  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3305  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3306  }
3307  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3308  {
3309  _vt->fFol_fl[fl] = 0.0;
3310  _vt->lai_fl[fl] = 0.0;
3311  _vt->sla_fl[fl] = 0.0;
3312  }
3313  }
3314  else
3315  {
3316  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3317  {
3318  _vt->fFol_fl[fl] = 0.0;
3319  _vt->lai_fl[fl] = 0.0;
3320  _vt->sla_fl[fl] = 0.0;
3321  }
3322  }
3323 }
lvector_t< double > lai_min
Minimum value of üplamt leaf area index (m^2:m^-2). For crops, this value is fixed until between sowi...
Definition: plamox.h:290

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

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

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

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

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

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