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

884 {
885  if ( root_system[_vt->slot] == NULL)
886  {
887  KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
888  return LDNDC_ERR_RUNTIME_ERROR;
889  }
890 
891  bool const mulching = _attributes.get( "/mulching", false);
892 
893  double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
894  double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
895  double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
896  double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
897  double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
898 
899  double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
900  double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
901 
902  double const fru_c( _vt->mBud * cbm::CCDM);
903  double const fru_n( _vt->n_bud());
904 
905  double fru_c_export( 0.0);
906  double fru_n_export( 0.0);
907 
908  double straw_c_export( 0.0);
909  double straw_n_export( 0.0);
910 
911  double mulching_c( 0.0);
912  double mulching_n( 0.0);
913 
914  double stubble_c( 0.0);
915  double stubble_n( 0.0);
916 
917  double gdd_sum( _vt->growing_degree_days );
918  double dvs_flush( _vt->dvsFlush );
919 
920  double const height( _attributes.get( "/height", invalid_flt));
921  double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
922  double remains_absolute( _attributes.get( "/remains_absolute", invalid_flt));
923  if( cbm::is_valid( remains_absolute))
924  {
925  remains_absolute *= cbm::HA_IN_M2;
926  }
927 
928  if ( !cbm::flt_greater_equal_zero( remains_relative)
929  && !cbm::flt_greater_equal_zero( remains_absolute)
930  && !cbm::flt_greater_equal_zero( height))
931  {
932  if ( _vt->is_covercrop)
933  {
934  remains_relative = 1.0;
935  }
936  else
937  {
938  KLOGWARN( "harvest event attribute \"remains_relative\" and \"remains_absolute\" and \"height\" not set;",
939  " \"remains_relative\" set to zero and used [species=", _vt->name(),"]");
940  }
941  }
942  else if ( (cbm::flt_greater_equal_zero( remains_relative) ||
943  cbm::flt_greater_equal_zero( remains_absolute))
944  && cbm::flt_greater_equal_zero( height))
945  {
946  KLOGWARN( "harvest event attribute \"remains_(relative/absolute)\" and \"height\" both set;"
947  " attribute \"remains_relative\" used [species=", _vt->name(),"]");
948  }
949 
950  if ( cbm::flt_greater_equal_zero( remains_relative))
951  {
952  /* no op */
953  }
954  else if ( cbm::flt_greater_equal_zero( remains_absolute))
955  {
956  remains_relative = cbm::bound( 0.0,
957  remains_absolute / (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst),
958  1.0);
959  }
960  else if ( cbm::flt_equal_zero( height))
961  {
962  remains_relative = 0.0;
963  }
964  else if ( cbm::flt_greater_zero( height))
965  {
966  double h_cum( 0.0);
967  double remains_relative_fol = 0.0;
968  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
969  {
970  remains_relative_fol += _vt->fFol_fl[fl];
971  h_cum += ph_.h_fl[fl];
972  if ( cbm::flt_greater_equal( h_cum, height))
973  {
974  break;
975  }
976  }
977 
978  h_cum = 0.0;
979  double remains_relative_lst = 0.0;
980  double remains_relative_lst_total = 0.0;
981  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
982  {
983  //lst decreases with height
984  remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
985  if ( cbm::flt_less_equal( h_cum, height))
986  {
987  remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
988  }
989  h_cum += ph_.h_fl[fl];
990  }
991  remains_relative_lst /= remains_relative_lst_total;
992 
993  remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
994  remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
995  (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
996  }
997  else
998  {
999  KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
1000  return LDNDC_ERR_FAIL;
1001  }
1002 
1003  stubble_c += remains_relative * straw_c;
1004  stubble_n += remains_relative * straw_n;
1005  if ( mulching)
1006  {
1007  mulching_c += (1.0-remains_relative) * straw_c;
1008  mulching_n += (1.0-remains_relative) * straw_n;
1009  }
1010  else
1011  {
1012  straw_c_export += (1.0-remains_relative) * straw_c;
1013  straw_n_export += (1.0-remains_relative) * straw_n;
1014  }
1015 
1016  if ( _vt->is_covercrop)
1017  {
1018  stubble_c += remains_relative * fru_c;
1019  stubble_n += remains_relative * fru_n;
1020  if ( mulching)
1021  {
1022  mulching_c += (1.0-remains_relative) * fru_c;
1023  mulching_n += (1.0-remains_relative) * fru_n;
1024  }
1025  else
1026  {
1027  stubble_c += (1.0-remains_relative) * fru_c;
1028  stubble_n += (1.0-remains_relative) * fru_n;
1029  }
1030  }
1031  else
1032  {
1033  fru_c_export = fru_c;
1034  fru_n_export = fru_n;
1035  }
1036 
1037  //export
1038  c_total_exported += straw_c_export + fru_c_export;
1039  c_fruit_exported += fru_c_export;
1040  n_total_exported += straw_n_export + fru_n_export;
1041  n_fruit_exported += fru_n_export;
1042 
1043  ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
1044  ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
1045 
1046  ph_.accumulated_c_fru_export_harvest += fru_c_export;
1047  ph_.accumulated_n_fru_export_harvest += fru_n_export;
1048 
1049  //stubble litter
1050  sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
1051  sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
1052  sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1053  sc_.accumulated_c_litter_stubble += stubble_c;
1054 
1055  sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
1056  sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
1057  sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1058  sc_.accumulated_n_litter_stubble += stubble_n;
1059 
1060  //raw litter
1061  sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1062  sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
1063  sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
1064  sc_.accumulated_c_litter_above += mulching_c;
1065 
1066  sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1067  sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
1068  sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
1069  sc_.accumulated_n_litter_above += mulching_n;
1070 
1071  //root litter
1072  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1073  {
1074  double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
1075  double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
1076 
1077  sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
1078  sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
1079  sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
1080  sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
1081 
1082  sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1083  sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
1084  sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
1085  sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
1086  }
1087 
1088  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
1089  std::string mcom_key;
1090 
1091  char const * species_name = _attributes.get( "/name", "?");
1092 
1093  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
1094  mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
1095 
1096  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
1097  mcom->set( mcom_key.c_str(), gdd_sum);
1098 
1099  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
1100  mcom->set( mcom_key.c_str(), dvs_flush);
1101 
1102  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
1103  mcom->set( mcom_key.c_str(), fru_c);
1104 
1105  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
1106  mcom->set( mcom_key.c_str(), fru_c_export);
1107 
1108  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
1109  mcom->set( mcom_key.c_str(), fru_n);
1110 
1111  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
1112  mcom->set( mcom_key.c_str(), fru_n_export);
1113 
1114  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
1115  mcom->set( mcom_key.c_str(), straw_c);
1116 
1117  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
1118  mcom->set( mcom_key.c_str(), straw_c_export);
1119 
1120  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
1121  mcom->set( mcom_key.c_str(), straw_n);
1122 
1123  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
1124  mcom->set( mcom_key.c_str(), straw_n_export);
1125 
1126  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
1127  mcom->set( mcom_key.c_str(), stubble_c);
1128 
1129  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1130  mcom->set( mcom_key.c_str(), stubble_n);
1131 
1132  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1133  mcom->set( mcom_key.c_str(), rootlitter_c);
1134 
1135  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1136  mcom->set( mcom_key.c_str(), rootlitter_n);
1137 
1138  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1139  {
1140  _vt->fFrt_sl[sl] = 0.0;
1141  }
1142 
1143  cbm::invalidate( root_q_vt_[_vt->slot]);
1144  _vt->rooting_depth = 0.0;
1145 
1146  days_after_emergence[_vt->slot] = -1;
1147 
1148  dw_retranslocation_stem[_vt->slot] = 0.0;
1149  dw_retranslocation_foliage[_vt->slot] = 0.0;
1150 
1151  _vt->mFol = 0.0;
1152  _vt->dw_dfol = 0.0;
1153  _vt->ncFol = 0.0;
1154  _vt->n_dfol = 0.0;
1155 
1156  _vt->dw_lst = 0.0;
1157  _vt->n_lst = 0.0;
1158 
1159  _vt->dw_dst = 0.0;
1160  _vt->n_dst = 0.0;
1161 
1162  _vt->mBud = 0.0;
1163  _vt->mBudStart = 0.0;
1164  _vt->ncBud = 0.0;
1165 
1166  _vt->mFrt = 0.0;
1167  _vt->ncFrt = 0.0;
1168 
1169  _vt->dEmerg = -1;
1170  _vt->growing_degree_days = 0.0;
1171  _vt->dvsMort = 0.0;
1172  _vt->dvsFlush = 0.0;
1173  _vt->dvsFlushOld = 0.0;
1174 
1175  n_plant[_vt->slot] = 0.0;
1176  _vt->a_fix_n = 0.0;
1177 
1178  _vt->height_max = 0.0;
1179  _vt->height_at_canopy_start = 0.0;
1180 
1181  _vt->f_area = 0.0;
1182  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1183  {
1184  _vt->fFol_fl[fl] = 0.0;
1185  _vt->lai_fl[fl] = 0.0;
1186  }
1187 
1188  _vt->f_fac = 0.0;
1189  chill_units[_vt->slot] = 0.0;
1190  chill_factor[_vt->slot] = 1.0;
1191 
1192  yearly_cuts[_vt->slot] = 0;
1193 
1194  allocation_factor_leafs[_vt->slot] = 0.0;
1195  allocation_factor_stems[_vt->slot] = 0.0;
1196  allocation_factor_fruit[_vt->slot] = 0.0;
1197  allocation_factor_roots[_vt->slot] = 0.0;
1198 
1199  m_fruit_maximum[_vt->slot] = -1.0;
1200  spikelets_sterility[_vt->slot] = 0.0;
1201  hypoxia[_vt->slot] = 0.0;
1202 
1203  LD_Allocator->destroy( root_system[_vt->slot]);
1204  root_system[_vt->slot] = NULL;
1205 
1206  return LDNDC_ERR_OK;
1207 }
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 
689  PlaMox_reset_phenology( _vt);
690 
691  if ( cbm::is_equal( _vt->group().c_str(), "crop"))
692  {
693  lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
694  if ( rc_plant)
695  {
696  return LDNDC_ERR_OK;
697  }
698 
699  //emergence has happened for biomass greater 50kg ha-1
700  if ( cbm::flt_greater( initial_biomass, 0.01) &&
701  m_veg->is_family( _vt, ":rice:"))
702  {
703  days_after_emergence[_vt->slot] = 0;
704  }
705 
706  /* only considered for rice so far */
707  int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
708  if ( seedbedduration > 0)
709  {
710  double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
711  _vt->growing_degree_days = seedbedduration * mean_gdd;
712  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
713  }
714  else if ( cbm::flt_greater_equal( initial_biomass, 0.01) &&
715  m_veg->is_family( _vt, ":rice:"))
716  {
717  _vt->growing_degree_days = 200.0;
718  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
719  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
720  initial_biomass * (1.0 - (*_vt)->FRACTION_ROOT()) * (*_vt)->SLAMAX());
721  }
722  else
723  {
724  _vt->growing_degree_days = 0.0;
725  _vt->dvsFlush = 0.0;
726  }
727 
728  transplanting_shock_vt[_vt->slot] = pow(initial_biomass/0.005, 0.2);
729 
730  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
731  allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
732  allocation_factor_stems[_vt->slot] = 0.0;
733  allocation_factor_fruit[_vt->slot] = 0.0;
734 
735  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
736  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
737  _vt->n_lst = 0.0;
738  _vt->ncBud = 0.0;
739  _vt->ncSap = 0.0;
740  _vt->ncCor = 0.0;
741 
742  double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
743  (*_vt)->FRACTION_ROOT_START() :
744  (*_vt)->FRACTION_ROOT());
745  double const initial_foliage_biomass_max( 0.02);
746  _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
747  initial_foliage_biomass_max );
748 
749  _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
750  _vt->dw_lst = 0.0;
751  _vt->mBud = 0.0;
752  _vt->mSap = 0.0;
753  _vt->mCor = 0.0;
754 
755  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
756  n_plant[_vt->slot] = _vt->total_nitrogen();
757 
759 
760  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
761  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
762  }
763  else if ( cbm::is_equal( _vt->cgroup(), "grass"))
764  {
765  lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
766  if ( rc_plant)
767  {
768  return LDNDC_ERR_OK;
769  }
770 
771  /* set to fixed value */
772  lai_min[_vt->slot] = 0.1;
773 
774  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
775  allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
776  allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
777  allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
778 
779  _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
780  _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
781  _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
782  _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
783 
784  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
785  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
786  _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
787  _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
788 
789  n_plant[_vt->slot] = _vt->total_nitrogen();
790 
792 
793  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
794  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
795  }
796  else
797  {
798  KLOGERROR( "I do not handle this group of species ",
799  "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
800  return LDNDC_ERR_RUNTIME_ERROR;
801  }
802 
803  // currently no concept for free available carbon
804  _vt->f_fac = 0.0;
805 
806  // initialize root system
807  if (root_system.size() <= _vt->slot)
808  {
809  root_system.resize(_vt->slot+1);
810  }
811 
812  ldndc_kassert( root_system[_vt->slot] == NULL);
813  root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
814  if ( !root_system[_vt->slot])
815  {
816  KLOGERROR( "Failed to allocate root-system object");
817  return LDNDC_ERR_NOMEM;
818  }
819 
820  double const seed_depth = _attributes.get( "/seed-depth", 0.05);
821  root_q_vt_[_vt->slot] = 0; // no rooted layers yet
822  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
823  {
824  if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
825  {
826  break;
827  }
828  root_q_vt_[_vt->slot] = sl; // no rooted layers yet
829  }
830 
831  PlaMox_update_root_structure( _vt, _vt->mFrt);
832 
833  return LDNDC_ERR_OK;
834 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h: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:3450
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().

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

3739 {
3740  if ( m_veg->is_family( _vt, ":wheat:"))
3741  {
3742  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3743  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3744 
3745  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3746  cbm::flt_greater( _vt->dw_lst, lst_opt))
3747  {
3748  return lst_opt / _vt->dw_lst;
3749  }
3750  }
3751 
3752  return 1.0;
3753 }
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().

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

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

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

2055 {
2056  DroughtStress droughtstress;
2057  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
2058  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
2059  double const fact_a( PlaMox_get_age_factor( _vt));
2060  double const fact_t( PlaMox_get_frost_factor( _vt, *mc_temp));
2061  double const fact_h( PlaMox_get_heat_factor( _vt));
2062  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
2063  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
2064  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
2065 
2066  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
2067 
2068  /* update activity of photosynthesis apparat */
2069  if ( cbm::flt_greater_zero( fact_all))
2070  {
2071  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2072  {
2073  //rubisco activity
2074  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
2075 
2076  //electron transport under standard conditions
2077  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
2078 
2079  //photorespiration under standard conditions
2080  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2081  }
2082  }
2083 
2084  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2085  {
2086  m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
2087  m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2088  m_photo.temp_fl[fl] = mc_.temp_fl[fl];
2089  m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
2090  m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
2091  m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
2092  m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2093  m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2094  }
2095  m_photo.nd_airpressure = mc_.nd_airpressure;
2096  m_photo.set_vegetation_base_state( _vt);
2097  m_photo.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
2098 
2099  m_photo.solve();
2100 
2101  m_photo.get_vegetation_state( _vt);
2102 
2103  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2104 
2105  if ( cbm::flt_greater_zero( carbonuptake_sum))
2106  {
2107  timestep_c_assi += carbonuptake_sum;
2108  double const dw_assi( carbonuptake_sum / cbm::CCDM);
2109 
2110  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2111  // the root length for mass from photosynthesis gets adapted in update root system
2112  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2113  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2114  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2115 
2116  dcFru[_vt->slot] = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2117  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2118  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2119  dcLst[_vt->slot] = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2120 
2126  }
2127 
2128  return LDNDC_ERR_OK;
2129 }
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3705
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3530
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:3688
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3508
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3777
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3738
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:3450
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.

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

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

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

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

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