LandscapeDNDC  1.36.0
ldndc::EcHy Class Reference

Watercycle model EcosystemHydrology - EcHy. More...

Inherits ldndc::MBE_LegacyModel.

Public Member Functions

lerr_t solve ()
 

Private Member Functions

lerr_t EcHyIrrigation ()
 Irrigation.
 
lerr_t EcHyFlood ()
 sets hydrologic conditions during flooding events, e.g., More...
 
lerr_t EcHyPercolation (size_t, size_t)
 Calculates water percolation within the soil profile.
 
lerr_t EcHyBypassFlow (double, double &)
 Calculates water percolation within the soil profile.
 
lerr_t EcHyEvapotranspiration ()
 Calculates evapotranspiration within the soil profile.
 
lerr_t EcHySubsl2 (double const &, double const &, int const &, double const &, double &)
 ... More...
 
lerr_t EcHyBalanceCheck (double &)
 ... More...
 
void EcHyreset ()
 ...
 
lerr_t EcHyGroundwater ()
 ... More...
 
lerr_t EcHyIntegration ()
 ... More...
 
lerr_t EcHyStepInit ()
 ...
 
lerr_t EcHyStepExit ()
 ...
 
double EcHyGetInterceptionCapacity ()
 ...
 
lerr_t EcHyCalculateLeafWaterDistribution (lvector_t< double > &, lvector_t< double > &)
 ...
 
lerr_t EcHyPotentialEvapotranspiration ()
 Calculates potential evapotranspiration. Specific concept can be given as model option.
 
lerr_t EcHySnowIce ()
 Calls SnowDNDC for the calculation of snowpack and soil ice formation.
 
double EcHyGetMinimumWater (size_t)
 ...
 
double EcHyGetWiltingPoint (size_t)
 ...
 
double EcHyGetAvailableWaterTranspiration (size_t)
 ...
 
double EcHyGetAvailableWaterEvaporation (size_t)
 ...
 
double EcHyGetRootLimitation (size_t _sl, double)
 ...
 
double EcHyGetWaterLimitationTranspiration (double, size_t)
 ...
 
double EcHySoilWaterChange (size_t)
 

Private Attributes

double kst_bottom
 
double gw_depth_static
 
double accumulated_potentialtranspiration_old
 
double accumulated_irrigation_old
 
lvector_t< double > trwl_sl
 
lvector_t< double > wlfl_sl
 
lvector_t< double > cr_fill_sl
 
lvector_t< double > gw_fill_sl
 
lvector_t< double > bypass_fill_sl
 
double ev_surfacewater
 
lvector_t< double > evsws_sl
 
lvector_t< double > kst_sl
 
lvector_t< double > wl_sl
 
lvector_t< double > wlfc_sl
 
lvector_t< double > wlwp_sl
 
double ev_leaf
 
double gw_fill_surface
 
double cr_fill_groundwater
 
double runoff
 
double throughfall_snow
 
double throughfall_water
 
double canopy_snowmelt
 
double canopy_water
 
double thornthwaite_heat_index
 
double daily_potential_evapotranspiration
 
double daily_potential_leaf_evaporation
 
double daily_potential_soil_evaporation
 
double daily_potential_transpiration
 
WaterCycleSnowDNDC::IceContentStateIn m_icecontent_in
 
cbm::string_t evapotranspiration_method
 
cbm::string_t runoff_method
 

Detailed Description

Watercycle model EcosystemHydrology - EcHy.

Member Function Documentation

◆ EcHyBalanceCheck()

lerr_t ldndc::EcHy::EcHyBalanceCheck ( double &  _balance)
private

...

Checks balance between all incoming and outgoing water fluxes.

References canopy_snowmelt, canopy_water, cr_fill_groundwater, ev_leaf, ev_surfacewater, evsws_sl, gw_fill_sl, gw_fill_surface, runoff, throughfall_snow, throughfall_water, trwl_sl, wl_sl, and wlfl_sl.

Referenced by solve().

502 {
503  double balance( canopy_water + surface_water + canopy_snow + surface_snow);
504  for ( size_t sl = 0; sl < soillayers_in->soil_layer_cnt(); ++sl)
505  {
506  balance += wl_sl[sl] + wc_.ice_sl[sl] * sc_.h_sl[sl];
507  }
508 
509  if ( _balance > 0.0)
510  {
511  balance += wlfl_sl[soillayers_in->soil_layer_cnt()]
512  + ev_leaf + ev_surfacewater + evsws_sl.sum() + trwl_sl.sum() + runoff
514  - irrigation - throughfall_water - throughfall_snow;
515 
516  double const balance_delta( std::abs( _balance - balance));
517  if ( cbm::flt_greater( balance_delta, 1.0e-4))
518  {
519  KLOGWARN( "Water leakage in: ", name(),
520  " Difference: ", balance - _balance);
521  KLOGWARN("throughfall_water ",throughfall_water);
522  KLOGWARN("throughfall_snow ",throughfall_snow);
523 
524  KLOGWARN("canopy_snowmelt ",canopy_snowmelt);
525  KLOGWARN("surface_snowmelt ",surface_snowmelt);
526  return LDNDC_ERR_FAIL;
527  }
528  }
529  else
530  {
531  _balance = balance;
532  }
533 
534  return LDNDC_ERR_OK;
535 }
double gw_fill_surface
Definition: echy.h:123
double ev_leaf
Definition: echy.h:120
lvector_t< double > evsws_sl
Definition: echy.h:104
double throughfall_water
Definition: echy.h:135
double cr_fill_groundwater
Definition: echy.h:126
lvector_t< double > gw_fill_sl
Definition: echy.h:95
double throughfall_snow
Definition: echy.h:132
lvector_t< double > wl_sl
Definition: echy.h:111
double canopy_snowmelt
Definition: echy.h:138
double canopy_water
Definition: echy.h:142
double runoff
Definition: echy.h:129
lvector_t< double > wlfl_sl
Definition: echy.h:89
double ev_surfacewater
Definition: echy.h:101
lvector_t< double > trwl_sl
Definition: echy.h:81
Here is the caller graph for this function:

◆ EcHyFlood()

lerr_t ldndc::EcHy::EcHyFlood ( )
private

sets hydrologic conditions during flooding events, e.g.,

Flooding.

  • surface water table
  • bund height

References kst_sl, and wl_sl.

Referenced by solve().

18 {
19  lerr_t rc = m_eventflood.solve();
20  if ( rc != LDNDC_ERR_OK){ return rc; }
21 
22  bund_height = m_eventflood.get_bund_height();
23 
24  /* todo */
25  //irrigation_amount = m_eventflood.get_irrigation_amount();
26 
27  /* todo */
28  //double const irrigation_height = m_eventflood.get_irrigation_height();
29  double const max_percolation = m_eventflood.get_maximum_percolation();
30  double const water_table_flooding = m_eventflood.get_water_table();
31 
32 
33  irrigation_switch = NONE;
34  minimum_watertable_height = 0.0;
35  if ( cbm::is_valid( water_table_flooding))
36  {
37  if ( cbm::flt_greater_zero( water_table_flooding))
38  {
39  irrigation_switch = CONSTANT_POSITIVE_WATER_TABLE;
40  minimum_watertable_height = water_table_flooding;
41  bund_height = water_table_flooding;
42  }
43  else
44  {
45  irrigation_switch = CONSTANT_NEGATIVE_WATER_TABLE;
46  minimum_watertable_height = water_table_flooding;
47  bund_height = 0.0;
48  }
49  }
50 
51  bool cracked( false);
52  for (size_t sl = 0; sl < soillayers_in->soil_layer_cnt()-1; sl++)
53  {
54  if ( cbm::flt_greater_equal( sc_.depth_sl[sl], 0.3))
55  {
56  if ( cbm::is_valid( max_percolation))
57  {
58  if ((kst_eq_sl[sl] > max_percolation / lclock()->time_resolution()))
59  {
60 
61  kst_sl[sl] = cbm::bound_min( 0.0,
62  kst_eq_sl[sl] -
63  (kst_eq_sl[sl] - max_percolation / lclock()->time_resolution()) *
64  (sc_.depth_sl[sl] - 0.2) / (sc_.depth_sl[soillayers_in->soil_layer_cnt()-1] - 0.2));
65  }
66  kst_sl[sl] = max_percolation / lclock()->time_resolution();
67  }
68  else if ( wl_sl[sl] < -0.8 * pore_space( sl))
69  {
70  cracked = true;
71  }
72 
73  if ( cracked)
74  {
75  double const time_rate( 0.1 / lclock()->time_resolution());
76  kst_sl[sl] = cbm::bound_min( 0.0,
77  kst_sl[sl] - (kst_sl[sl] - kst_eq_sl[sl]) * time_rate);
78  }
79  break;
80  }
81  }
82 
83  return LDNDC_ERR_OK;
84 }
lvector_t< double > kst_sl
Definition: echy.h:107
lvector_t< double > wl_sl
Definition: echy.h:111
Here is the caller graph for this function:

◆ EcHyGroundwater()

lerr_t ldndc::EcHy::EcHyGroundwater ( )
private

...

Negative groundwater table represents water on the soil surface

Negative groundwater table represents water on the soil surface

References cr_fill_groundwater, cr_fill_sl, EcHySoilWaterChange(), gw_depth_static, gw_fill_sl, gw_fill_surface, kst_sl, and wl_sl.

Referenced by solve().

21 {
22  cbm::invalidate( kst_bottom_gw_vertical);
23  if ( cbm::flt_greater( sc_.depth_sl[soillayers_in->soil_layer_cnt()-1], gw_depth_static))
24  {
29  if ( cbm::flt_greater( -gw_depth_static, surface_water))
30  {
31  gw_fill_surface = -gw_depth_static - surface_water;
32  }
33 
34  //groundwater access
35  {
36  size_t sl( 0);
37  double const layer_midpoint_depth( 0.5 * sc_.h_sl[sl]);
38  if ( cbm::flt_greater_equal( layer_midpoint_depth, gw_depth_static))
39  {
40  gw_fill_sl[sl] = cbm::bound_min( 0.0,
41  0.999 * pore_space( sl) - wc_.ice_sl[sl] * sc_.h_sl[sl]
42  - (wl_sl[sl] + EcHySoilWaterChange( sl)));
43  wc_.accumulated_groundwater_access += gw_fill_sl[sl];
44  }
45  else
46  {
47  double const wl_new( wl_sl[sl] + EcHySoilWaterChange( sl));
48  double const wc_new( cbm::bound( wc_.wc_res_sl[sl], wl_new / sc_.h_sl[sl], wc_.wc_sat_sl[sl]));
49  kst_bottom_gw_vertical = cbm::bound_min( 0.0,
50  ldndc::hydraulic_conductivity(
51  wc_new,
52  wc_.vgm_sl[sl],
53  wc_.mvg_tau_sl[sl],
54  wc_.wc_sat_sl[sl],
55  wc_.wc_res_sl[sl],
56  kst_sl[sl]));
57  gw_fill_sl[sl] = 0.0;
58  }
59  }
60 
61  for (size_t sl = 1; sl < soillayers_in->soil_layer_cnt()-1; sl++)
62  {
63  double const layer_midpoint_depth( sc_.depth_sl[sl] - 0.5 * sc_.h_sl[sl]);
64  if ( cbm::flt_greater_equal( layer_midpoint_depth, gw_depth_static))
65  {
66  gw_fill_sl[sl] = cbm::bound_min( 0.0,
67  0.999 * pore_space( sl) - wc_.ice_sl[sl] * sc_.h_sl[sl]
68  - (wl_sl[sl] + EcHySoilWaterChange( sl)));
69  wc_.accumulated_groundwater_access += gw_fill_sl[sl];
70  }
71  else
72  {
73  double const wl_new( wl_sl[sl] + EcHySoilWaterChange( sl));
74  double const wc_new( cbm::bound( wc_.wc_res_sl[sl], wl_new / sc_.h_sl[sl], wc_.wc_sat_sl[sl]));
75  kst_bottom_gw_vertical = cbm::bound_min( 0.0,
76  ldndc::hydraulic_conductivity(
77  wc_new,
78  wc_.vgm_sl[sl],
79  wc_.mvg_tau_sl[sl],
80  wc_.wc_sat_sl[sl],
81  wc_.wc_res_sl[sl],
82  kst_sl[sl]));
83  gw_fill_sl[sl] = 0.0;
84  }
85  }
86 
87  {
88  size_t sl( soillayers_in->soil_layer_cnt()-1);
89  double const layer_midpoint_depth( sc_.depth_sl[sl] - 0.5 * sc_.h_sl[sl]);
90  if ( cbm::flt_greater_equal( layer_midpoint_depth, gw_depth_static))
91  {
92  gw_fill_sl[sl] = cbm::bound_min( 0.0,
93  0.999 * pore_space( sl) - wc_.ice_sl[sl] * sc_.h_sl[sl]
94  - (wl_sl[sl] + EcHySoilWaterChange( sl)));
95  wc_.accumulated_groundwater_access += gw_fill_sl[sl];
96  }
97  else
98  {
99  double const wl_new( wl_sl[sl] + EcHySoilWaterChange( sl));
100  double const wc_new( cbm::bound( wc_.wc_res_sl[sl], wl_new / sc_.h_sl[sl], wc_.wc_sat_sl[sl]));
101  kst_bottom_gw_vertical = cbm::bound_min( 0.0,
102  ldndc::hydraulic_conductivity(
103  wc_new,
104  wc_.vgm_sl[sl],
105  wc_.mvg_tau_sl[sl],
106  wc_.wc_sat_sl[sl],
107  wc_.wc_res_sl[sl],
108  kst_sl[sl]));
109  gw_fill_sl[sl] = 0.0;
110  }
111  }
112  }
113 
114  //capillary rise
115  if ( m_param->WCDNDC_HAVE_CAPILLARY_ACTION())
116  {
117  size_t const STEPS( 10);
118  for (size_t steps = 0; steps < STEPS; steps++)
119  {
120  for (size_t sl = 0; sl < soillayers_in->soil_layer_cnt()-1; sl++)
121  {
122  double const layer_midpoint_depth( sc_.depth_sl[sl] - 0.5 * sc_.h_sl[sl]);
123  if ( cbm::flt_greater_equal( layer_midpoint_depth, gw_depth_static))
124  {
125  break;
126  }
127 
128  /* Water contents with until now calculated water balance */
129  double const wl_new_0( wl_sl[sl] + EcHySoilWaterChange( sl));
130  double const wl_new_1( wl_sl[sl+1] + EcHySoilWaterChange( sl+1));
131 
132  double const wc_vg_0( cbm::bound( wc_.wc_res_sl[sl], wl_new_0 / sc_.h_sl[sl], wc_.wc_sat_sl[sl]));
133  double const wc_vg_1( cbm::bound( wc_.wc_res_sl[sl+1], wl_new_1 / sc_.h_sl[sl+1], wc_.wc_sat_sl[sl+1]));
134 
135  /* Unsaturated hydraulic conductivity with until now calculated water balance */
136  double const kust_0( cbm::bound_min( 0.0,
137  ldndc::hydraulic_conductivity(
138  wc_vg_0, wc_.vgm_sl[sl], wc_.mvg_tau_sl[sl],
139  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl],
140  1.0/double(STEPS)*kst_sl[sl])));
141  double const kust_1( cbm::bound_min( 0.0,
142  ldndc::hydraulic_conductivity(
143  wc_vg_1, wc_.vgm_sl[sl+1], wc_.mvg_tau_sl[sl],
144  wc_.wc_sat_sl[sl+1], wc_.wc_res_sl[sl+1],
145  1.0/double(STEPS)*kst_sl[sl+1])));
146 
147  double const capillary_pressure_0( ldndc::capillary_pressure(
148  wl_new_0/sc_.h_sl[sl], wc_.vga_sl[sl],
149  wc_.vgn_sl[sl], wc_.vgm_sl[sl],
150  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl]));
151  double const capillary_pressure_1( ldndc::capillary_pressure(
152  wl_new_1/sc_.h_sl[sl+1], wc_.vga_sl[sl+1],
153  wc_.vgn_sl[sl+1], wc_.vgm_sl[sl+1],
154  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl+1]));
155 
156  double const kust( cbm::flt_greater( capillary_pressure_0, capillary_pressure_1) ? kust_1 : kust_0 );
157  double const flow( (capillary_pressure_1 - capillary_pressure_0) / (0.5 * (sc_.h_sl[sl] + sc_.h_sl[sl+1])) * kust);
158 
159  /* downward flow*/
160  if ( cbm::flt_greater_zero( flow))
161  {
162  double const left( wl_sl[sl] + EcHySoilWaterChange( sl) - (wc_.wc_res_sl[sl] * sc_.h_sl[sl]));
163  double const space( 0.999 * pore_space( sl+1) - wc_.ice_sl[sl+1] * sc_.h_sl[sl+1]
164  - (wl_sl[sl+1] + EcHySoilWaterChange( sl+1)));
165 
166  if ( cbm::flt_greater_zero( left) &&
167  cbm::flt_greater_zero( space))
168  {
169  double const bound_flow( cbm::bound_max( flow, std::min( left, space)) / static_cast<double>(STEPS));
170  cr_fill_sl[sl] -= bound_flow;
171  cr_fill_sl[sl+1] += bound_flow;
172  }
173  }
174  /* upward flow */
175  else if ( cbm::flt_less( flow, 0.0))
176  {
177  double const left( wl_sl[sl+1] + EcHySoilWaterChange( sl+1) - (wc_.wc_res_sl[sl+1] * sc_.h_sl[sl+1]));
178  double const space( 0.999 * pore_space( sl) - wc_.ice_sl[sl] * sc_.h_sl[sl]
179  - (wl_sl[sl] + EcHySoilWaterChange( sl)));
180 
181  if ( cbm::flt_greater_zero( left) &&
182  cbm::flt_greater_zero( space))
183  {
184  double const bound_flow( cbm::bound_max( -flow, std::min( left, space)) / static_cast<double>(STEPS));
185  cr_fill_sl[sl] += bound_flow;
186  cr_fill_sl[sl+1] -= bound_flow;
187  }
188  }
189  }
190 
191  size_t sl( soillayers_in->soil_layer_cnt()-1);
192  double const layer_midpoint_depth( sc_.depth_sl[sl] - 0.5 * sc_.h_sl[sl]);
193  if ( cbm::flt_greater( gw_depth_static, layer_midpoint_depth))
194  {
195  /* Water contents with until now calculated water balance */
196  double const wl_new( wl_sl[sl] + EcHySoilWaterChange( sl));
197 
198  double const wc_vg( cbm::bound( wc_.wc_res_sl[sl], wl_new / sc_.h_sl[sl], wc_.wc_sat_sl[sl]));
199 
200  /* Unsaturated hydraulic conductivity with until now calculated water balance */
201  double const kust( cbm::bound_min( 0.0,
202  ldndc::hydraulic_conductivity(
203  wc_vg, wc_.vgm_sl[sl], wc_.mvg_tau_sl[sl],
204  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl],
205  1.0/double(STEPS)*kst_sl[sl])));
206 
207  double const capillary_pressure( ldndc::capillary_pressure(
208  wl_new/sc_.h_sl[sl], wc_.vga_sl[sl],
209  wc_.vgn_sl[sl], wc_.vgm_sl[sl],
210  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl]));
211 
212  /* upward flow */
213  double const flow( -capillary_pressure / (gw_depth_static - layer_midpoint_depth) * kust);
214  if ( cbm::flt_less( flow, 0.0))
215  {
216  double const space( 0.999 * pore_space( sl) - wc_.ice_sl[sl] * sc_.h_sl[sl]
217  - (wl_sl[sl] + EcHySoilWaterChange( sl)));
218  if ( cbm::flt_greater_zero( space))
219  {
220  double const bound_flow( cbm::bound_max( -flow, 1.0 / static_cast<double>(STEPS) * space));
221  cr_fill_sl[sl] += bound_flow;
222  cr_fill_groundwater += bound_flow;
223  }
224  }
225  }
226  }
227  }
228 
229  return LDNDC_ERR_OK;
230 }
double gw_fill_surface
Definition: echy.h:123
double gw_depth_static
Definition: echy.h:72
lvector_t< double > kst_sl
Definition: echy.h:107
double cr_fill_groundwater
Definition: echy.h:126
lvector_t< double > gw_fill_sl
Definition: echy.h:95
lvector_t< double > wl_sl
Definition: echy.h:111
double EcHySoilWaterChange(size_t)
Definition: echy.cpp:452
lvector_t< double > cr_fill_sl
Definition: echy.h:92
Here is the call graph for this function:
Here is the caller graph for this function:

◆ EcHyIntegration()

lerr_t ldndc::EcHy::EcHyIntegration ( )
private

...

Integrates all water state variables.

References bypass_fill_sl, canopy_snowmelt, canopy_water, EcHySoilWaterChange(), ev_surfacewater, gw_fill_surface, runoff, throughfall_snow, throughfall_water, wl_sl, and wlfl_sl.

Referenced by solve().

466 {
467  canopy_snow = cbm::bound_min( 0.0,
468  canopy_snow - canopy_snowmelt);
469  surface_snow = cbm::bound_min( 0.0,
470  surface_snow
472  - surface_snowmelt);
473 
474  canopy_water = cbm::bound_min( 0.0,
476  + canopy_snowmelt);
477  surface_water = cbm::bound_min( 0.0,
478  surface_water
479  + throughfall_water + surface_snowmelt + gw_fill_surface + irrigation
480  - ev_surfacewater - wlfl_sl[0] - runoff - bypass_fill_sl.sum());
481 
482  for (size_t sl = 0; sl < soillayers_in->soil_layer_cnt(); sl++)
483  {
484  wl_sl[sl] = cbm::bound_min( 0.0, wl_sl[sl] + EcHySoilWaterChange( sl));
485  wc_.mskpa_sl[sl] = ldndc::hydrology::capillary_pressure( wl_sl[sl]/sc_.h_sl[sl], wc_.vga_sl[sl],
486  wc_.vgn_sl[sl], wc_.vgm_sl[sl],
487  wc_.wc_sat_sl[sl], wc_.wc_res_sl[sl]);
488  }
489 
490  return LDNDC_ERR_OK;
491 }
double gw_fill_surface
Definition: echy.h:123
double throughfall_water
Definition: echy.h:135
double throughfall_snow
Definition: echy.h:132
lvector_t< double > wl_sl
Definition: echy.h:111
double canopy_snowmelt
Definition: echy.h:138
double canopy_water
Definition: echy.h:142
double runoff
Definition: echy.h:129
lvector_t< double > wlfl_sl
Definition: echy.h:89
double ev_surfacewater
Definition: echy.h:101
double EcHySoilWaterChange(size_t)
Definition: echy.cpp:452
lvector_t< double > bypass_fill_sl
Definition: echy.h:98
Here is the call graph for this function:
Here is the caller graph for this function:

◆ EcHySoilWaterChange()

double ldndc::EcHy::EcHySoilWaterChange ( size_t  _sl)
private

Integrates all water state variables.

References cr_fill_sl, evsws_sl, gw_fill_sl, trwl_sl, and wlfl_sl.

Referenced by EcHyGetAvailableWaterEvaporation(), EcHyGetAvailableWaterTranspiration(), EcHyGroundwater(), EcHyIntegration(), and EcHyIrrigation().

454 {
455  return wlfl_sl[_sl] - wlfl_sl[_sl+1] + cr_fill_sl[_sl] - trwl_sl[_sl] - evsws_sl[_sl] + gw_fill_sl[_sl];
456 }
lvector_t< double > evsws_sl
Definition: echy.h:104
lvector_t< double > gw_fill_sl
Definition: echy.h:95
lvector_t< double > wlfl_sl
Definition: echy.h:89
lvector_t< double > trwl_sl
Definition: echy.h:81
lvector_t< double > cr_fill_sl
Definition: echy.h:92
Here is the caller graph for this function:

◆ EcHySubsl2()

lerr_t ldndc::EcHy::EcHySubsl2 ( double const &  _cp,
double const &  _delta_z,
int const &  _sl,
double const &  _saturation,
double &  _flow 
)
private

...

This routine calculates the rate of capillary flow or percolation between groundwater table and root zone. The stationary flow is found by integration of dZL = K.d(MH)/(K + FLW), where Z= height above groundwater, MH= matric head, K= conductivity and FLW= chosen flow. In an iteration loop the correct flow is found. The integration goes at most over four intervals: [0,45], [45,170], [170,330] and [330,MH-rootzone] (last one on logarithmic scale).

Author
C. Rappoldt M. Wopereis
Date
January 1986, revised June 1990

Chapter 15 in documentation WOFOST Version 4.1 (1988)

References kst_sl.

261 {
262  //calculation of pf from matrix head
263  double pf( std::log10( _cp));
264 
265  //in case of small matric head (high water contents)
266  if ( cbm::flt_greater( 1.0, pf))
267  {
268  _flow = 0.0;
269  return LDNDC_ERR_OK;
270  }
271 
272  double elog10( 2.302585);
273  double logst4( 2.518514);
274 
275  double start[4] = {0.0, 45.0, 170.0, 330.0};
276 
277  //number and width of integration intervals
278  int iint( 0);
279  double del[4] = { 0.0, 0.0, 0.0, 0.0};
280  for (int i1 = 0; i1 < 4; i1++)
281  {
282  if (i1 < 3)
283  {
284  del[i1] = std::min( start[i1+1], _cp) - start[i1];
285  }
286  else
287  {
288  del[i1] = pf - logst4;
289  }
290  if (del[i1] <= 0.0)
291  {
292  break;
293  }
294  iint += 1;
295  }
296 
297  //preparation of three-point gaussian integration
298  double hulp[12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
299  double conduc[12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
300  for (int i1 = 0; i1 < iint; i1++)
301  {
302  for (int i2 = 0; i2 < 3; i2++)
303  {
304  double pgau[3] = {0.1127016654, 0.5, 0.8872983346};
305  double wgau[3] = {0.2777778, 0.4444444, 0.2777778};
306 
307  int i3( 3 * i1 + i2);
308 
309  //the three points in the full-width intervals are standard
310  double pfstan[9] = {0.705143, 1.352183, 1.601282, 1.771497, 2.031409, 2.192880, 2.274233, 2.397940, 2.494110};
311  double pfgau( pfstan[i3]);
312 
313  //the three points in the last interval are calculated
314  if ( i1 == (iint-1))
315  {
316  if ( iint < 4)
317  {
318  pfgau = std::log10( start[iint-1] + pgau[i2] * del[iint-1]);
319  }
320  else
321  {
322  pfgau = logst4 + pgau[i2] * del[iint-1];
323  }
324  }
325 
326  double const wcl_loc( ldndc::hydrology::water_content( std::exp(elog10 * pfgau), wc_.vga_sl[_sl], wc_.vgn_sl[_sl], wc_.vgm_sl[_sl], _saturation, 0.1));
327  conduc[i3] = ldndc::hydraulic_conductivity( wcl_loc, wc_.vgm_sl[_sl], wc_.mvg_tau_sl[_sl],
328  _saturation, wc_.wc_wp_sl[_sl], kst_sl[_sl] * cbm::CM_IN_M);
329  hulp[i3] = del[i1] * wgau[i2] * conduc[i3];
330  if (i3 > 8)
331  {
332  hulp[i3] = hulp[i3] * elog10 * std::exp( elog10 * pfgau);
333  }
334  }
335  }
336 
337 
338  //setting upper and lower limit
339  double const wcl_loc( ldndc::hydrology::water_content( _cp, wc_.vga_sl[_sl], wc_.vgn_sl[_sl], wc_.vgm_sl[_sl], _saturation, 0.1));
340  double const kms( ldndc::hydraulic_conductivity( wcl_loc, wc_.vgm_sl[_sl], wc_.mvg_tau_sl[_sl],
341  _saturation, wc_.wc_wp_sl[_sl], kst_sl[_sl] * cbm::CM_IN_M));
342  double fu( (_cp <= _delta_z) ? 0.0 : 1.27);
343  double fl( (_cp >= _delta_z) ? 0.0 : -kms);
344 
345 
346  if ( !cbm::flt_equal( _cp, _delta_z))
347  {
348  //iteration loop
349  int imax( 3 * iint);
350  for ( int i1 = 0; i1 < 14; i1++)
351  {
352  double flw( (fu + fl) / 2.0);
353  double df( (fu - fl) / 2.0);
354  if ( (df < 0.01) &&
355  ((df / std::abs(flw)) < 0.1))
356  {
357  break;
358  }
359 
360  double z( 0.0);
361  for ( int i2 = 0; i2 < imax; i2++)
362  {
363  z = z + hulp[i2] / (conduc[i2] + flw);
364  }
365  if (z >= _delta_z)
366  {
367  fl = flw;
368  }
369  if (z <= _delta_z)
370  {
371  fu = flw;
372  }
373  }
374  }
375 
376  //flow output in mm
377  _flow = 10.0 * (fu + fl) / 2.0;
378 
379  return LDNDC_ERR_OK;
380 }
lvector_t< double > kst_sl
Definition: echy.h:107

◆ solve()

lerr_t ldndc::EcHy::solve ( )

Kicks off computation for one time step.

References EcHyBalanceCheck(), EcHyBypassFlow(), EcHyEvapotranspiration(), EcHyFlood(), EcHyGroundwater(), EcHyIntegration(), EcHyIrrigation(), EcHyPercolation(), EcHyreset(), EcHySnowIce(), EcHyStepExit(), EcHyStepInit(), kst_bottom, kst_sl, runoff, runoff_method, throughfall_water, and wlfl_sl.

46 {
47  /* reset of all fluxes */
48  EcHyreset();
49 
50  /* flooding events */
51  lerr_t rc = EcHyFlood();
52  if ( rc != LDNDC_ERR_OK)
53  {
54  KLOGERROR("Handling flooding event failed in: ", name());
55  return rc;
56  }
57 
58  /* tasks:
59  * - update internal state (e.g., throughfall_water, ...)
60  * - calculate evapotranspiration on demand
61  */
62  rc = EcHyStepInit();
63  if ( rc != LDNDC_ERR_OK)
64  { return rc; }
65 
66  /* begin water balance */
67  double balance( -1.0);
68  EcHyBalanceCheck( balance);
69 
70  /* snow and ice calculated */
71  EcHySnowIce();
72 
73  /*
74  * apply irrigation triggered by
75  * - irrigation events
76  * - flooding events
77  */
79 
80  double const potential_infiltration( surface_water + irrigation + throughfall_water + surface_snowmelt);
81  double bypass_flow( m_param->CRACK_FRACTION() * potential_infiltration);
82 
83  /* bypass flow */
84  EcHyBypassFlow( m_param->CRACK_DEPTH(), bypass_flow);
85  double const infiltration( potential_infiltration - bypass_flow);
86 
87  /* downward water flow */
88  wlfl_sl[0] = cbm::bound_max( infiltration, kst_sl[0]);
89  for ( size_t sl = 0; sl < soillayers_in->soil_layer_cnt(); ++sl)
90  {
91  EcHyPercolation( 1, sl);
92  }
93 
94  if ( cbm::is_valid( kst_bottom))
95  {
96  wlfl_sl[soillayers_in->soil_layer_cnt()] = cbm::bound_max( wlfl_sl[soillayers_in->soil_layer_cnt()],
97  kst_bottom);
98  }
99  if ( cbm::is_valid( kst_bottom_gw_lateral))
100  {
101  wlfl_sl[soillayers_in->soil_layer_cnt()] = cbm::bound_max( wlfl_sl[soillayers_in->soil_layer_cnt()],
102  kst_bottom_gw_lateral);
103  }
104  if ( cbm::is_valid( kst_bottom_gw_vertical))
105  {
106  wlfl_sl[soillayers_in->soil_layer_cnt()] = cbm::bound_max( wlfl_sl[soillayers_in->soil_layer_cnt()],
107  kst_bottom_gw_vertical);
108  }
109 
111 
112  /* upward water flow */
113  for ( int sl = soillayers_in->soil_layer_cnt()-1; sl >= 0; --sl)
114  {
115  EcHyPercolation( 2, sl);
116  }
117 
118  /* runoff */
119  if ( runoff_method == "curvenumber")
120  {
121  double const surface_water_in_mm( surface_water * cbm::MM_IN_M);
122  double const curvenumber( 70.0);
123 
124  //retention parameter [mm]
125  double const retention_factor( 25.4 * (1000.0 / curvenumber - 10));
126 
127  //runoff [mm]
128  double const q_surf( cbm::sqr( surface_water_in_mm) /
129  ((surface_water_in_mm + retention_factor) * lclock()->time_resolution()));
130 
131  runoff = cbm::bound( 0.0,
132  q_surf * cbm::M_IN_MM,
133  0.99 * (surface_water + irrigation + throughfall_water + surface_snowmelt
134  - wlfl_sl[0] - bypass_flow));
135  }
136  else
137  {
138  double const f_runoff( cbm::bound_max( m_param->FRUNOFF() / lclock()->time_resolution(), 1.0));
139  runoff = cbm::bound_min( 0.0, f_runoff * (surface_water + irrigation + throughfall_water + surface_snowmelt
140  - wlfl_sl[0] - bypass_flow - bund_height));
141  }
142 
143  /* groundwater interaction:
144  * - set soil layers water-saturated
145  * - capillary rise
146  */
147  EcHyGroundwater();
148 
149  /* integration of state variables */
150  EcHyIntegration();
151 
152  /* update external state */
153  EcHyStepExit();
154 
155  /* perform water balance */
156  rc = EcHyBalanceCheck( balance);
157  if ( rc){ return rc; }
158 
159  rc = EcHy_check_for_negative_value("exit");
160  if ( rc){ return rc; }
161 
162  return LDNDC_ERR_OK;
163 }
lvector_t< double > kst_sl
Definition: echy.h:107
lerr_t EcHySnowIce()
Calls SnowDNDC for the calculation of snowpack and soil ice formation.
Definition: echy-snow.cpp:22
lerr_t EcHyFlood()
sets hydrologic conditions during flooding events, e.g.,
Definition: echy-management.cpp:17
void EcHyreset()
...
Definition: echy.cpp:172
lerr_t EcHyBypassFlow(double, double &)
Calculates water percolation within the soil profile.
double throughfall_water
Definition: echy.h:135
lerr_t EcHyStepInit()
...
Definition: echy.cpp:205
lerr_t EcHyIntegration()
...
Definition: echy.cpp:465
lerr_t EcHyEvapotranspiration()
Calculates evapotranspiration within the soil profile.
cbm::string_t runoff_method
Definition: echy.h:194
double kst_bottom
Definition: echy.h:67
double runoff
Definition: echy.h:129
lvector_t< double > wlfl_sl
Definition: echy.h:89
lerr_t EcHyGroundwater()
...
Definition: echy-groundwater.cpp:20
lerr_t EcHyStepExit()
...
Definition: echy.cpp:332
lerr_t EcHyPercolation(size_t, size_t)
Calculates water percolation within the soil profile.
lerr_t EcHyBalanceCheck(double &)
...
Definition: echy.cpp:500
lerr_t EcHyIrrigation()
Irrigation.
Definition: echy-management.cpp:93
Here is the call graph for this function:

Member Data Documentation

◆ accumulated_irrigation_old

double ldndc::EcHy::accumulated_irrigation_old
private

Accumulated irrigation of last time step [m]

Referenced by EcHyIrrigation().

◆ accumulated_potentialtranspiration_old

double ldndc::EcHy::accumulated_potentialtranspiration_old
private

Accumulated potential transpiration of last time step [m]

Referenced by EcHyPotentialEvapotranspiration().

◆ bypass_fill_sl

lvector_t< double > ldndc::EcHy::bypass_fill_sl
private

Soillayer water input due to bypass flow

Referenced by EcHyIntegration(), EcHyPotentialEvapotranspiration(), and EcHyreset().

◆ canopy_snowmelt

double ldndc::EcHy::canopy_snowmelt
private

Snow melting

Referenced by EcHyBalanceCheck(), EcHyIntegration(), and EcHySnowIce().

◆ canopy_water

double ldndc::EcHy::canopy_water
private

◆ cr_fill_groundwater

double ldndc::EcHy::cr_fill_groundwater
private

Water addition to last soil layer from groundwater water by cappillary rise (only used for water balance calculation)

Referenced by EcHyBalanceCheck(), EcHyGroundwater(), and EcHyreset().

◆ cr_fill_sl

lvector_t< double > ldndc::EcHy::cr_fill_sl
private

Soillayer water input due to capillary rise

Referenced by EcHyGroundwater(), EcHyreset(), and EcHySoilWaterChange().

◆ daily_potential_evapotranspiration

double ldndc::EcHy::daily_potential_evapotranspiration
private

◆ daily_potential_leaf_evaporation

double ldndc::EcHy::daily_potential_leaf_evaporation
private

◆ daily_potential_soil_evaporation

double ldndc::EcHy::daily_potential_soil_evaporation
private

◆ daily_potential_transpiration

double ldndc::EcHy::daily_potential_transpiration
private

◆ ev_leaf

double ldndc::EcHy::ev_leaf
private

Evaporation from plant surface

Referenced by EcHyBalanceCheck(), EcHyPotentialEvapotranspiration(), and EcHyStepExit().

◆ ev_surfacewater

double ldndc::EcHy::ev_surfacewater
private

Evaporation from surface water

Referenced by EcHyBalanceCheck(), EcHyIntegration(), EcHyPotentialEvapotranspiration(), and EcHyreset().

◆ evapotranspiration_method

cbm::string_t ldndc::EcHy::evapotranspiration_method
private

◆ evsws_sl

lvector_t< double > ldndc::EcHy::evsws_sl
private

◆ gw_depth_static

double ldndc::EcHy::gw_depth_static
private

Depth of groundwater table [m]

Referenced by EcHyGroundwater(), and EcHyStepInit().

◆ gw_fill_sl

lvector_t< double > ldndc::EcHy::gw_fill_sl
private

Soillayer water input due to groundwater flow

Referenced by EcHyBalanceCheck(), EcHyGroundwater(), EcHyreset(), and EcHySoilWaterChange().

◆ gw_fill_surface

double ldndc::EcHy::gw_fill_surface
private

Water addition to surface water from groundwater water boundary condition

Referenced by EcHyBalanceCheck(), EcHyGroundwater(), EcHyIntegration(), and EcHyreset().

◆ kst_bottom

double ldndc::EcHy::kst_bottom
private

Saturated hydraulic conductivity below last soil layer [cm:min-1]

Referenced by EcHyStepInit(), and solve().

◆ kst_sl

lvector_t< double > ldndc::EcHy::kst_sl
private

Saturated hydraulic conductivity

Referenced by EcHyFlood(), EcHyGroundwater(), EcHySubsl2(), and solve().

◆ m_icecontent_in

WaterCycleSnowDNDC::IceContentStateIn ldndc::EcHy::m_icecontent_in
private

...

Referenced by EcHySnowIce().

◆ runoff

double ldndc::EcHy::runoff
private

Lateral surface runoff

Referenced by EcHyBalanceCheck(), EcHyIntegration(), EcHyreset(), EcHyStepExit(), and solve().

◆ runoff_method

cbm::string_t ldndc::EcHy::runoff_method
private

...

Referenced by solve().

◆ thornthwaite_heat_index

double ldndc::EcHy::thornthwaite_heat_index
private

◆ throughfall_snow

double ldndc::EcHy::throughfall_snow
private

◆ throughfall_water

double ldndc::EcHy::throughfall_water
private

◆ trwl_sl

lvector_t< double > ldndc::EcHy::trwl_sl
private

Water withdrawl by transpiration [m d−1]

Referenced by EcHyBalanceCheck(), EcHyPotentialEvapotranspiration(), EcHyreset(), EcHySoilWaterChange(), and EcHyStepExit().

◆ wl_sl

◆ wlfc_sl

lvector_t< double > ldndc::EcHy::wlfc_sl
private

Amount of water in soil layer at field capacity

Referenced by EcHyGetWaterLimitationTranspiration(), and EcHyIrrigation().

◆ wlfl_sl

lvector_t< double > ldndc::EcHy::wlfl_sl
private

Water flux at boundaries of soil layer [m d-1] the flux of water between soil layer is tracked by wlfl (mm d−1). in total, there are nl+1 flow rates, where nl is the number of soil layers, wlfl[1] is the flow rate between the ponded water layer and the soil surface, wlfl[2] is the flow rate between soil layer 1 and soil layer 2, etc.

Referenced by EcHyBalanceCheck(), EcHyIntegration(), EcHyPotentialEvapotranspiration(), EcHyreset(), EcHySoilWaterChange(), EcHyStepExit(), and solve().

◆ wlwp_sl

lvector_t< double > ldndc::EcHy::wlwp_sl
private

Amount of water in soil layer at wilting point

Referenced by EcHyGetWiltingPoint().