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. More...
 
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.
 
void PlaMox_update_height (MoBiLE_Plant *)
 calculates new height of plant depending on the ratio of current to optimum aboveground biomass
 
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_age_factor (MoBiLE_Plant *)
 Calculates an age factor.
 
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, NitrogenFixation_, PlaMox_allocation_grass(), PlaMox_bud_burst(), PlaMox_drought(), PlaMox_exsudation(), PlaMox_growing_degree_days(), PlaMox_heat_stress_limitation(), PlaMox_management(), PlaMox_nitrogen_fixation(), PlaMox_nitrogen_uptake(), PlaMox_photosynthesis(), PlaMox_redistribution(), PlaMox_respiration(), PlaMox_senescence(), PlaMox_step_init(), PlaMox_transpiration(), PlaMox_update_foliage_structure(), PlaMox_update_height(), PlaMox_update_root_structure(), PlaMox_update_specific_leaf_area(), PlaMox_vernalization(), plantfamilies, root_system, and transpiration_method.

217 {
218  for ( size_t r = 0; r < root_system.size(); ++r)
219  {
220  if ( root_system[r])
221  {
222  LD_Allocator->destroy( root_system[r]);
223  }
224  }
225 
226  delete NitrogenFixation_;
227 }
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:142
NitrogenFixation * NitrogenFixation_
Nitrogen fixation.
Definition: plamox.h:124
Here is the call graph for this function:

Member Function Documentation

◆ PlaMox_bud_burst()

lerr_t ldndc::PhysiologyPlaMox::PlaMox_bud_burst ( MoBiLE_Plant *  _vt)
private

Burst of buds.

Translocation of stored carbon from buds to foliage, e.g., during spring, after defoliation (grazing, cutting)

Nitrogen concentration:
Nitrogen concentrations are updated in each compartment update_nitrogen_concentrations()

References allocation_factor_fruit, FTS_TOT_, and PlaMox_update_nitrogen_concentrations().

Referenced by ~PhysiologyPlaMox().

2176 {
2177  if ( cbm::flt_greater( (1.0 - _vt->dvsMort) * _vt->mBud, allocation_factor_fruit[_vt->slot] * _vt->total_biomass())
2178  && cbm::flt_less( wc_.surface_ice, 0.01)
2179  && (_vt->dEmerg >= 0)
2180  && (_vt->dvsMort < 0.99))
2181  {
2182  double const retranslocate( 0.05 * FTS_TOT_ * _vt->mBud);
2183  _vt->mBud -= retranslocate;
2184  _vt->mFol += retranslocate;
2185  }
2186 
2187  /* nitrogen concentration */
2189 
2190  return LDNDC_ERR_OK;
2191 }
double const FTS_TOT_
Time resolution factor:
Definition: plamox.h:173
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:274
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3681
Here is the call graph for this function:
Here is the caller graph for this function:

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

1128 {
1129  if ( root_system[_vt->slot] == NULL)
1130  {
1131  KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
1132  return LDNDC_ERR_RUNTIME_ERROR;
1133  }
1134 
1135  bool const mulching = _attributes.get( "/mulching", false);
1136 
1137  double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
1138  double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
1139  double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
1140  double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
1141  double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
1142 
1143  double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
1144  double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
1145 
1146  double const fru_c( _vt->mBud * cbm::CCDM);
1147  double const fru_n( _vt->n_bud());
1148 
1149  double fru_c_export( 0.0);
1150  double fru_n_export( 0.0);
1151 
1152  double straw_c_export( 0.0);
1153  double straw_n_export( 0.0);
1154 
1155  double mulching_c( 0.0);
1156  double mulching_n( 0.0);
1157 
1158  double stubble_c( 0.0);
1159  double stubble_n( 0.0);
1160 
1161  double gdd_sum( _vt->growing_degree_days );
1162  double dvs_flush( _vt->dvsFlush );
1163 
1164  double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
1165  double const height( _attributes.get( "/height", invalid_flt));
1166 
1167  if ( !cbm::flt_greater_equal_zero( remains_relative)
1168  && !cbm::flt_greater_equal_zero( height))
1169  {
1170  if ( _vt->is_covercrop)
1171  {
1172  remains_relative = 1.0;
1173  }
1174  else
1175  {
1176  KLOGWARN( "harvest event attribute \"remains_relative\" and \"height\" not set; \"remains_relative\" set to zero",
1177  " [species=", _vt->name(),"]");
1178  }
1179  }
1180  else if ( cbm::flt_greater_equal_zero( remains_relative)
1181  && cbm::flt_greater_equal_zero( height))
1182  {
1183  KLOGWARN( "harvest event attribute \"remains_relative\" and \"height\" were both set; attribute \"remains_relative\" used",
1184  " [species=", _vt->name(),"]");
1185  }
1186 
1187  if ( cbm::flt_greater_equal_zero( remains_relative))
1188  {
1189  /* no op */
1190  }
1191  else if ( cbm::flt_equal_zero( height))
1192  {
1193  remains_relative = 0.0;
1194  }
1195  else if ( cbm::flt_greater_zero( height))
1196  {
1197  double h_cum( 0.0);
1198  double remains_relative_fol = 0.0;
1199  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1200  {
1201  remains_relative_fol += _vt->fFol_fl[fl];
1202  h_cum += ph_.h_fl[fl];
1203  if ( cbm::flt_greater_equal( h_cum, height))
1204  {
1205  break;
1206  }
1207  }
1208 
1209  h_cum = 0.0;
1210  double remains_relative_lst = 0.0;
1211  double remains_relative_lst_total = 0.0;
1212  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1213  {
1214  //lst decreases with height
1215  remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
1216  if ( cbm::flt_less_equal( h_cum, height))
1217  {
1218  remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
1219  }
1220  h_cum += ph_.h_fl[fl];
1221  }
1222  remains_relative_lst /= remains_relative_lst_total;
1223 
1224  remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
1225  remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
1226  (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
1227  }
1228  else
1229  {
1230  KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
1231  return LDNDC_ERR_FAIL;
1232  }
1233 
1234  stubble_c += remains_relative * straw_c;
1235  stubble_n += remains_relative * straw_n;
1236  if ( mulching)
1237  {
1238  mulching_c += (1.0-remains_relative) * straw_c;
1239  mulching_n += (1.0-remains_relative) * straw_n;
1240  }
1241  else
1242  {
1243  straw_c_export += (1.0-remains_relative) * straw_c;
1244  straw_n_export += (1.0-remains_relative) * straw_n;
1245  }
1246 
1247  if ( _vt->is_covercrop)
1248  {
1249  stubble_c += remains_relative * fru_c;
1250  stubble_n += remains_relative * fru_n;
1251  if ( mulching)
1252  {
1253  mulching_c += (1.0-remains_relative) * fru_c;
1254  mulching_n += (1.0-remains_relative) * fru_n;
1255  }
1256  else
1257  {
1258  stubble_c += (1.0-remains_relative) * fru_c;
1259  stubble_n += (1.0-remains_relative) * fru_n;
1260  }
1261  }
1262  else
1263  {
1264  fru_c_export = fru_c;
1265  fru_n_export = fru_n;
1266  }
1267 
1268  //export
1269  c_total_exported += straw_c_export + fru_c_export;
1270  c_fruit_exported += fru_c_export;
1271  n_total_exported += straw_n_export + fru_n_export;
1272  n_fruit_exported += fru_n_export;
1273 
1274  ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
1275  ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
1276 
1277  ph_.accumulated_c_fru_export_harvest += fru_c_export;
1278  ph_.accumulated_n_fru_export_harvest += fru_n_export;
1279 
1280  //stubble litter
1281  sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
1282  sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
1283  sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1284  sc_.accumulated_c_litter_stubble += stubble_c;
1285 
1286  sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
1287  sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
1288  sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
1289  sc_.accumulated_n_litter_stubble += stubble_n;
1290 
1291  //raw litter
1292  sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1293  sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
1294  sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
1295  sc_.accumulated_c_litter_above += mulching_c;
1296 
1297  sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1298  sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
1299  sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
1300  sc_.accumulated_n_litter_above += mulching_n;
1301 
1302  //root litter
1303  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1304  {
1305  double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
1306  double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
1307 
1308  sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
1309  sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
1310  sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
1311  sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
1312 
1313  sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
1314  sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
1315  sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
1316  sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
1317  }
1318 
1319  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
1320  std::string mcom_key;
1321 
1322  char const * species_name = _attributes.get( "/name", "?");
1323 
1324  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
1325  mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
1326 
1327  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
1328  mcom->set( mcom_key.c_str(), gdd_sum);
1329 
1330  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
1331  mcom->set( mcom_key.c_str(), dvs_flush);
1332 
1333  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
1334  mcom->set( mcom_key.c_str(), fru_c);
1335 
1336  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
1337  mcom->set( mcom_key.c_str(), fru_c_export);
1338 
1339  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
1340  mcom->set( mcom_key.c_str(), fru_n);
1341 
1342  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
1343  mcom->set( mcom_key.c_str(), fru_n_export);
1344 
1345  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
1346  mcom->set( mcom_key.c_str(), straw_c);
1347 
1348  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
1349  mcom->set( mcom_key.c_str(), straw_c_export);
1350 
1351  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
1352  mcom->set( mcom_key.c_str(), straw_n);
1353 
1354  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
1355  mcom->set( mcom_key.c_str(), straw_n_export);
1356 
1357  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
1358  mcom->set( mcom_key.c_str(), stubble_c);
1359 
1360  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1361  mcom->set( mcom_key.c_str(), stubble_n);
1362 
1363  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1364  mcom->set( mcom_key.c_str(), rootlitter_c);
1365 
1366  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1367  mcom->set( mcom_key.c_str(), rootlitter_n);
1368 
1369  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1370  {
1371  _vt->fFrt_sl[sl] = 0.0;
1372  }
1373 
1374  cbm::invalidate( root_q_vt_[_vt->slot]);
1375  _vt->rooting_depth = 0.0;
1376 
1377  days_after_emergence[_vt->slot] = -1;
1378 
1379  dw_retranslocation_stem[_vt->slot] = 0.0;
1380  dw_retranslocation_foliage[_vt->slot] = 0.0;
1381 
1382  _vt->mFol = 0.0;
1383  _vt->dw_dfol = 0.0;
1384  _vt->ncFol = 0.0;
1385  _vt->n_dfol = 0.0;
1386 
1387  _vt->dw_lst = 0.0;
1388  _vt->n_lst = 0.0;
1389 
1390  _vt->dw_dst = 0.0;
1391  _vt->n_dst = 0.0;
1392 
1393  _vt->mBud = 0.0;
1394  _vt->mBudStart = 0.0;
1395  _vt->ncBud = 0.0;
1396 
1397  _vt->mFrt = 0.0;
1398  _vt->ncFrt = 0.0;
1399 
1400  _vt->dEmerg = -1;
1401  _vt->growing_degree_days = 0.0;
1402  _vt->dvsMort = 0.0;
1403  _vt->dvsFlush = 0.0;
1404  _vt->dvsFlushOld = 0.0;
1405 
1406  n_plant[_vt->slot] = 0.0;
1407  _vt->a_fix_n = 0.0;
1408 
1409  _vt->height_max = 0.0;
1410  _vt->height_at_canopy_start = 0.0;
1411 
1412  _vt->f_area = 0.0;
1413  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1414  {
1415  _vt->fFol_fl[fl] = 0.0;
1416  _vt->lai_fl[fl] = 0.0;
1417  }
1418 
1419  _vt->f_fac = 0.0;
1420  chill_units[_vt->slot] = 0.0;
1421  chill_factor[_vt->slot] = 1.0;
1422 
1423  yearly_cuts[_vt->slot] = 0;
1424 
1425  allocation_factor_leafs[_vt->slot] = 0.0;
1426  allocation_factor_stems[_vt->slot] = 0.0;
1427  allocation_factor_fruit[_vt->slot] = 0.0;
1428  allocation_factor_roots[_vt->slot] = 0.0;
1429 
1430  m_fruit_maximum[_vt->slot] = -1.0;
1431  spikelets_sterility[_vt->slot] = 0.0;
1432  hypoxia[_vt->slot] = 0.0;
1433 
1434  LD_Allocator->destroy( root_system[_vt->slot]);
1435  root_system[_vt->slot] = NULL;
1436 
1437  return LDNDC_ERR_OK;
1438 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:329
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:268
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:274
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:299
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:280
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:305
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:262
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:142
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_resize().

856 {
857  species_t const * sp = NULL;
858  if ( m_species)
859  {
860  sp = m_species->get_species( _vt->cname());
861  }
862 
864 
865  seconds_crop_planting[_vt->slot] = lclock()->seconds();
866  fractional_cover[_vt->slot] = _attributes.get( "/fractional-cover", 1.0);
867 
868  _vt->is_covercrop = _attributes.get( "/cover-crop", false);
869 
870  //_vt->f_fac = (*_vt)->FFACMAX();
871 
872  //amount of seeds
873  double initial_biomass = _attributes.get( "/initial-biomass", 0.0);
874  if ( cbm::flt_equal( initial_biomass, 0.0))
875  {
876  if ( m_veg->is_family( _vt, ":rice:"))
877  {
878  initial_biomass = 200.0;
879  }
880  else if ( m_veg->is_family( _vt, ":wheat:"))
881  {
882  initial_biomass = 150.0;
883  }
884  else if ( m_veg->is_family( _vt, ":corn:"))
885  {
886  initial_biomass = 50.0;
887  }
888  else if ( m_veg->is_family( _vt, ":rapeseed:"))
889  {
890  initial_biomass = 10.0;
891  }
892  }
893 
894  initial_biomass = cbm::bound_min( 0.0001, initial_biomass * cbm::HA_IN_M2);
895  lai_min[_vt->slot] = 0.01;
896 
897  location[_vt->slot] = _attributes.get( "/location", "?");
898 
899  dw_retranslocation_stem[_vt->slot] = 0.0;
900  dw_retranslocation_foliage[_vt->slot] = 0.0;
901 
902  //plant gets biomass by species initializer
903  //store and substract later according amounts of C and N
904  //for balance check at day of planting
905  double const plant_n_old( _vt->total_nitrogen());
906  double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
907 
908  _vt->height_max = 0.0;
909  _vt->height_at_canopy_start = 0.0;
910 
911  chill_units[_vt->slot] = 0.0;
912  chill_factor[_vt->slot] = 1.0;
913 
914  if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
915  {
916  m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
917  }
918  else
919  {
920  m_fruit_maximum[_vt->slot] = -1.0;
921  }
922  spikelets_sterility[_vt->slot] = 0.0;
923 
924  if ( m_veg->is_family( _vt, ":rice:"))
925  {
926  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
927  }
928  else if ( m_veg->is_family( _vt, ":wheat:"))
929  {
930  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
931  }
932  else
933  {
934  nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
935  }
936 
937  gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
938 
939  hypoxia[_vt->slot] = 0.0;
940 
941  PlaMox_reset_phenology( _vt);
942 
943  if ( cbm::is_equal( _vt->group().c_str(), "crop"))
944  {
945  lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
946  if ( rc_plant)
947  {
948  return LDNDC_ERR_OK;
949  }
950 
951  //emergence has happened for biomass greater 50kg ha-1
952  if ( cbm::flt_greater( initial_biomass, 0.01) &&
953  m_veg->is_family( _vt, ":rice:"))
954  {
955  days_after_emergence[_vt->slot] = 0;
956  }
957 
958  /* only considered for rice so far */
959  int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
960  if ( seedbedduration > 0)
961  {
962  double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
963  _vt->growing_degree_days = seedbedduration * mean_gdd;
964  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
965  }
966  else if ( cbm::flt_greater_equal( initial_biomass, 0.01) &&
967  m_veg->is_family( _vt, ":rice:"))
968  {
969  _vt->growing_degree_days = 200.0;
970  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
971  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
972  initial_biomass * (1.0 - (*_vt)->FRACTION_ROOT()) * (*_vt)->SLAMAX());
973  }
974  else
975  {
976  _vt->growing_degree_days = 0.0;
977  _vt->dvsFlush = 0.0;
978  }
979 
980  transplanting_shock_vt[_vt->slot] = pow(initial_biomass/0.005, 0.2);
981 
982  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
983  allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
984  allocation_factor_stems[_vt->slot] = 0.0;
985  allocation_factor_fruit[_vt->slot] = 0.0;
986 
987  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
988  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
989  _vt->n_lst = 0.0;
990  _vt->ncBud = 0.0;
991  _vt->ncSap = 0.0;
992  _vt->ncCor = 0.0;
993 
994  double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
995  (*_vt)->FRACTION_ROOT_START() :
996  (*_vt)->FRACTION_ROOT());
997  double const initial_foliage_biomass_max( 0.02);
998  _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
999  initial_foliage_biomass_max );
1000 
1001  _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
1002  _vt->dw_lst = 0.0;
1003  _vt->mBud = 0.0;
1004  _vt->mSap = 0.0;
1005  _vt->mCor = 0.0;
1006 
1007  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
1008  n_plant[_vt->slot] = _vt->total_nitrogen();
1009 
1011 
1012  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
1013  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
1014  }
1015  else if ( cbm::is_equal( _vt->cgroup(), "grass"))
1016  {
1017  lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
1018  if ( rc_plant)
1019  {
1020  return LDNDC_ERR_OK;
1021  }
1022 
1023  /* set to fixed value */
1024  lai_min[_vt->slot] = 0.1;
1025 
1026  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
1027  allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
1028  allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
1029  allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
1030 
1031  _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
1032  _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
1033  _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
1034  _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
1035 
1036  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
1037  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
1038  _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
1039  _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
1040 
1041  n_plant[_vt->slot] = _vt->total_nitrogen();
1042 
1044 
1045  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
1046  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
1047  }
1048  else
1049  {
1050  KLOGERROR( "I do not handle this group of species ",
1051  "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
1052  return LDNDC_ERR_RUNTIME_ERROR;
1053  }
1054 
1055  // currently no concept for free available carbon
1056  _vt->f_fac = 0.0;
1057 
1058  // initialize root system
1059  if (root_system.size() <= _vt->slot)
1060  {
1061  root_system.resize(_vt->slot+1);
1062  }
1063 
1064  ldndc_kassert( root_system[_vt->slot] == NULL);
1065  root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
1066  if ( !root_system[_vt->slot])
1067  {
1068  KLOGERROR( "Failed to allocate root-system object");
1069  return LDNDC_ERR_NOMEM;
1070  }
1071 
1072  root_q_vt_[_vt->slot] = 0; // no rooted layers yet
1073  PlaMox_update_root_structure( _vt, _vt->mFrt);
1074 
1075  return LDNDC_ERR_OK;
1076 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:329
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:268
lvector_t< double > daytime_temperatures
store daytime temperature for heat stress analysis
Definition: plamox.h:335
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:274
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:299
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3681
LD_PlantFunctions m_pf
All kind of plant related functions.
Definition: plamox.h:130
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:280
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:305
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:293
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:262
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:287
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > root_system
Root system.
Definition: plamox.h:142
Here is the call graph for this function:
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
Returns
Temperature factor

Temperature factor is calculated depending on species parameter TLIMIT = Temperature limit for plant growth
For simplification reasons the soil temperature from the top soiler layer is used instead of the global temperature

  • If the temperarure \( \text{T} < (0.9 * \text{TLIMIT}) \):
    • \( f_{t} = 0.0 \)
  • If the temperarure \( \text{T} < (1.1 * \text{TLIMIT}) \) for a smother transition:
    • \( f_{t} = T - \frac{(0.9 * \text{TLIMIT})}{(0.2 * \text{TLIMIT})} \)
  • All other cases:
    • \( f_{t} = 1.0 \)

Referenced by PlaMox_exsudation(), and PlaMox_photosynthesis().

3744 {
3745  double const t_min( (*_vt)->TLIMIT() - 2.0);
3746  double const t_max( (*_vt)->TLIMIT());
3747 
3748  if ( cbm::flt_less( _temp, t_min))
3749  {
3750  return 0.0;
3751  }
3752  else if ( cbm::flt_less( _temp, t_max))
3753  {
3754  return (_temp - t_min) / (t_max - t_min);
3755  }
3756  else
3757  {
3758  return 1.0;
3759  }
3760 }
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().

3664 {
3665  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3666  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3667  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3668  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3669 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:4053
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_frost_factor(), PlaMox_get_heat_factor(), PlaMox_get_hypoxia_factor(), PlaMox_n_opt(), PlaMox_nitrogen_fixation(), PlaMox_nitrogen_uptake(), PlaMox_respiration(), PlaMox_update_nitrogen_concentrations(), root_q_vt_, and root_system.

Referenced by ~PhysiologyPlaMox().

2295 {
2296  DroughtStress droughtstress;
2297  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
2298  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
2299  double const fact_a( PlaMox_get_age_factor( _vt));
2300  double const fact_t( PlaMox_get_frost_factor( _vt, *mc_temp));
2301  double const fact_h( PlaMox_get_heat_factor( _vt));
2302  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
2303  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
2304  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
2305 
2306  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
2307 
2308  /* update activity of photosynthesis apparat */
2309  if ( cbm::flt_greater_zero( fact_all))
2310  {
2311  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2312  {
2313  //rubisco activity
2314  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
2315 
2316  //electron transport under standard conditions
2317  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
2318 
2319  //photorespiration under standard conditions
2320  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
2321  }
2322  }
2323 
2324  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
2325  {
2326  m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
2327  m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
2328  m_photo.temp_fl[fl] = mc_.temp_fl[fl];
2329  m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
2330  m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
2331  m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
2332  m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
2333  m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
2334  }
2335  m_photo.nd_airpressure = mc_.nd_airpressure;
2336  m_photo.set_vegetation_base_state( _vt);
2337  m_photo.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0);
2338 
2339  m_photo.solve();
2340 
2341  m_photo.get_vegetation_state( _vt);
2342 
2343  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
2344 
2345  if ( cbm::flt_greater_zero( carbonuptake_sum))
2346  {
2347  timestep_c_assi += carbonuptake_sum;
2348  double const dw_assi( carbonuptake_sum / cbm::CCDM);
2349 
2350  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2351  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2352  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2353  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2354 
2355  dcFru[_vt->slot] = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2356  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2357  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2358  dcLst[_vt->slot] = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2359 
2365  }
2366 
2367  return LDNDC_ERR_OK;
2368 }
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3765
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:268
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3924
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3742
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:4014
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:274
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3681
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:280
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:262
Here is the call graph for this function:
Here is the caller 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
  • 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.

Referenced by ~PhysiologyPlaMox().

3521 {
3522  size_t const fl_cnt( _vt->nb_foliagelayers());
3523 
3524  double sla_cum( 0.0);
3525  for (size_t fl = 0; fl < fl_cnt; ++fl)
3526  {
3527  sla_cum += _vt->sla_fl[fl];
3528  }
3529 
3530  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3531  double const mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3532  _vt->mFol));
3533 
3534  if ( cbm::flt_greater_zero( sla_cum))
3535  {
3536  DroughtStress droughtstress;
3537  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3538 
3539  for (size_t fl = 0; fl < fl_cnt; ++fl)
3540  {
3541  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3542  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3543  }
3544  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3545  {
3546  _vt->fFol_fl[fl] = 0.0;
3547  _vt->lai_fl[fl] = 0.0;
3548  _vt->sla_fl[fl] = 0.0;
3549  }
3550  }
3551  else
3552  {
3553  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3554  {
3555  _vt->fFol_fl[fl] = 0.0;
3556  _vt->lai_fl[fl] = 0.0;
3557  _vt->sla_fl[fl] = 0.0;
3558  }
3559  }
3560 }
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:287
Here is the caller graph for this function:

◆ PlaMox_update_nitrogen_concentrations()

void ldndc::PhysiologyPlaMox::PlaMox_update_nitrogen_concentrations ( MoBiLE_Plant *  _vt)
private

Distribution of total plant nitrogen throughout complete plant assumed to occur instantaneously.

Parameters
[in]_vtPlant species

References PlaMox_get_foliage_nitrogen_concentration(), and PlaMox_n_opt().

Referenced by PlaMox_bud_burst(), PlaMox_event_plant(), PlaMox_exsudation(), and PlaMox_photosynthesis().

3682 {
3683  double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3684  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);
3685 
3686 // double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3687 
3688  double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3689  cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3690  _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3691  + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3692  _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3693  double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3694  cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3695  _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3696  + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3697  _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3698  double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3699  cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3700  _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3701  + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3702  _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3703  double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3704  cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3705  _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3706  + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3707  _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3708 
3709  double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3710  if ( cbm::flt_greater_zero( n_tot_opt))
3711  {
3712  // CB: fraction of available N to optimum N
3713  double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3714  // CB: N gets distributed evenly over all compartments regarding their optimum N content
3715  _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3716  (*_vt)->NC_FOLIAGE_MAX();
3717  _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3718  0.0;
3719  _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3720  (*_vt)->NC_FRUIT_MAX();
3721  _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3722  (*_vt)->NC_FINEROOTS_MAX();
3723  }
3724 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:4053
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3663
Here is the call graph for this function:
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.

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

Referenced by ~PhysiologyPlaMox().

3578 {
3579  size_t const fl_cnt( _vt->nb_foliagelayers());
3580 
3591  if ( IS_SPECIE( _vt->cname(), "mungbean"))
3592  {
3593  double slamax( 26.0);
3594  if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3595  {
3596  slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3597  }
3598  else
3599  {
3600  slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3601  }
3602 
3603  for (size_t fl = 0; fl < fl_cnt; ++fl)
3604  {
3605  _vt->sla_fl[fl] = slamax;
3606  }
3607  }
3608  else if ( m_veg->is_family( _vt, ":rice:"))
3609  {
3610  double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3611  cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3612  _vt->dvsMort);
3613 
3614  double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3615  for (size_t fl = 0; fl < fl_cnt; ++fl)
3616  {
3617  _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3618  }
3619  }
3620  else
3621  {
3622  // reduction of specific leaf area with crop age
3623  double sla_red( 1.0);
3624  if (_vt->groupId() == SPECIES_GROUP_GRASS)
3625  {
3626  if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3627  {
3628  sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3629  }
3630  }
3631  else
3632  {
3633  sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3634  }
3635 
3636  for (size_t fl = 0; fl < fl_cnt; ++fl)
3637  {
3638  _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3639  }
3640  }
3641 
3642  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3643  {
3644  _vt->sla_fl[fl] = 0.0;
3645  }
3646 }
Here is the caller graph for this function:

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