LandscapeDNDC  1.37.0
ldndc::PhysiologyPlaMox Class Reference

Vegetation model 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 *)
 
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

Vegetation model 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
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:3338
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().

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

3633 {
3634  if ( m_veg->is_family( _vt, ":wheat:"))
3635  {
3636  double const fol_opt( (*_vt)->MFOLOPT() * fractional_cover[_vt->slot]);
3637  double const lst_opt( (1.0 - (*_vt)->FALEAF()) / (*_vt)->FALEAF() * fol_opt);
3638 
3639  if ( cbm::flt_greater_zero( _vt->dw_lst) &&
3640  cbm::flt_greater( _vt->dw_lst, lst_opt))
3641  {
3642  return lst_opt / _vt->dw_lst;
3643  }
3644  }
3645 
3646  return 1.0;
3647 }
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().

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

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

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

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

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

Referenced by PlaMox_transpiration().

Here is the caller graph for this function:

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

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

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

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