API documentation for the hydrology_model module

The hydrology_model module creates a HydrologyModel class as a child of the BaseModel class.

There are still a number of open TODOs related to process implementation and improvement , time step and model structure, and units and module coordination.

TODO processes

  • spin up soil moisture and accumulated runoff

  • set boundaries for river discharge

  • add canopy evaporation

  • update infiltration process

TODO time step and model structure

  • Move calculation of static arrays and selection of indices to LayerStructure

  • find a way to load daily (precipitation) data and loop over daily time_index

  • add time dimension to required_init_vars

  • allow for different time steps (currently only 30 days)

  • potentially move calculate_drainage_map to core

  • add abiotic constants from config

TODO units and module coordination

  • change temperature to Kelvin

  • change soil moisture to mm

Classes:

HydrologyModel(data, core_components, ...[, ...])

A class describing the hydrology model.

class virtual_ecosystem.models.hydrology.hydrology_model.HydrologyModel(data: Data, core_components: CoreComponents, initial_soil_moisture: float, initial_groundwater_saturation: float, model_constants: HydroConsts = HydroConsts(), **kwargs: Any)

A class describing the hydrology model.

Parameters:
  • data – The data object to be used in the model.

  • core_components – The core components used across models.

  • initial_soil_moisture – The initial volumetric relative water content [unitless] for all layers. This will be converted to soil moisture in mm.

  • initial_groundwater_saturation – Initial level of groundwater saturation (between 0 and 1) for all layers and grid cells identical. This will be converted to groundwater storage in mm.

  • model_constants – Set of constants for the hydrology model.

Raises:

InitialisationError – when soil moisture or saturation parameters are not numeric or out of [0, 1] bounds.

Methods:

cleanup()

Placeholder function for hydrology model cleanup.

from_config(data, core_components, config)

Factory function to initialise the hydrology model from configuration.

setup()

Function to set up the hydrology model.

spinup()

Placeholder function to spin up the hydrology model.

update(time_index, **kwargs)

Function to update the hydrology model.

Attributes:

core_constants

Set of core constants for the hydrology model

drainage_map

Upstream neighbours for the calculation of accumulated horizontal flow.

initial_groundwater_saturation

Initial level of groundwater saturation for all layers identical.

initial_soil_moisture

Initial volumetric relative water content [unitless] for all layers and grid cells identical.

model_constants

Set of constants for the hydrology model

nan_fill_atmosphere

Array of nan representing non-soil layers.

soil_layer_thickness

Soil layer thickness in mm.

subcanopy_layer_index

Subcanopy layer index.

cleanup() None

Placeholder function for hydrology model cleanup.

core_constants: CoreConsts

Set of core constants for the hydrology model

data: Data

A Data instance providing access to the shared simulation data.

drainage_map

Upstream neighbours for the calculation of accumulated horizontal flow.

classmethod from_config(data: Data, core_components: CoreComponents, config: Config) HydrologyModel

Factory function to initialise the hydrology model from configuration.

This function unpacks the relevant information from the configuration file, and then uses it to initialise the model. If any information from the config is invalid rather than returning an initialised model instance an error is raised.

Parameters:
  • data – A Data instance.

  • core_components – The core components used across models.

  • config – A validated Virtual Ecosystem model configuration object.

initial_groundwater_saturation: float

Initial level of groundwater saturation for all layers identical.

initial_soil_moisture: float

Initial volumetric relative water content [unitless] for all layers and grid cells identical.

layer_structure: LayerStructure

The LayerStructure details used in the model.

model_constants: HydroConsts

Set of constants for the hydrology model

model_timing: ModelTiming

The ModelTiming details used in the model.

model_update_bounds: tuple[pint.Quantity, pint.Quantity] = (<Quantity(1, 'day')>, <Quantity(1, 'month')>)

Bounds on model update frequencies.

This class attribute defines two time intervals that define a lower and upper bound on the update frequency that can reasonably be used with a model. Models updated more often than the lower bound may fail to capture transient dynamics and models updated more slowly than the upper bound may fail to capture important temporal patterns.

nan_fill_atmosphere

Array of nan representing non-soil layers.

required_init_vars: tuple[tuple[str, tuple[str, ...]], ...] = (('layer_heights', ('spatial',)), ('elevation', ('spatial',)))

Required variables for model initialisation.

This class property defines a set of variable names that must be present in the Data instance used to initialise an instance of this class. It is a tuple containing zero or more tuples, each providing a variable name and then a tuple of zero or more core axes that the variable must map onto.

For example: (('temperature', ('spatial', 'temporal')),)

setup() None

Function to set up the hydrology model.

At the moment, this function initializes variables that are required to run the first update(). Air temperature, relative humidity, atmospheric pressure, and wind speed below the canopy are set to the 2 m reference values.

For the within grid cell hydrology, soil moisture is initialised homogenously for all soil layers and groundwater storage is set to the percentage of it’s capacity that was defined in the model configuration. This design might change with the implementation of the SPLASH model (Davis et al., 2017) which will take care of part of the above-ground hydrology.

For the hydrology across the grid, this function initialises the accumulated surface runoff variable and the subsurface accumulated flow variable. Both require a spinup which is currently not implemented.

soil_layer_thickness

Soil layer thickness in mm.

spinup() None

Placeholder function to spin up the hydrology model.

subcanopy_layer_index

Subcanopy layer index.

update(time_index: int, **kwargs: Any) None

Function to update the hydrology model.

This function calculates the main hydrological components of the Virtual Ecosystem and updates the following variables in the data object:

  • precipitation_surface, [mm]

  • soil_moisture, [mm]

  • matric_potential, [kPa]

  • surface_runoff, [mm], equivalent to SPLASH runoff

  • surface_runoff_accumulated, [mm]

  • subsurface_flow_accumulated, [mm]

  • soil_evaporation, [mm]

  • aerodynamic_resistance_surface

  • vertical_flow, [mm d-1]

  • latent_heat_vapourisation, [J kg-1]

  • molar_density_air, [mol m-3]

  • groundwater_storage, [mm]

  • subsurface_flow, [mm]

  • baseflow, [mm]

  • total_river_discharge, [mm]

  • river_discharge_rate, [m3 s-1]

Many of the underlying processes are problematic at a monthly timestep, which is currently the only supported update interval. As a short-term work around, the input precipitation is randomly distributed over 30 days and input evapotranspiration is divided by 30, and the return variables are monthly means or monthly accumulated values.

Precipitation that reaches the surface is defined as incoming precipitation minus canopy interception, which is estimated using a stroage-based approach, see calculate_interception() .

Surface runoff is calculated with a simple bucket model based on Davis et al. (2017), see calculate_surface_runoff() : if precipitation exceeds top soil moisture capacity , the excess water is added to runoff and top soil moisture is set to soil moisture capacity value; if the top soil is not saturated, precipitation is added to the current soil moisture level and runoff is set to zero. Note that this function will likely change with the implementation of the SPLASH model (Davis et al., 2017) in the plant module which will take care of the grid cell based above-ground hydrology. The accumulated surface runoff is calculated as the sum of current runoff and the runoff from upstream cells at the previous time step, see accumulate_horizontal_flow() .

Potential soil evaporation is calculated with classical bulk aerodynamic formulation, following the so-called ‘\(\alpha\) method’, see calculate_soil_evaporation() , and reduced to actual evaporation as a function of leaf area index.

Vertical flow between soil layers is calculated using the Richards equation, see calculate_vertical_flow() . Here, the mean vertical flow in mm per day that goes though the top soil layer is returned to the data object. 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!

Soil moisture is updated by iteratively updating the soil moisture of individual layers under consideration of the vertical flow in and out of each layer, see update_soil_moisture() . The conversion to matric potential is based on Campbell (1974), see convert_soil_moisture_to_water_potential() .

Groundwater storage and flows are modelled using two parallel linear reservoirs, see update_groundwater_storage() . The horizontal flow between grid cells currently uses the same function as the above ground runoff.

Total river discharge is calculated as the sum of above- and below ground horizontal flow and converted to river discharge rate in m3/s.

The function requires the following input variables from the data object:

  • air temperature, [C]

  • relative humidity, []

  • atmospheric pressure, [kPa]

  • precipitation, [mm]

  • wind speed, [m s-1]

  • leaf area index, [m m-2]

  • layer heights, [m]

  • Soil moisture (previous time step), [mm]

  • evapotranspiration (current time step), [mm]

  • accumulated surface runoff (previous time step), [mm]

  • accumulated subsurface flow (previous time step), [mm]

and a number of parameters that as described in detail in HydroConsts.

vars_updated: tuple[str, ...] = ('precipitation_surface', 'soil_moisture', 'surface_runoff', 'vertical_flow', 'latent_heat_vapourisation', 'molar_density_air', 'soil_evaporation', 'aerodynamic_resistance_surface', 'surface_runoff_accumulated', 'subsurface_flow_accumulated', 'matric_potential', 'groundwater_storage', 'river_discharge_rate', 'total_river_discharge', 'subsurface_flow', 'baseflow')

Variables that are updated by the model.

At the moment, this tuple is used to decide which variables to output from the Data object, i.e. every variable updated by a model used in the specific simulation. In future, this could also be used to prevent multiple models from updating the same variable and similar problems.