dam_v006

Controlled lake version of HydPy-Dam.

Conceptionally, dam_v006 is similar to the “controlled lake” model of LARSIM (selectable via the “SEEG” option). It simulates flood retention processes only and neglects losses due to evaporation.

One can regard dam_v006 as controlled in two ways. First, it allows for seasonal modifications of the rating curve via parameter WaterLevel2FloodDischarge; second, it allows to restrict the speed of the water level decrease during periods with little inflow via parameter AllowedWaterLevelDrop.

Like all models of the HydPy-D family, dam_v006 solves its underlying continuous ordinary differential equations with an error-adaptive numerical integration method. Hence, simulation speed, robustness, and accuracy depend both on the configuration of the parameters of the model equations and the underlying solver. We discuss these topics in more detail in the documentation on the application model dam_v001. Before the first usage of any HydPy-Dam model, you should at least read how to set proper smoothing parameter values and how to configure the artificial neural networks used to model the relationships between stage and volume (WaterVolume2WaterLevel) and between discharge and stage (WaterLevel2FloodDischarge).

Integration tests

Note

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

We are going to perform all example calculations over 20 days:

>>> from hydpy import pub
>>> pub.timegrids = "01.01.2000", "21.01.2000", "1d"

Now, we prepare a dam_v006 model instance in the usual manner:

>>> from hydpy.models.dam_v006 import *
>>> parameterstep("1d")

Next, we embed this model instance into an Element, being connected to one inlet Node (input_) and one outlet Node (output):

>>> from hydpy import Element
>>> element = Element("element", inlets="input_", outlets="output")
>>> element.model = model

To execute the following examples conveniently, we prepare a test function object and change some of its default output settings:

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

WaterVolume is the only state sequence of dam_v006. We set its initial value for each example to zero:

>>> test.inits = [(states.watervolume, 0.0)]

dam_v006 assumes the relationship between WaterLevel and WaterVolume to be constant over time. To allow for maximum flexibility, it uses parameter WaterVolume2WaterLevel, which extends the artificial neural network parameter ANN. For simplicity, we enforce a linear relationship between WaterLevel and WaterVolume (as shown in the following graph):

>>> watervolume2waterlevel(
...     weights_input=1.0, weights_output=1.0,
...     intercepts_hidden=0.0, intercepts_output=0.0,
...     activation=0)
>>> watervolume2waterlevel.plot(0.0, 1.0)
>>> from hydpy.core.testtools import save_autofig
>>> save_autofig("dam_v006_watervolume2waterlevel.png")
_images/dam_v006_watervolume2waterlevel.png

dam_v006 uses parameter WaterLevel2FloodDischarge (which extends parameter SeasonalANN) to allow for annual changes in the relationship between FloodDischarge and WaterLevel. Please read the documentation on class SeasonalANN on how to model seasonal patterns. Here, we again keep things as simple as possible and define a single linear relationship which applies for the whole year:

>>> waterlevel2flooddischarge(ann(
...     weights_input=1.0, weights_output=10.0,
...     intercepts_hidden=0.0, intercepts_output=0.0,
...     activation=0))
>>> waterlevel2flooddischarge.plot(0.0, 1.0)
>>> save_autofig("dam_v006_waterlevel2flooddischarge.png")
_images/dam_v006_waterlevel2flooddischarge.png

Additionally, we set the value of the related smoothing parameter DischargeTolerance to 0.1 m³/s (this is a value we can recommend for many cases – see the documentation on application model dam_v001 on how to fine-tune such smoothing parameter to your needs):

>>> dischargetolerance(0.1)

Finally, we define the ingoing flood wave, starting and ending with zero discharge:

>>> element.inlets.input_.sequences.sim.series = [
...     0.0, 1.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

For our first example, we set the AllowedWaterLevelDrop to inf, to make sure this possible restriction does never affect the calculated lake outflow:

>>> allowedwaterleveldrop(inf)

The only purpose of parameter CatchmentArea is to determine reasonable default values for the parameter AbsErrorMax automatically, controlling the accuracy of the numerical integration process:

>>> catchmentarea(86.4)
>>> from hydpy import round_
>>> round_(solver.abserrormax.INIT)
0.01
>>> parameters.update()
>>> solver.abserrormax
abserrormax(0.01)

The following test results show the expected storage retention pattern. The sums of inflow and outflow are nearly identical, and the maximum of the outflow graph intersects with the falling limb of the inflow graph:

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

dam_v006 achieves this sufficiently high accuracy with 174 calls to its underlying system of differential equations, which averages to less than nine calls per day:

>>> model.numvars.nmb_calls
174

low accuracy

Through increasing the numerical tolerance, e.g. setting AbsErrorMax to 0.1 m³/s, we can gain some additional speedups without relevant deteriorations of the results (dam_v006 usually achieves higher accuracies than indicated by the actual tolerance value):

>>> model.numvars.nmb_calls = 0
>>> solver.abserrormax(0.1)
>>> test("dam_v006_low_accuracy")
Click to see the table
Click to see the graph
>>> model.numvars.nmb_calls
104

water level drop

When setting AllowedWaterLevelDrop to 0.1 m/d, the resulting outflow hydrograph shows a plateau in its falling limb. This plateau is placed in the period where little inflow occurs, but the potential outflow (FloodDischarge) is still high due to large amounts of stored water:

>>> allowedwaterleveldrop(0.1)
>>> solver.abserrormax(0.01)
>>> test("dam_v006_water_level_drop")
Click to see the table
Click to see the graph
class hydpy.models.dam_v006.Model[source]

Bases: hydpy.core.modeltools.ELSModel

Version 6 of HydPy-Dam.

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):
  • Pic_Inflow_V1 Update the inlet link sequence.

  • Calc_WaterLevel_V1 Determine the water level based on an artificial neural network describing the relationship between water level and water stage.

  • Calc_SurfaceArea_V1 Determine the surface area based on an artificial neural network describing the relationship between water level and water stage.

  • Calc_FloodDischarge_V1 Calculate the discharge during and after a flood event based on an SeasonalANN describing the relationship(s) between discharge and water stage.

  • Calc_AllowedDischarge_V1 Calculate the maximum discharge not leading to exceedance of the allowed water level drop.

  • Calc_Outflow_V2 Calculate the total outflow of the dam, taking the allowed water discharge into account.

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:
The following “additional methods” might be called by one or more of the other methods or are meant to be directly called by the user:
  • Fix_Min1_V1 Apply function smooth_min1() without risking negative results.

numconsts: hydpy.core.modeltools.NumConstsELS
numvars: hydpy.core.modeltools.NumVarsELS
class hydpy.models.dam_v006.AideSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.ModelSequences[AideSequence, hydpy.core.variabletools.FastAccess]

Aide sequences of model dam_v006.

The following classes are selected:
class hydpy.models.dam_v006.ControlParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Control parameters of model dam_v006.

The following classes are selected:
class hydpy.models.dam_v006.DerivedParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Derived parameters of model dam_v006.

The following classes are selected:
class hydpy.models.dam_v006.FluxSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.OutputSequences[FluxSequence]

Flux sequences of model dam_v006.

The following classes are selected:
class hydpy.models.dam_v006.InletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.LinkSequences[InletSequence]

Inlet sequences of model dam_v006.

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

class hydpy.models.dam_v006.OutletSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.LinkSequences[OutletSequence]

Outlet sequences of model dam_v006.

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

class hydpy.models.dam_v006.SolverParameters(master: hydpy.core.parametertools.Parameters, cls_fastaccess: Optional[Type[hydpy.core.parametertools.FastAccessParameter]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.variabletools.SubVariables[hydpy.core.parametertools.Parameters, Parameter, hydpy.core.parametertools.FastAccessParameter]

Solver parameters of model dam_v006.

The following classes are selected:
  • AbsErrorMax() Absolute numerical error tolerance [m3/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_v006.StateSequences(master: hydpy.core.sequencetools.Sequences, cls_fastaccess: Optional[Type[FastAccessType]] = None, cymodel: Optional[hydpy.core.typingtools.CyModelProtocol] = None)

Bases: hydpy.core.sequencetools.OutputSequences[StateSequence]

State sequences of model dam_v006.

The following classes are selected: