Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tests/models/hydrology/test_below_ground.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
HydroConsts.soil_moisture_residual,
HydroConsts.hydraulic_conductivity,
HydroConsts.hydraulic_gradient,
HydroConsts.nonlinearily_parameter,
HydroConsts.van_genuchten_nonlinearily_parameter,
HydroConsts.groundwater_capacity,
),
(
Expand Down Expand Up @@ -94,7 +94,7 @@ def test_convert_soil_moisture_to_water_potential():
actual_potentials = convert_soil_moisture_to_water_potential(
soil_moisture=np.repeat(0.2, 3),
air_entry_water_potential=HydroConsts.air_entry_water_potential,
water_retention_curvature=HydroConsts.water_retention_curvature,
campbell_pore_size_distribution=HydroConsts.campbell_pore_size_distribution,
soil_moisture_capacity=HydroConsts.soil_moisture_capacity,
)

Expand Down
6 changes: 3 additions & 3 deletions virtual_ecosystem/models/hydrology/above_ground.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ def calculate_bypass_flow(
top_soil_moisture: NDArray[np.float32],
sat_top_soil_moisture: NDArray[np.float32],
available_water: NDArray[np.float32],
infiltration_shape_parameter: float,
bypass_flow_coefficient: float,
) -> NDArray[np.float32]:
r"""Calculate preferential bypass flow.

Expand All @@ -358,15 +358,15 @@ def calculate_bypass_flow(
top_soil_moisture: Soil moisture of top soil layer, [mm]
sat_top_soil_moisture: Soil moisture of top soil layer at saturation, [mm]
available_water: Amount of water available for infiltration, [mm]
infiltration_shape_parameter: Shape parameter for infiltration
bypass_flow_coefficient: Bypass flow coefficient

Returns:
preferential bypass flow, [mm]
"""

return (
available_water
* (top_soil_moisture / sat_top_soil_moisture) ** infiltration_shape_parameter
* (top_soil_moisture / sat_top_soil_moisture) ** bypass_flow_coefficient
)


Expand Down
17 changes: 9 additions & 8 deletions virtual_ecosystem/models/hydrology/below_ground.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def calculate_vertical_flow(
soil_moisture_residual: float | NDArray[np.float32],
hydraulic_conductivity: float | NDArray[np.float32],
hydraulic_gradient: float | NDArray[np.float32],
nonlinearily_parameter: float | NDArray[np.float32],
van_genuchten_nonlinearily_parameter: float | NDArray[np.float32],
groundwater_capacity: float | NDArray[np.float32],
seconds_to_day: float,
) -> NDArray[np.float32]:
Expand Down Expand Up @@ -56,16 +56,16 @@ def calculate_vertical_flow(
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.
van_genuchten_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]
"""
shape_parameter = 1 - 1 / nonlinearily_parameter
shape_parameter = 1 - 1 / van_genuchten_nonlinearily_parameter

# Calculate soil effective saturation in rel. vol. water content for each layer:
# TODO make this function a tool
Expand Down Expand Up @@ -174,7 +174,7 @@ def update_soil_moisture(
def convert_soil_moisture_to_water_potential(
soil_moisture: NDArray[np.float32],
air_entry_water_potential: float,
water_retention_curvature: float,
campbell_pore_size_distribution: float,
soil_moisture_capacity: float,
) -> NDArray[np.float32]:
r"""Convert soil moisture into an estimate of water potential.
Expand All @@ -194,7 +194,8 @@ def convert_soil_moisture_to_water_potential(
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]
campbell_pore_size_distribution: Curvature of water retention curve, an
indicator of pore size distribution, [unitless]
soil_moisture_capacity: The relative water content at which the soil is fully
saturated, [unitless].

Expand All @@ -203,7 +204,7 @@ def convert_soil_moisture_to_water_potential(
"""

return air_entry_water_potential * (
(soil_moisture / soil_moisture_capacity) ** water_retention_curvature
(soil_moisture / soil_moisture_capacity) ** campbell_pore_size_distribution
)


Expand Down
15 changes: 8 additions & 7 deletions virtual_ecosystem/models/hydrology/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class HydroConsts(ConstantsDataclass):
movement of water and indicates the direction in which water will flow.
"""

nonlinearily_parameter: float = 2.0
van_genuchten_nonlinearily_parameter: float = 2.0
"""Nonlinearity parameter n (dimensionless) in Mualem-van Genuchten model.

This parameter is a fitting shape parameters of soil water retention curve, see
Expand Down Expand Up @@ -93,8 +93,8 @@ class HydroConsts(ConstantsDataclass):
which affects the vertical flow of water and the horizontal sub-surface flow. This
parameter is currently set to an arbitrary value and might."""

infiltration_shape_parameter: float = 1.0
"""Empirical infiltration shape parameter, unitless.
bypass_flow_coefficient: float = 1.0
"""Empirical bypass flow coefficient, unitless.

This parameter affects how much of the water available for infiltration goes
directly to groundwater via preferential bypass flow. A value of
Expand All @@ -111,11 +111,12 @@ class HydroConsts(ConstantsDataclass):
texture.
"""

water_retention_curvature: float = -7.22
"""Curvature of the water retention curve.
campbell_pore_size_distribution: float = -7.22
"""Curvature of the water retention curve as indicator of pore size distribution.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Campbell mean here, is it from a specific model?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the reference to the constants; the reference is also in the function docstring.


The value is the average across all soil types found in
:cite:t:`cosby_statistical_1984`; see documentation for
This constant is used to convert soil moisture to matric potential following
:cite:t:`campbell_simple_1974`. The value is the average across all soil types found
in :cite:t:`cosby_statistical_1984`; see documentation for
:attr:`air_entry_water_potential` for further details.
"""

Expand Down
12 changes: 6 additions & 6 deletions virtual_ecosystem/models/hydrology/hydrology_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,7 @@ def _update(self, time_index: int, **kwargs: Any) -> None:
top_soil_moisture=hydro_input["current_soil_moisture"][0],
sat_top_soil_moisture=hydro_input["top_soil_moisture_capacity"],
available_water=precipitation_surface - surface_runoff,
infiltration_shape_parameter=(
self.model_constants.infiltration_shape_parameter
),
bypass_flow_coefficient=(self.model_constants.bypass_flow_coefficient),
)
daily_lists["bypass_flow"].append(bypass_flow)

Expand Down Expand Up @@ -555,7 +553,9 @@ def _update(self, time_index: int, **kwargs: Any) -> None:
self.model_constants.hydraulic_conductivity
), # m/s
hydraulic_gradient=self.model_constants.hydraulic_gradient, # m/m
nonlinearily_parameter=self.model_constants.nonlinearily_parameter,
van_genuchten_nonlinearily_parameter=(
self.model_constants.van_genuchten_nonlinearily_parameter
),
groundwater_capacity=self.model_constants.groundwater_capacity,
seconds_to_day=self.core_constants.seconds_to_day,
)
Expand Down Expand Up @@ -588,8 +588,8 @@ def _update(self, time_index: int, **kwargs: Any) -> None:
air_entry_water_potential=(
self.model_constants.air_entry_water_potential
),
water_retention_curvature=(
self.model_constants.water_retention_curvature
campbell_pore_size_distribution=(
self.model_constants.campbell_pore_size_distribution
),
soil_moisture_capacity=self.model_constants.soil_moisture_capacity,
)
Expand Down