LandscapeDNDC  1.36.0
ldndc::PhysiologyPlaMox Class Reference

Plamox. More...

Inherits ldndc::MBE_LegacyModel.

Public Member Functions

 ~PhysiologyPlaMox ()
 Delete allocated classes. More...
 

Private Member Functions

lerr_t PlaMox_step_init ()
 pre-run initialization each time step
 
lerr_t PlaMox_step_resize ()
 resize plant species vector
 
lerr_t PlaMox_management ()
 Applies grazing and cutting.
 
lerr_t PlaMox_event_plant (MoBiLE_Plant *, EventAttributes const &)
 handle plant event More...
 
lerr_t PlaMox_event_harvest (MoBiLE_Plant *, EventAttributes const &)
 handle harvest event More...
 
lerr_t PlaMox_photosynthesis (MoBiLE_Plant *)
 Update of information needed by photofarquhar. More...
 
void PlaMox_vernalization (MoBiLE_Plant *)
 Determines the growing degree days and the plant development stage based on if vernalization requirements are fullfilled or not.
 
void PlaMox_growing_degree_days (MoBiLE_Plant *)
 Calculates growing degree days depending on daily average temperature.
 
void PlaMox_heat_stress_limitation (MoBiLE_Plant *_vt)
 Limits pod filling due to heat stress around anthesis.
 
lerr_t PlaMox_allocation_grass (MoBiLE_Plant *)
 Allocation metrics for grass species.
 
lerr_t PlaMox_bud_burst (MoBiLE_Plant *)
 Burst of buds.
 
lerr_t PlaMox_redistribution (MoBiLE_Plant *)
 Redistribution of reserves.
 
void PlaMox_respiration (MoBiLE_Plant *)
 Calculates maintenance/residual and growth respiration.
 
void PlaMox_exsudation (MoBiLE_Plant *)
 Determines root exsudation as fraction of root growth respiration.
 
void PlaMox_nitrogen_uptake (MoBiLE_Plant *)
 Calculates plant nitrogen uptake based on daily demand.
 
lerr_t PlaMox_nitrogen_fixation (MoBiLE_Plant *)
 Calculates plant nitrogen fixation.
 
lerr_t PlaMox_senescence (MoBiLE_Plant *)
 Calculates aboveground and belowground plant senecsence.
 
void PlaMox_drought (MoBiLE_Plant *)
 Calculates drought stress.
 
void PlaMox_transpiration (MoBiLE_Plant *)
 Calculates potential transpiration.
 
void PlaMox_update_root_structure (MoBiLE_Plant *, double)
 Updates all relevant root structural matters. More...
 
void PlaMox_update_height (MoBiLE_Plant *)
 calculates new height of plant depending on the ratio of current to optimum aboveground biomass More...
 
void PlaMox_update_ground_cover (MoBiLE_Plant *)
 
void PlaMox_update_foliage_structure (MoBiLE_Plant *)
 Calculation of canopy layer properties: More...
 
void PlaMox_update_specific_leaf_area (MoBiLE_Plant *)
 Calculates specific leaf area (sla) in each canopy layer. More...
 
void PlaMox_update_nitrogen_concentrations (MoBiLE_Plant *)
 
double PlaMox_get_nitrogen_deficiency (MoBiLE_Plant *)
 
double PlaMox_get_biomass_induced_downregulation (MoBiLE_Plant *)
 
double PlaMox_get_age_factor (MoBiLE_Plant *)
 Calculates an age factor. More...
 
double PlaMox_get_frost_factor (MoBiLE_Plant *, double)
 Calculates a temperature factor. More...
 
double PlaMox_get_hypoxia_factor (MoBiLE_Plant *)
 Calculates a temperature factor.
 
double PlaMox_get_heat_factor (MoBiLE_Plant *)
 Calculates a temperature factor.
 
double PlaMox_get_foliage_nitrogen_concentration (MoBiLE_Plant *)
 Calculates optimum foliage nitrogen concentration.
 
double PlaMox_n_opt (MoBiLE_Plant *)
 Determines optimum nitrogen concentration. More...
 

Private Attributes

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.
 
cbm::string_t droughtstress_method
 Transpiration method used by PlaMox.
 
cbm::string_t::cbmstring_array_t plantfamilies
 Plant families that are considered by PlaMox.
 
double const FTS_TOT_
 
Time resolution factor:

\( \text{FTS_TOT_} = \frac{1.0}{\text{time resolution}} \)

 
lvector_t< double > allocation_factor_leafs
 Allocation factor of daily assimilated carbon to leaf growth [-].
 
lvector_t< double > allocation_factor_stems
 Allocation factor of daily assimilated carbon to stem growth [-].
 
lvector_t< double > allocation_factor_fruit
 Allocation factor of daily assimilated carbon to fruit growth [-].
 
lvector_t< double > allocation_factor_roots
 Allocation factor of daily assimilated carbon to root growth [-].
 
lvector_t< double > lai_min
 Minimum value of üplamt leaf area index (m^2:m^-2). For crops, this value is fixed until between sowing and emergence.
 
lvector_t< double > fractional_cover
 Density of seeded plants with regard to optimum (full area) seeding (-).
 
lvector_t< double > chill_factor
 Factor that retards plant development if vernalization requirement is not fullfilled.
 
lvector_t< double > chill_units
 Accumulated chilling units for vernalization;.
 
lvector_t< unsigned int > root_q_vt_
 Largest soil layer index where roots exist [-].
 
lvector_t< double > daytime_temperatures
 store daytime temperature for heat stress analysis
 
lvector_t< double > influence_heat_daily
 store daily impact factor of heat stress on grain yield;
 
double influence_heat_reduction_grainfilling
 Resulting impact factor of the heat stress influence on grain yield.
 
double day_of_flowering
 day after emergence where flowering is onset
 
double Tcrit
 the timing of the episode of high temperatures relative to flowering More...
 
double Tzero
 The temperature at which there is zero pod-set (°C)
 

Detailed Description

Plamox.

Author
David Kraus

Constructor & Destructor Documentation

◆ ~PhysiologyPlaMox()

ldndc::PhysiologyPlaMox::~PhysiologyPlaMox ( )

Delete allocated classes.

Delete:

  • roots system
  • nitrogen fixation

References droughtstress_method, have_drought_stress, m_pf, plamox_berryball, plamox_nitrogen_fixation, plamox_root_system, plantfamilies, and transpiration_method.

202 {
203  for ( size_t r = 0; r < plamox_root_system.size(); ++r)
204  {
205  if ( plamox_root_system[r])
206  {
207  LD_Allocator->destroy( plamox_root_system[r]);
208  }
209  }
210 
212 }
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:334
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:273
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:279
lvector_t< double > chill_factor
Factor that retards plant development if vernalization requirement is not fullfilled.
Definition: plamox.h:304
lvector_t< double > allocation_factor_roots
Allocation factor of daily assimilated carbon to root growth [-].
Definition: plamox.h:285
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:310
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:267
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:334
lvector_t< double > allocation_factor_stems
Allocation factor of daily assimilated carbon to stem growth [-].
Definition: plamox.h:273
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:340
lvector_t< double > allocation_factor_fruit
Allocation factor of daily assimilated carbon to fruit growth [-].
Definition: plamox.h:279
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:304
void PlaMox_update_nitrogen_concentrations(MoBiLE_Plant *)
Definition: plamox.cpp:3336
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:285
lvector_t< double > chill_units
Accumulated chilling units for vernalization;.
Definition: plamox.h:310
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:298
lvector_t< double > allocation_factor_leafs
Allocation factor of daily assimilated carbon to leaf growth [-].
Definition: plamox.h:267
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:292
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().

3664 {
3665  if ( PlaMox_get_life_cycle( _p) > PhysiologyPlaMox::ANNUAL)
3666  {
3667  if ( (*_p)->GDD_EMERGENCE() > _p->growing_degree_days)
3668  {
3669  return ( 1.0 - ((*_p)->GDD_EMERGENCE() - _p->growing_degree_days) / (*_p)->GDD_EMERGENCE());
3670  }
3671  return ( 1.0);
3672  }
3673  else
3674  {
3675  if ( days_after_emergence[_p->slot] < 0)
3676  {
3677  return 0.0;
3678  }
3679  else
3680  {
3681  if ( cbm::flt_less_equal( _p->growing_degree_days, (*_p)->GDD_MATURITY()))
3682  {
3683  return ( 1.0);
3684  }
3685  else
3686  {
3687  return 1.0 / std::exp( 0.01 * (_p->growing_degree_days - (*_p)->GDD_MATURITY()));
3688  }
3689  }
3690  }
3691 }
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().

3625 {
3626  if ( m_veg->is_family( _vt, ":wheat:"))
3627  {
3628  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3629  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3630 
3631  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3632  cbm::flt_greater( _vt->dw_lst, lst_opt))
3633  {
3634  return lst_opt / _vt->dw_lst;
3635  }
3636  }
3637 
3638  return 1.0;
3639 }
lvector_t< double > fractional_cover
Density of seeded plants with regard to optimum (full area) seeding (-).
Definition: plamox.h:298
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().

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

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

3321 {
3322  return ( _vt->mFol * PlaMox_get_foliage_nitrogen_concentration( _vt)
3323  + _vt->dw_lst * (*_vt)->NC_STRUCTURAL_TISSUE_MAX()
3324  + _vt->mFrt * (*_vt)->NC_FINEROOTS_MAX()
3325  + _vt->mBud * (*_vt)->NC_FRUIT_MAX());
3326 }
double PlaMox_get_foliage_nitrogen_concentration(MoBiLE_Plant *)
Calculates optimum foliage nitrogen concentration.
Definition: plamox.cpp:3702
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_.

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

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

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

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

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

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

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

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