HYMOD Model¶
HYMOD is a conceptual rainfall-runoff model combining an exponential soil-moisture accounting store with a series of linear reservoirs (Nash cascade) for routing.
- Registered name:
hymod - Parameters: 5
- Routing: Nash cascade
API Reference¶
hymod(p_and_e, parameters, warmup_length=30, return_state=False, normalized_params='auto', **kwargs)
¶
Run Hymod model
See https://www.proc-iahs.net/368/180/2015/piahs-368-180-2015.pdf for a scientific paper: Quan, Z.; Teng, J.; Sun, W.; Cheng, T. & Zhang, J. (2015): Evaluation of the HYMOD model for rainfall–runoff simulation using the GLUE method. Remote Sensing and GIS for Hydrology and Water Resources, 180 - 185, IAHS Publ. 368. DOI: 10.5194/piahs-368-180-2015.
Parameters¶
p_and_e precipitation and potential evapotranspiration, 3-dim variable: [time, basin, feature=1] parameters five parameters: cmax, bexp, alpha, ks, kq warmup_length the length of warmup period return_state if True, return x_slow, x_quick, x_loss, else only return streamflow normalized_params parameter format specification: - "auto": automatically detect if parameters are normalized (0-1) or original scale (default) - True: parameters are normalized (0-1 range), will be converted to original scale - False: parameters are already in original scale, use as-is
Returns¶
Union[list, np.array] streamflow, x_slow, x_quick, x_loss or streamflow
Source code in hydromodel/models/hymod.py
def hymod(
p_and_e,
parameters,
warmup_length=30,
return_state=False,
normalized_params="auto",
**kwargs,
):
"""
Run Hymod model
See https://www.proc-iahs.net/368/180/2015/piahs-368-180-2015.pdf for a scientific paper:
Quan, Z.; Teng, J.; Sun, W.; Cheng, T. & Zhang, J. (2015): Evaluation of the HYMOD model
for rainfall–runoff simulation using the GLUE method. Remote Sensing and GIS for Hydrology
and Water Resources, 180 - 185, IAHS Publ. 368. DOI: 10.5194/piahs-368-180-2015.
Parameters
----------
p_and_e
precipitation and potential evapotranspiration, 3-dim variable: [time, basin, feature=1]
parameters
five parameters: cmax, bexp, alpha, ks, kq
warmup_length
the length of warmup period
return_state
if True, return x_slow, x_quick, x_loss, else only return streamflow
normalized_params
parameter format specification:
- "auto": automatically detect if parameters are normalized (0-1) or original scale (default)
- True: parameters are normalized (0-1 range), will be converted to original scale
- False: parameters are already in original scale, use as-is
Returns
-------
Union[list, np.array]
streamflow, x_slow, x_quick, x_loss or streamflow
"""
model_param_dict = get_model_param_config("hymod", kwargs)
# params
param_ranges = model_param_dict["param_range"]
# Process parameters using unified parameter handling
processed_params = process_parameters(
parameters, param_ranges, normalized=normalized_params
)
# Extract individual parameters from processed array
cmax = processed_params[:, 0]
bexp = processed_params[:, 1]
alpha = processed_params[:, 2]
ks = processed_params[:, 3]
kq = processed_params[:, 4]
if warmup_length > 0:
# set no_grad for warmup periods
p_and_e_warmup = p_and_e[0:warmup_length, :, :]
_, _, x_slow, x_quick, x_loss = hymod(
p_and_e_warmup,
parameters,
warmup_length=0,
return_state=True,
**kwargs,
)
else:
# Initialize slow tank state
# x_slow = 2.3503 / (ks * 22.5)
x_slow = np.full(
(p_and_e.shape[1], 1), 0.0
) # --> works ok if calibration data starts with low discharge
# Initialize state(s) of quick tank(s)
x_quick = np.full((p_and_e.shape[1], 3), 0.0)
# HYMOD PROGRAM IS SIMPLE RAINFALL RUNOFF MODEL
x_loss = np.full((p_and_e.shape[1], 1), 0.0)
precip = p_and_e[warmup_length:, :, 0]
pet = p_and_e[warmup_length:, :, 1]
t = 0
output = np.full(precip.shape, 0.0)
# START PROGRAMMING LOOP WITH DETERMINING RAINFALL - RUNOFF AMOUNTS
while t <= precip.shape[0] - 1:
pval = precip[t, :]
pet_val = pet[t, :]
# Compute excess precipitation and evaporation
er1, er2, x_loss = excess(x_loss, cmax, bexp, pval, pet_val)
# Calculate total effective rainfall
et = er1 + er2
# Now partition ER between quick and slow flow reservoirs
uq = alpha * et
us = (1 - alpha) * et
# Route slow flow component with single linear reservoir
x_slow, qs = linres(x_slow, us, ks)
# Route quick flow component with linear reservoirs
inflow = uq
for i in range(3):
# Linear reservoir
x_quick[:, i], outflow = linres(x_quick[:, i], inflow, kq)
inflow = outflow
# Compute total flow for timestep
output[t, :] = qs + outflow
t += 1
streamflow = np.expand_dims(output, axis=2)
if return_state:
return streamflow, et, x_slow, x_quick, x_loss
return streamflow, et