API for the below_ground module

The models.hydrology.below_ground module simulates the below-ground hydrological processes for the Virtual Ecosystem. This includes vertical flow, soil moisture and matric potential, groundwater storage, and subsurface horizontal flow.

Functions:

calculate_vertical_flow(soil_moisture, ...)

Calculate vertical water flow through soil column, [mm d-1].

convert_soil_moisture_to_water_potential(...)

Convert soil moisture into an estimate of water potential.

update_groundwater_storage(...)

Update groundwater storage and calculate below ground horizontal flow.

update_soil_moisture(soil_moisture, ...)

Update soil moisture profile.

virtual_ecosystem.models.hydrology.below_ground.calculate_vertical_flow(soil_moisture: ndarray[Any, dtype[float32]], soil_layer_thickness: ndarray[Any, dtype[float32]], soil_moisture_capacity: float | ndarray[Any, dtype[float32]], soil_moisture_residual: float | ndarray[Any, dtype[float32]], hydraulic_conductivity: float | ndarray[Any, dtype[float32]], hydraulic_gradient: float | ndarray[Any, dtype[float32]], nonlinearily_parameter: float | ndarray[Any, dtype[float32]], groundwater_capacity: float | ndarray[Any, dtype[float32]], seconds_to_day: float) ndarray[Any, dtype[float32]]

Calculate vertical water flow through soil column, [mm d-1].

To calculate the flow of water through unsaturated soil, this function uses the Richards equation. First, the function calculates the effective saturation \(S\) and effective hydraulic conductivity \(K(S)\) based on the moisture content \(\Theta\) using the Mualem-van Genuchten model (Van Genuchten, 1980):

\(S = \frac{\Theta - \Theta_{r}}{\Theta_{s} - \Theta_{r}}\)

and

\(K(S) = K_{s}* \sqrt{S} *(1-(1-S^{1/m})^{m})^{2}\)

where \(\Theta_{r}\) is the residual moisture content, \(\Theta_{s}\) is the saturated moisture content, \(K_{s}\) is the saturated hydraulic conductivity, and \(m=1-1/n\) is a shape parameter derived from the non-linearity parameter \(n\). Then, the function applies Darcy’s law to calculate the water flow rate \(q\) in \(\frac{m^3}{s^1}\) considering the effective hydraulic conductivity:

\(q = - K(S)*(\frac{dh}{dl}-1)\)

where \(\frac{dh}{dl}\) is the hydraulic gradient with \(l\) the length of the flow path in meters (here equal to the soil depth).

Note that there are severe limitations to this approach on the temporal and spatial scale of this model and this can only be treated as a very rough approximation!

Parameters:
  • soil_moisture – Volumetric relative water content in top soil, [unitless]

  • soil_layer_thickness – Thickness of all soil_layers, [mm]

  • soil_moisture_capacity – soil moisture capacity, [unitless]

  • soil_moisture_residual – residual soil moisture, [unitless]

  • hydraulic_conductivity – hydraulic conductivity of soil, [m/s]

  • hydraulic_gradient – hydraulic gradient (change in hydraulic head) along the flow path, positive values indicate downward flow, [m/m]

  • nonlinearily_parameter – dimensionless parameter in van Genuchten model that describes the degree of nonlinearity of the relationship between the volumetric water content and the soil matric potential.

  • groundwater_capacity – storage capacity of groundwater, [mm]

  • seconds_to_day – factor to convert between second and day

Returns:

volumetric flow rate of water, [mm d-1]

virtual_ecosystem.models.hydrology.below_ground.convert_soil_moisture_to_water_potential(soil_moisture: ndarray[Any, dtype[float32]], air_entry_water_potential: float, water_retention_curvature: float, soil_moisture_capacity: float) ndarray[Any, dtype[float32]]

Convert soil moisture into an estimate of water potential.

This function provides a coarse estimate of soil water potential \(\Psi_{m}\). It is taken from Campbell (1974):

\(\Psi_{m} = \Psi_{e} * (\frac{\Theta}{\Theta_{s}})^{b}\)

where \(\Psi_{e}\) is the air-entry, \(\Theta\) is the volumetric water content, \(\Theta_{s}\) is the saturated water content, and \(b\) is the water retention curvature parameter.

Parameters:
  • soil_moisture – Volumetric relative water content [unitless]

  • air_entry_water_potential – Water potential at which soil pores begin to aerate [kPa]

  • water_retention_curvature – Curvature of water retention curve [unitless]

  • soil_moisture_capacity – The relative water content at which the soil is fully saturated [unitless].

Returns:

An estimate of the water potential of the soil [kPa]

virtual_ecosystem.models.hydrology.below_ground.update_groundwater_storage(groundwater_storage: ndarray[Any, dtype[float32]], vertical_flow_to_groundwater: ndarray[Any, dtype[float32]], bypass_flow: ndarray[Any, dtype[float32]], max_percolation_rate_uzlz: float | ndarray[Any, dtype[float32]], groundwater_loss: float | ndarray[Any, dtype[float32]], reservoir_const_upper_groundwater: float | ndarray[Any, dtype[float32]], reservoir_const_lower_groundwater: float | ndarray[Any, dtype[float32]]) dict[str, ndarray[Any, dtype[float32]]]

Update groundwater storage and calculate below ground horizontal flow.

Groundwater storage and transport are modelled using two parallel linear reservoirs, similar to the approach used in the HBV-96 model (Lindström et al., 1997) and the LISFLOOD (Van Der Knijff et al., 2010) (see for full documentation).

The upper zone represents a quick runoff component, which includes fast groundwater and subsurface flow through macro-pores in the soil. The lower zone represents the slow groundwater component that generates the base flow.

The outflow from the upper zone to the channel, \(Q_{uz}\), [mm], equals:

\(Q_{uz} = \frac{1}{T_{uz}} * UZ * \Delta t\)

where \(T_{uz}\) is the reservoir constant for the upper groundwater layer [days], and \(UZ\) is the amount of water that is stored in the upper zone [mm]. The amount of water stored in the upper zone is computed as follows:

\(UZ = D_{ls,gw} + D_{pref,gw} - D{uz,lz}\)

where \(D_{ls,gw}\) is the flow from the lower soil layer to groundwater, \(D_{pref,gw}\) is the amount of preferential flow or bypass flow per time step, \(D_{uz,lz}\) is the amount of water that percolates from the upper to the lower zone, all in [mm].

The water percolates from the upper to the lower zone is the inflow to the lower groundwater zone. This amount of water is provided by the upper groundwater zone. \(D_{uz,lz}\) is a fixed amount per computational time step and it is defined as follows:

\(D_{uz,lz} = min(GW_{perc} * \Delta t, UZ)\)

where \(GW_{perc}\), [mm day], is the maximum percolation rate from the upper to the lower groundwater zone. The outflow from the lower zone to the channel is then computed by:

\(Q_{lz} = \frac{1}{T_{lz}} * LZ * \Delta t\)

\(T_{lz}\) is the reservoir constant for the lower groundwater layer, [days], and \(LZ\) is the amount of water that is stored in the lower zone, [mm]. \(LZ\) is computed as follows:

\(LZ = D_{uz,lz} - (GW_{loss} * \Delta t)\)

where \(D_{uz,lz}\) is the percolation from the upper groundwater zone,[mm], and \(GW_{loss}\) is the maximum percolation rate from the lower groundwater zone, [mm day].

The amount of water defined by \(GW_{loss}\) never rejoins the river channel and is lost beyond the catchment boundaries or to deep groundwater systems. The larger the value of ath:GW_{loss}, the larger the amount of water that leaves the system.

Parameters:
  • groundwater_storage – amount of water that is stored in the groundwater reservoir , [mm]

  • vertical_flow_to_groundwater – flux from the lower soil layer to groundwater for this timestep, [mm]

  • bypass_flow – flow that bypasses the soil matrix and drains directly to the groundwater, [mm]

  • max_percolation_rate_uzlz – maximum percolation rate between upper and lower groundwater zone, [mm d-1]

  • groundwater_loss – constant amount of water that never rejoins the river channel and is lost beyond the catchment boundaries or to deep groundwater systems, [mm]

  • reservoir_const_upper_groundwater – reservoir constant for the upper groundwater layer, [days]

  • reservoir_const_lower_groundwater – reservoir constant for the lower groundwater layer, [days]

Returns:

updated amount of water stored in upper and lower zone, outflow from the upper zone to the channel, and outflow from the lower zone to the channel

virtual_ecosystem.models.hydrology.below_ground.update_soil_moisture(soil_moisture: ndarray[Any, dtype[float32]], vertical_flow: ndarray[Any, dtype[float32]], evapotranspiration: ndarray[Any, dtype[float32]], soil_moisture_capacity: ndarray[Any, dtype[float32]], soil_moisture_residual: ndarray[Any, dtype[float32]]) ndarray[Any, dtype[float32]]

Update soil moisture profile.

This function calculates soil moisture for each layer by removing the vertical flow of the current layer and adding it to the layer below. The implementation is based on Van Der Knijff et al. (2010). Additionally, the evapotranspiration is removed from the second soil layer.

Parameters:
  • soil_moisture – soil moisture after infiltration and surface evaporation, [mm]

  • vertical_flow – vertical flow between all layers, [mm]

  • evapotranspiration – canopy evaporation, [mm]

  • soil_moisture_capacity – soil moisture capacity for each layer, [mm]

  • soil_moisture_residual – residual soil moisture for each layer, [mm]

Returns:

updated soil moisture profile, relative volumetric water content, dimensionless