LandscapeDNDC 1.37.0
Loading...
Searching...
No Matches
ldndc Namespace Reference

Spatially explicit groundwater model. More...

Classes

class  EcHy
 Hydrology model EcHy. More...
 
class  PhysiologyGrowthPSIM
 Vegetation model GrowthPSIM. More...
 
class  PhysiologyPlaMox
 Vegetation model PlaMox. More...
 
class  PhysiologyPNET
 Vegetation model PNET. More...
 
class  SoilChemistryMeTrX
 Biogeochemical model MeTrx. More...
 
class  WatercycleDNDC
 Watercycle model WatercycleDNDC. More...
 

Enumerations

enum  lmodule_flag_e {
  LMOD_FLAG_NONE = 0u ,
  LMOD_FLAG_CONTROL = 1u << 0 ,
  LMOD_FLAG_USER = 1u << 1 ,
  LMOD_FLAG_SYSTEM = 1u << 2 ,
  LMOD_FLAG_INITIALIZER = 1u << 3 ,
  LMOD_FLAG_FINALIZER = 1u << 4 ,
  LMOD_FLAG_MAINTENANCE = 1u << 5 ,
  LMOD_FLAG_OUTPUT = 1u << 6 ,
  LMOD_FLAG_TEST_MODULE = 1u << 7 ,
  LMOD_FLAG_CNT_ ,
  LMOD_FLAG_CNT = 1 + 1 + cbm::log2_t< LMOD_FLAG_CNT_-1 >::LOG2
}
 
enum  { LSUB_FLAG_NONE = 0u }
 
enum  
 Lower bounds for number of foliage layers.
 
enum  stomatalconductance_method_e
 Stomatal conductance methods.
 
enum  {
  CPOOL_VL ,
  CPOOL_L ,
  CPOOL_R ,
  CPOOL_B ,
  CPOOL_CNT
}
 Order of carbon pools in array passed to allocate_litter. More...
 

Functions

lerr_t assign_soillayer_porosity (double &_porosity_with_stones, size_t const &_nd_stratum, double const &_depth, double const &_stone_fraction, double const &_c_org_without_stones, double const &_bulk_density_without_stones, const ldndc::site::input_class_site_t *_site, const ldndc::soillayers::input_class_soillayers_t *_soillayers, const ldndc::soilparameters::input_class_soilparameters_t *_soilparameters, bool _info=false)
 
lerr_t assign_soillayer_macropores (double &_macropores_with_stones, double &_wc_fc, double &_wc_sat, size_t const &_nd_stratum, double const &_depth, double const &_stone_fraction, double const &_porosity_with_stones, const ldndc::site::input_class_site_t *_site, const ldndc::soillayers::input_class_soillayers_t *_soillayers, const ldndc::soilparameters::input_class_soilparameters_t *_soilparameters, bool _info=false)
 
double resistance_aero_abovecanopy (double const &, double const &)
 returns boundary layer resistance above canopy
 
double resistance_aero_incanopy (double const &, double const &, double const &)
 returns boundary layer resistance within canopy
 
double crown_shape_parameter (double _length, double lref, double ps)
 Returns a crown shape parameter which is modified by canopy length.
 
void canopy_biomass_distribution (size_t const _fl_cnt_max, size_t const _fl_cnt, double const _ps, double const _h_bottom, double const _h_top, double const *_h_fl, double *_fFol_fl)
 Foliage biomass distribution vertically across canopy.
 
void canopy_lai_distribution (double _sla_min, double _sla_max, double _height_max, double _height_min, double _mFol, double const *_fFol_fl, double const *_h_fl, double *_lai_fl, double *_sla_fl, size_t _foliage_layer_cnt, size_t _foliage_layer_cnt_max)
 Leaf area distribution vertically across the whole canopy.
 
void estimate_single_layer_biomass (double const _ps, double const _h_bottom, double const _h_top, double _lw, double &_fract, double _h_cum_bottom, double _h_cum_top)
 Vertical biomass estimation.
 
void fineroots_biomass_distribution (size_t _sl_cnt_litter, size_t _sl_cnt_soil, double _ps, double _rooting_depth, double *_f_frt_sl, double const *_h_sl)
 
double get_optimum_sap_wood_biomass (MoBiLE_Plant *_p)
 
double get_sapwood_foliage_ratio (MoBiLE_Plant *_p)
 
double sapwood_foliage_area_ratio (double _height, double _qsf_p1, double _qsf_p2)
 
double stomatal_conductance_ballberry_1987 (double, double, double, double)
 Stomatal conductance according to Berry, Woodward and Ball 1987.
 
double stomatal_conductance_leuning_1990 (double, double, double, double, double)
 Stomatal conductance according to Leuning 1990.
 
double stomatal_conductance_leuning_1995_a (double, double, double, double, double, double, double)
 Stomatal conductance according to Leuning 1995.
 
double stomatal_conductance_eller_2020 (double, double, double, double, double, double, double, double, double, double, double)
 Stomatal conductance according to Eller et al. 2020.
 
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.
 
double potential_crop_transpiration (double _co2, double _carbon_uptake, double _wuecmax)
 Returns potential transpiration in [m] for crops and grass.
 
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.
 
lerr_t get_voc_emission_factors (ldndc::MoBiLE_Plant *, int, bool, double, int, double, double)
 
lerr_t LDNDC_API allocate_litter (double _c, double _n, double _RCNRVL, double _RCNRL, double _RCNRR, double _C[], double &_n_diff)
 calculates the amount of C which is added to the very labile, labile and recalcitrant decomposition pool
 
double LDNDC_API cation_exchange_capacity (double _clay, double _sand, double _som, double _ph, ecosystem_type_e _ecosystem)
 Detailed description provided here .
 
double d_eff_air_a (double const &, double const &)
 Returns effective diffusion coefficient depending on gas content.
 
double d_eff_air_b (double const &, double const &, double const &, double const &)
 Returns effective diffusion coefficient depending on gas content and porosity.
 
double d_eff_air_millington_and_quirk_1961 (double const &, double const &)
 Returns effective diffusion coefficient after [55].
 
lerr_t update_litter_height (soillayers::input_class_soillayers_t const &, substate_watercycle_t &, substate_soilchemistry_t &)
 Detailed description provided here .
 
bool forest_floor (size_t, soillayers::input_class_soillayers_t const &, const ldndc::site::input_class_site_t &)
 First floor defined by:
 
double LDNDC_API sap_wood_fraction (double _lai_max, double _qsfa, double _height_min, double _height_max, double _depth)
 sap_wood_fraction The calculation of the fraction of sapwood in coarse roots is based on the idealized volume fraction and assumes that the stem in the crown as well as the coarse roots are shaped as cones, and that core wood reaches a third of the cone
 
lerr_t wood_initialization (soillayers::input_class_soillayers_t const &, MoBiLE_Plant *, substate_soilchemistry_t &, ecosystem_type_e)
 Initialization of aboveground and belowground wood debris, derived from existing vegetation.
 
double non_stomatal_water_limitation (double const &_var, double const &_var_ref, double const &_var_scale)
 Non stomatal water limitation.
 
double LDNDC_API thornthwaite_heat_index (double, size_t, double, double)
 Thornthwaite heat index.
 
double LDNDC_API thornthwaite (double, double, double, double, double)
 Potential evapotranspiration after [65].
 

Variables

LDNDC_API lflags_t const TMODE_DEFAULTS = TMODE_SUBDAILY|TMODE_PRE_DAILY|TMODE_POST_DAILY|TMODE_PRE_YEARLY|TMODE_POST_YEARLY
 

Detailed Description

Spatially explicit groundwater model.

data synthesizer base class

declare common types related to species

common types related to species (implementation)

declare species groups known to the simulation system

container class for one complete soil and humus parameters set

container class for site parameters

Declare common types related to site input.

declare common types related to setup input

common types related to setup input

declare common types related to remotesensing input

collection of various helper functions

class containing full set of van Genuchten parametrization

declare common types related to groundwater input

declare common types related to geometry input

common event related data types

(management) event factories

base class for (management) events

declare common types related to climate input

declare common types related to checkpoint input

declare common types related to air chemistry input

Author
David Kraus
steffen klatt (created on: mar 05, 2013), edwin haas
steffen klatt (created on: aug 13, 2012), edwin haas
steffen klatt (created on: may 23, 2014), edwin haas
Steffen Klatt (created on: dec 16, 2012), Edwin Haas David Kraus
steffen klatt (created on: dec 10, 2011)
Author
steffen klatt (created on: dec 10, 2011)
Steffen Klatt (created on: dec 10, 2011), Edwin Haas
steffen klatt (created on: feb 03, 2014), edwin haas
Steffen Klatt (created on: may 29, 2015), David Kraus
steffen klatt (created on: may 29, 2015), david kraus
David Kraus (created on: february 28, 2017)
david kraus, ruediger grote, steffen klatt, ...
Steffen Klatt on: may 29, 2015), David Kraus
steffen klatt (created on: sep 03, 2013), edwin haas


for now, also pulls in all kernel specific input declarations

Author
steffen klatt (created on: aug 11, 2012), edwin haas
  • Steffen Klatt (created on: jun 06, 2013)
  • David Kraus
  • Edwin Haas
steffen klatt (created on: jun 19, 2013), edwin haas
Ruediger Grote, David Kraus
Steffen Klatt (created on: jun 20, 2013) Edwin Haas David Kraus
Steffen Klatt (created on: mar 31, 2013) Edwin Haas David Kraus
steffen klatt (created on jun 19, 2013), edwin haas
steffen klatt (created on: jun 20, 2013), edwin haas
Steffen Klatt (created on: apr 04, 2013), Edwin Haas David Kraus
steffen klatt, edwin haas
steffen klatt (created on: jan 19, 2013)

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
LSUB_FLAG_NONE 

empty flag

75{
78};
@ LSUB_FLAG_NONE
Definition mbe_substate.h:77

◆ anonymous enum

anonymous enum

Order of carbon pools in array passed to allocate_litter.

Enumerator
CPOOL_VL 

very labile

CPOOL_L 

labile

CPOOL_R 

recalcitrant

CPOOL_B 

wood

20{
24 CPOOL_L,
26 CPOOL_R,
28 CPOOL_B,
29
30 CPOOL_CNT
31};
@ CPOOL_VL
Definition ld_allocatelitter.h:22
@ CPOOL_B
Definition ld_allocatelitter.h:28
@ CPOOL_L
Definition ld_allocatelitter.h:24
@ CPOOL_R
Definition ld_allocatelitter.h:26

◆ lmodule_flag_e

Enumerator
LMOD_FLAG_NONE 

empty flag

LMOD_FLAG_CONTROL 

marks model as control model

LMOD_FLAG_USER 

marks model as user model

LMOD_FLAG_SYSTEM 

marks model as internal system model

LMOD_FLAG_INITIALIZER 

marks model as initializer (runs before user legacy models)

LMOD_FLAG_FINALIZER 

marks model as finalizer (runs after user legacy models)

LMOD_FLAG_MAINTENANCE 

marks model as maintenance model (e.g. updates, resets, etc)

LMOD_FLAG_OUTPUT 

marks model as output model (always added last)

LMOD_FLAG_TEST_MODULE 

marks model as test model

65{
67 LMOD_FLAG_NONE = 0u,
68
70 LMOD_FLAG_CONTROL = 1u << 0,
71
73 LMOD_FLAG_USER = 1u << 1,
74
76 LMOD_FLAG_SYSTEM = 1u << 2,
78 LMOD_FLAG_INITIALIZER = 1u << 3,
80 LMOD_FLAG_FINALIZER = 1u << 4,
82 LMOD_FLAG_MAINTENANCE = 1u << 5,
83
85 LMOD_FLAG_OUTPUT = 1u << 6,
86
88 LMOD_FLAG_TEST_MODULE = 1u << 7,
89
90 LMOD_FLAG_CNT_,
91 LMOD_FLAG_CNT = 1 + 1 + cbm::log2_t< LMOD_FLAG_CNT_-1 >::LOG2
92};
@ LMOD_FLAG_FINALIZER
Definition mbe_legacymodel.h:80
@ LMOD_FLAG_TEST_MODULE
Definition mbe_legacymodel.h:88
@ LMOD_FLAG_MAINTENANCE
Definition mbe_legacymodel.h:82
@ LMOD_FLAG_INITIALIZER
Definition mbe_legacymodel.h:78
@ LMOD_FLAG_USER
Definition mbe_legacymodel.h:73
@ LMOD_FLAG_NONE
Definition mbe_legacymodel.h:67
@ LMOD_FLAG_CONTROL
Definition mbe_legacymodel.h:70
@ LMOD_FLAG_OUTPUT
Definition mbe_legacymodel.h:85
@ LMOD_FLAG_SYSTEM
Definition mbe_legacymodel.h:76

Function Documentation

◆ allocate_litter()

lerr_t ldndc::allocate_litter ( double _c,
double _n,
double _RCNRVL,
double _RCNRL,
double _RCNRR,
double _C[],
double & _n_diff )

calculates the amount of C which is added to the very labile, labile and recalcitrant decomposition pool

The needed information in this function are the amount of carbon in litter _c and the corresponding CN ratio (determined from nitrogen _n).

four cases: If the CN ratio is lower than the CN ratio of the very labile litter pool, all litter-C goes to the very labile decomposition pool.

If the CN ratio is between RCNRVL and the harmonic mean of RCNRVL and RCNRR, an increasing CN ratio decreases C_0 and increases C_1 and C_2.

If thc CN ratio is between the harmonic mean of RCNRVL and RCNRR and RCNRR, C_1 and C_2 decrease and only C_0 increases.

If CN ratio is higher than RCNRR, all Litter-C goes to C_2.

Parameters
_cCarbon in litter flux
_nNitrogen in litter flux
_COrganic carbon that is added to the
  • very labile,
  • labile,
  • recalcitrant decomposition pool (kgC ha-1)
_n_diff
Note
rr_vl_l harmonic mean of RCNRL and RCNRVL; used to calculate weights how addC is partitioned into C1,C2 and C3 rr_l_r harmonic mean of RCNRL and RCNRR
Author
david kraus (created on: may 6, 2014)
19{
20 ldndc_assert( _n >= 0.0);
21
22 if (cbm::flt_equal_zero(_n))
23 {
24 _C[CPOOL_VL] = 0.0;
25 _C[CPOOL_L] = 0.0;
26 _C[CPOOL_R] = 0.0;
27 _C[CPOOL_B] = _c;
28 _n_diff = 0.0;
29 }
30 else
31 {
32 ldndc_assert(( _RCNRVL > 0.0) && ( _RCNRL > 0.0) && ( _RCNRR > 0.0));
33 double const cn( _c / _n);
34
35 if ( cn < _RCNRVL)
36 {
37 /* cn \in (0,rL) */
38 _C[CPOOL_VL] = _c;
39 _C[CPOOL_L] = 0.0;
40 _C[CPOOL_R] = 0.0;
41 _C[CPOOL_B] = 0.0;
42 _n_diff = ( _n - _c/_RCNRVL);
43 }
44 else if (( cn >= _RCNRVL) && ( cn < _RCNRL))
45 {
46 /* cn \in [rL,r) */
47 double rr_l_r( 2.0 * _RCNRR * _RCNRL / ( _RCNRR + _RCNRL));
48 double addrr( _c * ( rr_l_r - cn) / ( rr_l_r - _RCNRVL) * ( _RCNRVL / cn));
49 _C[CPOOL_VL] = ( 1.25 * addrr - _c * 0.25);
50 _C[CPOOL_L] = ( _c - addrr);
51 _C[CPOOL_R] = (( _c - addrr) * 0.25);
52 _C[CPOOL_B] = 0.0;
53 _n_diff = 0.0;
54 }
55 else if (( cn >= _RCNRL) && ( cn <= _RCNRR))
56 {
57 /* cn \in [r,rR] */
58 double rr_vl_l( 2.0 * _RCNRVL * _RCNRL / ( _RCNRVL + _RCNRL));
59 double addrr( _c * ( rr_vl_l - cn) / (rr_vl_l - _RCNRR) * ( _RCNRR / cn));
60 _C[CPOOL_VL] = (( _c - addrr) * 0.25);
61 _C[CPOOL_L] = ( _c - addrr);
62 _C[CPOOL_R] = ( _c - ( _C[0] + _C[1]));
63 _C[CPOOL_B] = 0.0;
64 _n_diff = 0.0;
65 }
66 else
67 {
68 /* cn \in (rR,\inf) */
69 _C[CPOOL_VL] = 0.0;
70 _C[CPOOL_L] = 0.0;
71 _C[CPOOL_R] = _n * _RCNRR;
72 _C[CPOOL_B] = _c - _n * _RCNRR;
73 _n_diff = 0.0;
74 }
75 }
76
77 return LDNDC_ERR_OK;
78}

References CPOOL_B, CPOOL_L, CPOOL_R, and CPOOL_VL.

◆ assign_soillayer_macropores()

lerr_t ldndc::assign_soillayer_macropores ( double & _macropores_with_stones,
double & _wc_fc,
double & _wc_sat,
size_t const & _nd_stratum,
double const & _depth,
double const & _stone_fraction,
double const & _porosity_with_stones,
const ldndc::site::input_class_site_t * _site,
const ldndc::soillayers::input_class_soillayers_t * _soillayers,
const ldndc::soilparameters::input_class_soilparameters_t * _soilparameters,
bool _info = false )

Hydraulic parameters are checked for consistency against each other.

771{
772 ldndc::site::iclass_site_stratum_t stratum;
773 lerr_t rc_stratum = _soillayers->stratum( _nd_stratum, &stratum);
774 RETURN_IF_NOT_OK( rc_stratum);
775
776 if ( cbm::is_valid( stratum.macropores))
777 {
778 _macropores_with_stones = stratum.macropores;
779 }
780 else
781 {
782 if ( forest_floor( _depth, *_soillayers, *_site))
783 {
784 _macropores_with_stones = _soilparameters->HUMUS_MACROPORES( _soillayers->humus_type());
785 }
786 else
787 {
788 double clay( 0.0);
789 double sand( 0.0);
790 double silt( 0.0);
791 lerr_t rc_texture = assign_soillayer_soil_texture( clay, sand, silt, _nd_stratum, _depth,
792 _site, _soillayers, _soilparameters, false);
793 if ( rc_texture)
794 {
795 LOGERROR( "Initialization of field capacity and wilting point of stratum ",
796 _nd_stratum+1, " not successful due to invalid soil texture info");
797 return LDNDC_ERR_FAIL;
798 }
799
800 cbm::string_t texture_name( ldndc::get_soil_texture( sand * 100.0, clay * 100.0));
801 ldndc::soillayers::soil_type_e texture_type( ldndc::get_soil_texture_type( texture_name));
802
803 if ( ldndc::use_usda_soil_texture_triangle( _soillayers->soil_type()) &&
804 (texture_type != ldndc::soillayers::SOIL_NONE))
805 {
806 _macropores_with_stones = _soilparameters->SOIL_MACROPORES( texture_type);
807 }
808 else
809 {
810 _macropores_with_stones = _soilparameters->SOIL_MACROPORES( _soillayers->soil_type());
811 }
812 }
813 }
814
815 _macropores_with_stones *= (1.0 - _stone_fraction);
816
820 if( cbm::flt_greater( _wc_fc + _macropores_with_stones, _porosity_with_stones))
821 {
822 double const scale_down( _porosity_with_stones / ( _wc_fc + _macropores_with_stones));
823 _wc_fc *= scale_down;
824 STRATUM_INFO( "Field capacity exceeded porosity minus macropores in stratum ", _nd_stratum+1, ". ",
825 "Adjusted field capacity: ", _wc_fc / (1.0 - _stone_fraction) * 100.0," [%]");
826 }
827
828 if( cbm::flt_less_equal( _wc_sat, _wc_fc))
829 {
830 _wc_sat = 0.5 * (_wc_fc + _porosity_with_stones);
831 STRATUM_INFO( "Saturated water content smaller than field capacity in stratum ", _nd_stratum+1, ". ",
832 "Adjusted saturated water content: ", _wc_sat / (1.0 - _stone_fraction) * 100.0," [%]");
833 }
834
835 return LDNDC_ERR_OK;
836}
bool forest_floor(size_t, soillayers::input_class_soillayers_t const &, const ldndc::site::input_class_site_t &)
First floor defined by:
Definition ld_litterheight.cpp:133

References forest_floor().

Here is the call graph for this function:

◆ assign_soillayer_porosity()

lerr_t ldndc::assign_soillayer_porosity ( double & _porosity_with_stones,
size_t const & _nd_stratum,
double const & _depth,
double const & _stone_fraction,
double const & _c_org_without_stones,
double const & _bulk_density_without_stones,
const ldndc::site::input_class_site_t * _site,
const ldndc::soillayers::input_class_soillayers_t * _soillayers,
const ldndc::soilparameters::input_class_soilparameters_t * _soilparameters,
bool _info = false )

Porosity is estimated based on organic carbon fraction and bulk density for the soil including stones. Porosity is given by a value between 0 and 1. See: porosity()

643{
644 ldndc::site::iclass_site_stratum_t stratum;
645 lerr_t rc_stratum = _soillayers->stratum( _nd_stratum, &stratum);
646 if ( rc_stratum)
647 {
648 LOGERROR( "Invalid stratum [nd=", _nd_stratum,"]");
649 return LDNDC_ERR_FAIL;
650 }
651
652 double porosity_without_stones( invalid_dbl);
653 if( cbm::flt_greater_equal_zero( stratum.porosity))
654 {
655 porosity_without_stones = stratum.porosity;
656 }
657 else
658 {
659 double clay( 0.0);
660 double sand( 0.0);
661 double silt( 0.0);
662 lerr_t rc_texture = assign_soillayer_soil_texture( clay, sand, silt, _nd_stratum, _depth, _site, _soillayers, _soilparameters, false);
663 if ( rc_texture)
664 {
665 LOGERROR( "Initialization of porosity of stratum ", _nd_stratum+1, " [site id=",_site->object_id(),"] not successful due to invalid soil texture info");
666 return LDNDC_ERR_FAIL;
667 }
668
674 double mineral_soil_density( cbm::DMIN);
675 double const clay_sand_silt( clay + sand + silt);
676 if ( cbm::flt_greater_zero( clay_sand_silt))
677 {
678 mineral_soil_density = (clay * cbm::DCLA + sand * cbm::DSAN + silt * cbm::DSIL) / clay_sand_silt;
679 }
680 porosity_without_stones = ldndc::porosity( _c_org_without_stones, _bulk_density_without_stones, mineral_soil_density);
681 STRATUM_INFO( "Porosity of stratum ",_nd_stratum+1," not initialized, estimated value (without stones): ", porosity_without_stones*100.0," [%]");
682 }
683
684 _porosity_with_stones = porosity_without_stones * (1.0 - _stone_fraction);
685
686 if ( !cbm::flt_in_range_lu( 0.0, _porosity_with_stones, 1.0))
687 {
688 LOGERROR( "Porosity of stratum ", _nd_stratum+1, " [site id=",_site->object_id(),"] out of range: ",
689 _porosity_with_stones / (1.0 - _stone_fraction)*100," [%]");
690 return LDNDC_ERR_FAIL;
691 }
692 else
693 {
694 return LDNDC_ERR_OK;
695 }
696}

◆ canopy_biomass_distribution()

void ldndc::canopy_biomass_distribution ( size_t const _fl_cnt_max,
size_t const _fl_cnt,
double const _ps,
double const _h_bottom,
double const _h_top,
double const * _h_fl,
double * _fFol_fl )

Foliage biomass distribution vertically across canopy.

Parameters
_fl_cnt_maxmaximum number of foliage parameters
_fl_cntcurrent actively used number of foliage parameters
_ps
_h_bottom
_h_top
_h_fl
_fFol_fl
Returns
no return value
44{
45 /* reset */
46 for ( size_t fl = 0; fl < _fl_cnt_max; ++fl)
47 {
48 _fFol_fl[fl] = 0.0;
49 }
50
51 // total distribution length
52 if ( cbm::flt_greater( _h_top, _h_bottom))
53 {
54 double h_cum_top( 0.0);
55 for ( size_t fl = 0; fl < _fl_cnt; ++fl)
56 {
57 double const h_cum_bottom( h_cum_top);
58 h_cum_top += _h_fl[fl];
59
61 _ps, _h_bottom, _h_top,
62 _h_fl[fl], _fFol_fl[fl],
63 h_cum_bottom, h_cum_top);
64 }
65
66 double const fFol_sum( cbm::sum( _fFol_fl, _fl_cnt));
67 if ( cbm::flt_equal_zero( fFol_sum))
68 {
69 for ( size_t fl = 0; fl < _fl_cnt; ++fl)
70 {
71 _fFol_fl[fl] = 1.0 / double( _fl_cnt);
72 }
73 }
74 else
75 {
76 for ( size_t fl = 0; fl < _fl_cnt; ++fl)
77 {
78 _fFol_fl[fl] /= fFol_sum;
79 }
80 }
81 }
82}
void estimate_single_layer_biomass(double const _ps, double const _h_bottom, double const _h_top, double _lw, double &_fract, double _h_cum_bottom, double _h_cum_top)
Vertical biomass estimation.
Definition ld_plantfunctions.cpp:1731

References estimate_single_layer_biomass().

Here is the call graph for this function:

◆ canopy_lai_distribution()

void ldndc::canopy_lai_distribution ( double _sla_min,
double _sla_max,
double _height_max,
double _height_min,
double _mFol,
double const * _fFol_fl,
double const * _h_fl,
double * _lai_fl,
double * _sla_fl,
size_t _foliage_layer_cnt,
size_t _foliage_layer_cnt_max )

Leaf area distribution vertically across the whole canopy.

Parameters
_sla_minspecific leaf area at canopy top
_sla_maxspecific leaf area at canopy bottom
_height_maxtotal plant height
_height_minplant height at start of canopy
_mFolfoliage biomass
_fFol_flfoliage biomass distribution
_h_flcanopy discretization
_lai_flcanopy layer leaf area index
_sla_flcanopy layer specific leaf are
_foliage_layer_cntnumber of canopy layers
_foliage_layer_cnt_maxmaximum number of canopy layers
Returns
no return value
101{
102 /* reset canopy */
103 for ( size_t fl = 0; fl < _foliage_layer_cnt_max; ++fl)
104 {
105 _sla_fl[fl] = 0.0;
106 _lai_fl[fl] = 0.0;
107 }
108
109 double const crown_length( _height_max - _height_min);
110 if ( cbm::flt_greater_zero( crown_length))
111 {
112 double const delta_sla( cbm::bound_min( 0.0, _sla_max - _sla_min));
113
114 /* cumulative height of total plant */
115 double h_cum_total_top( 0.0);
116 double h_cum_crown_bottom( 0.0);
117 for (size_t fl = 0; fl < _foliage_layer_cnt; ++fl)
118 {
119 h_cum_total_top += _h_fl[fl];
120
121 /* sla and lai are greater zero only within canopy */
122 if ( cbm::flt_greater( h_cum_total_top, _height_min))
123 {
124 double const h_cum_crown_top( cbm::bound_max( h_cum_total_top - _height_min, crown_length));
125 double const h_cum_crown( 0.5 * (h_cum_crown_bottom + h_cum_crown_top));
126
127 _sla_fl[fl] = _sla_max - (delta_sla * h_cum_crown / crown_length);
128 _lai_fl[fl] = _sla_fl[fl] * _mFol * _fFol_fl[fl];
129
130 h_cum_crown_bottom = h_cum_crown_top;
131 }
132 }
133 }
134}

◆ cation_exchange_capacity()

double LDNDC_API ldndc::cation_exchange_capacity ( double _clay,
double _sand,
double _som,
double _ph,
ecosystem_type_e _ecosystem )

Detailed description provided here .

Parameters
_clayClay content [%]
_sandSand content [%]
_somSoil organic matter content [%]
_phpH value [-]
_ecosystemEcosystem type [-]
Returns
Cation exchange capacity [mol:g-1:1e-5]

Referenced by ldndc::SoilChemistryMeTrX::MeTrX_clay_nh4_equilibrium().

Here is the caller graph for this function:

◆ crown_shape_parameter()

double ldndc::crown_shape_parameter ( double _length,
double lref,
double ps )

Returns a crown shape parameter which is modified by canopy length.

modification of crown shape by canopy length

1251{
1252 // crown/ root profile shape value shifts with crown length/ root profile depth
1253 double ps2(ps);
1254 if (_length <= 1.0)
1255 {
1256 ps2 = 1.0;
1257 }
1258 else if (lref > 1.0)
1259 {
1260 ps2 = cbm::bound_max(1.0 + (ps - 1.0) * (_length - 1.0) / (lref - 1.0), ps);
1261 }
1262
1263 return ps2;
1264}

◆ d_eff_air_a()

double ldndc::d_eff_air_a ( double const & _exp,
double const & _gas_content )

Returns effective diffusion coefficient depending on gas content.

Parameters
[in]_expExponent [-]
[in]_gas_contentGas content [m^3:m^-3]
Returns
Effective diffusion coefficient [-]
18{
19 return std::pow( _gas_content, _exp);
20}

◆ d_eff_air_b()

double ldndc::d_eff_air_b ( double const & _exp_g,
double const & _exp_p,
double const & _gas_content,
double const & _porosity )

Returns effective diffusion coefficient depending on gas content and porosity.

Parameters
[in]_exp_gExponent for gas content [-]
[in]_exp_pExponent for porosity [-]
[in]_gas_contentGas content [m^3:m^-3]
[in]_porosityPorosity [m^3:m^-3]
Returns
Effective diffusion coefficient [-]
31{
32 return std::pow( _gas_content, _exp_g) / std::pow( _porosity, _exp_p);
33}

◆ d_eff_air_millington_and_quirk_1961()

double ldndc::d_eff_air_millington_and_quirk_1961 ( double const & _gas_content,
double const & _porosity )

Returns effective diffusion coefficient after [55].

Parameters
[in]_gas_contentGas content [m^3:m^-3]
[in]_porosityPorosity [m^3:m^-3]
Returns
Effective diffusion coefficient [-]
42{
43 return std::pow( _gas_content, 10.0/3.0) / (_porosity * _porosity);
44}

◆ estimate_single_layer_biomass()

void ldndc::estimate_single_layer_biomass ( double const _ps,
double const _h_bottom,
double const _h_top,
double _lw,
double & _fract,
double _h_cum_bottom,
double _h_cum_top )

Vertical biomass estimation.

Parameters
_psform parameter
_h_bottomheight of start of distributed biomass
_h_topheight of end of distributed biomass
_lw
_fract
_h_cum_bottom
_h_cum_top
Returns
No return value

The standard vertical distribution of biomass is done with the same assumptions for canopy (veglibs_canopy) and rooting space (Root distribution). Only for root distribution there are several more options available.

1739{
1740 // calculation proceeds as long as cumulative length is smaller than total crown length
1741 if ( cbm::flt_greater( _h_cum_top, _h_bottom) &&
1742 cbm::flt_less_equal( _h_cum_bottom, _h_top))
1743 {
1744 // distance from the crown start/ soil surface for which the relative biomass shall be estimated
1745 double hAct( 0.0);
1746 double const length( _h_top - _h_bottom);
1747
1748 // if total crown height is within the first canopy layer
1749 if ( cbm::flt_less( _h_top, _lw))
1750 {
1751 hAct = length;
1752 }
1753 // for the partially filled last canopy/ soil layer
1754 else if ( cbm::flt_less_equal( _h_top, _h_cum_top))
1755 {
1756 hAct = length - ( _h_top - _h_cum_bottom) * 0.5;
1757 }
1758 // for the partially filled first canopy/ soil layer
1759 else if ( cbm::flt_less( _h_cum_bottom, _h_bottom))
1760 {
1761 hAct = ( _h_cum_top - _h_bottom) * 0.5;
1762 }
1763 // for fully filled canopy/ soil layers
1764 else
1765 {
1766 hAct = ( _h_cum_bottom - _h_bottom) + (_h_cum_top - _h_cum_bottom) * 0.5;
1767 }
1768
1769 double const relH( cbm::flt_less( length, _lw) ? 1.0 : ((length - hAct) / length));
1770
1771 // relative biomass distribution throughout the canopy/ soil according to Grote 2007
1772 double fH( pow( _ps, 100.0 * hAct / ( cbm::flt_greater( length, 5.0) ? (length * length) : 25.0)));
1773
1774 _fract = relH * fH;
1775 }
1776 else
1777 {
1778 _fract = 0.0;
1779 }
1780}

Referenced by canopy_biomass_distribution(), and fineroots_biomass_distribution().

Here is the caller graph for this function:

◆ fineroots_biomass_distribution()

void ldndc::fineroots_biomass_distribution ( size_t _sl_cnt_litter,
size_t _sl_cnt_soil,
double _ps,
double _rooting_depth,
double * _f_frt_sl,
double const * _h_sl )

Root distribution and root properties are generally fixed throughout the simulation period. Only, if the initial condition of planting doesn't allow the soil profile to be fully rooted (e.g. plants are too small), rooting depth increases linearly with \( GZRTZ \) until the maximum root depth (defined by the soil profile) is reached. This is different in Plamox, where plant roots start growing down with planting and should not grow as deep as the soil profile depth, but stop at the species parameter, the maximum rooting depth \( ZRTMC \).

Standard empirial root distribution

The distribution of fine root biomass \( m(z) \) within the rooting space depends on the rooting depth and is calculated with the same empirical equation as the foliage biomass (veglibs_canopy). The main difference is that the parameter 'p' is generally below 1 now to get a concave distribution ([28]).

\[ m(z) = M \cdot \frac{r_{ih} f(z)}{\int r_{ih} f(z)} \\ r_{ih} = \frac{RD - z}{RD} \\ f(z) = p^{100 \frac{z}{RD^2}} \]

\( RD \): root depth (m)
\( z \): distribution depth for which the percentage roots should be defined (between 0-1, from upper soil boundary to rooting depth)
\( p \): shape parameter

Fine roots biomass distribution
Note
This function is currently the standard option for PSIM/TREEDYN (implicitly)

scaling factor for root distribution (basically to enable root and canopy profile calculations with the same function)

fraction of fine roots in the litter layer

fraction of fine roots in the mineral soil

1818{
1819 if ( cbm::flt_greater_zero( _rooting_depth))
1820 {
1822 double const SCALE( 10.0);
1823
1825 double f_litter( 0.0);
1826
1827 double litter_depth( 0.0);
1828 for ( size_t sl = 0; sl < _sl_cnt_litter; ++sl)
1829 {
1830 litter_depth += _h_sl[sl];
1831 }
1832
1833 /* if rooting depth <= litter depth neglect litter layer (new seedlings start in mineral layer)*/
1834 if ( cbm::flt_greater( litter_depth, _rooting_depth))
1835 {
1836 _sl_cnt_litter = 0;
1837 f_litter = 0.0;
1838 }
1839 /* else assume that fine roots are distributed according to litter height relative to soil profile*/
1840 else
1841 {
1842 f_litter = litter_depth / _rooting_depth;
1843 }
1844
1845 for ( size_t sl = 0; sl < _sl_cnt_litter; ++sl)
1846 {
1847 _f_frt_sl[sl] = f_litter / (double)_sl_cnt_litter;
1848 }
1849
1851 double const f_soil( 1.0 - f_litter);
1852
1853 double h_cum( 0.0);
1854 double f_frt_sum( 0.0);
1855 for ( size_t sl = _sl_cnt_litter; sl < _sl_cnt_soil; ++sl)
1856 {
1857 double const h_cum_old( h_cum);
1858 h_cum += _h_sl[sl] * SCALE;
1859
1860 estimate_single_layer_biomass( _ps, 0.0, SCALE * _rooting_depth,
1861 SCALE * _h_sl[sl], _f_frt_sl[sl],
1862 h_cum_old, h_cum);
1863 f_frt_sum += _f_frt_sl[sl];
1864 }
1865
1866 for ( size_t sl = _sl_cnt_litter; sl < _sl_cnt_soil; ++sl)
1867 {
1868 _f_frt_sl[sl] = _f_frt_sl[sl] / f_frt_sum * f_soil;
1869 }
1870 }
1871 else
1872 {
1873 for ( size_t sl = 0; sl < _sl_cnt_soil; ++sl)
1874 {
1875 _f_frt_sl[sl] = 0.0;
1876 }
1877 }
1878}

References estimate_single_layer_biomass().

Here is the call graph for this function:

◆ forest_floor()

bool ldndc::forest_floor ( size_t _sl,
soillayers::input_class_soillayers_t const & _soillayers,
const ldndc::site::input_class_site_t &  )

First floor defined by:

  • litter height
  • ecosystem type
137{
138 if ( _sl < _soillayers.soil_layers_in_litter_cnt())
139 {
140 return true;
141 }
142
143 return false;
144}

Referenced by assign_soillayer_macropores().

Here is the caller graph for this function:

◆ get_optimum_sap_wood_biomass()

double ldndc::get_optimum_sap_wood_biomass ( MoBiLE_Plant * _p)
Parameters
_pPlant
Returns
Optimum sap wood biomass depending on foliage biomass.
28{
29 double const sapwood_area_demand( _p->lai_max * _p->qsfa);
30 double const branch_sapwood(_p->aboveground_wood() * _p->f_branch);
31 double const optimum_msap_tree( (*_p)->DSAP() * cbm::DM3_IN_M3 * sapwood_area_demand
32 * ( _p->height_at_canopy_start
33 + (_p->rooting_depth / 3.0)
34 + (_p->height_max - _p->height_at_canopy_start) / 3.0));
35 double const optimum_sap_wood( optimum_msap_tree + branch_sapwood);
36
37 if ( (*_p)->IS_WOOD())
38 {
39 double const total_wood( _p->aboveground_wood() + _p->belowground_wood());
40 return cbm::bound_max( optimum_sap_wood, total_wood);
41 }
42 else
43 {
44 return optimum_sap_wood;
45 }
46}

Referenced by get_sapwood_foliage_ratio().

Here is the caller graph for this function:

◆ get_sapwood_foliage_ratio()

double ldndc::get_sapwood_foliage_ratio ( MoBiLE_Plant * _p)
Parameters
_pPlant
Returns
sap wood to foliage ratio
56{
57 double const biomass_limit( 0.001);
58
59 if ( !(*_p)->FREEGROWTH() && (_p->nb_ageclasses() > 0) )
60 {
61 size_t na_max( _p->nb_ageclasses() - 1);
62 if ( cbm::flt_greater( _p->mBud + _p->mFol - _p->mFol_na[na_max], biomass_limit))
63 {
64 double const m_sap_opt( get_optimum_sap_wood_biomass(_p));
65 return m_sap_opt / ( _p->mBud + _p->mFol - _p->mFol_na[na_max]);
66 }
67 }
68 else if ( cbm::flt_greater( _p->mFol + _p->mBud, biomass_limit))
69 {
70 double const m_sap_opt( get_optimum_sap_wood_biomass(_p));
71 return m_sap_opt / ( _p->mFol + _p->mBud);
72 }
73
74 return 0.0;
75}
double get_optimum_sap_wood_biomass(MoBiLE_Plant *_p)
Definition ld_sapwoodbiomass.cpp:27

References get_optimum_sap_wood_biomass().

Here is the call graph for this function:

◆ get_voc_emission_factors()

lerr_t ldndc::get_voc_emission_factors ( ldndc::MoBiLE_Plant * _vt,
int _fl,
bool _calc_synthase_activity,
double _latitude,
int _yearday,
double _foliage_temperature,
double _foliage_radiation )

Daily calculation of voc (isoprene and monoterpenes) synthase activity NOTE that fCO2 depends on outside CO2, internal CO2 would probably be better (explaining relatively high emissions when stomata closed)

141{
142// if running subdaily calc activity on last subdaily time step
143
144
145// if ("beginning of simulation and first time that pointers are assigned")
146// --> assign ef with sef
147// --> assign ef with iso/monoAct
148//
149// else if ( "further within simulation ")
150// --> assign ef with iso/monoAct
151
152
153
154 if ( !_calc_synthase_activity)
155 {
156 ldndc_use_standard_emission_factors( _vt, _fl);
157 return LDNDC_ERR_OK;
158 }
159
160 else if (( _calc_synthase_activity) && (( ( *_vt)->ALPHA0_IS() + ( *_vt)->ALPHA0_MT()) > 0.0) && ( ( *_vt)->PA() > 0.0))
161 {
162 LOGINFO_ONCE( "Calculation of voc synthase activity instead of standard emission factors");
163 ldndc_calc_voc_synthase_activity( _vt, _fl, _latitude, _yearday, _foliage_temperature, _foliage_radiation);
164
165 /* factors for conversion from enzyme activity (nmol m-2 (leaf area) s-1) to emission factor (ug component gDW-1 h-1) */
166 double const lsw = cbm::G_IN_KG / _vt->sla_fl[_fl];
167 double const UNIT_CONV = cbm::SEC_IN_HR * cbm::UMOL_IN_NMOL;
168
169 /* "isoAct_vtfl"/"monoAct_vtfl" [nmol enzyme product m-2 leaf area s-1] activity of isoprene/monterpene synthase to produce isoprene/monoterpenes */
170 _vt->ef_iso_fl[_fl] = _vt->isoAct_fl[_fl] * cbm::MC5H8 * UNIT_CONV / ( lsw * ( *_vt)->SCALE_I());
171 _vt->ef_mono_fl[_fl] = _vt->monoAct_fl[_fl] * cbm::MC10H16 * UNIT_CONV / ( lsw * ( *_vt)->SCALE_M());
172
173
174 return LDNDC_ERR_OK;
175 }
176
177 else if (( _calc_synthase_activity) && ((( ( *_vt)->ALPHA0_IS() + ( *_vt)->ALPHA0_MT()) <= 0.0) || ( ( *_vt)->PA() <= 0.0)))
178 {
179 LOGWARN_ONCE( "Dynamic calculation of emission activity not possible",
180 " because species specific paramters ALPHA0_IS + ALPHA0_MT, or PA is equal or less than zero",
181 " [ALPHA0_IS=",( *_vt)->ALPHA0_IS(),",ALPHA0_MT=",( *_vt)->ALPHA0_MT(),",PA=",( *_vt)->PA(),"]",
182 " Thus standard emission factors are used!");
183
184 ldndc_use_standard_emission_factors( _vt, _fl);
185 return LDNDC_ERR_OK;
186
187 }
188
189 else
190 {
191 LOGERROR("Wrong configuration of CalcSynthaseActivity, CalcParTempDependence, or species specific parameters...");
192 return LDNDC_ERR_FAIL;
193 }
194
195}

◆ non_stomatal_water_limitation()

double ldndc::non_stomatal_water_limitation ( double const & _var,
double const & _var_ref,
double const & _var_scale )

Non stomatal water limitation.

Parameters
_var...
_var_ref...
_var_scale...
Returns
Drought stress scaling factor [0-1]
140{
141 // water impact on non-stomatal limitations based on Tuzet et al.2003
142 if ( cbm::flt_greater_equal_zero( _var))
143 {
144 return 1.0;
145 }
146 else
147 {
148 return cbm::bound(0.0, (1.0 + std::exp(_var_ref * _var_scale)) / (1.0 + std::exp((_var_ref - _var) * _var_scale)), 1.0);
149 }
150}

Referenced by ldndc::PhysiologyGrowthPSIM::PSIM_PhotosynthesisRates().

Here is the caller graph for this function:

◆ sap_wood_fraction()

double ldndc::sap_wood_fraction ( double _lai_max,
double _qsfa,
double _height_min,
double _height_max,
double _depth )

sap_wood_fraction The calculation of the fraction of sapwood in coarse roots is based on the idealized volume fraction and assumes that the stem in the crown as well as the coarse roots are shaped as cones, and that core wood reaches a third of the cone

Calculation is based on the sapwood area demand for foliage. Sapwood volume is assumed to equal a cone within the canopy and across the rooted soil, and a column between the ground and canopy start.

Author
David Kraus (created on: may 6, 2014)
21{
22 /* sapwood area (assumed to be in equilibrium with foliage demand) */
23 double const sap_area( _lai_max * _qsfa);
24
25 /* estimated aboveground sapwood biomass */
26 double const msap_a( sap_area * _height_min + sap_area / 3.0 * (_height_max - _height_min));
27
28 /* estimated belowground sapwood biomass */
29 double const msap_b( sap_area / 3.0 * _depth);
30
31 if ( cbm::flt_greater_zero( msap_a + msap_b))
32 {
33 return msap_b / ( msap_a + msap_b);
34 }
35
36 return 0.0;
37}

Referenced by ldndc::PhysiologyPNET::TransformPhysiology().

Here is the caller graph for this function:

◆ sapwood_foliage_area_ratio()

double ldndc::sapwood_foliage_area_ratio ( double _height,
double _qsf_p1,
double _qsf_p2 )
Parameters
_heightTree height
_qsf_p1species parameter
_qsf_p2species parameter
Returns
Ratio of sap wood area to foliage area.
99{
100 return (_qsf_p1 + _height * _qsf_p2) * cbm::M2_IN_CM2;
101}

◆ update_litter_height()

lerr_t ldndc::update_litter_height ( soillayers::input_class_soillayers_t const & _soillayers,
substate_watercycle_t & _wc,
substate_soilchemistry_t & _sc )

Detailed description provided here .

Parameters
_slSoil layers class
_wcWatercycle state
_scSoilchemistry state
Returns
Error code
30{
31 double const raw_litter_above( _sc.c_raw_lit_1_above +
32 _sc.c_raw_lit_2_above +
33 _sc.c_raw_lit_3_above);
34
35 double h_cum( 0.0);
36 for( size_t sl = 0; sl < _soillayers.soil_layer_cnt(); ++sl)
37 {
38 if ( sl < _soillayers.soil_layers_in_litter_cnt())
39 {
40 if ( cbm::flt_greater_zero( _sc.dens_sl[sl] * _sc.fcorg_sl[sl]) &&
41 cbm::flt_greater_zero( _sc.som_sl[sl]))
42 {
43 double const volume_water( _wc.wc_sl[sl] * _sc.h_sl[sl]);
44
45 double const mass_soil( _sc.min_sl[sl] + _sc.som_sl[sl] + raw_litter_above / _soillayers.soil_layers_in_litter_cnt());
46 double const density_soil( cbm::DM3_IN_M3 * _sc.dens_sl[sl]);
47
48 // soil organic matter increases --> inc sl-height
49 double const h_new( mass_soil / density_soil);
50 _sc.h_sl[sl] = h_new;
51
52 double const wc_new( volume_water / _sc.h_sl[sl]);
53 if ( cbm::flt_less_equal( wc_new, _sc.poro_sl[sl]))
54 {
55 _wc.wc_sl[sl] = wc_new;
56 }
57 else
58 {
59 _wc.wc_sl[sl] = _sc.poro_sl[sl];
60 _wc.surface_water += (wc_new - _sc.poro_sl[sl]) * h_new;
61 }
62 }
63 else if ( !cbm::flt_greater_zero( _sc.som_sl[sl]))
64 {
65 _sc.h_sl[sl] = 0.0;
66 _wc.wc_sl[sl] = 0.0;
67
68 LOGERROR( "Soil litter layer height vanished. Illegal situation!");
69 return LDNDC_ERR_FAIL;
70 }
71 }
72
73 h_cum += _sc.h_sl[sl];
74 _sc.depth_sl[sl] = h_cum;
75 }
76
77 return LDNDC_ERR_OK;
78}

◆ wood_initialization()

lerr_t ldndc::wood_initialization ( soillayers::input_class_soillayers_t const & _sl,
MoBiLE_Plant * _p,
substate_soilchemistry_t & _sc,
ecosystem_type_e _ecosystemtype )

Initialization of aboveground and belowground wood debris, derived from existing vegetation.

23{
29 double const add_c_wood( ((_ecosystemtype == ECOSYS_FOREST_NATURAL) ? 0.3 : 0.1) * ( _p->mSap + _p->mCor) * cbm::CCDM);
30
31 //add 80% aboveground
32 _sc.c_wood += 0.8 * add_c_wood;
33 _sc.n_wood += 0.8 * add_c_wood / cbm::CCDM * _p->ncCor;
34
35 //add 20% belowground
36 for ( size_t sl = 0; sl < _sl.soil_layer_cnt(); ++sl)
37 {
38 _sc.c_wood_sl[sl] += 0.2 * _p->fFrt_sl[sl] * add_c_wood;
39 _sc.n_wood_sl[sl] += 0.2 * _p->fFrt_sl[sl] * add_c_wood / cbm::CCDM * _p->ncCor;
40 }
41
42 return LDNDC_ERR_OK;
43}

Referenced by ldndc::SoilChemistryMeTrX::MeTrX_update().

Here is the caller graph for this function:

Variable Documentation

◆ TMODE_DEFAULTS

lflags_t const ldndc::TMODE_DEFAULTS = TMODE_SUBDAILY|TMODE_PRE_DAILY|TMODE_POST_DAILY|TMODE_PRE_YEARLY|TMODE_POST_YEARLY
extern
Author
steffen klatt, edwin haas