LandscapeDNDC 1.37.0
Loading...
Searching...
No Matches
ldndc::PhysiologyGrowthPSIM Class Reference

Vegetation model GrowthPSIM. More...

#include <models/physiology/psim/psim.h>

Public Attributes

cbm::string_t branchfraction_opt
 ...
 
cbm::string_t crownlength_opt
 ...
 
bool competition_opt
 ...
 
cbm::string_t timemode_opt
 ...
 
int stand_structure_opt
 ...
 

Static Public Attributes

static const unsigned int IMAX_W = 24
 
static const double C1 = 0.0367
 
static const double CCOMNOX = 1.0
 
static const double CSATNH3 = 50.0
 
static const double CSATNOX = 5.0
 
static const double EPOTNOX = 1.0
 
static const double FRFRT = 0.5
 
static const double FMIN = 0.05
 
static const double KMMM = 0.0
 
static const double PAMM = 0.17
 
static const double PGDD = 0.0075
 
static const double PMIN = 0.06
 
static const double PNIT = 0.34
 
static const double PPHLOE = 0.06
 
static const double PREDFRT = 1.72
 
static const double PREDSAP = 0.855
 
static const double PTW = 0.29
 
static const double TAU = 330.0
 
static const double TGLIM = 6.0
 
static const double TRMAX = 45.0
 
static const double TRMIN = -7.0
 
static const double TROPT = 20.0
 
static const double UPOTNH3 = 10000.0
 

Protected Member Functions

lerr_t PSIM_ResizeVegetationVectors ()
 
lerr_t PSIM_StepInit ()
 
lerr_t PSIM_PlantingEvent ()
 
lerr_t PSIM_HydraulicConductance ()
 
lerr_t PSIM_Photosynthesis ()
 
lerr_t PSIM_Potentialtranspiration ()
 
lerr_t PSIM_AgriculturalManagement ()
 
lerr_t PSIM_NitrogenFixation ()
 Nitrogen fixation described similar to agricultural routines. Noted under PSIM_NitrogenUptake.
 
lerr_t PSIM_BiomassUpdate ()
 Biomass growth according to allocation gains and respiration losses in different plant compartments.
 
lerr_t PSIM_PhotosynthesisRates ()
 

Private Attributes

std::map< int, RootSystemDNDC > root_system
 Root system.
 

Detailed Description

Vegetation model GrowthPSIM.

Author
Ruediger Grote

Member Function Documentation

◆ PSIM_AgriculturalManagement()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_AgriculturalManagement ( )
protected

PSIM considers:

  • grazing (for grasses)
  • cutting (for grasses) (for other management options on trees, see ref@ ld_treeDyn:treedyn_events)
1457{
1458 m_eventgraze.update_available_freshfood_c( m_veg, species_groups_select_t< species::grass >());
1459
1460 for ( PlantIterator vt = m_veg->begin(); vt != m_veg->end(); ++vt)
1461 {
1462 MoBiLE_Plant *p = (*vt);
1463 if ( p->group() == "grass")
1464 {
1465 lerr_t rc_graze = m_eventgraze.event_graze_physiology( *vt);
1466 if ( (rc_graze != LDNDC_ERR_EVENT_MATCH) &&
1467 (rc_graze != LDNDC_ERR_EVENT_EMPTY_QUEUE))
1468 {
1469 LOGERROR("Grazing not successful");
1470 return rc_graze;
1471 }
1472 }
1473 }
1474
1475 // cutting event by external module
1476 lerr_t rc_cut = m_eventcut.event_cut_physiology( m_veg, species_groups_select_t< species::grass >());
1477 if ( (rc_cut != LDNDC_ERR_EVENT_MATCH) &&
1478 (rc_cut != LDNDC_ERR_EVENT_EMPTY_QUEUE))
1479 {
1480 LOGERROR("Cutting not successful");
1481 return rc_cut;
1482 }
1483 else if (rc_cut == LDNDC_ERR_EVENT_MATCH)
1484 {
1485 for (PlantIterator vt = m_veg->begin(); vt != m_veg->end(); ++vt)
1486 {
1487 MoBiLE_Plant* p = (*vt);
1488 m_treedyn.OnStructureChange(p);
1489 }
1490 }
1491
1492 return LDNDC_ERR_OK;
1493}

References PSIM_AgriculturalManagement().

Referenced by PSIM_AgriculturalManagement().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_BiomassUpdate()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_BiomassUpdate ( )
protected

Biomass growth according to allocation gains and respiration losses in different plant compartments.

3177{
3178 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
3179 {
3180 MoBiLE_Plant *p = (*vt);
3181
3182 // remembering starting values
3183 double const fFacOld = p->f_fac;
3184
3185 double const mFolOld = p->mFol;
3186 double const mBudOld = p->mBud;
3187 double const mFrtOld = p->mFrt;
3188 double const mSapOld = p->mSap;
3189 double const mLivOld = mFolOld + mBudOld + mFrtOld + mSapOld;
3190
3191 // increase of dry matter
3192 double const groFol = p->dcFol / cbm::CCDM;
3193 double const groBud = p->dcBud / cbm::CCDM;
3194 double const groFrt = p->dcFrt / cbm::CCDM;
3195 double const groSap = p->dcSap / cbm::CCDM;
3196 double const groSum = groBud + groFrt + groSap;
3197
3198 /* biomass adjustment according to the shift in free available carbon
3199 * following the basic assumption that free available carbon is proportionally
3200 * distributed between or taken from the compartments but leaving reserves unchanged.*/
3201 if ( cbm::flt_greater_zero( mLivOld))
3202 {
3203 double const redistribC( p->dcFac / cbm::CCDM);
3204 p->mFol += (redistribC * mFolOld / mLivOld);
3205 p->mBud += (redistribC * mBudOld / mLivOld);
3206 p->mFrt += (redistribC * mFrtOld / mLivOld);
3207 p->mSap += (redistribC * mSapOld / mLivOld);
3208 }
3209
3210 // considering growth and loss effects on compartment biomasses
3211 p->mFol += (groFol - p->sFol + mBudLoss_vt[p->slot]);
3212 p->mBud += (groBud - p->sBud - mBudLoss_vt[p->slot]);
3213 p->mFrt += (groFrt - cbm::sum( p->sFrt_sl, sl_.soil_layer_cnt()));
3214 p->mSap += (groSap - mSapLoss_vt[p->slot]);
3215 p->mCor += (mSapLoss_vt[p->slot] * (1.0 - p->f_branch));
3216
3217 if ( !cbm::flt_greater_zero( p->mFol)) p->mFol = 0.0;
3218 if ( !cbm::flt_greater_zero( p->mBud)) p->mBud = 0.0;
3219 if ( !cbm::flt_greater_zero( p->mFrt)) p->mFrt = 0.0;
3220 if ( !cbm::flt_greater_zero( p->mSap)) p->mSap = 0.0;
3221
3222 // biomass and foliage area in layers
3223 m_pf.update_foliage_layer_biomass_and_lai((*vt), fl_cnt_, 0.0);
3224
3225 // change foliage biomass in age classes due to growth and senescence
3226 if ( p->nb_ageclasses() == 1)
3227 {
3228 p->mFol_na[0] = p->mFol;
3229 }
3230 else
3231 {
3232 // allowing foliage mass increase in plants with non-annual growth behaviour
3233 p->mFol_na[0] += cbm::bound_min( 0.0, groFol + mBudLoss_vt[p->slot] - p->sFol_na[0]);
3234 for ( size_t na = 1; na < p->nb_ageclasses(); ++na)
3235 {
3236 p->mFol_na[na] = cbm::bound_min( 0.0, p->mFol_na[na] - p->sFol_na[na]);
3237 }
3238 }
3239
3240 // total living biomass after growth (kgDM)
3241 double const mLivNew( p->mFol + p->mBud + p->mFrt + p->mSap);
3242
3246 if ( cbm::flt_greater( mLivNew, 0.001))
3247 {
3248 // ratio of free available carbohydrates
3249 double const senSum = cbm::sum( p->sFrt_sl, sl_.soil_layer_cnt()) + mSapLoss_vt[p->slot] + p->sFol;
3250 p->f_fac = (fFacOld * (mLivOld - senSum) * cbm::CCDM + vt->FFACMAX() * groSum * cbm::CCDM + p->dcFac ) / (mLivNew * cbm::CCDM);
3251
3252 if ( !cbm::flt_greater_zero( p->f_fac)) p->f_fac = 0.0;
3253 }
3254 else
3255 {
3256 p->f_fac = 0.0;
3257 }
3258
3259 // peak foliage amount
3260 if ( cbm::flt_greater( p->mFol, p->mFolMax))
3261 {
3262 p->mFolMax = p->mFol;
3263 }
3264 }
3265
3266 return LDNDC_ERR_OK;
3267}

References PSIM_BiomassUpdate().

Referenced by PSIM_BiomassUpdate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_HydraulicConductance()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_HydraulicConductance ( )
protected
Returns
error code
1539{
1540 // realized (soil water limited) transpiration (per ground area) in m per time step (should vary per hour) and vegetation type
1541 accumulated_wateruptake_old = wc_.accumulated_wateruptake_sl.sum();
1542
1543 // transpiration demand given from potential demand derived from different stomata methods
1544 double transpiration_demand(wc_.accumulated_potentialtranspiration - accumulated_potentialtranspiration_old);
1545 accumulated_potentialtranspiration_old = wc_.accumulated_potentialtranspiration;
1546
1547 // relative recovery of plant water deficit from the last time step
1548 double rehydrationindex(0.0);
1549 if (cbm::flt_greater_zero(plant_waterdeficit_old))
1550 {
1551 rehydrationindex = cbm::bound(0.0,
1552 (plant_waterdeficit_old - wc_.plant_waterdeficit) / plant_waterdeficit_old,
1553 1.0);
1554 }
1555 plant_waterdeficit_old = wc_.plant_waterdeficit;
1556
1557 // number of hours per day
1558 double const daylength_hours(meteo::daylength(m_setup->latitude(), this->lclock()->yearday()));
1559
1560 // setting soil to root hydraulic conductance equal to soil conductance
1561 double const lai_sum(m_veg->lai());
1562 for (PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
1563 {
1564 MoBiLE_Plant* p = *vt;
1565
1566 // length of timestep [s]
1567 double const tslength = double(cbm::SEC_IN_HR) * double(cbm::HR_IN_DAY) / double(this->lclock_ref().time_resolution());
1568
1569 // transform transpiration units from m timestep-1 to mol m-2leaf s-1 and relate it to daylength
1570 // TODO: find a better way to differentiate transpiration into vegetation classes
1571 double transp_mol(0.0);
1572 double const dayl(meteo::daylength(m_setup->latitude(), this->lclock()->yearday()));
1573 if ( cbm::flt_greater_zero( lai_sum))
1574 {
1575 double transp_vt = transpiration_demand * p->lai() / lai_sum;
1576 if (cbm::flt_greater_zero( dayl))
1577 {
1578 transp_mol = transp_vt * cbm::MM_IN_M * cbm::G_IN_KG / (tslength * cbm::MH2O * p->lai())
1579 / (dayl / cbm::HR_IN_DAY);
1580 }
1581 }
1582
1583 // soil layer water potential at which roots get detached (in MPa, positive units)
1584 double psi_detach(m_sipar->CP_WP() * cbm::MPA_IN_MH2O); // 150 mWS (1.5 MPa) is the predefined value for the water content at wilting point
1585
1586 // plant (root) hydraulic conductance calculated from soil water potential, weighted by fine root abundance
1587 double const SCALE_WP(1.2);
1588 p->psi_sr = 0.0;
1589 for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1590 {
1591 double const wc( cbm::bound( 1.001 * wc_.wc_res_sl[sl],
1592 wc_.wc_sl[sl],
1593 0.999 * wc_.wc_sat_sl[sl]));
1594
1595 // soil layer water potential (in MPa, positive units)
1596 double const psi_sl( ldndc::capillary_pressure( wc, wc_.vga_sl[sl], wc_.vgn_sl[sl], wc_.vgm_sl[sl],
1597 wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl] ) * cbm::MPA_IN_MH2O );
1598
1599 // soil to root water potential (MPa) weighted by fine root abundance
1600 p->psi_sr += ( std::min(SCALE_WP * m_sipar->CP_WP() * cbm::MPA_IN_MH2O, psi_sl) * p->fFrt_sl[sl] );
1601 }
1602
1603 p->psi_sr *= -1.0;
1604 psi_detach *= -1.0;
1605
1606 // plant water potential calculated considering previous declines (without gravitational impact)
1607 double psi_vt(std::max(p->psi_sr, psi_detach) + psidecline_cum_vt[p->slot]);
1608
1609 // canopy water potential
1610 // (calculated in a lumped fashion, alternatively define psi for each canopy layer separately)
1611 // - average canopy height
1612 double h_weighted(0.0); // [m]
1613 double height_cum(0.0); // [m]
1614 for (size_t fl = 0; fl < p->nb_foliagelayers(); ++fl)
1615 {
1616 height_cum += 0.5 * ph_.h_fl[fl];
1617 h_weighted += height_cum * p->fFol_fl[fl];
1618 height_cum += 0.5 * ph_.h_fl[fl];
1619 }
1620
1621 // - increase of water potential due to vertical transport (gravitational impact)
1622 double const dpsi = h_weighted * cbm::MPA_IN_KPA * cbm::KPA_IN_PA * cbm::DWAT * cbm::DM3_IN_M3 * cbm::G;
1623
1624 // decrease and recovery of plant water potential
1625 int night(1); // 1=false, 0=true
1626 // - state determination after daytime
1627 if (cbm::flt_equal_zero(mc_.shortwaveradiation_in)) // nighttime without radiation (NOTE: problems occur if there is radiation input during night)
1628 {
1629 // in the night, the multiplier for psi that accounts for increasing tension is set to zero
1630 night = 0;
1631
1632 if (daytime == true)
1633 {
1634 // weighting by leaf/wood ratio as proxy for capacitance change
1635 // NOTE1: assuming that the degree of capacitance deficit (if it occurs) is the same in all compartments
1636 // NOTE2: doesn't consider a possible capacitance change with relative water content
1637 double const qcapacitance = (p->mFol + p->f_branch * p->mSap) / (p->mFol + p->mSap + p->mFrt); // assuming that transpiration affects primarily the crown tissue relation to all living tissue
1638// double const qcapacitance = p->mFol / (p->mFol + p->mSap + p->mFrt); // assuming that transpiration only affects foliage tissue in relation to all living tissue
1639// double const qcapacitance = p->mFol / (p->mFol + p->mSap + p->mCor + p->mFrt); // assuming that transpiration only affects foliage tissue in relation to all tissues including core wood
1640// double const qcapacitance = 1.0; // assuming that only transpiration affects tree water potential
1641// double const qcapacitanc = p->mFol / (p->mFol + p->mSap * (*vt)->wc_rel + p->mFrt); // assuming that transpiration only affects foliage tissue in relation to all living tissues reduced by water content
1642
1643 // recovery of cumulative plant water potential due to rehydration during the previous day
1644 psidecline_cum_vt[p->slot] *= std::min(1.0, (1.0 - rehydrationindex_cum_vt[p->slot])); // assumes that relative rehydration and plant water potential recovers in parallel
1645// psidecline_cum_vt[p->slot] *= std::min(1.0, (1.0 - qcapacitance)); // assumes that the recovery is slowed down according to the relation between affected and total tissue
1646
1647 // in case of root detachment (soil water potential below wilting point) plant water potential decline is accumulated
1648 if (cbm::flt_greater_equal(psi_detach, p->psi_sr))
1649 {
1650 psidecline_cum_vt[p->slot] += std::min(0.0, (psidecline_daycum_vt[p->slot] / daylength_hours) * qcapacitance);
1651 }
1652
1653 // reset of the cumulative rehydration index
1654 rehydrationindex_cum_vt[p->slot] = 0.0;
1655
1656 // reset the cumulative water potential deficit
1657 psidecline_daycum_vt[p->slot] = 0.0;
1658 }
1659
1660 daytime = false;
1661 }
1662 // - state determination during daytime
1663 else
1664 {
1665 // calculations directly after nighttime
1666 if (daytime == false)
1667 {
1668 // predawn canopy water potential
1669 p->psi_pd = psi_vt - dpsi;
1670
1671 // predawn (minimum) tree water deficit = maximum diurnal radius
1672 (*vt)->twd_pd_vt = (*vt)->stem_shrinkage;
1673 (*vt)->twd_max_vt = 0.0;
1674 }
1675
1676 daytime = true;
1677
1678 // minimum shrinkage (maximum tree water deficit) during the day
1679 if ((*vt)->stem_shrinkage > (*vt)->twd_max_vt)
1680 {
1681 (*vt)->twd_max_vt = (*vt)->stem_shrinkage;
1682 }
1683
1684 }
1685
1686 // relative xylem conductivity based on current plant water potential
1687 double krc_rel_vt = 1.0 - (1.0 - std::exp(-std::pow(psi_vt / vt->PSI_REF(), vt->PSI_EXP())));
1688 krc_rel_vt = std::max(0.001, krc_rel_vt);
1689
1690 // canopy hydraulic potential in MPa (negative) due to water loss (only at daytime) considering height induced gradient
1691 p->psi_cr = psi_vt;
1692 if (cbm::flt_greater_zero(krc_rel_vt))
1693 {
1694 p->psi_cr = psi_vt - (transp_mol * double(night) / (vt->CWP_REF() * krc_rel_vt)) - dpsi; // CWP_REF is the conductance of the whole pathlength
1695 }
1696
1697 // mean canopy water potential (not important, but smoothing between timesteps)
1698 p->psi_mean = (p->psi_pd + p->psi_cr) * 0.5;
1699
1700 // drop in plant water potential (!) due to evaporative demand cumulated over the day
1701 psidecline_daycum_vt[p->slot] += std::min(0.0, (p->psi_cr + dpsi - psi_vt));
1702
1703 // daily cumulative reduction of drop in water potential after refilling (rehydration_index is in fraction per hour, needed in fraction per day)
1704 rehydrationindex_cum_vt[p->slot] += rehydrationindex;
1705 rehydrationindex_cum_vt[p->slot] = cbm::bound(0.0, rehydrationindex_cum_vt[p->slot], 1.0);
1706
1707 // overall root-to-canopy (plant hydraulic) conductance considering current day demands (in mol MPa-1 s-1 m-2)
1708 double k_rc_rel_mean = 1.0 - (1.0 - std::exp(-std::pow(p->psi_mean / vt->PSI_REF(), vt->PSI_EXP())));
1709 k_rc_rel_mean = std::max(0.001, k_rc_rel_mean);
1710
1711 // whole plant resistances (in MPa s m2 mol-1)
1712 // NOTE: resistance is reversible and is not affected by xylem senescence (e.g. embolism). Possible solutions would be to increase
1713 // a) proportionally to the difference between qsaparea_vt[p->slot] and p->qsfa, or b) to the deficit of sapwood demand (RPMIN / (k_rc_rel * qsaparea_vt[p->slot]) )
1714 p->xylem_resistance = vt->RPMIN(); // 1/RPMIN is the conductance in the crown area
1715 if (cbm::flt_greater_zero(k_rc_rel_mean))
1716 {
1717 p->xylem_resistance /= k_rc_rel_mean;
1718 }
1719
1720 } // vegetation type loop end
1721
1722 return LDNDC_ERR_OK;
1723}

References PSIM_HydraulicConductance().

Referenced by PSIM_HydraulicConductance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_Photosynthesis()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_Photosynthesis ( )
protected
Returns
error code
833{
834 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
835 {
836 MoBiLE_Plant *p = *vt;
837
838 for (size_t fl = 0; fl < p->nb_foliagelayers(); ++fl)
839 {
840 m_photo.vpd_fl[fl] = mc_.vpd_fl[fl];
841 m_photo.rh_fl[fl] = cl_.rel_humidity_subday( lclock_ref());
842 m_photo.temp_fl[fl] = mc_.temp_fl[fl];
843 m_photo.parsun_fl[fl] = mc_.parsun_fl[fl];
844 m_photo.parshd_fl[fl] = mc_.parshd_fl[fl];
845 m_photo.tFol_fl[fl] = mc_.tFol_fl[fl];
846 m_photo.co2_concentration_fl[fl] = ac_.ts_co2_concentration_fl[fl];
847 m_photo.sunlitfoliagefraction_fl[fl] = mc_.ts_sunlitfoliagefraction_fl[fl];
848 }
849 m_photo.nd_airpressure = mc_.nd_airpressure;
850
851 m_photo.set_vegetation_base_state( p);
852
853 m_photo.set_vegetation_non_stomatal_water_limitation_state( p->xylem_resistance, p->psi_mean, p->psi_sr, p->psi_pd);
854
855 m_photo.solve();
856
857 m_photo.get_vegetation_state( p);
858 }
859
860 return LDNDC_ERR_OK;
861}

References PSIM_Photosynthesis().

Referenced by PSIM_Photosynthesis().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_PhotosynthesisRates()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_PhotosynthesisRates ( )
protected

Nitrogen concentration is related to specific leaf area but declines generally not linear. Therefore, an exponential relationship with a parameter of 0.3 is used, fitted to various canopy gradient studies (e.g. Meir et al. 2002, Al Afas et al. 2007, Ellsworth and Reich 1993) (parameter should be consistent with the one used in m_pf.optimum_nitrogen_content_foliage())

3326{
3327 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
3328 {
3329 MoBiLE_Plant *p = (*vt);
3330
3331 // phenological state
3332 bool const evergreen( (p->nb_ageclasses() > 1) && cbm::flt_greater_zero( p->mFol));
3333 double const pstatus( evergreen ?
3334 (p->dvsFlush * p->mFol_na[0] + (1.0 - p->dvsMort) * (cbm::sum( p->mFol_na, p->nb_ageclasses()) - p->mFol_na[0])) / p->mFol :
3335 std::min( p->dvsFlush, 1.0 - p->dvsMort));
3336
3337 // drought stress impact
3338 // NOTE: consideration of water potential effects is only warranted if the whole hydraulic model is used
3339 double fwat(1.0);
3340 if (m_photo.stomatalconductance_method == eller_2020 && p->dvsFlush > 0.99)
3341 {
3342 fwat = ldndc::non_stomatal_water_limitation( p->psi_pd, (*p)->A_REF(), (*p)->A_EXP() );
3343 }
3344
3345 // - in case drought stress decreases, its decrease is limited by recovery rate (legacy effect)
3346 const double RECOVER(0.01); // fraction recovery per hour
3347 if (fwat > p->fwatOld)
3348 {
3349 double const tslength = double(cbm::HR_IN_DAY) / double(this->lclock_ref().time_resolution());
3350 fwat = std::min(fwat, p->fwatOld + RECOVER * tslength);
3351 }
3352 p->fwatOld = fwat;
3353
3354 // enzyme activity
3355 // (activity of isoprene and monoterpene enzymes are unchanged during the dormant season)
3356 double nFolOpt(m_pf.optimum_nitrogen_content_foliage(p));
3357 double const ncFol_top = (p->mFol * p->ncFol / nFolOpt) * vt->NCFOLOPT();
3358
3359 if ( cbm::flt_greater_zero( pstatus))
3360 {
3361 for ( size_t fl = 0; fl < fl_cnt_; ++fl)
3362 {
3363 if ( cbm::flt_greater_zero( p->m_fol_fl(fl)) &&
3364 cbm::flt_greater_zero( p->sla_fl[fl]))
3365 {
3366 // nitrogen supply in dependence on specific leaf area
3373 double const ncFol_fl( ncFol_top * pow( vt->SLAMIN() / p->sla_fl[fl], 0.3));
3374
3375 // dependency of photosynthesis linearly related to nitrogen (Reynolds et al. 1992)
3376 double const fnit( cbm::bound( 0.0, (ncFol_fl - vt->NC_FOLIAGE_MIN()) / (vt->NCFOLOPT() - vt->NC_FOLIAGE_MIN()), 1.0));
3377
3378 // seasonality factor
3379 double fdorm(0.0);
3380 // - deciduous
3381 if (p->nb_ageclasses() == 1)
3382 {
3383 if ( p->dvsFlush < 1.0)
3384 {
3385 fdorm = cbm::sqr( p->dvsFlush);
3386 }
3387 else
3388 {
3389 fdorm = 1.0 - cbm::sqr( p->dvsMort);
3390 }
3391 }
3392 // - evergreen
3393 else
3394 {
3395 // - equal to the relative pool size of free available carbon reserves (fsub_vt)*/
3396 fdorm = fsub_vt[p->slot];
3397
3398 // - temperature dependent according to Maekelae et al. 2004 (S model)
3399/* if ((mc_.tFol24_fl[fl] + cbm::HR_IN_DAY / TAU * (mc_.nd_temp_fl[fl] - mc_.tFol24_fl[fl])) >= vt->PSNTFROST())
3400 {
3401// fdorm = C1 * (mc_.tFol24_fl[fl] + cbm::HR_IN_DAY / TAU * ( mc_.nd_temp_fl[fl] - mc_.tFol24_fl[fl]) - vt->PSNTFROST());
3402// fdorm = 1.0;
3403 }
3404 else
3405 {
3406 fdorm = 0.0;
3407 }
3408*/
3409 }
3410
3411 fdorm = cbm::bound( 0.0, fdorm, 1.0);
3412
3413 // activity of rubisco under standard conditions
3414 p->vcAct25_fl[fl] = vt->VCMAX25() * fnit * fdorm * fwat;
3415 // activity of maximum electron transport rate under standard conditions
3416 p->jAct25_fl[fl] = p->vcAct25_fl[fl] * vt->QJVC();
3417 // activity of dark respiration under standard conditions
3418 p->rdAct25_fl[fl] = p->vcAct25_fl[fl] * vt->QRD25();
3419 }
3420 else
3421 {
3422 p->vcAct25_fl[fl] = 0.0;
3423 p->jAct25_fl[fl] = 0.0;
3424 p->rdAct25_fl[fl] = 0.0;
3425 }
3426 }
3427 }
3428 else
3429 {
3430 for ( size_t fl = 0; fl < fl_cnt_; ++fl)
3431 {
3432 p->vcAct25_fl[fl] = 0.0;
3433 p->jAct25_fl[fl] = 0.0;
3434 p->rdAct25_fl[fl] = 0.0;
3435 }
3436 }
3437 }
3438
3439 return LDNDC_ERR_OK;
3440}
double non_stomatal_water_limitation(double const &_var, double const &_var_ref, double const &_var_scale)
Non stomatal water limitation.
Definition ld_droughtstress.cpp:136

References ldndc::non_stomatal_water_limitation(), and PSIM_PhotosynthesisRates().

Referenced by PSIM_PhotosynthesisRates().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_PlantingEvent()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_PlantingEvent ( )
protected
Returns
error code
507{
508 EventAttributes const * ev_plant = NULL;
509 while ( (ev_plant = this->m_PlantEvents.pop()) != NULL)
510 {
511 MoBiLE_Plant *vt = this->m_veg->get_plant( ev_plant->get( "/name", "?"));
512 if ( !vt)
513 {
514 KLOGERROR( "Handling plant event failed [species=", ev_plant->get( "/name", "?"),"]");
515 return LDNDC_ERR_RUNTIME_ERROR;
516 }
517 CBM_LogDebug( "Seed plant '",vt->name(),"'");
518
519 species_t const * sp = NULL;
520 if ( m_species)
521 {
522 sp = m_species->get_species( vt->cname());
523 }
524
525 root_system.insert( { vt->slot, RootSystemDNDC( m_state, io_kcomm) } );
526
527 char const * group = ev_plant->get( "/group", "?");
528 if ( cbm::is_equal( group, "wood"))
529 {
530 lerr_t rc_plant = m_pf.initialize_tree( vt, sp->wood(), branchfraction_opt, crownlength_opt, competition_opt);
531 if ( rc_plant)
532 {
533 KLOGERROR( "Plant initialization failed [species=", vt->name(),"]");
534 return LDNDC_ERR_FAIL;
535 }
536 }
537 else if ( cbm::is_equal( group, "grass")) // TODO could be done at "push-time"
538 {
539 lerr_t rc_plant = m_pf.initialize_grass( vt, sp->grass());
540 if ( rc_plant)
541 {
542 KLOGERROR( "Plant initialization failed [species=", vt->name(),"]");
543 return LDNDC_ERR_FAIL;
544 }
545 }
546 else if ( cbm::is_equal( group, "crop")) // TODO could be done at "push-time"
547 {
548 lerr_t rc_plant = m_pf.initialize_crop( vt, sp->crop());
549 if ( rc_plant)
550 {
551 KLOGERROR( "Plant initialization failed [species=", vt->name(),"]");
552 return LDNDC_ERR_FAIL;
553 }
554 }
555
556 // initialize local state variables after planting
557 if ( vt->dEmerg > 0)
558 {
559 if ( (int)lclock()->yearday() > vt->dEmerg)
560 {
561 days_since_emergence[vt->slot] = (int)(lclock()->yearday()) - vt->dEmerg;
562 }
563 else
564 {
565 // use 366 on purpose to ensure always: days_since_emergence > 0
566 days_since_emergence[vt->slot] = (int)(lclock()->yearday()) + (366 - vt->dEmerg);
567 }
568 }
569 else
570 {
571 days_since_emergence[vt->slot] = 0;
572 }
573
574 if ( lclock()->yearday() >= PSIM_YEAR_START)
575 {
576 phenological_year[vt->slot] = lclock()->year();
577 }
578 else
579 {
580 phenological_year[vt->slot] = lclock()->year() - 1;
581 }
582
583 foliage_age_of_start_senescence[vt->slot] = m_pf.get_foliage_age_of_senescence( vt, 0.0);
584
585 for ( size_t na = 0; na < vt->nb_ageclasses(); ++na)
586 {
587 foliage_age_na[vt->slot][na] = m_pf.get_foliage_age( PSIM_YEAR_START, lclock()->yearday(), na);
588 }
589 }
590
591 return LDNDC_ERR_OK;
592}
cbm::string_t branchfraction_opt
...
Definition psim.h:113
cbm::string_t crownlength_opt
...
Definition psim.h:119
std::map< int, RootSystemDNDC > root_system
Root system.
Definition psim.h:377
bool competition_opt
...
Definition psim.h:125

References branchfraction_opt, competition_opt, crownlength_opt, PSIM_PlantingEvent(), and root_system.

Referenced by PSIM_PlantingEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_Potentialtranspiration()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_Potentialtranspiration ( )
protected
Returns
error code
3445{
3446 double potential_transpiration_vt(0.0);
3447 double potential_transpiration_sum (0.0);
3448
3449 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
3450 {
3451 MoBiLE_Plant *p = (*vt);
3452 if (vt->IS_WOOD())
3453 {
3454 if ( wc_.transpiration_method == substate_watercycle_t::WATERUSEEFFICIENCY)
3455 {
3456 potential_transpiration_vt += potential_wood_transpiration(
3457 sl_,
3458 mc_.nd_watervaporsaturationdeficit,
3459 ph_.carbonuptake(m_veg, fl_cnt_),
3460 p->f_area,
3461 vt->WUECMAX(),
3462 vt->WUECMIN(),
3463 sc_.h_sl,
3464 wc_.wc_sl,
3465 wc_.wc_wp_sl,
3466 wc_.wc_fc_sl);
3467 }
3468 else // transpiration_method == "treewaterdeficit", "potentialtranspiration"
3469 {
3470 potential_transpiration_vt += potential_transpiration(
3471 p->nb_foliagelayers(),
3472 vt->GSMIN(),
3473 vt->GSMAX(),
3474 p->lai_fl,
3475 mc_.vpd_fl,
3476 p->relativeconductance_fl) * cbm::HR_IN_DAY * lclock()->day_fraction();
3477 }
3478 }
3479 else
3480 {
3481 potential_transpiration_vt += potential_crop_transpiration(
3482 ac_.nd_co2_concentration,
3483 ph_.carbonuptake( m_veg, fl_cnt_),
3484 vt->WUECMAX());
3485 }
3486
3487 potential_transpiration_sum += potential_transpiration_vt;
3488 wc_.accumulated_potentialtranspiration += potential_transpiration_vt;
3489 }
3490
3491 for (PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
3492 {
3493 MoBiLE_Plant* p = (*vt);
3494 if (cbm::flt_greater_zero(potential_transpiration_sum))
3495 {
3496 p->f_ptransp = potential_transpiration_vt / potential_transpiration_sum;
3497 }
3498 else
3499 {
3500 p->f_ptransp = 0.0;
3501 }
3502 }
3503
3504 return LDNDC_ERR_OK;
3505}
double potential_transpiration(size_t, double gsmin, double gsmax, double *_lai_fl, lvector_t< double > _vpd_fl, double *_relative_conductance_fl)
Returns potential transpiration in [m] for any species type.
Definition ld_transpiration.cpp:225
double potential_wood_transpiration(soillayers::input_class_soillayers_t const &, double _vpd, double _carbon_uptake, double _f_area, double _wuecmax, double _wuecmin, lvector_t< double > _h_sl, lvector_t< double > _wc, lvector_t< double > _wc_min, lvector_t< double > _wc_max)
Returns potential transpiration in [m] for trees.
Definition ld_transpiration.cpp:144
double potential_crop_transpiration(double _co2, double _carbon_uptake, double _wuecmax)
Returns potential transpiration in [m] for crops and grass.
Definition ld_transpiration.cpp:45

References ldndc::potential_crop_transpiration(), ldndc::potential_transpiration(), ldndc::potential_wood_transpiration(), and PSIM_Potentialtranspiration().

Referenced by PSIM_Potentialtranspiration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_ResizeVegetationVectors()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_ResizeVegetationVectors ( )
protected
Returns
error code
390{
391 // compare number of vegetation types
392 size_t const slot_cnt( m_veg->slot_cnt());
393 size_t const slot_cnt_old( additional_season.size());
394
395 if ( slot_cnt <= slot_cnt_old)
396 {
397 return LDNDC_ERR_OK;
398 }
399
400 matrix_2d_dbl_t::extent_type const vtsl[] =
401 { static_cast< matrix_2d_dbl_t::extent_type >( slot_cnt),
402 static_cast< matrix_2d_dbl_t::extent_type >( sl_.soil_layer_cnt())};
403
404 additional_season.resize_and_preserve( slot_cnt, false);
405 phenological_year.resize_and_preserve( slot_cnt, 0);
406 foliage_age_of_start_senescence.resize_and_preserve( slot_cnt, 0);
407 days_since_emergence.resize_and_preserve( slot_cnt, 0);
408
409 // average (effective) temperatures of all leaves of a vegetation type
410 ts_leaftemp_vt.resize_and_preserve( slot_cnt, 0.0);
411 nd_leaftemp_vt.resize_and_preserve( slot_cnt, 0.0);
412
413 uptNH4Max_vt.resize_and_preserve( slot_cnt, 0.0); // max. ammonium uptake
414 uptNO3Max_vt.resize_and_preserve( slot_cnt, 0.0); // max. nitrate uptake
415 uptDONMax_vt.resize_and_preserve( slot_cnt, 0.0); // max. dissolved organic nitrogen uptake
416 uptNWetMax_vt.resize_and_preserve( slot_cnt, 0.0); // tot. nitrogen uptake
417 uptNWet_vt.resize_and_preserve( slot_cnt, 0.0); // tot. nitrogen uptake
418 uptNTot_vt.resize_and_preserve( slot_cnt, 0.0); // tot. nitrogen uptake
419
420 rFolOld_vt.resize_and_preserve( slot_cnt, 0.0);
421 rBudOld_vt.resize_and_preserve( slot_cnt, 0.0);
422 rSapOld_vt.resize_and_preserve( slot_cnt, 0.0);
423 rFrtOld_vt.resize_and_preserve( slot_cnt, 0.0);
424 rTraOld_vt.resize_and_preserve( slot_cnt, 0.0);
425 exsuLossOld_vt.resize_and_preserve( slot_cnt, 0.0);
426
427 uptNH4_vt.resize_and_preserve( slot_cnt, 0.0);
428 uptNO3_vt.resize_and_preserve( slot_cnt, 0.0);
429 uptNH3_vt.resize_and_preserve( slot_cnt, 0.0);
430 uptDON_vt.resize_and_preserve( slot_cnt, 0.0);
431
432 uptNH4Old_vt.resize_and_preserve( slot_cnt, 0.0);
433 uptNO3Old_vt.resize_and_preserve( slot_cnt, 0.0);
434 uptNH3Old_vt.resize_and_preserve( slot_cnt, 0.0);
435 uptDONOld_vt.resize_and_preserve( slot_cnt, 0.0);
436
437 uptNOxOld_vt.resize_and_preserve( slot_cnt, 0.0);
438 uptNHyOld_vt.resize_and_preserve(slot_cnt, 0.0);
439
440 while ( slot_cnt > uptNH4Max_vtsl.size())
441 {
442 std::vector<double> help_sl( sl_.soil_layer_cnt(), 0.0);
443 uptNH4Max_vtsl.push_back( help_sl);
444 }
445 while ( slot_cnt > uptNO3Max_vtsl.size())
446 {
447 std::vector<double> help_sl( sl_.soil_layer_cnt(), 0.0);
448 uptNO3Max_vtsl.push_back( help_sl);
449 }
450 while ( slot_cnt > uptDONMax_vtsl.size())
451 {
452 std::vector<double> help_sl( sl_.soil_layer_cnt(), 0.0);
453 uptDONMax_vtsl.push_back( help_sl);
454 }
455 while ( slot_cnt > foliage_age_na.size())
456 {
457 std::vector< int > help_sl( MoBiLE_MaximumAgeClasses, 0);
458 foliage_age_na.push_back( help_sl);
459 }
460
461 carbonuptake_vt.resize_and_preserve( slot_cnt, 0.0);
462 //xylem_resistance_smoothed_vt.resize_and_preserve(slot_cnt, 0.0);
463 xylem_resistance_smoothed_old_vt.resize_and_preserve(slot_cnt, 0.0);
464 psidecline_cum_vt.resize_and_preserve(slot_cnt, 0.0);
465 psidecline_daycum_vt.resize_and_preserve(slot_cnt, 0.0);
466 rehydrationindex_cum_vt.resize_and_preserve(slot_cnt, 0.0);
467
468 //do not initialize to zero!
469 mSapOpt_vt.resize_and_preserve( slot_cnt, 0.0);
470 mSapOld_vt.resize_and_preserve( slot_cnt, 0.0);
471 mCorOld_vt.resize_and_preserve( slot_cnt, 0.0);
472 qsaparea_vt.resize_and_preserve(slot_cnt, 0.0);
473 fsub_vt.resize_and_preserve(slot_cnt, 0.0);
474
475 mBudLoss_vt.resize_and_preserve( slot_cnt, 0.0); // dry matter transfered from buds to foliage
476 mSapLoss_vt.resize_and_preserve( slot_cnt, 0.0); // dry matter transfered from sapwood to corewood
477 ncFolOpt.resize_and_preserve( slot_cnt, 0.0); // optimum nitrogen concentration of the whole foliage of one species (gN gDW-1)
478 ncBudOpt.resize_and_preserve( slot_cnt, 0.0); // optimum nitrogen concentration of the whole structural storage of one species (gN gDW-1)
479 nDem_vt.resize_and_preserve( slot_cnt, 0.0); // species specific nitrogen demand (kgN)
480 nFol_vt.resize_and_preserve( slot_cnt, 0.0); // last days foliage nitrogen content (kg)
481 nFrt_vt.resize_and_preserve( slot_cnt, 0.0); // last days fine root nitrogen content (kg)
482 nSap_vt.resize_and_preserve( slot_cnt, 0.0); // last days sapwood nitrogen content (kg)
483 nCor_vt.resize_and_preserve( slot_cnt, 0.0); // last days corwood nitrogen content (kg)
484 nBud_vt.resize_and_preserve( slot_cnt, 0.0); // last days bud nitrogen content (kg)
485
486 n_bud_to_fol_vt.resize_and_preserve( vtsl, 0.0);
487 n_sap_to_cor_vt.resize_and_preserve( vtsl, 0.0);
488 n_bud_to_cor_vt.resize_and_preserve( vtsl, 0.0);
489 n_fol_to_cor_vt.resize_and_preserve( vtsl, 0.0);
490 n_frt_to_cor_vt.resize_and_preserve( vtsl, 0.0);
491 n_sap_to_litter_vt.resize_and_preserve( vtsl, 0.0);
492 n_sap_to_redistribute_vt.resize_and_preserve( vtsl, 0.0);
493 n_bud_to_redistribute_vt.resize_and_preserve( vtsl, 0.0);
494 n_fol_to_redistribute_vt.resize_and_preserve( vtsl, 0.0);
495 n_frt_to_redistribute_vt.resize_and_preserve( vtsl, 0.0);
496 n_sap_gain_vt.resize_and_preserve( vtsl, 0.0);
497 n_bud_gain_vt.resize_and_preserve( vtsl, 0.0);
498 n_fol_gain_vt.resize_and_preserve( vtsl, 0.0);
499 n_frt_gain_vt.resize_and_preserve( vtsl, 0.0);
500
501 return LDNDC_ERR_OK;
502}

References PSIM_ResizeVegetationVectors().

Referenced by PSIM_ResizeVegetationVectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PSIM_StepInit()

lerr_t ldndc::PhysiologyGrowthPSIM::PSIM_StepInit ( )
protected
Returns
error code
597{
598 for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
599 {
600 nh4_sl[sl] = sc_.nh4_sl[sl];
601 no3_sl[sl] = sc_.no3_sl[sl] + sc_.an_no3_sl[sl];
602 don_sl[sl] = sc_.don_sl[sl];
603 }
604
605 fl_cnt_ = m_veg->canopy_layers_used();
606
607 if ( subdaily_timemode())
608 {
609 temp_sl.reference( mc_.temp_sl);
610 ts_temp_fl.reference( mc_.temp_fl);
611
612 no_concentration_fl.reference( ac_.ts_no_concentration_fl);
613 no2_concentration_fl.reference( ac_.ts_no2_concentration_fl);
614 nh3_concentration_fl.reference( ac_.ts_nh3_concentration_fl);
615 nh3_uptake_fl.reference( ph_.ts_nh3_uptake_fl);
616 nox_uptake_fl.reference( ph_.ts_nox_uptake_fl);
617
618 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
619 {
620 MoBiLE_Plant *p = *vt;
621 carbonuptake_vt[p->slot] = 0.0;
622 for ( size_t fl = 0; fl < p->nb_foliagelayers(); ++fl)
623 {
624 carbonuptake_vt[p->slot] += p->carbonuptake_fl[fl];
625 }
626 }
627
628 // grazing event by external module
629 if ( lclock()->subday() == 1)
630 {
631 m_eventgraze.reset_daily_food_consumption();
632 }
633 }
634 else
635 {
636 temp_sl.reference( mc_.nd_temp_sl);
637 ts_temp_fl.reference( mc_.nd_temp_fl); // fw: both the same ...
638
639 no_concentration_fl.reference( ac_.nd_no_concentration_fl);
640 no2_concentration_fl.reference( ac_.nd_no2_concentration_fl);
641 nh3_concentration_fl.reference( ac_.nd_nh3_concentration_fl);
642 nh3_uptake_fl.reference( ph_.nd_nh3_uptake_fl);
643 nox_uptake_fl.reference( ph_.nd_nox_uptake_fl);
644
645 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
646 {
647 MoBiLE_Plant *p = *vt;
648 carbonuptake_vt[p->slot] = 0.0;
649 for ( size_t fl = 0; fl < p->nb_foliagelayers(); ++fl)
650 {
651 carbonuptake_vt[p->slot] += p->d_carbonuptake_fl[fl];
652 }
653 }
654
655 m_eventgraze.reset_daily_food_consumption();
656 }
657
658 for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
659 {
660 MoBiLE_Plant *p = *vt;
661
662 PSIM_Reset( p);
663
664 // leaf temperature
665 ts_leaftemp_vt[p->slot] = m_pf.leaf_temperature_( ts_temp_fl, p);
666 nd_leaftemp_vt[p->slot] = m_pf.leaf_temperature_( mc_.nd_temp_fl, p);
667 }
668
669 // nitrous oxygen concentration in the air
670 for ( size_t fl = 0; fl < fl_cnt_; ++fl)
671 {
672 cNOx_fl[fl] = no_concentration_fl[fl] + no2_concentration_fl[fl];
673 }
674
675 return LDNDC_ERR_OK;
676}

References PSIM_StepInit().

Referenced by PSIM_StepInit().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ C1

const double ldndc::PhysiologyGrowthPSIM::C1 = 0.0367
static

second parameter for temperature influence on vcmax activity

◆ CCOMNOX

const double ldndc::PhysiologyGrowthPSIM::CCOMNOX = 1.0
static

compensation NOx concentration without gas exchange [ppb]

◆ CSATNH3

const double ldndc::PhysiologyGrowthPSIM::CSATNH3 = 50.0
static

saturation NH3 concentration [ppb]

◆ CSATNOX

const double ldndc::PhysiologyGrowthPSIM::CSATNOX = 5.0
static

saturation NOx concentration [ppb]

◆ EPOTNOX

const double ldndc::PhysiologyGrowthPSIM::EPOTNOX = 1.0
static

potential specific emission rate of NOx [ppb]

◆ FMIN

const double ldndc::PhysiologyGrowthPSIM::FMIN = 0.05
static

average concentration of minerals others than nitrogen [kg/kgDW]

◆ FRFRT

const double ldndc::PhysiologyGrowthPSIM::FRFRT = 0.5
static

fraction of nitrate that is reduced in the roots

◆ IMAX_W

const int unsigned ldndc::PhysiologyGrowthPSIM::IMAX_W = 24
static

number of iteration steps within a day

◆ KMMM

const double ldndc::PhysiologyGrowthPSIM::KMMM = 0.0
static

Michaelis Menten constant

◆ PAMM

const double ldndc::PhysiologyGrowthPSIM::PAMM = 0.17
static

carbon costs for ammonia uptake

◆ PGDD

const double ldndc::PhysiologyGrowthPSIM::PGDD = 0.0075
static

parameter for GDD relation to temperature related site conditions

◆ PMIN

const double ldndc::PhysiologyGrowthPSIM::PMIN = 0.06
static

carbon costs for minerals

◆ PNIT

const double ldndc::PhysiologyGrowthPSIM::PNIT = 0.34
static

carbon costs for nitrate uptake

◆ PPHLOE

const double ldndc::PhysiologyGrowthPSIM::PPHLOE = 0.06
static

carbon costs for carbon transport from the leafs

◆ PREDFRT

const double ldndc::PhysiologyGrowthPSIM::PREDFRT = 1.72
static

carbon costs for nitrate reduction in the roots

◆ PREDSAP

const double ldndc::PhysiologyGrowthPSIM::PREDSAP = 0.855
static

carbon costs for nitrate reduction in the shoot

◆ PTW

const double ldndc::PhysiologyGrowthPSIM::PTW = 0.29
static

weighting factor for maximum temperature

◆ root_system

std::map< int, RootSystemDNDC > ldndc::PhysiologyGrowthPSIM::root_system
private

Root system.

  • rooting depth
  • root distribution

Referenced by PSIM_PlantingEvent().

◆ TAU

const double ldndc::PhysiologyGrowthPSIM::TAU = 330.0
static

first parameter for temperature influence on vcmax activity

◆ TGLIM

const double ldndc::PhysiologyGrowthPSIM::TGLIM = 6.0
static

soil temperature below which no fine root growth occurs (oC)

◆ TRMAX

const double ldndc::PhysiologyGrowthPSIM::TRMAX = 45.0
static

maximum temperature for maintanence respiration

◆ TRMIN

const double ldndc::PhysiologyGrowthPSIM::TRMIN = -7.0
static

minimum temperature for maintanence respiration

◆ TROPT

const double ldndc::PhysiologyGrowthPSIM::TROPT = 20.0
static

temperature for optimum maintanence respiration

◆ UPOTNH3

const double ldndc::PhysiologyGrowthPSIM::UPOTNH3 = 10000.0
static

potential specific uptake rate of NH3 (ppb)