LandscapeDNDC  1.37.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

BerryBall plamox_berryball
 Photosynthesis.
 
NitrogenFixation * plamox_nitrogen_fixation
 Nitrogen fixation.
 
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
 Root system. More...
 
LD_PlantFunctions m_pf
 All kind of plant related functions.
 
cbm::string_t transpiration_method
 Transpiration method used by PlaMox.
 
bool have_drought_stress
 Consider drought stress yes/no.
 
bool have_heat_stress
 Consider heat 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, have_heat_stress, m_pf, plamox_berryball, plamox_nitrogen_fixation, plamox_root_system, plantfamilies, and transpiration_method.

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

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, plamox_root_system, and root_q_vt_.

Referenced by PlaMox_event_plant().

754 {
755  if ( plamox_root_system[_vt->slot] == NULL)
756  {
757  KLOGERROR( "[BUG] ", "root_system is NULL when not expected \"",_vt->name(),"\"!");
758  return LDNDC_ERR_RUNTIME_ERROR;
759  }
760 
761  bool const mulching = _attributes.get( "/mulching", false);
762 
763  double const export_root = _attributes.get( "/fraction-export-rootwood", 0.0);
764  double const rootlitter_c( (1.0 - export_root) * _vt->mFrt * cbm::CCDM);
765  double const rootlitter_n( (1.0 - export_root) * _vt->n_frt());
766  double const root_c_export( export_root * _vt->mFrt * cbm::CCDM);
767  double const root_n_export( export_root * _vt->mFrt * _vt->ncFrt);
768 
769  double const straw_c( (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst) * cbm::CCDM);
770  double const straw_n( _vt->n_fol() + _vt->n_dfol + _vt->n_lst + _vt->n_dst);
771 
772  double const fru_c( _vt->mBud * cbm::CCDM);
773  double const fru_n( _vt->n_bud());
774 
775  double fru_c_export( 0.0);
776  double fru_n_export( 0.0);
777 
778  double straw_c_export( 0.0);
779  double straw_n_export( 0.0);
780 
781  double mulching_c( 0.0);
782  double mulching_n( 0.0);
783 
784  double stubble_c( 0.0);
785  double stubble_n( 0.0);
786 
787  double gdd_sum( _vt->growing_degree_days );
788  double dvs_flush( _vt->dvsFlush );
789 
790  double const height( _attributes.get( "/height", invalid_flt));
791  double remains_relative( _attributes.get( "/remains_relative", invalid_flt));
792  double remains_absolute( _attributes.get( "/remains_absolute", invalid_flt));
793  if( cbm::is_valid( remains_absolute))
794  {
795  remains_absolute *= cbm::HA_IN_M2;
796  }
797 
798  if ( !cbm::flt_greater_equal_zero( remains_relative)
799  && !cbm::flt_greater_equal_zero( remains_absolute)
800  && !cbm::flt_greater_equal_zero( height))
801  {
802  if ( _vt->is_covercrop)
803  {
804  remains_relative = 1.0;
805  }
806  else
807  {
808  KLOGWARN( "harvest event attribute \"remains_relative\" and \"remains_absolute\" and \"height\" not set;",
809  " \"remains_relative\" set to zero and used [species=", _vt->name(),"]");
810  }
811  }
812  else if ( (cbm::flt_greater_equal_zero( remains_relative) ||
813  cbm::flt_greater_equal_zero( remains_absolute))
814  && cbm::flt_greater_equal_zero( height))
815  {
816  KLOGWARN( "harvest event attribute \"remains_(relative/absolute)\" and \"height\" both set;"
817  " attribute \"remains_relative\" used [species=", _vt->name(),"]");
818  }
819 
820  if ( cbm::flt_greater_equal_zero( remains_relative))
821  {
822  /* no op */
823  }
824  else if ( cbm::flt_greater_equal_zero( remains_absolute))
825  {
826  remains_relative = cbm::bound( 0.0,
827  remains_absolute / (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst),
828  1.0);
829  }
830  else if ( cbm::flt_equal_zero( height))
831  {
832  remains_relative = 0.0;
833  }
834  else if ( cbm::flt_greater_zero( height))
835  {
836  double h_cum( 0.0);
837  double remains_relative_fol = 0.0;
838  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
839  {
840  remains_relative_fol += _vt->fFol_fl[fl];
841  h_cum += ph_.h_fl[fl];
842  if ( cbm::flt_greater_equal( h_cum, height))
843  {
844  break;
845  }
846  }
847 
848  h_cum = 0.0;
849  double remains_relative_lst = 0.0;
850  double remains_relative_lst_total = 0.0;
851  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
852  {
853  //lst decreases with height
854  remains_relative_lst_total += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
855  if ( cbm::flt_less_equal( h_cum, height))
856  {
857  remains_relative_lst += pow( cbm::bound_min( 0.0, _vt->height_max - h_cum), 0.3);
858  }
859  h_cum += ph_.h_fl[fl];
860  }
861  remains_relative_lst /= remains_relative_lst_total;
862 
863  remains_relative = (remains_relative_fol * (_vt->mFol + _vt->dw_dfol) +
864  remains_relative_lst * (_vt->dw_lst+ _vt->dw_dst)) /
865  (_vt->mFol + _vt->dw_dfol + _vt->dw_lst+ _vt->dw_dst);
866  }
867  else
868  {
869  KLOGERROR( "[BUG] ", "harvest event attribute \"remains_relative\" and \"height\" are invalid [species=", _vt->name(),"]");
870  return LDNDC_ERR_FAIL;
871  }
872 
873  stubble_c += remains_relative * straw_c;
874  stubble_n += remains_relative * straw_n;
875  if ( mulching)
876  {
877  mulching_c += (1.0-remains_relative) * straw_c;
878  mulching_n += (1.0-remains_relative) * straw_n;
879  }
880  else
881  {
882  straw_c_export += (1.0-remains_relative) * straw_c;
883  straw_n_export += (1.0-remains_relative) * straw_n;
884  }
885 
886  if ( _vt->is_covercrop)
887  {
888  stubble_c += remains_relative * fru_c;
889  stubble_n += remains_relative * fru_n;
890  if ( mulching)
891  {
892  mulching_c += (1.0-remains_relative) * fru_c;
893  mulching_n += (1.0-remains_relative) * fru_n;
894  }
895  else
896  {
897  stubble_c += (1.0-remains_relative) * fru_c;
898  stubble_n += (1.0-remains_relative) * fru_n;
899  }
900  }
901  else
902  {
903  fru_c_export = fru_c;
904  fru_n_export = fru_n;
905  }
906 
907  //export
908  c_total_exported += straw_c_export + fru_c_export;
909  c_fruit_exported += fru_c_export;
910  n_total_exported += straw_n_export + fru_n_export;
911  n_fruit_exported += fru_n_export;
912 
913  ph_.accumulated_c_export_harvest += straw_c_export + fru_c_export + root_c_export;
914  ph_.accumulated_n_export_harvest += straw_n_export + fru_n_export + root_n_export;
915 
916  ph_.accumulated_c_fru_export_harvest += fru_c_export;
917  ph_.accumulated_n_fru_export_harvest += fru_n_export;
918 
919  //stubble litter
920  sc_.c_stubble_lit3 += stubble_c * (*_vt)->LIGNIN();
921  sc_.c_stubble_lit2 += stubble_c * (*_vt)->CELLULOSE();
922  sc_.c_stubble_lit1 += stubble_c * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
923  sc_.accumulated_c_litter_stubble += stubble_c;
924 
925  sc_.n_stubble_lit3 += stubble_n * (*_vt)->LIGNIN();
926  sc_.n_stubble_lit2 += stubble_n * (*_vt)->CELLULOSE();
927  sc_.n_stubble_lit1 += stubble_n * (1.0 - (*_vt)->LIGNIN() - (*_vt)->CELLULOSE());
928  sc_.accumulated_n_litter_stubble += stubble_n;
929 
930  //raw litter
931  sc_.c_raw_lit_1_above += mulching_c * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
932  sc_.c_raw_lit_2_above += mulching_c * (*_vt)->CELLULOSE();
933  sc_.c_raw_lit_3_above += mulching_c * (*_vt)->LIGNIN();
934  sc_.accumulated_c_litter_above += mulching_c;
935 
936  sc_.n_raw_lit_1_above += mulching_n * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
937  sc_.n_raw_lit_2_above += mulching_n * (*_vt)->CELLULOSE();
938  sc_.n_raw_lit_3_above += mulching_n * (*_vt)->LIGNIN();
939  sc_.accumulated_n_litter_above += mulching_n;
940 
941  //root litter
942  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
943  {
944  double const dw_rootlitter( rootlitter_c / cbm::CCDM * _vt->fFrt_sl[sl]);
945  double const n_rootlitter( dw_rootlitter * _vt->ncFrt);
946 
947  sc_.c_raw_lit_1_sl[sl] += dw_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN()) * cbm::CCDM;
948  sc_.c_raw_lit_2_sl[sl] += dw_rootlitter * (*_vt)->CELLULOSE() * cbm::CCDM;
949  sc_.c_raw_lit_3_sl[sl] += dw_rootlitter * (*_vt)->LIGNIN() * cbm::CCDM;
950  sc_.accumulated_c_litter_below_sl[sl] += dw_rootlitter * cbm::CCDM;
951 
952  sc_.n_raw_lit_1_sl[sl] += n_rootlitter * (1.0 - (*_vt)->CELLULOSE() - (*_vt)->LIGNIN());
953  sc_.n_raw_lit_2_sl[sl] += n_rootlitter * (*_vt)->CELLULOSE();
954  sc_.n_raw_lit_3_sl[sl] += n_rootlitter * (*_vt)->LIGNIN();
955  sc_.accumulated_n_litter_below_sl[sl] += n_rootlitter;
956  }
957 
958  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
959  std::string mcom_key;
960 
961  char const * species_name = _attributes.get( "/name", "?");
962 
963  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:daysOnField", species_name);
964  mcom->set( mcom_key.c_str(), (double)((lclock()->seconds() - seconds_crop_planting[_vt->slot]) / cbm::SEC_IN_DAY));
965 
966  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:gddsum", species_name);
967  mcom->set( mcom_key.c_str(), gdd_sum);
968 
969  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:dvsflush", species_name);
970  mcom->set( mcom_key.c_str(), dvs_flush);
971 
972  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru", species_name);
973  mcom->set( mcom_key.c_str(), fru_c);
974 
975  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_fru_export", species_name);
976  mcom->set( mcom_key.c_str(), fru_c_export);
977 
978  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru", species_name);
979  mcom->set( mcom_key.c_str(), fru_n);
980 
981  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_fru_export", species_name);
982  mcom->set( mcom_key.c_str(), fru_n_export);
983 
984  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw", species_name);
985  mcom->set( mcom_key.c_str(), straw_c);
986 
987  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_straw_export", species_name);
988  mcom->set( mcom_key.c_str(), straw_c_export);
989 
990  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw", species_name);
991  mcom->set( mcom_key.c_str(), straw_n);
992 
993  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_straw_export", species_name);
994  mcom->set( mcom_key.c_str(), straw_n_export);
995 
996  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_stubble", species_name);
997  mcom->set( mcom_key.c_str(), stubble_c);
998 
999  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_stubble", species_name);
1000  mcom->set( mcom_key.c_str(), stubble_n);
1001 
1002  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:c_frt", species_name);
1003  mcom->set( mcom_key.c_str(), rootlitter_c);
1004 
1005  cbm::state_scratch_t::make_item_key( &mcom_key, "harvest:%s:n_frt", species_name);
1006  mcom->set( mcom_key.c_str(), rootlitter_n);
1007 
1008  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1009  {
1010  _vt->fFrt_sl[sl] = 0.0;
1011  }
1012 
1013  cbm::invalidate( root_q_vt_[_vt->slot]);
1014  _vt->rooting_depth = 0.0;
1015 
1016  days_after_emergence[_vt->slot] = -1;
1017 
1018  dw_retranslocation_stem[_vt->slot] = 0.0;
1019  dw_retranslocation_foliage[_vt->slot] = 0.0;
1020 
1021  dw_fol_old[_vt->slot] = 0.0;
1022  lai_dynamic[_vt->slot] = 0.0;
1023 
1024  _vt->mFol = 0.0;
1025  _vt->dw_dfol = 0.0;
1026  _vt->ncFol = 0.0;
1027  _vt->n_dfol = 0.0;
1028 
1029  _vt->dw_lst = 0.0;
1030  _vt->n_lst = 0.0;
1031 
1032  _vt->dw_dst = 0.0;
1033  _vt->n_dst = 0.0;
1034 
1035  _vt->mBud = 0.0;
1036  _vt->mBudStart = 0.0;
1037  _vt->ncBud = 0.0;
1038 
1039  _vt->mFrt = 0.0;
1040  _vt->ncFrt = 0.0;
1041 
1042  _vt->dEmerg = -1;
1043  _vt->growing_degree_days = 0.0;
1044  _vt->dvsMort = 0.0;
1045  _vt->dvsFlush = 0.0;
1046  _vt->dvsFlushOld = 0.0;
1047 
1048  n_plant[_vt->slot] = 0.0;
1049  _vt->a_fix_n = 0.0;
1050 
1051  _vt->height_max = 0.0;
1052  _vt->height_at_canopy_start = 0.0;
1053 
1054  _vt->f_area = 0.0;
1055  for ( int fl = 0; fl < m_setup->canopylayers(); ++fl)
1056  {
1057  _vt->fFol_fl[fl] = 0.0;
1058  _vt->lai_fl[fl] = 0.0;
1059  }
1060 
1061  _vt->f_fac = 0.0;
1062  chill_units[_vt->slot] = 0.0;
1063  chill_factor[_vt->slot] = 1.0;
1064 
1065  yearly_cuts[_vt->slot] = 0;
1066 
1067  allocation_factor_leafs[_vt->slot] = 0.0;
1068  allocation_factor_stems[_vt->slot] = 0.0;
1069  allocation_factor_fruit[_vt->slot] = 0.0;
1070  allocation_factor_roots[_vt->slot] = 0.0;
1071 
1072  m_fruit_maximum[_vt->slot] = -1.0;
1073  spikelets_sterility[_vt->slot] = 0.0;
1074  hypoxia[_vt->slot] = 0.0;
1075 
1076  LD_Allocator->destroy( plamox_root_system[_vt->slot]);
1077  plamox_root_system[_vt->slot] = NULL;
1078 
1079  return LDNDC_ERR_OK;
1080 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:338
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:277
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
Root system.
Definition: plamox.h:145
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:283
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:308
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:289
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:314
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:271
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_root_system, PlaMox_update_nitrogen_concentrations(), PlaMox_update_root_structure(), plantfamilies, and root_q_vt_.

Referenced by PlaMox_step_init().

462 {
463  species_t const * sp = NULL;
464  if ( m_species)
465  {
466  sp = m_species->get_species( _vt->cname());
467  }
468 
470 
471  seconds_crop_planting[_vt->slot] = lclock()->seconds();
472  fractional_cover[_vt->slot] = _attributes.get( "/fractional-cover", 1.0);
473 
474  //Scale growing degree days
475  //Currently only used by FarmSystem to dynamically adjust species
476  //over larger regions and/or time periods
477  double gdd_maturity_target( _attributes.get( "/gdd-maturity-target", -1.0));
478  if ( cbm::flt_less( gdd_maturity_target, 0.0) &&
479  (std::strstr( _vt->cname(), "GDD-MATURITY-TARGET") != NULL) &&
480  gdd_target.find( _vt->cname()) != gdd_target.end())
481  {
482  gdd_maturity_target = gdd_target[_vt->cname()];
483  }
484 
485  if ( cbm::flt_greater_zero( gdd_maturity_target) &&
486  cbm::flt_greater_zero( (*_vt)->GDD_MATURITY()))
487  {
488  double const scale_gdd( gdd_maturity_target / (*_vt)->GDD_MATURITY());
489  MoBiLE_PlantParameters p_parameters = (*m_speciesparameters)[_vt->ctype()];
490  p_parameters.GDD_EMERGENCE_UPDATE( (*_vt)->GDD_EMERGENCE() * scale_gdd);
491  p_parameters.GDD_STEM_ELONGATION_UPDATE( (*_vt)->GDD_STEM_ELONGATION() * scale_gdd);
492  p_parameters.GDD_FLOWERING_UPDATE( (*_vt)->GDD_FLOWERING() * scale_gdd);
493  p_parameters.GDD_GRAIN_FILLING_UPDATE( (*_vt)->GDD_GRAIN_FILLING() * scale_gdd);
494  p_parameters.GDD_ROOTS_GROWN_UPDATE( (*_vt)->GDD_ROOTS_GROWN() * scale_gdd);
495  p_parameters.GDD_MATURITY_UPDATE( gdd_maturity_target);
496  _vt->switchparameters( p_parameters);
497  }
498 
499  _vt->is_covercrop = _attributes.get( "/cover-crop", false);
500  //_vt->f_fac = (*_vt)->FFACMAX();
501 
502  //amount of seeds
503  double const initial_biomass( cbm::bound_min( 10.0,
504  cbm::flt_greater_zero( _attributes.get( "/initial-biomass", 0.0)) ?
505  _attributes.get( "/initial-biomass", 0.0) :
506  (*_vt)->SEED_RATE()) * cbm::HA_IN_M2);
507 
508  lai_min[_vt->slot] = 0.01;
509 
510  location[_vt->slot] = _attributes.get( "/location", "?");
511 
512  dw_retranslocation_stem[_vt->slot] = 0.0;
513  dw_retranslocation_foliage[_vt->slot] = 0.0;
514 
515  dw_fol_old[_vt->slot] = 0.0;
516  lai_dynamic[_vt->slot] = 0.0;
517 
518  //plant gets biomass by species initializer
519  //store and substract later according amounts of C and N
520  //for balance check at day of planting
521  double const plant_n_old( _vt->total_nitrogen());
522  double const plant_c_old( _vt->total_biomass() * cbm::CCDM);
523 
524  _vt->height_max = 0.0;
525  _vt->height_at_canopy_start = 0.0;
526 
527  chill_units[_vt->slot] = 0.0;
528  chill_factor[_vt->slot] = 1.0;
529 
530  if ( cbm::flt_greater_zero( (*_vt)->M_FRUIT_OPT()))
531  {
532  m_fruit_maximum[_vt->slot] = (*_vt)->M_FRUIT_OPT();
533  }
534  else
535  {
536  m_fruit_maximum[_vt->slot] = -1.0;
537  }
538  spikelets_sterility[_vt->slot] = 0.0;
539 
540  if ( m_veg->is_family( _vt, ":rice:"))
541  {
542  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
543  }
544  else if ( m_veg->is_family( _vt, ":wheat:"))
545  {
546  nc_fol_opt[_vt->slot] = 0.5 * ((*_vt)->NC_FOLIAGE_MAX() + (*_vt)->NC_FOLIAGE_MIN());
547  }
548  else
549  {
550  nc_fol_opt[_vt->slot] = (*_vt)->NC_FOLIAGE_MAX();
551  }
552 
553  gdd_grain_filling[_vt->slot] = (*_vt)->GDD_GRAIN();
554 
555  hypoxia[_vt->slot] = 0.0;
556  transplanting_shock_vt[_vt->slot] = 0.0;
557 
558  PlaMox_reset_phenology( _vt);
559 
560  if ( cbm::is_equal( _vt->group().c_str(), "crop"))
561  {
562  lerr_t rc_plant = m_pf.initialize_crop( _vt, sp ? sp->crop() : NULL);
563  if ( rc_plant)
564  {
565  return LDNDC_ERR_OK;
566  }
567 
568  /* only considered for rice so far */
569  int const seedbedduration( _attributes.get( "/seedbed-duration", 0));
570  if ( seedbedduration > 0)
571  {
572  double const mean_gdd( cbm::bound_max(mc_.nd_airtemperature - (*_vt)->GDD_BASE_TEMPERATURE(), (*_vt)->GDD_MAX_TEMPERATURE()));
573  _vt->growing_degree_days = seedbedduration * mean_gdd;
574  _vt->dvsFlush = _vt->growing_degree_days / (*_vt)->GDD_MATURITY();
575  transplanting_shock_vt[_vt->slot] = 1.0;
576  days_after_emergence[_vt->slot] = 0;
577  }
578  else
579  {
580  _vt->growing_degree_days = 0.0;
581  _vt->dvsFlush = 0.0;
582  }
583 
584  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
585  allocation_factor_leafs[_vt->slot] = 1.0 - (*_vt)->FRACTION_ROOT();
586  allocation_factor_stems[_vt->slot] = 0.0;
587  allocation_factor_fruit[_vt->slot] = 0.0;
588 
589  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
590  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
591  _vt->n_lst = 0.0;
592  _vt->ncBud = 0.0;
593  _vt->ncSap = 0.0;
594  _vt->ncCor = 0.0;
595 
596  double const fraction_root_start( cbm::flt_greater_zero( (*_vt)->FRACTION_ROOT_START()) ?
597  (*_vt)->FRACTION_ROOT_START() :
598  (*_vt)->FRACTION_ROOT());
599  double const initial_foliage_biomass_max( 0.02);
600  _vt->mFol = cbm::bound_max( (1.0 - fraction_root_start) * initial_biomass,
601  initial_foliage_biomass_max );
602 
603  _vt->mFrt = cbm::bound_min( 0.0, initial_biomass - _vt->mFol);
604  _vt->dw_lst = 0.0;
605  _vt->mBud = 0.0;
606  _vt->mSap = 0.0;
607  _vt->mCor = 0.0;
608 
609  lai_min[_vt->slot] = cbm::bound_min( lai_min[_vt->slot], _vt->mFol * (*_vt)->SLAMAX());
610  n_plant[_vt->slot] = _vt->total_nitrogen();
612 
613  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
614  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
615  }
616  else if ( cbm::is_equal( _vt->cgroup(), "grass"))
617  {
618  lerr_t rc_plant = m_pf.initialize_grass( _vt, sp ? sp->grass() : NULL);
619  if ( rc_plant)
620  {
621  return LDNDC_ERR_OK;
622  }
623 
624  if ( lclock()->seconds() > cbm::SEC_IN_DAY)
625  {
626  PlaMox_reset_phenology( _vt);
627  }
628 
629  /* set to fixed value */
630  lai_min[_vt->slot] = 0.1;
631 
632  allocation_factor_roots[_vt->slot] = (*_vt)->FRACTION_ROOT();
633  allocation_factor_fruit[_vt->slot] = (*_vt)->FRACTION_FRUIT();
634  allocation_factor_leafs[_vt->slot] = (*_vt)->FRACTION_FOLIAGE();
635  allocation_factor_stems[_vt->slot] = (1.0 - allocation_factor_leafs[_vt->slot] - allocation_factor_roots[_vt->slot] - allocation_factor_fruit[_vt->slot]);
636 
637  _vt->mFrt = allocation_factor_roots[_vt->slot] * initial_biomass;
638  _vt->mFol = allocation_factor_leafs[_vt->slot] * initial_biomass;
639  _vt->dw_lst = allocation_factor_stems[_vt->slot] * initial_biomass;
640  _vt->mBud = allocation_factor_fruit[_vt->slot] * initial_biomass;
641 
642  _vt->ncFrt = (*_vt)->NC_FINEROOTS_MAX();
643  _vt->ncFol = (*_vt)->NC_FOLIAGE_MAX();
644  _vt->n_lst = (*_vt)->NC_STRUCTURAL_TISSUE_MAX() * _vt->dw_lst;
645  _vt->ncBud = (*_vt)->NC_FRUIT_MAX();
646 
647  n_plant[_vt->slot] = _vt->total_nitrogen();
648 
650 
651  n_at_planting += (n_plant[_vt->slot] - plant_n_old);
652  timestep_c_assi += (initial_biomass * cbm::CCDM - plant_c_old);
653  }
654  else
655  {
656  KLOGERROR( "I do not handle this group of species ",
657  "[species=\"",_vt->name(),"\",group=",_vt->group(),"]");
658  return LDNDC_ERR_RUNTIME_ERROR;
659  }
660 
661  // currently no concept for free available carbon
662  _vt->f_fac = 0.0;
663 
664  // initialize root system
665  if (plamox_root_system.size() <= _vt->slot)
666  {
667  plamox_root_system.resize(_vt->slot+1);
668  }
669 
670  ldndc_kassert( plamox_root_system[_vt->slot] == NULL);
671  plamox_root_system[_vt->slot] = LD_Allocator->construct_args< RootSystemDNDC >( 1, m_state, io_kcomm);
672  if ( !plamox_root_system[_vt->slot])
673  {
674  KLOGERROR( "Failed to allocate root-system object");
675  return LDNDC_ERR_NOMEM;
676  }
677 
678  double const seed_depth = _attributes.get( "/seed-depth", 0.05);
679  root_q_vt_[_vt->slot] = 0; // no rooted layers yet
680  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
681  {
682  if (cbm::flt_greater( sc_.depth_sl[sl], seed_depth))
683  {
684  break;
685  }
686  root_q_vt_[_vt->slot] = sl; // no rooted layers yet
687  }
688 
689  PlaMox_update_root_structure( _vt, _vt->mFrt);
690 
691  return LDNDC_ERR_OK;
692 }
lvector_t< unsigned int > root_q_vt_
Largest soil layer index where roots exist [-].
Definition: plamox.h:338
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:277
speciesparameters::speciesparameters_set_t MoBiLE_PlantParameters
Definition: mbe_plant.h:25
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > plamox_root_system
Root system.
Definition: plamox.h:145
lvector_t< double > daytime_temperatures
store daytime temperature for heat stress analysis
Definition: plamox.h:344
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:283
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:308
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3339
LD_PlantFunctions m_pf
All kind of plant related functions.
Definition: plamox.h:151
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:289
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:314
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:302
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:271
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:296
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().

3673 {
3674  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3675  {
3676  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3677  {
3678  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3679  }
3680  return ( 1.0);
3681  }
3682  else
3683  {
3684  if ( days_after_emergence[_p->slot] < 0)
3685  {
3686  return 0.0;
3687  }
3688  else
3689  {
3690  if ( cbm::flt_less_equal( _p->growing_degree_days, (*_p)->GDD_MATURITY()))
3691  {
3692  return ( 1.0);
3693  }
3694  else
3695  {
3696  return 1.0 / std::exp( 0.01 * (_p->growing_degree_days - (*_p)->GDD_MATURITY()));
3697  }
3698  }
3699  }
3700 }
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().

3634 {
3635  if ( m_veg->is_family( _vt, ":wheat:"))
3636  {
3637  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3638  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3639 
3640  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3641  cbm::flt_greater( _vt->dw_lst, lst_opt))
3642  {
3643  return lst_opt / _vt->dw_lst;
3644  }
3645  }
3646 
3647  return 1.0;
3648 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:302
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().

3399 {
3400  double const t_min( (*_vt)->TLIMIT() - 2.0);
3401  double const t_max( (*_vt)->TLIMIT());
3402 
3403  if ( cbm::flt_less( _temp, t_min))
3404  {
3405  return 0.0;
3406  }
3407  else if ( cbm::flt_less( _temp, t_max))
3408  {
3409  return (_temp - t_min) / (t_max - t_min);
3410  }
3411  else
3412  {
3413  return 1.0;
3414  }
3415 }
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().

3601 {
3602 // if ( m_veg->is_family( _vt, ":winterwheat:"))
3603 // {
3604 // double const nc_lai_based_opt( cbm::flt_greater_zero( _vt->lai()) ?
3605 // (*_vt)->NC_FOLIAGE_MAX() * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3606 // double const nc_lai_based( cbm::flt_greater_zero( _vt->lai()) ?
3607 // _vt->ncFol * _vt->mFol * cbm::G_IN_KG / _vt->lai() : 0.0);
3608 // double const vc( cbm::bound_min( 0.01, 87.3 * (nc_lai_based - 0.33)));
3609 // double const vc_max( cbm::bound_min( 0.01, 87.3 * (nc_lai_based_opt - 0.33))) ;
3610 //
3611 // return cbm::bound( 0.01,
3612 // vc / vc_max,
3613 // 1.0);
3614 // }
3615 // else
3616  {
3617  double const n_ratio( _vt->ncFol / nc_fol_opt[_vt->slot]);
3618  if ( n_ratio < 1.0)
3619  {
3620  return cbm::bound( 0.01,
3621  pow( n_ratio, (*_vt)->N_DEF_FACTOR()),
3622  1.0);
3623  }
3624  else
3625  {
3626  return 1.0;
3627  }
3628  }
3629 }
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().

3324 {
3325  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3326  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3327  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3328  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3329 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3711
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlaMox_photosynthesis()

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

Update of information needed by photofarquhar.

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

References allocation_factor_fruit, allocation_factor_leafs, allocation_factor_roots, allocation_factor_stems, chill_factor, fractional_cover, FTS_TOT_, have_drought_stress, m_pf, plamox_berryball, 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_fixation(), PlaMox_nitrogen_uptake(), PlaMox_respiration(), plamox_root_system, PlaMox_update_nitrogen_concentrations(), and root_q_vt_.

1944 {
1945  DroughtStress droughtstress;
1946  droughtstress.fh2o_ref = (*_vt)->H2OREF_A();
1947  double const fact_d( droughtstress.linear_threshold( _vt->f_h2o));
1948  double const fact_a( PlaMox_get_age_factor( _vt));
1949  double const fact_t( PlaMox_get_frost_factor( _vt, mc_.ts_airtemperature));
1950  double const fact_h( PlaMox_get_heat_factor( _vt));
1951  double const fact_o( PlaMox_get_hypoxia_factor( _vt));
1952  double const fact_n( PlaMox_get_nitrogen_deficiency( _vt));
1953  double const fact_b( PlaMox_get_biomass_induced_downregulation( _vt));
1954 
1955  double const fact_all( cbm::bound_max( fact_d * fact_t * fact_h * fact_o * fact_n * fact_b, fact_a));
1956 
1957  /* update activity of photosynthesis apparat */
1958  if ( cbm::flt_greater_zero( fact_all))
1959  {
1960  for ( size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
1961  {
1962  //rubisco activity
1963  _vt->vcAct25_fl[fl] = (*_vt)->VCMAX25() * fact_all;
1964 
1965  //electron transport under standard conditions
1966  _vt->jAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QJVC();
1967 
1968  //photorespiration under standard conditions
1969  _vt->rdAct25_fl[fl] = _vt->vcAct25_fl[fl] * (*_vt)->QRD25();
1970  }
1971  }
1972 
1973  for (size_t fl = 0; fl < _vt->nb_foliagelayers(); ++fl)
1974  {
1975  plamox_berryball.vpd_fl[fl] = mc_.vpd_fl[fl];
1976  plamox_berryball.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
1977  plamox_berryball.temp_fl[fl] = mc_.temp_fl[fl];
1978  plamox_berryball.parsun_fl[fl] = mc_.parsun_fl[fl];
1979  plamox_berryball.parshd_fl[fl] = mc_.parshd_fl[fl];
1980  plamox_berryball.tFol_fl[fl] = mc_.tFol_fl[fl];
1981  plamox_berryball.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
1982  plamox_berryball.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
1983  }
1984  plamox_berryball.nd_airpressure = mc_.nd_airpressure;
1985  plamox_berryball.set_vegetation_base_state( _vt);
1986  plamox_berryball.set_vegetation_non_stomatal_water_limitation_state( 0.0, 0.0, 0.0, 0.0);
1987 
1988  plamox_berryball.solve();
1989 
1990  plamox_berryball.get_vegetation_state( _vt);
1991 
1992  double const carbonuptake_sum( cbm::sum( _vt->carbonuptake_fl, _vt->nb_foliagelayers()));
1993 
1994  if ( cbm::flt_greater_zero( carbonuptake_sum))
1995  {
1996  timestep_c_assi += carbonuptake_sum;
1997  double const dw_assi( carbonuptake_sum / cbm::CCDM);
1998 
1999  _vt->mBud += dw_assi * allocation_factor_fruit[_vt->slot];
2000  // the root length for mass from photosynthesis gets adapted in update root system
2001  _vt->mFrt += dw_assi * allocation_factor_roots[_vt->slot];
2002  _vt->mFol += dw_assi * allocation_factor_leafs[_vt->slot];
2003  _vt->dw_lst += dw_assi * allocation_factor_stems[_vt->slot];
2004 
2005  _vt->dcBud = allocation_factor_fruit[_vt->slot] * carbonuptake_sum;
2006  _vt->dcFrt = allocation_factor_roots[_vt->slot] * carbonuptake_sum;
2007  _vt->dcFol = allocation_factor_leafs[_vt->slot] * carbonuptake_sum;
2008  _vt->dcSap = allocation_factor_stems[_vt->slot] * carbonuptake_sum;
2009 
2015  }
2016 
2017  return LDNDC_ERR_OK;
2018 }
double PlaMox_get_nitrogen_deficiency(MoBiLE_Plant *)
Definition: plamox.cpp:3600
double PlaMox_get_hypoxia_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3419
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:277
double PlaMox_get_heat_factor(MoBiLE_Plant *)
Calculates a temperature factor.
Definition: plamox.cpp:3577
double PlaMox_get_frost_factor(MoBiLE_Plant *, double)
Calculates a temperature factor.
Definition: plamox.cpp:3397
double PlaMox_get_age_factor(MoBiLE_Plant *)
Calculates an age factor.
Definition: plamox.cpp:3672
double PlaMox_get_biomass_induced_downregulation(MoBiLE_Plant *)
Definition: plamox.cpp:3633
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:283
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3339
BerryBall plamox_berryball
Photosynthesis.
Definition: plamox.h:131
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:289
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:271
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.

3176 {
3177  size_t const fl_cnt( _vt->nb_foliagelayers());
3178 
3179  double sla_cum( 0.0);
3180  for (size_t fl = 0; fl < fl_cnt; ++fl)
3181  {
3182  sla_cum += _vt->sla_fl[fl];
3183  }
3184 
3185  /* Foliage biomass for lai calculation has lower boundary ensuring: lai >= lai_min */
3186  double mFol_lai( cbm::bound_min( lai_min[_vt->slot] / (*_vt)->SLAMAX(),
3187  _vt->mFol));
3188  lai_dynamic[_vt->slot] = cbm::bound_min( lai_min[_vt->slot],
3189  lai_dynamic[_vt->slot] + (_vt->mFol - dw_fol_old[_vt->slot]) * _vt->sla_fl[fl_cnt-1]);
3190  if (cbm::flt_greater_zero( transplanting_shock_vt[_vt->slot]))
3191  {
3192  mFol_lai = mFol_lai * cbm::bound_min( 0.01, 1.0 - transplanting_shock_vt[_vt->slot]);
3193  }
3194 
3195  if ( cbm::flt_greater_zero( sla_cum))
3196  {
3197  DroughtStress droughtstress;
3198  droughtstress.fh2o_ref = (*_vt)->H2OREF_LEAF_GROWTH();
3199 
3200  for (size_t fl = 0; fl < fl_cnt; ++fl)
3201  {
3202  _vt->fFol_fl[fl] = _vt->sla_fl[fl] / sla_cum;
3203  _vt->lai_fl[fl] = mFol_lai * _vt->fFol_fl[fl] * _vt->sla_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3204  //_vt->lai_fl[fl] = lai_dynamic[_vt->slot] * _vt->fFol_fl[fl] * droughtstress.linear_threshold( _vt->f_h2o);
3205  }
3206  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3207  {
3208  _vt->fFol_fl[fl] = 0.0;
3209  _vt->lai_fl[fl] = 0.0;
3210  _vt->sla_fl[fl] = 0.0;
3211  }
3212  }
3213  else
3214  {
3215  for (int fl = 0; fl < m_setup->canopylayers(); ++fl)
3216  {
3217  _vt->fFol_fl[fl] = 0.0;
3218  _vt->lai_fl[fl] = 0.0;
3219  _vt->sla_fl[fl] = 0.0;
3220  }
3221  }
3222 }
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:296

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

3124 {
3125  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3126  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3127  if ( _vt->group() == "crop")
3128  {
3129  //height evegrowth starts with stem elongation
3130  //minimum of 1% development until start of height growth required: dvs_of_start_height !> 0.0
3131  double const dvs_of_start_height( cbm::bound_min( 0.01, (*_vt)->GDD_STEM_ELONGATION() / (*_vt)->GDD_MATURITY()));
3132  //minimum of 2% development until end of height growth required: dvs_of_end_height !> dvs_of_start_height
3133  double const dvs_of_max_height( cbm::bound_min( 0.02, gdd_grain_filling[_vt->slot] / (*_vt)->GDD_MATURITY()));
3134 
3135  //until start of stem elongation, height modeled with plant development
3136  //10% of final height is always reached until start of stem elongation
3137  double const height_fraction_at_stem_elongation( 0.1);
3138  double height_fraction( cbm::bound_max( _vt->dvsFlush / dvs_of_start_height, 1.0) * height_fraction_at_stem_elongation);
3139  if ( cbm::flt_greater( _vt->dvsFlush, dvs_of_start_height))
3140  {
3141  double const biomass_fraction( cbm::bound_max( cbm::sqrt((_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt)), 1.0));
3142  //bound biomass-depending height by plant development
3143  //max should not be reached before start of grain filling (end of phase of stem elongation)
3144  height_fraction = cbm::bound( height_fraction,
3145  biomass_fraction,
3146  height_fraction_at_stem_elongation +
3147  (1.0 - height_fraction_at_stem_elongation) *
3148  (_vt->dvsFlush - dvs_of_start_height)/ (dvs_of_max_height- dvs_of_start_height));
3149  }
3150  _vt->height_max = cbm::bound_min( _vt->height_max, height_fraction * (*_vt)->HEIGHT_MAX());
3151  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3152  }
3153  else
3154  {
3155  _vt->height_max = cbm::bound_max( (_vt->dw_lst + _vt->mFol) / (lst_opt + fol_opt) * (*_vt)->HEIGHT_MAX(), (*_vt)->HEIGHT_MAX());
3156  _vt->height_at_canopy_start = (*_vt)->CB() * _vt->height_max;
3157  }
3158 
3159  // update height of canopy layers (m)
3160  ph_.update_canopy_layers_height( m_veg);
3161 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:302

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

3340 {
3341  double const n_living_plant( cbm::bound_min( 0.0, n_plant[_vt->slot] - _vt->n_dst - _vt->n_dfol));
3342  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);
3343 
3344 // double const n_fol_opt( get_foliage_nitrogen_concentration( _vt) * _vt->mFol);
3345 
3346  double const n_fol_opt( (cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MAX()) &&
3347  cbm::flt_greater_zero( (*_vt)->NC_FOLIAGE_MIN())) ?
3348  _vt->mFol * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FOLIAGE_MIN()
3349  + (nitrogen_satisfaction * PlaMox_get_foliage_nitrogen_concentration( _vt))) :
3350  _vt->mFol * (*_vt)->NC_FOLIAGE_MAX());
3351  double const n_lst_opt( (cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MAX()) &&
3352  cbm::flt_greater_zero( (*_vt)->NC_STRUCTURAL_TISSUE_MIN())) ?
3353  _vt->dw_lst * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_STRUCTURAL_TISSUE_MIN()
3354  + (nitrogen_satisfaction * (*_vt)->NC_STRUCTURAL_TISSUE_MAX())) :
3355  _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX());
3356  double const n_frt_opt( (cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MAX()) &&
3357  cbm::flt_greater_zero( (*_vt)->NC_FINEROOTS_MIN())) ?
3358  _vt->mFrt * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FINEROOTS_MIN()
3359  + (nitrogen_satisfaction * (*_vt)->NC_FINEROOTS_MAX())) :
3360  _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX());
3361  double const n_fru_opt( (cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MAX()) &&
3362  cbm::flt_greater_zero( (*_vt)->NC_FRUIT_MIN())) ?
3363  _vt->mBud * ((1.0 - nitrogen_satisfaction) * (*_vt)->NC_FRUIT_MIN()
3364  + (nitrogen_satisfaction * (*_vt)->NC_FRUIT_MAX())) :
3365  _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3366 
3367  double const n_tot_opt( n_fol_opt + n_lst_opt + n_fru_opt + n_frt_opt);
3368  if ( cbm::flt_greater_zero( n_tot_opt))
3369  {
3370  // CB: fraction of available N to optimum N
3371  double const n_tot_opt_scale( n_living_plant / n_tot_opt);
3372  // CB: N gets distributed evenly over all compartments regarding their optimum N content
3373  _vt->ncFol = cbm::flt_greater_zero( _vt->mFol) ? n_tot_opt_scale * n_fol_opt / _vt->mFol :
3374  (*_vt)->NC_FOLIAGE_MAX();
3375  _vt->n_lst = cbm::flt_greater_zero( _vt->dw_lst) ? n_tot_opt_scale * n_lst_opt :
3376  0.0;
3377  _vt->ncBud = cbm::flt_greater_zero( _vt->mBud) ? n_tot_opt_scale * n_fru_opt / _vt->mBud :
3378  (*_vt)->NC_FRUIT_MAX();
3379  _vt->ncFrt = cbm::flt_greater_zero( _vt->mFrt) ? n_tot_opt_scale * n_frt_opt / _vt->mFrt :
3380  (*_vt)->NC_FINEROOTS_MAX();
3381  }
3382 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3711
double PlaMox_n_opt(MoBiLE_Plant *)
Determines optimum nitrogen concentration.
Definition: plamox.cpp:3323
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

3239 {
3240  size_t const fl_cnt( _vt->nb_foliagelayers());
3241 
3252  if ( IS_SPECIE( _vt->cname(), "mungbean"))
3253  {
3254  double slamax( 26.0);
3255  if ( !cbm::flt_greater( _vt->dvsFlush, 0.5))
3256  {
3257  slamax = 26.0 + _vt->dvsFlush / 0.5 * 7.0;
3258  }
3259  else
3260  {
3261  slamax = 33.0 - (_vt->dvsFlush - 0.5) / 0.5 * 17.0;
3262  }
3263 
3264  for (size_t fl = 0; fl < fl_cnt; ++fl)
3265  {
3266  _vt->sla_fl[fl] = slamax;
3267  }
3268  }
3269  else if ( m_veg->is_family( _vt, ":rice:"))
3270  {
3271  double const dvs( (*_vt)->GDD_FLOWERING() > 0.0 ?
3272  cbm::bound_max( _vt->growing_degree_days / (*_vt)->GDD_FLOWERING(), 1.0) :
3273  _vt->dvsMort);
3274 
3275  double const delta_sla( dvs * (*_vt)->SLADECLINE() * (*_vt)->SLAMAX());
3276  for (size_t fl = 0; fl < fl_cnt; ++fl)
3277  {
3278  _vt->sla_fl[fl] = cbm::bound_min( 0.0, (*_vt)->SLAMAX() - delta_sla);
3279  }
3280  }
3281  else
3282  {
3283  // reduction of specific leaf area with crop age
3284  double sla_red( 1.0);
3285  if (_vt->groupId() == SPECIES_GROUP_GRASS)
3286  {
3287  if ( cbm::flt_greater( _vt->dvsMort, 0.5))
3288  {
3289  sla_red = 1.0 - ((*_vt)->SLADECLINE() * (_vt->dvsMort - 0.5) / 0.5);
3290  }
3291  }
3292  else
3293  {
3294  sla_red = 1.0 - ((*_vt)->SLADECLINE() * _vt->dvsMort);
3295  }
3296 
3297  for (size_t fl = 0; fl < fl_cnt; ++fl)
3298  {
3299  _vt->sla_fl[fl] = (*_vt)->SLAMAX() * sla_red;
3300  }
3301  }
3302 
3303  for (int fl = fl_cnt; fl < m_setup->canopylayers(); ++fl)
3304  {
3305  _vt->sla_fl[fl] = 0.0;
3306  }
3307 }

Member Data Documentation

◆ plamox_root_system

ldndc::growable_array< BaseRootSystemDNDC*, 1000, 1 > ldndc::PhysiologyPlaMox::plamox_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().