HydPy-Dam-L-RB (retention basin model adopted from LARSIM)

dam_lretention is a simple “retention basin” model, similar to the “RUEC” model of LARSIM. One can understand it as an extension of dam_llake, which partly requires equal specifications. Hence, before continuing, please first the documentation on dam_llake.

In extension to dam_llake, dam_lretention implements the control parameter AllowedRelease (and the related parameters WaterLevelMinimumThreshold and WaterLevelMinimumTolerance). Usually, one takes the discharge that does not cause any harm downstream the “allowed release”, making dam_lretention behave like a retention basin without active control. However, one can vary the allowed release seasonally (AllowedRelease inherits from class SeasonalParameter).

In contrast to dam_llake, dam_lretention does not allow to restrict the speed of the water level decrease during periods with little inflow, and thus does not use the parameter AllowedWaterLevelDrop.

Integration tests

Note

When new to HydPy, consider reading section Integration Tests first.

We reuse the dam_llake test set,, including identical input series and an identical relationship between stage and volume:

>>> from hydpy import IntegrationTest, Element, pub
>>> pub.timegrids = "01.01.2000", "21.01.2000", "1d"
>>> parameterstep("1d")
>>> element = Element("element", inlets="input_", outlets="output")
>>> element.model = model
>>> test = IntegrationTest(element)
>>> test.dateformat = "%d.%m."
>>> test.plotting_options.axis1 = fluxes.inflow, fluxes.outflow
>>> test.plotting_options.axis2 = states.watervolume
>>> test.inits = [
...     (states.watervolume, 0.0),
...     (logs.loggedadjustedevaporation, 0.0)]
>>> test.reset_inits()
>>> conditions = model.conditions
>>> watervolume2waterlevel(PPoly.from_data(xs=[0.0, 1.0], ys=[0.0, 1.0]))
>>> surfacearea(1.44)
>>> catchmentarea(86.4)
>>> correctionprecipitation(1.2)
>>> correctionevaporation(1.2)
>>> weightevaporation(0.8)
>>> thresholdevaporation(0.0)
>>> toleranceevaporation(0.001)
>>> with model.add_precipmodel_v2("meteo_precip_io") as precipmodel:
...     precipitationfactor(1.0)
>>> precipmodel.prepare_inputseries()
>>> precipmodel.sequences.inputs.precipitation.series = [
...     0.0, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
>>> element.inlets.input_.sequences.sim.series = [
...     0.0, 0.0, 6.0, 12.0, 10.0, 6.0, 3.0, 2.0, 1.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

base scenario

To show that dam_lretention extends dam_llake correctly, we also define the same quasi-linear relation between discharge and stage used throughout the integration tests of dam_llake and additionally set the allowed release to 0 m³/s (which makes the values of the two water-related control parameters irrelevant). As expected, dam_lretention now calculates outflow values identical to the ones of the base scenario example of dam_llake (where AllowedWaterLevelDrop is inf):

>>> waterlevel2flooddischarge(PPoly.from_data(xs=[0.0, 1.0], ys=[0.0, 10.0]))
>>> allowedrelease(0.0)
>>> waterlevelminimumtolerance(0.1)
>>> waterlevelminimumthreshold(0.0)
>>> test("dam_lretention_base_scenario")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> from hydpy import round_
>>> round_(model.check_waterbalance(conditions))
0.0

spillway

Now, we introduce a more realistic relationship between flood discharge and stage based on class ANN, where the spillway of the retention basin starts to become relevant when the water volume exceeds about 1.4 million m³:

>>> waterlevel2flooddischarge(ANN(weights_input=10.0, weights_output=50.0,
...                               intercepts_hidden=-20.0, intercepts_output=0.0))
>>> figure = waterlevel2flooddischarge.plot(0.0, 2.0)
>>> from hydpy.core.testtools import save_autofig
>>> save_autofig("dam_lretention_waterlevel2flooddischarge.png", figure=figure)
_images/dam_lretention_waterlevel2flooddischarge.png

The initial storage volume of about 1.4 million m³ reduces the peak flow to 7.3 m³/s:

>>> test("dam_lretention_spillway")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

allowed release

In the spillway example, dam_lretention would not handle a second event following the first one similarly well due to the retention basin not releasing the remaining 1.4 million m³ water. Setting the allowed release to 4 m³/s solves this problem and decreases the amount of water stored during the beginning of the event and thus further reduces the peak flow to 4.6 m³/s:

>>> allowedrelease(4.0)
>>> waterlevelminimumthreshold(0.1)
>>> test("dam_lretention_allowed_release")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

The initial and final water volumes shown in the last table are slightly negative due to the periods of zero inflow in combination with the value of parameter WaterLevelMinimumTolerance set to 0.1 m. One could avoid such negative values by increasing WaterLevelMinimumThreshold or decreasing WaterLevelMinimumTolerance. Theoretically, one could set WaterLevelMinimumTolerance to zero at the cost of potentially increased computation times.

evaporation

This example takes up the evaporation example of application model dam_llake. The effect of evaporation on the retention of the flood wave is as little as expected:

>>> with model.add_pemodel_v1("evap_ret_io") as pemodel:
...     evapotranspirationfactor(1.0)
>>> pemodel.prepare_inputseries()
>>> pemodel.sequences.inputs.referenceevapotranspiration.series = 10 * [1.0] + 10 * [5.0]
>>> test("dam_lretention_evaporation")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0
class hydpy.models.dam_lretention.Model[source]

Bases: Main_PrecipModel_V2, Main_PEModel_V1

HydPy-Dam-L-RB (retention basin model adopted from LARSIM).

The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
The following methods define the relevant components of a system of ODE equations (e.g. direct runoff):
The following methods define the complete equations of an ODE system (e.g. change in storage of fast water due to effective precipitation and direct runoff):
The following “outlet update methods” are called in the given sequence at the end of each simulation step:
  • Calc_WaterLevel_V1 Determine the water level based on an interpolation approach approximating the relationship between water volume and water level.

  • Pass_Outflow_V1 Update the outlet link sequence Q.

Users can hook submodels into the defined main model if they satisfy one of the following interfaces:
  • PrecipModel_V2 Simple interface for determining precipitation in one step.

  • PETModel_V1 Simple interface for calculating all potential evapotranspiration values in one step.

DOCNAME: DocName = ('Dam-L-RB', 'retention basin model adopted from LARSIM')
precipmodel: modeltools.SubmodelProperty

Optional submodel that complies with the following interface: PrecipModel_V2.

pemodel: modeltools.SubmodelProperty

Optional submodel that complies with the following interface: PETModel_V1.

check_waterbalance(initial_conditions: dict[str, dict[str, dict[str, float | ndarray[Any, dtype[float64]]]]]) float[source]

Determine the water balance error of the previous simulation run in million m³.

Method check_waterbalance() calculates the balance error as follows:

\(Seconds \cdot 10^{-6} \cdot \sum_{t=t0}^{t1} \big( AdjustedPrecipitation_t - ActualEvaporation_t + Inflow_t - Outflow_t \big) + \big( WaterVolume_{t0}^k - WaterVolume_{t1}^k \big)\)

The returned error should always be in scale with numerical precision so that it does not affect the simulation results in any relevant manner.

Pick the required initial conditions before starting the simulation run via property conditions. See the integration tests of the application model dam_lretention for some examples.

REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()
class hydpy.models.dam_lretention.ControlParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Control parameters of model dam_lretention.

The following classes are selected:
class hydpy.models.dam_lretention.DerivedParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Derived parameters of model dam_lretention.

The following classes are selected:
class hydpy.models.dam_lretention.FactorSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FactorSequences

Factor sequences of model dam_lretention.

The following classes are selected:
class hydpy.models.dam_lretention.FluxSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FluxSequences

Flux sequences of model dam_lretention.

The following classes are selected:
class hydpy.models.dam_lretention.InletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InletSequences

Inlet sequences of model dam_lretention.

The following classes are selected:
  • Q() Inflow [m³/s].

class hydpy.models.dam_lretention.LogSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: LogSequences

Log sequences of model dam_lretention.

The following classes are selected:
class hydpy.models.dam_lretention.OutletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: OutletSequences

Outlet sequences of model dam_lretention.

The following classes are selected:
  • Q() Outflow [m³/s].

class hydpy.models.dam_lretention.SolverParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Solver parameters of model dam_lretention.

The following classes are selected:
  • AbsErrorMax() Absolute numerical error tolerance [m³/s].

  • RelErrorMax() Relative numerical error tolerance [1/T].

  • RelDTMin() Smallest relative integration time step size allowed [-].

  • RelDTMax() Largest relative integration time step size allowed [-].

class hydpy.models.dam_lretention.StateSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: StateSequences

State sequences of model dam_lretention.

The following classes are selected: