dam_v002

Version 2 of HydPy-Dam.

Application model dam_v002 is a simplification of dam_v001. While most functionalities are identical, dam_v002 does not calculate RequiredRemoteRelease on its own but picks this information from the simulation results of another model.

The following explanations focus on this difference. For further information on using dam_v002, please read the documentation on model dam_v001.

Integration tests

Note

When new to HydPy, consider reading section How to understand integration tests? first.

Each of the following examples repeats one example demonstrating a specific functionality of application model dam_v001. To achieve comparability, we define identical parameter values, initial conditions, and input time series. The sequence RequiredRemoteRelease requires special care. dam_v001 calculates its values based on other information but dam_v002 expects externally calculated values for it. Hence, we use the tabulated results of the selected dam_v001 examples as the input data of the node object demand, which passes this information to dam_v002 during simulation. The limited precision of the copy-pasted RequiredRemoteRelease values causes some tiny deviations between the results of both models.

The following time- and space-related setup is identical to the one of dam_v001, except we do not need to add other models to construct meaningful examples:

>>> from hydpy import pub
>>> pub.timegrids = "01.01.2000", "21.01.2000",  "1d"
>>> from hydpy import Node
>>> inflow = Node("inflow")
>>> outflow = Node("outflow")
>>> demand = Node("demand", variable="D")
>>> from hydpy import Element
>>> dam = Element("dam", inlets=inflow, outlets=outflow, receivers=demand)
>>> from hydpy.models.dam_v002 import *
>>> parameterstep("1d")
>>> dam.model = model

We prepare an identical IntegrationTest object:

>>> from hydpy import IntegrationTest
>>> test = IntegrationTest(dam)
>>> test.dateformat = "%d.%m."
>>> test.plotting_options.axis1 = fluxes.inflow, fluxes.outflow
>>> test.plotting_options.axis2 = states.watervolume

As initial conditions, dam_v002 requires logged values for the required remote release instead of logged values for the total remote discharge and its outflow. Following the above reasoning, we copy-paste the first value of the “requiredremoterelease” column that is identical for all drought-related calculations performed by dam_v001:

>>> test.inits=((states.watervolume, 0.0),
...             (logs.loggedadjustedevaporation, 0.0),
...             (logs.loggedrequiredremoterelease, 0.005))

Apart from the unnecessary “natural” discharge of the subcatchment underneath the dam, we define identical (for now, constant) input time series:

>>> inflow.sequences.sim.series = 1.0
>>> inputs.precipitation.series = 0.0
>>> inputs.evaporation.series = 0.0

dam_v002 implements fewer parameters than dam_v001. Besides that, all parameter settings are identical:

>>> watervolume2waterlevel(PPoly.from_data(xs=[0.0, 1.0], ys=[0.0, 0.25]))
>>> waterlevel2flooddischarge(PPoly.from_data(xs=[0.0], ys=[0.0]))
>>> catchmentarea(86.4)
>>> neardischargeminimumthreshold(0.2)
>>> neardischargeminimumtolerance(0.2)
>>> waterlevelminimumthreshold(0.0)
>>> waterlevelminimumtolerance(0.0)
>>> restricttargetedrelease(True)
>>> surfacearea(1.44)
>>> correctionprecipitation(1.2)
>>> correctionevaporation(1.2)
>>> weightevaporation(0.8)
>>> thresholdevaporation(0.0)
>>> toleranceevaporation(0.001)

smooth near minimum

This example repeats the smooth near minimum example of application model dam_v001. We use the values of RequiredRemoteRelease calculated by dam_v001, as explained above:

>>> demand.sequences.sim.series = [
...     0.008588, 0.010053, 0.013858, 0.027322, 0.064075, 0.235523, 0.470414,
...     0.735001, 0.891263, 0.696325, 0.349797, 0.105231, 0.111928, 0.240436,
...     0.229369, 0.058622, 0.016958, 0.008447, 0.004155, 0.0]

Note that the first tabulated value (0.005 m³/s) serves as an initial condition, and we have to assign the following nineteen values to the time series of the demand node. The last value of the node’s time series is of no importance. We arbitrarily set it to 0.0 m³/s.

The test results confirm that both models behave identically under low flow conditions for a “near” and a “remote” need for water supply:

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

restriction enabled

This example repeats the restriction enabled example of application model dam_v001. We update the time series of the inflow and the required remote release accordingly:

>>> inflow.sequences.sim.series[10:] = 0.1
>>> demand.sequences.sim.series = [
...     0.008746, 0.010632, 0.015099, 0.03006, 0.068641, 0.242578, 0.474285,
...     0.784512, 0.95036, 0.35, 0.034564, 0.299482, 0.585979, 0.557422,
...     0.229369, 0.142578, 0.068641, 0.029844, 0.012348, 0.0]
>>> neardischargeminimumtolerance(0.0)

The recalculation confirms that the restriction on releasing water when there is little inflow works as explained for model dam_v001:

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

smooth stage minimum

This example repeats the smooth stage minimum example of application model dam_v001. We update parameters NearDischargeMinimumThreshold, WaterLevelMinimumThreshold, and WaterLevelMinimumTolerance, as well as the time series of the inflow and the required remote release, accordingly:

>>> inflow.sequences.sim.series = numpy.linspace(0.2, 0.0, 20)
>>> neardischargeminimumthreshold(0.0)
>>> waterlevelminimumthreshold(0.005)
>>> waterlevelminimumtolerance(0.01)
>>> demand.sequences.sim.series = [
...     0.01232, 0.029323, 0.064084, 0.120198, 0.247367, 0.45567, 0.608464,
...     0.537314, 0.629775, 0.744091, 0.82219, 0.841916, 0.701812, 0.533258,
...     0.351863, 0.185207, 0.107697, 0.055458, 0.025948, 0.0]

dam_v002 deals with limited water available as already known from dam_v001:

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

evaporation

This example repeats the evaporation example of application model dam_v001. We update the time series of potential evaporation and the required remote release accordingly:

>>> inputs.evaporation.series = 10 * [1.0] + 10 * [5.0]
>>> demand.sequences.sim.series = [
...     0.012321, 0.029352, 0.064305, 0.120897, 0.248435, 0.453671, 0.585089,
...     0.550583, 0.694398, 0.784979, 0.81852, 0.840207, 0.72592, 0.575373,
...     0.386003, 0.198088, 0.113577, 0.05798, 0.026921, 0.0]

dam_v002 uses the given evaporation values as discussed for dam_v001:

>>> test("dam_v002_evaporation")
Click to see the table
Click to see the graph
>>> inputs.evaporation.series = 0.0

flood retention

This example repeats the flood retention example of application model dam_v001. We use the same parameter and input time series configuration:

>>> neardischargeminimumthreshold(0.0)
>>> neardischargeminimumtolerance(0.0)
>>> waterlevelminimumthreshold(0.0)
>>> waterlevelminimumtolerance(0.0)
>>> waterlevel2flooddischarge(PPoly.from_data(xs=[0.0, 1.0], ys=[0.0, 2.5]))
>>> neardischargeminimumthreshold(0.0)
>>> 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]
>>> inflow.sequences.sim.series = [0.0, 0.0, 5.0, 9.0, 8.0, 5.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]
>>> demand.sequences.sim.series = 0.0
>>> test.inits.loggedrequiredremoterelease = 0.0

The recalculation results confirm the equality of both models for high flow conditions:

>>> test("dam_v002_flood_retention")
Click to see the table
Click to see the graph
class hydpy.models.dam_v002.Model[source]

Bases: ELSModel

Version 2 of HydPy-Dam.

The following “receiver update methods” are called in the given sequence before performing a simulation step:
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.

class hydpy.models.dam_v002.ControlParameters(master: Parameters, cls_fastaccess: Type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Control parameters of model dam_v002.

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

Bases: SubParameters

Derived parameters of model dam_v002.

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

Bases: FactorSequences

Factor sequences of model dam_v002.

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

Bases: FluxSequences

Flux sequences of model dam_v002.

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

Bases: InletSequences

Inlet sequences of model dam_v002.

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

class hydpy.models.dam_v002.InputSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InputSequences

Input sequences of model dam_v002.

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

Bases: LogSequences

Log sequences of model dam_v002.

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

Bases: OutletSequences

Outlet sequences of model dam_v002.

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

class hydpy.models.dam_v002.ReceiverSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: ReceiverSequences

Receiver sequences of model dam_v002.

The following classes are selected:
  • D() Water demand [m³/s].

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

Bases: SubParameters

Solver parameters of model dam_v002.

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_v002.StateSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: StateSequences

State sequences of model dam_v002.

The following classes are selected: