LandscapeDNDC 1.37.0
Loading...
Searching...
No Matches
ldndc::RootSystemDNDC Struct Reference

Fine root system used by PlaMox and, for the distribution functions and nitrogen uptake, by other physiology modules (see Root system). More...

#include <models/physiology/ld_rootsystem.h>

Inheritance diagram for ldndc::RootSystemDNDC:
Collaboration diagram for ldndc::RootSystemDNDC:

Public Member Functions

 RootSystemDNDC (MoBiLE_State *, cbm::io_kcomm_t *)
 Connects the root system to the model state (soil, microclimate, water, vegetation).
 
void reset (MoBiLE_Plant *)
 Resets rooting depth, fine root mass and the fine root distribution across soil layers of a plant to zero.
 
void set_rooting_depth (unsigned int &, MoBiLE_Plant *, double, double _max_rooting_depth=invalid_dbl)
 Sets the rooting depth, limited by a given maximum or, if none is given, by the species parameter ZRTMC, and determines the number of rooted layers.
 
void update_root_fraction_sigmoid (double, unsigned int, double, double, double, double, MoBiLE_Plant *)
 Updates the fine root distribution of a plant with the sigmoid shape (Sigmoid root distribution).
 
template<class _S>
void update_root_fraction_sigmoid (double, unsigned int, double, double, double, double, _S _fFrt_sl, unsigned int nb_layers)
 Sigmoid root distribution applied to an arbitrary array of root fractions.
 
void update_root_fraction_exponential (double, unsigned int, double, MoBiLE_Plant *)
 Updates the fine root distribution of a plant with the exponential shape (Exponential root distribution).
 
template<class _S>
void update_root_fraction_exponential (double, unsigned int, double, _S _fFrt_sl, unsigned int nb_layers)
 Exponential root distribution applied to an arbitrary array of root fractions.
 
void update_roots_static (const double, unsigned int &, MoBiLE_Plant *, ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > &, double)
 Root growth of one time step with the static approach (Static root growth model).
 
void specific_root_length (unsigned int const &, MoBiLE_Plant *, lvector_t< double > &)
 Specific root length of every evaluated layer (Root length and density).
 
void reduce_root_system (unsigned int &, MoBiLE_Plant *, double)
 Removes root mass uniformly from all layers (respiration, exudation); the root distribution stays the same and root length is reduced accordingly.
 
void reduce_root_system (unsigned int &, MoBiLE_Plant *, lvector_t< double >)
 Removes root mass from individual layers (e.g., senescence depending on layer conditions); root length, total root mass and the root distribution are updated.
 
void update_rootlength (unsigned int &, MoBiLE_Plant *, double)
 Root length change for a root mass change of the whole root system, which is distributed over the layers according to the current fractions (see Root length and density).
 
void update_rootlength (unsigned int &, MoBiLE_Plant *, lvector_t< double >)
 Root length change for root mass changes of individual layers (see Root length and density).
 
void update_roots_dynamic (const double, unsigned int &, MoBiLE_Plant *, double)
 Root growth of one time step with the dynamic approach (Dynamic root growth model).
 
lvector_t< double > root_restrictions_coarse_fragments (unsigned int)
 Root growth restriction by coarse fragments (stones) for every layer (Root growth restrictions).
 
lvector_t< double > root_restrictions_soil_strength (unsigned int)
 Root growth restriction by soil strength for every layer (Root growth restrictions).
 
lvector_t< double > root_restrictions_aeration (unsigned int, MoBiLE_Plant *)
 Root growth restriction by oxygen shortage for every layer (Root growth restrictions).
 
lvector_t< double > root_restrictions_temperature (unsigned int, MoBiLE_Plant *)
 Root growth restriction by soil temperature for every layer (Root growth restrictions).
 
void update_rooting_depth (const double, double &, unsigned int &, MoBiLE_Plant *)
 Increases the rooting depth by the restricted target increment (step 4 of the Dynamic root growth model) and updates the number of rooted layers.
 
void target_rooting_depth_increase (double &_rooting_depth_increase, unsigned int &_sl_min_no_roots, double const _dt_per_day, MoBiLE_Plant *const _p)
 Target increase of the rooting depth under optimum conditions (Target rooting depth).
 
unsigned int first_layer_below (double) const
 Number of rooted soil layers for a given rooting depth [m].
 
void nitrogen_uptake (unsigned int _deepest_rooted_layer, double &n_plant, double n_opt, double _fts_tot, lvector_t< double > _no3_sl, lvector_t< double > _no3_uptake_sl, lvector_t< double > _nh4_sl, lvector_t< double > _nh4_uptake_sl, lvector_t< double > _don_sl, lvector_t< double > _don_uptake_sl, lvector_t< double > _temp_sl, MoBiLE_Plant *)
 Uptake of NH4, NO3 and DON from the rooted layers (Nitrogen uptake).
 

Public Attributes

input_class_soillayers_t const * m_soillayers
 soil layer input (number of layers)
 
LD_PlantFunctions m_pf
 plant functions (e.g., temperature dependency of nitrogen uptake)
 
substate_soilchemistry_t & sc_
 soil state (layer depths and thicknesses, stones, density, texture)
 
substate_microclimate_t & mc_
 microclimate state (soil temperature)
 
substate_physiology_t & ph_
 physiology state
 
substate_watercycle_t & wc_
 water state (water content, wilting point, field capacity)
 
MoBiLE_PlantVegetation * m_veg
 vegetation
 

Detailed Description

Fine root system used by PlaMox and, for the distribution functions and nitrogen uptake, by other physiology modules (see Root system).

Member Function Documentation

◆ first_layer_below()

unsigned int ldndc::RootSystemDNDC::first_layer_below ( double _rooting_depth) const

Number of rooted soil layers for a given rooting depth [m].

Number of rooted soil layers for a given rooting depth, i.e., the index of the first soil layer that does not hold any roots.

Layer depths are not commensurate with the root elongation, so the layer that contains the root tip counts as rooted. Used for the target and the actual rooting depth alike.

Parameters
_rooting_depthrooting depth [m]
Returns
number of rooted layers, at most the number of soil layers
529{
530 for ( size_t sl = 0; sl < m_soillayers->soil_layer_cnt(); ++sl)
531 {
532 if ( cbm::flt_greater( sc_.depth_sl[sl], _rooting_depth))
533 {
534 return static_cast< unsigned int >( sl+1);
535 }
536 }
537 return static_cast< unsigned int >( m_soillayers->soil_layer_cnt());
538}
input_class_soillayers_t const * m_soillayers
soil layer input (number of layers)
Definition ld_rootsystem.h:218
substate_soilchemistry_t & sc_
soil state (layer depths and thicknesses, stones, density, texture)
Definition ld_rootsystem.h:223

References m_soillayers, and sc_.

Referenced by set_rooting_depth(), target_rooting_depth_increase(), and update_rooting_depth().

Here is the caller graph for this function:

◆ nitrogen_uptake()

void ldndc::RootSystemDNDC::nitrogen_uptake ( unsigned int _deepest_rooted_layer,
double & _n_plant,
double _n_opt,
double _fts_tot,
lvector_t< double > _no3_sl,
lvector_t< double > _no3_uptake_sl,
lvector_t< double > _nh4_sl,
lvector_t< double > _nh4_uptake_sl,
lvector_t< double > _don_sl,
lvector_t< double > _don_uptake_sl,
lvector_t< double > _temp_sl,
MoBiLE_Plant * _vt )
virtual

Uptake of NH4, NO3 and DON from the rooted layers (Nitrogen uptake).

Parameters
_deepest_rooted_layerindex of the deepest rooted layer (inclusive)
_n_plantplant nitrogen [kgN m-2] (updated)
_n_optoptimum plant nitrogen [kgN m-2]
_fts_totlength of the time step [d]
_no3_slnitrate of every layer [kgN m-2] (updated)
_no3_uptake_slnitrate uptake of every layer [kgN m-2] (accumulated)
_nh4_slammonium of every layer [kgN m-2] (updated)
_nh4_uptake_slammonium uptake of every layer [kgN m-2] (accumulated)
_don_sldissolved organic nitrogen of every layer [kgN m-2] (updated)
_don_uptake_slDON uptake of every layer [kgN m-2] (accumulated)
_temp_slsoil temperature of every layer [oC]
_vtplant

Implements ldndc::BaseRootSystemDNDC.

1252{
1253 /* Nitrogen status update */
1254 double const n_demand( _n_opt - _n_plant);
1255
1256 if ( cbm::flt_greater_zero( n_demand))
1257 {
1258 double n_up_total(0.0);
1259 for (size_t sl = 0; sl <= _deepest_rooted_layer; sl++)
1260 {
1261 double const mFrt( cbm::bound_min( 0.01, _vt->mFrt) * _vt->fFrt_sl[sl]);
1262 if ( !cbm::flt_greater_zero( mFrt))
1263 {
1264 break;
1265 }
1266
1267 // temperature dependency
1268 double const fact_t( m_pf.nitrogen_uptake_temperature_dependency(
1269 0.8 * (*_vt)->TLIMIT(),
1270 1.2 * (*_vt)->TLIMIT(),
1271 _temp_sl[sl]));
1272
1273 // potential uptake of NH4, NO3 and DON
1274 double const nh4_up( cbm::bound_max( (*_vt)->US_NH4() * mFrt * fact_t * _fts_tot
1275 * _nh4_sl[sl] / (_nh4_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1276 0.9 * _nh4_sl[sl]));
1277 double const no3_up( cbm::bound_max( (*_vt)->US_NO3() * mFrt * fact_t * _fts_tot
1278 * _no3_sl[sl] / (_no3_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1279 0.9 * _no3_sl[sl] ));
1280 double const don_up( cbm::bound_max( (*_vt)->US_NO3() * mFrt * fact_t * _fts_tot
1281 * _don_sl[sl] / (_don_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1282 0.9 * _don_sl[sl]));
1283 n_up_total += nh4_up + no3_up + don_up;
1284 }
1285
1286
1287 double const scale( ( n_up_total > 0.0) ? cbm::bound_max(n_demand / n_up_total, 1.0) : 0.0);
1288
1289 if ( cbm::flt_greater_zero( scale))
1290 {
1291 for (size_t sl = 0; sl <= _deepest_rooted_layer; sl++)
1292 {
1293 double const mFrt( cbm::bound_min( 0.01, _vt->mFrt) * _vt->fFrt_sl[sl]);
1294
1295 if ( !cbm::flt_greater_zero( mFrt))
1296 {
1297 break;
1298 }
1299
1300 double const fact_t( m_pf.nitrogen_uptake_temperature_dependency(
1301 0.8 * (*_vt)->TLIMIT(),
1302 1.2 * (*_vt)->TLIMIT(),
1303 _temp_sl[sl]));
1304
1305 double const nh4_up( scale * cbm::bound_max( (*_vt)->US_NH4() * mFrt * fact_t * _fts_tot
1306 * _nh4_sl[sl] / (_nh4_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1307 0.9 * _nh4_sl[sl]));
1308 double const no3_up( scale * cbm::bound_max( (*_vt)->US_NO3() * mFrt * fact_t * _fts_tot
1309 * _no3_sl[sl] / (_no3_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1310 0.9 * _no3_sl[sl] ));
1311 double const don_up( scale * cbm::bound_max( (*_vt)->US_NO3() * mFrt * fact_t * _fts_tot
1312 * _don_sl[sl] / (_don_sl[sl] + (*_vt)->K_MM_NITROGEN_UPTAKE() * sc_.h_sl[sl]),
1313 0.9 * _don_sl[sl]));
1314 if ( cbm::flt_greater_zero( nh4_up))
1315 {
1316 _nh4_uptake_sl[sl] += nh4_up;
1317 _nh4_sl[sl] -= nh4_up;
1318 if ( _nh4_sl[sl] < 0.0)
1319 {
1320 _nh4_sl[sl] = 0.0;
1321 }
1322 _n_plant += nh4_up;
1323 }
1324
1325 if ( cbm::flt_greater_zero( no3_up))
1326 {
1327 _no3_uptake_sl[sl] += no3_up;
1328 _no3_sl[sl] -= no3_up;
1329 if ( _no3_sl[sl] < 0.0)
1330 {
1331 _no3_sl[sl] = 0.0;
1332 }
1333 _n_plant += no3_up;
1334 }
1335
1336 if ( cbm::flt_greater_zero(don_up))
1337 {
1338 _don_uptake_sl[sl] += don_up;
1339 _don_sl[sl] -= don_up;
1340 if ( _don_sl[sl] < 0.0)
1341 {
1342 _don_sl[sl] = 0.0;
1343 }
1344 _n_plant += don_up;
1345 }
1346 }
1347 }
1348 }
1349}
LD_PlantFunctions m_pf
plant functions (e.g., temperature dependency of nitrogen uptake)
Definition ld_rootsystem.h:221

References m_pf, and sc_.

◆ reduce_root_system() [1/2]

void ldndc::RootSystemDNDC::reduce_root_system ( unsigned int & _sl_below_roots,
MoBiLE_Plant * _p,
double _delta_dw_frt )
virtual

Removes root mass uniformly from all layers (respiration, exudation); the root distribution stays the same and root length is reduced accordingly.

Parameters
_sl_below_rootsnumber of rooted soil layers
_pplant
_delta_dw_frtroot mass loss [kgDW m-2] (> 0)

Implements ldndc::BaseRootSystemDNDC.

1167{
1168 //layer specific root length reduction
1169 update_rootlength( _sl_below_roots, _p, -_delta_dw_frt);
1170 //root mass reduction
1171 _p->mFrt -= _delta_dw_frt;
1172}
void update_rootlength(unsigned int &, MoBiLE_Plant *, double)
Root length change for a root mass change of the whole root system, which is distributed over the lay...
Definition ld_rootsystem.cpp:1099

References update_rootlength().

Here is the call graph for this function:

◆ reduce_root_system() [2/2]

void ldndc::RootSystemDNDC::reduce_root_system ( unsigned int & _sl_below_roots,
MoBiLE_Plant * _p,
lvector_t< double > _delta_dw_frt_sl )
virtual

Removes root mass from individual layers (e.g., senescence depending on layer conditions); root length, total root mass and the root distribution are updated.

Parameters
_sl_below_rootsnumber of rooted soil layers
_pplant
_delta_dw_frt_slroot mass loss of every rooted layer [kgDW m-2] (> 0)

Implements ldndc::BaseRootSystemDNDC.

1188{
1189 //layer specific root length reduction
1190 update_rootlength( _sl_below_roots, _p, -_delta_dw_frt_sl);
1191
1192 //root mass reduction
1193 double const dw_frt_new( _p->mFrt - _delta_dw_frt_sl.sum());
1194 for ( size_t sl = 0; sl < _sl_below_roots; ++sl)
1195 {
1196 _p->fFrt_sl[sl] = (_p->mFrt * _p->fFrt_sl[sl] - _delta_dw_frt_sl[sl]) / dw_frt_new;
1197 }
1198 _p->mFrt = dw_frt_new;
1199}

References update_rootlength().

Here is the call graph for this function:

◆ reset()

void ldndc::RootSystemDNDC::reset ( MoBiLE_Plant * _p)
virtual

Resets rooting depth, fine root mass and the fine root distribution across soil layers of a plant to zero.

Note
Root length (rootlength_sl) is not reset here.

Implements ldndc::BaseRootSystemDNDC.

77{
78 _p->rooting_depth = 0.0;
79 _p->mFrt = 0.0;
80 for ( size_t sl = 0; sl < _p->nb_soillayers(); ++sl)
81 {
82 _p->fFrt_sl[sl] = 0.0;
83 }
84}

◆ root_restrictions_aeration()

lvector_t< double > ldndc::RootSystemDNDC::root_restrictions_aeration ( unsigned int _sl_no_roots,
MoBiLE_Plant * _p )
virtual

Root growth restriction by oxygen shortage for every layer (Root growth restrictions).

Parameters
_sl_no_rootsnumber of soil layers to evaluate
_pplant
Returns
restriction for every evaluated layer [0-1]

Implements ldndc::BaseRootSystemDNDC.

752{
753 lvector_t< double > layer_restrictions( _sl_no_roots, 1.0);
754 // new version employing O2 content in soil directly rather than water filled pore space
755 for( unsigned int sl = 0; sl < _sl_no_roots; ++sl)
756 {
757 if ( !cbm::flt_greater_zero( (*_p)->RS_CONDUCT()))
758 {
759 layer_restrictions[sl] = cbm::bound_min( 0.0, 1.0 - _p->hypoxia_sl[sl]);
760 }
761 }
762
763 return layer_restrictions;
764}

Referenced by update_roots_dynamic().

Here is the caller graph for this function:

◆ root_restrictions_coarse_fragments()

lvector_t< double > ldndc::RootSystemDNDC::root_restrictions_coarse_fragments ( unsigned int _sl_no_roots)
virtual

Root growth restriction by coarse fragments (stones) for every layer (Root growth restrictions).

Parameters
_sl_no_rootsnumber of soil layers to evaluate
Returns
restriction for every evaluated layer [0-1]

Implements ldndc::BaseRootSystemDNDC.

629{
630 lvector_t< double > layer_restrictions( _sl_no_roots, 1.0);
631 for( unsigned int sl = 0; sl < _sl_no_roots; ++sl)
632 {
633 layer_restrictions[sl] = 1.0 - sc_.stone_frac_sl[sl];
634 }
635 return layer_restrictions;
636}

References sc_.

Referenced by update_roots_dynamic().

Here is the caller graph for this function:

◆ root_restrictions_soil_strength()

lvector_t< double > ldndc::RootSystemDNDC::root_restrictions_soil_strength ( unsigned int _sl_no_roots)
virtual

Root growth restriction by soil strength for every layer (Root growth restrictions).

Parameters
_sl_no_rootsnumber of soil layers to evaluate
Returns
restriction for every evaluated layer [0-1]

Implements ldndc::BaseRootSystemDNDC.

678{
679 lvector_t< double > layer_restrictions( _sl_no_roots, 1.0);
680 for( unsigned int sl = 0; sl < _sl_no_roots; ++sl)
681 {
682 // bulk density
683 // estimate limits via sand content (without stones)
684 double const bdo( 1.1 + 0.5 * sc_.sand_sl[sl]);
685 double const bdx( 1.6 + 0.4 * sc_.sand_sl[sl]);
686 // Reduction due to stones is already contained in coarse fragments.
687 double const density_without_stones( (sc_.dens_sl[sl] - sc_.stone_frac_sl[sl] * cbm::DMIN) / (1. - sc_.stone_frac_sl[sl]));
688 if( cbm::flt_greater( density_without_stones, bdo))
689 {
690 if( cbm::flt_greater( density_without_stones, bdx))
691 {
692 layer_restrictions[sl] = 0.0;
693 }
694 else
695 {
696 layer_restrictions[sl] = (bdx - density_without_stones)/(bdx-bdo);
697 }
698 }
699 // take water content into account
700 double thetaf = 99.0;
701 if( cbm::flt_greater( wc_.wc_wp_sl[sl], wc_.wc_sl[sl]))
702 {
703 thetaf = 0.0;
704 }
705 else
706 {
707 if( cbm::flt_greater_equal( wc_.wc_fc_sl[sl], wc_.wc_sl[sl]))
708 {
709 thetaf = (wc_.wc_sl[sl] - wc_.wc_wp_sl[sl])/(wc_.wc_fc_sl[sl] - wc_.wc_wp_sl[sl]);
710 }
711 else
712 {
713 thetaf = 1.0;
714 }
715 }
716
717 layer_restrictions[sl] *= sin( cbm::PI/2. * thetaf);
718 if( !cbm::flt_in_range_lu( 0., layer_restrictions[sl], 1.))
719 {
720 LOGERROR( "layerrestriction soil strength in layer ", sl, " < 0 or > 1: ", layer_restrictions[sl]);
721 }
722 }
723
724 return layer_restrictions;
725}
substate_watercycle_t & wc_
water state (water content, wilting point, field capacity)
Definition ld_rootsystem.h:229

References sc_, and wc_.

Referenced by update_roots_dynamic().

Here is the caller graph for this function:

◆ root_restrictions_temperature()

lvector_t< double > ldndc::RootSystemDNDC::root_restrictions_temperature ( unsigned int _sl_no_roots,
MoBiLE_Plant *  )
virtual

Root growth restriction by soil temperature for every layer (Root growth restrictions).

Parameters
_sl_no_rootsnumber of soil layers to evaluate
Returns
restriction for every evaluated layer [0-1]

Implements ldndc::BaseRootSystemDNDC.

797{
798 double const t_min( 0.0);//(*_p)->TLIMIT());
799 double const t_max( 45.0);
800 lvector_t< double > layer_restrictions( _sl_no_roots, 1.0);
801 for( unsigned int sl = 0; sl < _sl_no_roots; ++sl)
802 {
803 if( cbm::flt_greater( t_min, mc_.temp_sl[sl]))
804 {
805 layer_restrictions[sl] = 0.0;
806 }
807 else
808 {
809 if( cbm::flt_greater( t_max, mc_.temp_sl[sl]))
810 {
811 double const Topt( t_min + (t_max - t_min) / 2.0);
812 layer_restrictions[sl] = sin( cbm::PI / 2.0 * (mc_.temp_sl[sl] - t_min) /
813 (Topt - t_min));
814 }
815 else
816 {
817 layer_restrictions[sl] = 0.0;
818 }
819 }
820 if( !cbm::flt_in_range_lu( 0., layer_restrictions[sl], 1.))
821 {
822 LOGERROR( "layerrestriction temperature in layer ", sl, " < 0 or > 1: ", layer_restrictions[sl]);
823 }
824 }
825
826 return layer_restrictions;
827}
substate_microclimate_t & mc_
microclimate state (soil temperature)
Definition ld_rootsystem.h:225

References mc_.

Referenced by update_roots_dynamic().

Here is the caller graph for this function:

◆ set_rooting_depth()

void ldndc::RootSystemDNDC::set_rooting_depth ( unsigned int & _root_q_vt,
MoBiLE_Plant * _p,
double _rooting_depth,
double _max_rooting_depth = invalid_dbl )
virtual

Sets the rooting depth, limited by a given maximum or, if none is given, by the species parameter ZRTMC, and determines the number of rooted layers.

The number of rooted layers follows the same definition as in the dynamic root model (first_layer_below()): the layer that contains the root tip is rooted; if the rooting depth reaches the bottom of the soil profile, all layers are rooted. The rooting depth itself is not limited by the soil depth.

Used by ArableDNDC, GrasslandDNDC and Oryza2000.

Parameters
_root_q_vtnumber of rooted soil layers (output)
_pplant
_rooting_depthnew rooting depth [m]
_max_rooting_depthoptional maximum rooting depth [m]

Implements ldndc::BaseRootSystemDNDC.

585{
586 if ( cbm::is_valid( _max_rooting_depth))
587 {
588 _p->rooting_depth = ( _rooting_depth > _max_rooting_depth) ? _max_rooting_depth : _rooting_depth;
589 }
590 else
591 {
592 _p->rooting_depth = ( _rooting_depth > (*_p)->ZRTMC()) ? (*_p)->ZRTMC() : _rooting_depth;
593 }
594
595 if ( cbm::flt_equal_zero( _p->rooting_depth))
596 {
597 _root_q_vt = 0u;
598 }
599 else
600 {
601 unsigned int const layer_cnt( static_cast< unsigned int >( std::min( _p->nb_soillayers(),
602 static_cast<size_t>(m_soillayers->soil_layer_cnt()))));
603 _root_q_vt = std::min( first_layer_below( _p->rooting_depth), layer_cnt);
604 }
605}
unsigned int first_layer_below(double) const
Number of rooted soil layers for a given rooting depth [m].
Definition ld_rootsystem.cpp:528

References first_layer_below(), and m_soillayers.

Here is the call graph for this function:

◆ specific_root_length()

void ldndc::RootSystemDNDC::specific_root_length ( unsigned int const & _sl_below_roots,
MoBiLE_Plant * _p,
lvector_t< double > & specifific_root_length_sl )
virtual

Specific root length of every evaluated layer (Root length and density).

Parameters
_sl_below_rootsnumber of layers to evaluate \( n \)
_pplant
specifific_root_length_slspecific root length of every evaluated layer [m kgDW-1] (output)

Implements ldndc::BaseRootSystemDNDC.

1075{
1076 for ( size_t sl = 0; sl < _sl_below_roots; ++sl)
1077 {
1078 double const srl_min( (*_p)->SRL_MAX() * (1.0 - (*_p)->SRL_DECLINE()));
1079 double const scale(cbm::bound( 0.0, 1.0 - sc_.depth_sl[sl] / sc_.depth_sl[_sl_below_roots-1], 1.0));
1080 // GS = growth stage elem [0,1]
1081 specifific_root_length_sl[sl] = (*_p)->SRL_MAX() - _p->dvsFlush * ((*_p)->SRL_MAX() - srl_min) * scale;
1082 }
1083}

References sc_.

Referenced by update_roots_dynamic(), and update_roots_static().

Here is the caller graph for this function:

◆ target_rooting_depth_increase()

void ldndc::RootSystemDNDC::target_rooting_depth_increase ( double & _rooting_depth_increase,
unsigned int & _sl_min_no_roots,
double const _dt_per_day,
MoBiLE_Plant *const _p )
virtual

Target increase of the rooting depth under optimum conditions (Target rooting depth).

Parameters
_rooting_depth_increasetarget increase of the rooting depth [m] (output)
_sl_min_no_rootsnumber of rooted layers at the target depth (output)
_dt_per_daylength of the time step [d]
_pplant

Implements ldndc::BaseRootSystemDNDC.

495{
496 // growth: currently linear as in Jones 1991
497 // a) similar to conventional model
498 _rooting_depth_increase = (*_p)->FRT_DGR_MAX() * _dt_per_day;
499 // b) as suggested by Jones
500 // todo: what is deltaGDD?
501 //~ target_rooting_depth_increase = (*_vt)->FRT_DGR_MAX() * (_vt->growing_degree_days - GDD(t-1)???) / (*_vt)->GDD_ROOTS_GROWN();
502
503 bool const gdd_ok( cbm::flt_greater( (*_p)->GDD_ROOTS_GROWN(), _p->growing_degree_days));
504 if ( !gdd_ok)
505 {
506 _rooting_depth_increase = 0.0;
507 }
508 _rooting_depth_increase = cbm::bound( 0.0, _rooting_depth_increase, (*_p)->ZRTMC() - _p->rooting_depth);
509
510 // first non-rooted layer (same definition as in update_rooting_depth)
511 _sl_min_no_roots = first_layer_below( _p->rooting_depth + _rooting_depth_increase);
512}

References first_layer_below().

Referenced by update_roots_dynamic().

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

◆ update_root_fraction_exponential() [1/2]

template<class _S>
void ldndc::RootSystemDNDC::update_root_fraction_exponential ( double _adaption_rate,
unsigned int _deepest_rooted_layer,
double _fact_exp,
_S _fFrt_sl,
unsigned int nb_layers )

Exponential root distribution applied to an arbitrary array of root fractions.

Exponential root distribution (Exponential root distribution) applied to an arbitrary array of root fractions.

Parameters
_adaption_rateadaption rate \( a \) [0-1]
_deepest_rooted_layernumber of rooted soil layers \( n_r \)
_fact_exp\( k \) [m-1]
_fFrt_slroot fractions to update
nb_layerssize of _fFrt_sl; entries of non-rooted layers are set to 0
1003{
1004 ldndc_kassert( cbm::flt_greater_equal( 1.0, _adaption_rate));
1005
1006 double fFrt_sum( 0.0);
1007 for ( size_t sl = 0; sl < _deepest_rooted_layer; ++sl)
1008 {
1009 double const fFrt_target( exp(-_fact_exp * sc_.depth_sl[sl]) * sc_.h_sl[sl]);
1010 _fFrt_sl[sl] -= (_fFrt_sl[sl] - fFrt_target) * _adaption_rate;
1011 _fFrt_sl[sl] = cbm::bound_min( 0.0, _fFrt_sl[sl]);
1012 fFrt_sum += _fFrt_sl[sl];
1013 }
1014
1015 if ( cbm::flt_greater_zero( fFrt_sum))
1016 {
1017 for ( size_t sl = 0; sl < _deepest_rooted_layer; ++sl)
1018 {
1019 _fFrt_sl[sl] /= fFrt_sum;
1020 }
1021 for ( size_t sl = _deepest_rooted_layer; sl < nb_layers; ++sl)
1022 {
1023 _fFrt_sl[sl] = 0.0;
1024 }
1025 }
1026 else
1027 {
1028 for ( size_t sl = 0; sl < nb_layers; ++sl)
1029 {
1030 _fFrt_sl[sl] = 0.0;
1031 }
1032 }
1033}

References sc_.

◆ update_root_fraction_exponential() [2/2]

void ldndc::RootSystemDNDC::update_root_fraction_exponential ( double _adaption_rate,
unsigned int _deepest_rooted_layer,
double _fact_exp,
MoBiLE_Plant * _vt )
virtual

Updates the fine root distribution of a plant with the exponential shape (Exponential root distribution).

Parameters
_adaption_rateadaption rate \( a \) [0-1]
_deepest_rooted_layernumber of rooted soil layers \( n_r \)
_fact_exp\( k \) [m-1]
_vtplant (its fFrt_sl is updated)

Implements ldndc::BaseRootSystemDNDC.

980{
981 //not needed if parent function is called with MoBiLE_Plant*
982 update_root_fraction_exponential( _adaption_rate, _deepest_rooted_layer, _fact_exp, _vt->fFrt_sl, _vt->nb_soillayers());
983}
void update_root_fraction_exponential(double, unsigned int, double, MoBiLE_Plant *)
Updates the fine root distribution of a plant with the exponential shape (Exponential root distributi...
Definition ld_rootsystem.cpp:976

References update_root_fraction_exponential().

Referenced by update_root_fraction_exponential(), and update_roots_dynamic().

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

◆ update_root_fraction_sigmoid() [1/2]

template<class _S>
void ldndc::RootSystemDNDC::update_root_fraction_sigmoid ( double _adaption_rate,
unsigned int _deepest_rooted_layer,
double _root_min,
double _root_max,
double _root_width,
double _root_height,
_S _fFrt_sl,
unsigned int _nb_layers )

Sigmoid root distribution applied to an arbitrary array of root fractions.

Sigmoid root distribution (Sigmoid root distribution) applied to an arbitrary array of root fractions.

Parameters
_adaption_rateadaption rate \( a \) [0-1]
_deepest_rooted_layernumber of rooted soil layers \( n_r \)
_root_min\( r_{min} \) [-]
_root_max\( r_{max} \), depth of maximum root density [cm]
_root_width\( r_{width} \) [cm2]
_root_height\( r_{height} \) [-]
_fFrt_slroot fractions to update
_nb_layerssize of _fFrt_sl; entries of non-rooted layers are set to 0
913{
914 ldndc_kassert( cbm::flt_greater_equal( 1.0, _adaption_rate));
915
916 double fFrt_sum( 0.0);
917 for ( size_t sl = 0; sl < _deepest_rooted_layer; ++sl)
918 {
919 double const fFrt_target( (exp( -( cbm::sqr( (sc_.depth_sl[sl] * cbm::CM_IN_M) - _root_max) / _root_width))
920 / _root_height + _root_min)
921 * sc_.h_sl[sl]);
922 _fFrt_sl[sl] -= (_fFrt_sl[sl] - fFrt_target) * _adaption_rate;
923 _fFrt_sl[sl] = cbm::bound_min( 0.0, _fFrt_sl[sl]);
924 fFrt_sum += _fFrt_sl[sl];
925 }
926
927 if ( cbm::flt_greater_zero( fFrt_sum))
928 {
929 for ( size_t sl = 0; sl < _deepest_rooted_layer; ++sl)
930 {
931 _fFrt_sl[sl] /= fFrt_sum;
932 }
933 for ( size_t sl = _deepest_rooted_layer; sl < _nb_layers; ++sl)
934 {
935 _fFrt_sl[sl] = 0.0;
936 }
937 }
938 else
939 {
940 for ( size_t sl = 0; sl < _nb_layers; ++sl)
941 {
942 _fFrt_sl[sl] = 0.0;
943 }
944 }
945}

References sc_.

◆ update_root_fraction_sigmoid() [2/2]

void ldndc::RootSystemDNDC::update_root_fraction_sigmoid ( double _adaption_rate,
unsigned int _deepest_rooted_layer,
double _root_min,
double _root_max,
double _root_width,
double _root_height,
MoBiLE_Plant * _vt )
virtual

Updates the fine root distribution of a plant with the sigmoid shape (Sigmoid root distribution).

Parameters
_adaption_rateadaption rate \( a \) [0-1]
_deepest_rooted_layernumber of rooted soil layers \( n_r \)
_root_min\( r_{min} \) [-]
_root_max\( r_{max} \), depth of maximum root density [cm]
_root_width\( r_{width} \) [cm2]
_root_height\( r_{height} \) [-]
_vtplant (its fFrt_sl is updated)

Implements ldndc::BaseRootSystemDNDC.

878{
879 update_root_fraction_sigmoid( _adaption_rate,
880 _deepest_rooted_layer,
881 _root_min,
882 _root_max,
883 _root_width,
884 _root_height,
885 _vt->fFrt_sl,
886 _vt->nb_soillayers());
887}
void update_root_fraction_sigmoid(double, unsigned int, double, double, double, double, MoBiLE_Plant *)
Updates the fine root distribution of a plant with the sigmoid shape (Sigmoid root distribution).
Definition ld_rootsystem.cpp:871

References update_root_fraction_sigmoid().

Referenced by update_root_fraction_sigmoid(), and update_roots_dynamic().

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

◆ update_rooting_depth()

void ldndc::RootSystemDNDC::update_rooting_depth ( const double target_rooting_depthincrease,
double & growthrestriction,
unsigned int & root_q_vt_,
MoBiLE_Plant * _p )
virtual

Increases the rooting depth by the restricted target increment (step 4 of the Dynamic root growth model) and updates the number of rooted layers.

Parameters
target_rooting_depthincreasetarget increase under optimum conditions [m]
growthrestrictioncombined restriction at the root front [0-1]
root_q_vt_number of rooted soil layers (output)
_pplant

Implements ldndc::BaseRootSystemDNDC.

556{
557 _p->rooting_depth = cbm::bound_max( _p->rooting_depth + target_rooting_depthincrease * growthrestriction, (*_p)->ZRTMC());
558
559 root_q_vt_ = first_layer_below( _p->rooting_depth);
560}

References first_layer_below().

Referenced by update_roots_dynamic().

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

◆ update_rootlength() [1/2]

void ldndc::RootSystemDNDC::update_rootlength ( unsigned int & _sl_below_roots,
MoBiLE_Plant * _p,
double _delta_dw_frt )
virtual

Root length change for a root mass change of the whole root system, which is distributed over the layers according to the current fractions (see Root length and density).

Must be called before the root mass is changed.

Parameters
_sl_below_rootsnumber of rooted soil layers
_pplant
_delta_dw_frtroot mass change of the whole root system [kgDW m-2] (< 0 for losses)

Implements ldndc::BaseRootSystemDNDC.

1102{
1103 lvector_t< double > delta_dw_frt_sl( _sl_below_roots, 0.0);
1104 for ( size_t sl = 0; sl < _sl_below_roots; ++sl)
1105 {
1106 delta_dw_frt_sl[sl] = _delta_dw_frt * _p->fFrt_sl[sl];
1107 }
1108 update_rootlength( _sl_below_roots, _p, delta_dw_frt_sl);
1109}

References update_rootlength().

Referenced by reduce_root_system(), reduce_root_system(), and update_rootlength().

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

◆ update_rootlength() [2/2]

void ldndc::RootSystemDNDC::update_rootlength ( unsigned int & _sl_below_roots,
MoBiLE_Plant * _p,
lvector_t< double > _delta_dw_frt_sl )
virtual

Root length change for root mass changes of individual layers (see Root length and density).

Must be called before the root mass is changed. The mean specific root length of each layer is kept and bounded by SRL_MAX with respect to the root mass after the change; no lower bound is applied, since it would undo the SRL reduction of the Dynamic root growth model. Layers with root mass but without root length get \( L_i = SRL_{min} \, m_i \).

Parameters
_sl_below_rootsnumber of rooted soil layers
_pplant
_delta_dw_frt_slroot mass change of every rooted layer [kgDW m-2] (< 0 for losses)

Implements ldndc::BaseRootSystemDNDC.

1131{
1132 for ( size_t sl = 0; sl < _sl_below_roots; ++sl)
1133 {
1134 double const srl_min( (*_p)->SRL_MAX() * (1.0 - (*_p)->SRL_DECLINE()));
1135 double const dw_frt_sl( _p->mFrt * _p->fFrt_sl[sl]);
1136 double const dw_frt_sl_new( cbm::bound_min( 0.0, dw_frt_sl + _delta_dw_frt_sl[sl]));
1137 if ( cbm::flt_greater_zero( _p->rootlength_sl[sl]) &&
1138 cbm::flt_greater_zero( dw_frt_sl))
1139 {
1140 // determine average SRL in this soil layer
1141 double const srl_mean( _p->rootlength_sl[sl] / dw_frt_sl);
1142 _p->rootlength_sl[sl] = cbm::bound( 0.0,
1143 srl_mean * dw_frt_sl_new,
1144 (*_p)->SRL_MAX() * dw_frt_sl_new);
1145 }
1146 else
1147 {
1148 _p->rootlength_sl[sl] = srl_min * dw_frt_sl_new;
1149 }
1150 }
1151}

◆ update_roots_dynamic()

void ldndc::RootSystemDNDC::update_roots_dynamic ( const double FTS_TOT_,
unsigned int & _sl_min_no_roots,
MoBiLE_Plant * _p,
double _dw_frt_growth )
virtual

Root growth of one time step with the dynamic approach (Dynamic root growth model).

Parameters
FTS_TOT_length of the time step [d]
_sl_min_no_rootsnumber of rooted soil layers (updated)
_pplant; mFrt already includes the new growth
_dw_frt_growthfine root growth of this time step [kgDW m-2]

Implements ldndc::BaseRootSystemDNDC.

234{
235 unsigned int sl_min_no_roots_tminusone( _sl_min_no_roots);
236
237 // dry weight of fine roots before growth
238 // (not considered so far for root length)
239 double const dw_frt_tminusone( cbm::bound_min( 0.0, _p->mFrt - _dw_frt_growth));
240
241 // dry weight of fine roots that can be redistributed
242 double const dw_frt_redistribute( (*_p)->REDISTRIBUTION_ROOT() * FTS_TOT_ * dw_frt_tminusone);
243 double const dw_frt_redistribute_and_growth( dw_frt_redistribute + _dw_frt_growth);
244
245 // reduce root length by redistributed part (proportionally in all layers, i.e., mean SRL per layer is kept)
246 if ( cbm::flt_greater_zero( dw_frt_tminusone))
247 {
248 double const f_remain( cbm::bound( 0.0, 1.0 - dw_frt_redistribute / dw_frt_tminusone, 1.0));
249 for ( size_t sl = 0; sl < sl_min_no_roots_tminusone; ++sl)
250 {
251 _p->rootlength_sl[sl] *= f_remain;
252 }
253 }
254
255 // root mass in every layer before growth and redistribution
256 lvector_t< double > mFrt_sl_tminusone( sl_min_no_roots_tminusone, 0.0);
257 for ( size_t sl = 0; sl < sl_min_no_roots_tminusone; ++sl)
258 {
259 mFrt_sl_tminusone[sl] = _p->fFrt_sl[sl] * cbm::bound_min( 0.0, _p->mFrt - _dw_frt_growth - dw_frt_redistribute);
260 }
261
262 // target rooting depth (step 2) and growth restrictions (step 3)
263 double delta_rooting_depth_target( 0.0);
264 unsigned int sl_min_no_roots_target( 0);
265 target_rooting_depth_increase( delta_rooting_depth_target,
266 sl_min_no_roots_target,
267 FTS_TOT_,
268 _p);
269
270 unsigned int const sl_restrictions( std::max( sl_min_no_roots_target, sl_min_no_roots_tminusone));
271 lvector_t< double > root_res_coarse_fragments_sl = root_restrictions_coarse_fragments( sl_restrictions);
272 lvector_t< double > root_res_soil_strength_sl = root_restrictions_soil_strength( sl_restrictions);
273 lvector_t< double > root_res_aeration_sl = root_restrictions_aeration( sl_restrictions, _p);
274 lvector_t< double > root_res_temperature_sl = root_restrictions_temperature( sl_restrictions, _p);
275
276 // actual rooting depth with restriction at the root front (step 4)
277 if( cbm::flt_greater_zero( dw_frt_redistribute_and_growth) && (sl_min_no_roots_target > 0))
278 {
279 unsigned int sl_max_roots( sl_min_no_roots_target-1);
280 double root_res_all( std::min( pow( std::min( {root_res_coarse_fragments_sl[sl_max_roots],
281 root_res_soil_strength_sl[sl_max_roots],
282 root_res_aeration_sl[sl_max_roots]}),
283 0.5),
284 root_res_temperature_sl[sl_max_roots]));
285
286 update_rooting_depth( delta_rooting_depth_target, root_res_all, _sl_min_no_roots, _p);
287 // actual depth never exceeds target depth, i.e., restrictions are available for all rooted layers
288 ldndc_kassert( _sl_min_no_roots <= sl_restrictions);
289 }
290
291 size_t const sl_min_no_roots_common( std::min( {_sl_min_no_roots,
292 sl_min_no_roots_tminusone,
293 sl_min_no_roots_target}));
294 size_t const sl_min_no_roots_max( std::max( {_sl_min_no_roots,
295 sl_min_no_roots_tminusone,
296 sl_min_no_roots_target}));
297
298 // root mass in every layer before new mass is placed
299 lvector_t< double > mFrt_sl( _sl_min_no_roots, 0.0);
300
301 // initialize with static part of old biomass
302 for (size_t sl = 0; sl < sl_min_no_roots_common; ++sl)
303 {
304 mFrt_sl[sl] = mFrt_sl_tminusone[sl];
305 }
306
307 if ( cbm::flt_greater_zero( dw_frt_redistribute_and_growth))
308 {
309 // placement of new root mass (step 5): optimum profile ...
310 lvector_t< double > fFrt_opt_sl( _sl_min_no_roots, 0.0);
311 if( cbm::flt_equal_zero( (*_p)->EXP_ROOT_DISTRIBUTION()))
312 {
313 update_root_fraction_sigmoid( 1.0, _sl_min_no_roots, 0.005, 10.0, 200.0, 10.0, fFrt_opt_sl, _sl_min_no_roots);
314 }
315 else
316 {
317 update_root_fraction_exponential( 1.0, _sl_min_no_roots, (*_p)->EXP_ROOT_DISTRIBUTION(), fFrt_opt_sl, _sl_min_no_roots);
318 }
319
320 // ... weighted with the restrictions to target masses ...
321 lvector_t< double > fFrt_opt_rest_sl( _sl_min_no_roots, 0.0);
322 lvector_t< double > mFrt_opt_rest_sl( _sl_min_no_roots, 0.0);
323 double normalize_opt_rest( 0.0);
324 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
325 {
326 double root_res_all( std::min( pow( std::min( {root_res_coarse_fragments_sl[sl],
327 root_res_soil_strength_sl[sl],
328 root_res_aeration_sl[sl]}),
329 0.5),
330 root_res_temperature_sl[sl]));
331 fFrt_opt_rest_sl[sl] = root_res_all * fFrt_opt_sl[sl];
332 normalize_opt_rest += fFrt_opt_rest_sl[sl];
333 }
334
335 if ( cbm::flt_greater_zero( normalize_opt_rest))
336 {
337 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
338 {
339 mFrt_opt_rest_sl[sl] = fFrt_opt_rest_sl[sl] / normalize_opt_rest * _p->mFrt; // mass(t=i)
340 }
341 }
342 else
343 {
344 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
345 {
346 mFrt_opt_rest_sl[sl] = fFrt_opt_sl[sl] * _p->mFrt; // mass(t=i)
347 }
348 }
349
350 // ... deficits (negative values set to 0, roots are removed elsewhere) ...
351 lvector_t< double > delta_mFrt_pot_sl( _sl_min_no_roots, 0.0);
352 double normalize_delta_mFrt_pot( 0.0);
353 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
354 {
355 delta_mFrt_pot_sl[sl] = cbm::bound_min( 0.0, mFrt_opt_rest_sl[sl] - mFrt_sl[sl]); // t=i - t=i-1 overall >0
356 normalize_delta_mFrt_pot += delta_mFrt_pot_sl[sl];
357 }
358
359 // ... and distribution of the new mass proportionally to the deficits
360 if( cbm::flt_greater_zero( normalize_delta_mFrt_pot))
361 {
362 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
363 {
364 mFrt_sl[sl] += dw_frt_redistribute_and_growth * delta_mFrt_pot_sl[sl] / normalize_delta_mFrt_pot; // t=i
365 }
366 }
367 else
368 {
369 // no potential growth (for instance, fully frozen ground)
370 // However, the root mass must currently go somewhere..
371 // todo: potentially better to allocate less C to roots
372 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
373 {
374 mFrt_sl[sl] += dw_frt_redistribute_and_growth * _p->fFrt_sl[sl];
375 }
376 }
377
378 // new root distribution
379 double mFrt_normalize( 0.0);
380 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
381 {
382 mFrt_normalize += mFrt_sl[sl];
383 }
384 if ( cbm::flt_greater_zero( mFrt_normalize))
385 {
386 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
387 {
388 _p->fFrt_sl[sl] = mFrt_sl[sl] / mFrt_normalize;
389 }
390 for ( size_t sl = _sl_min_no_roots; sl < _p->nb_soillayers(); ++sl)
391 {
392 _p->fFrt_sl[sl] = 0.0;
393 }
394 }
395 else if ( _sl_min_no_roots > 0)
396 {
397 for ( size_t sl = 0; sl < _sl_min_no_roots; ++sl)
398 {
399 _p->fFrt_sl[sl] = 1.0 / double(_sl_min_no_roots);
400 }
401 for ( size_t sl = _sl_min_no_roots; sl < _p->nb_soillayers(); ++sl)
402 {
403 _p->fFrt_sl[sl] = 0.0;
404 }
405 }
406 else
407 {
408 for ( size_t sl = _sl_min_no_roots; sl < _p->nb_soillayers(); ++sl)
409 {
410 _p->fFrt_sl[sl] = 0.0;
411 }
412 }
413 } // end if deltamass > 0
414
415 // root length (step 6): specific root length, reduced by stones and soil strength
416 lvector_t< double > specifific_root_length_sl( sl_min_no_roots_max, 0.0);
417 specific_root_length( sl_min_no_roots_max, _p, specifific_root_length_sl);
418 // use restrictions for SRL
419 for( size_t sl = 0; sl < sl_min_no_roots_target; ++sl)
420 {
421 specifific_root_length_sl[sl] /= (4.0 - 3.0 * std::min( root_res_coarse_fragments_sl[sl],
422 root_res_soil_strength_sl[sl]));
423 }
424
425 // root length in every soil layer
426 for ( size_t sl = 0; sl < sl_min_no_roots_common; ++sl)
427 {
428 double const deltamass_sl( mFrt_sl[sl] - mFrt_sl_tminusone[sl]);
429 if ( cbm::flt_greater_equal_zero( deltamass_sl))
430 {
431 _p->rootlength_sl[sl] = cbm::bound_max( _p->rootlength_sl[sl] + specifific_root_length_sl[sl] * deltamass_sl,
432 (*_p)->SRL_MAX() * mFrt_sl[sl]);
433 }
434 else if ( cbm::flt_greater_zero( mFrt_sl_tminusone[sl]))
435 {
436 double const srl_min( (*_p)->SRL_MAX() * (1.0 - (*_p)->SRL_DECLINE()));
437 double const srl_mean( _p->rootlength_sl[sl] / mFrt_sl_tminusone[sl]);
438 _p->rootlength_sl[sl] = cbm::bound_min( srl_min * mFrt_sl[sl],
439 _p->rootlength_sl[sl] + srl_mean * deltamass_sl);
440 }
441 else
442 {
443 _p->rootlength_sl[sl] = specifific_root_length_sl[sl] * mFrt_sl[sl];
444 }
445 }
446
447 for ( size_t sl = sl_min_no_roots_common; sl < _sl_min_no_roots; ++sl)
448 {
449 if ( cbm::flt_greater_zero( mFrt_sl[sl]))
450 {
451 _p->rootlength_sl[sl] = cbm::bound_max( _p->rootlength_sl[sl] + specifific_root_length_sl[sl] * mFrt_sl[sl],
452 (*_p)->SRL_MAX() * mFrt_sl[sl]);
453 }
454 else
455 {
456 _p->rootlength_sl[sl] = 0.0;
457 }
458 }
459
460 for ( size_t sl = _sl_min_no_roots; sl < m_soillayers->soil_layer_cnt(); ++sl)
461 {
462 _p->rootlength_sl[sl] = 0.0;
463 }
464}
void target_rooting_depth_increase(double &_rooting_depth_increase, unsigned int &_sl_min_no_roots, double const _dt_per_day, MoBiLE_Plant *const _p)
Target increase of the rooting depth under optimum conditions (Target rooting depth).
Definition ld_rootsystem.cpp:491
lvector_t< double > root_restrictions_soil_strength(unsigned int)
Root growth restriction by soil strength for every layer (Root growth restrictions).
Definition ld_rootsystem.cpp:677
void specific_root_length(unsigned int const &, MoBiLE_Plant *, lvector_t< double > &)
Specific root length of every evaluated layer (Root length and density).
Definition ld_rootsystem.cpp:1072
lvector_t< double > root_restrictions_coarse_fragments(unsigned int)
Root growth restriction by coarse fragments (stones) for every layer (Root growth restrictions).
Definition ld_rootsystem.cpp:628
lvector_t< double > root_restrictions_temperature(unsigned int, MoBiLE_Plant *)
Root growth restriction by soil temperature for every layer (Root growth restrictions).
Definition ld_rootsystem.cpp:795
void update_rooting_depth(const double, double &, unsigned int &, MoBiLE_Plant *)
Increases the rooting depth by the restricted target increment (step 4 of the Dynamic root growth mod...
Definition ld_rootsystem.cpp:552
lvector_t< double > root_restrictions_aeration(unsigned int, MoBiLE_Plant *)
Root growth restriction by oxygen shortage for every layer (Root growth restrictions).
Definition ld_rootsystem.cpp:750

References m_soillayers, root_restrictions_aeration(), root_restrictions_coarse_fragments(), root_restrictions_soil_strength(), root_restrictions_temperature(), specific_root_length(), target_rooting_depth_increase(), update_root_fraction_exponential(), update_root_fraction_sigmoid(), and update_rooting_depth().

Here is the call graph for this function:

◆ update_roots_static()

void ldndc::RootSystemDNDC::update_roots_static ( const double FTS_TOT_,
unsigned int & root_q_vt_,
MoBiLE_Plant * _vt,
ldndc::growable_array< BaseRootSystemDNDC *, 1000, 1 > & root_system,
double rootgrowthrestriction )
virtual

Root growth of one time step with the static approach (Static root growth model).

Parameters
FTS_TOT_length of the time step [d]
root_q_vt_number of rooted soil layers (updated)
_vtplant
root_systemroot systems of all plants (indexed by plant slot)
rootgrowthrestrictionfactor reducing root extension [0-1]

Implements ldndc::BaseRootSystemDNDC.

126{
127 if (cbm::flt_less(_vt->rooting_depth, (*_vt)->ZRTMC()))
128 {
129 _vt->rooting_depth += rootgrowthrestriction * (*_vt)->FRT_DGR_MAX() * FTS_TOT_;
130 }
131
132 //update rooted layers
133 root_q_vt_ = m_soillayers->soil_layer_cnt();
134 for (size_t sl = 0; sl < m_soillayers->soil_layer_cnt(); ++sl)
135 {
136 if (cbm::flt_greater(sc_.depth_sl[sl], _vt->rooting_depth))
137 {
138 /* The layer depths are not necessarily commensurate with FRT_DGR_MAX. So the current layer probably still holds roots.
139 * For the first non-rooted layer the index needs to be shifted. */
140 root_q_vt_ = (sl + 1);
141 break;
142 }
143 }
144
145 //root distribution
146 if( cbm::flt_equal_zero( (*_vt)->EXP_ROOT_DISTRIBUTION()))
147 {
148 root_system[_vt->slot]->update_root_fraction_sigmoid( 1.0, root_q_vt_, 0.005, 10.0, 200.0, 10.0, _vt);
149 }
150 else
151 {
152 root_system[_vt->slot]->update_root_fraction_exponential( 1.0, root_q_vt_, (*_vt)->EXP_ROOT_DISTRIBUTION(), _vt);
153 }
154
155 // specific root length of every rooted layer
156 lvector_t< double > specifific_root_length_sl(root_q_vt_, 99.0);
157 specific_root_length( root_q_vt_, _vt, specifific_root_length_sl);
158
159 // root length in every rooted layer
160 for (size_t sl = 0; sl <= root_q_vt_ - 1; ++sl)
161 {
162 //~ _vt->rootlength_sl[sl] = specifific_root_length_sl[sl] * _vt->fFrt_sl[sl] * (deltamassFrt + _vt->mFrt);
163 _vt->rootlength_sl[sl] = specifific_root_length_sl[sl] * _vt->fFrt_sl[sl] * _vt->mFrt;
164 }
165}

References m_soillayers, sc_, and specific_root_length().

Here is the call graph for this function: