dam_v008¶
Reservoir version of HydPy-Dam.
dam_v008
is a relatively simple reservoir model, similar to the “TALS”
model of LARSIM. It combines the features of dam_v006
(“controlled
lake”) and dam_v007
(“retention basin”). Additionally, it allows
controlling the stored water volume via defining target values that can
vary seasonally.
Like dam_v007
, dam_v008
allows for combining controlled, “harmless
outflow” (via parameter AllowedRelease
) and uncontrolled, “spillway
outflow” (via parameter WaterLevel2FloodDischarge
), and like dam_v006
,
it allows to restrict the speed of the water level decrease during periods
with little inflow via parameter AllowedWaterLevelDrop
(only through
reducing the controlled outflow, of course). Before continuing, please
first read the documentation on these two application models.
The additional feature of dam_v008
is that it tries to track target
volumes that can vary seasonally. Define these target volumes via
parameter TargetVolume
. The parameters VolumeTolerance
,
TargetRangeAbsolute
, and TargetRangeRelative
serve to yield more
smooth and realistic reservoir responses for small deviations from
the given target values. Setting TargetRangeRelative
to 0.2 and
both other parameters to zero corresponds to selecting the
“TALSPERRE SOLLRANGE” option in LARSIM. Please see the following
examples and the documentation on method Calc_ActualRelease_V3
for
more information on how to set and combine the individual parameter
values for different use-cases.
Integration tests¶
Note
When new to HydPy, consider reading section How to understand integration tests? first.
We create the same test set as for application models dam_v006
and
dam_v007
, including an identical inflow series and an identical
relationship between stage and volume:
>>> from hydpy import IntegrationTest, Element, pub
>>> pub.timegrids = "01.01.2000", "21.01.2000", "1d"
>>> from hydpy.models.dam_v008 import *
>>> parameterstep("1d")
>>> element = Element("element", inlets="input_", outlets="output")
>>> element.model = model
>>> IntegrationTest.plotting_options.axis1 = fluxes.inflow, fluxes.outflow
>>> IntegrationTest.plotting_options.axis2 = states.watervolume
>>> test = IntegrationTest(element)
>>> test.inits = [(states.watervolume, 0.0)]
>>> test.dateformat = "%d.%m."
>>> watervolume2waterlevel(
... weights_input=1.0, weights_output=1.0,
... intercepts_hidden=0.0, intercepts_output=0.0,
... activation=0)
>>> catchmentarea(86.4)
>>> 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¶
First, we again use the quasi-linear relation between discharge
and stage used throughout the integration tests of dam_v006
and in the
base scenario example of dam_v007
:
>>> waterlevel2flooddischarge(ann(
... weights_input=1.0, weights_output=10.0,
... intercepts_hidden=0.0, intercepts_output=0.0,
... activation=0))
Additionally, we set some of the remaining parameter values extremely high or low, to make sure that the reservoir stores all water except the one activating the spillway and thus becoming “flood discharge”:
>>> targetvolume(100.0)
>>> neardischargeminimumthreshold.shape = 1
>>> neardischargeminimumthreshold.values = -100.0
>>> targetrangeabsolute(0.1)
>>> targetrangerelative(0.2)
>>> watervolumeminimumthreshold(0.0)
>>> volumetolerance(0.1)
>>> dischargetolerance(0.1)
>>> allowedrelease(100.0)
>>> allowedwaterleveldrop(100.0)
Due to the same the neural network configuration, the results are identical
with the ones of the base scenario example of dam_v006
and
the base scenario example of dam_v007
:
>>> test("dam_v008_base_scenario")
Click to see the table
Click to see the graph
spillway¶
When we reuse the more realistic relationship between flood discharge
and stage of the spillway example on dam_v007
, we again
get the same flood discharge time series:
>>> waterlevel2flooddischarge(ann(
... weights_input=10.0, weights_output=50.0,
... intercepts_hidden=-20.0, intercepts_output=0.0))
>>> test("dam_v008_spillway")
Click to see the table
Click to see the graph
target volume¶
During dry periods, application model dam_v007
generally releases all
its water until the basin runs dry, as long as parameter AllowedRelease
is larger than zero. Application model dam_v008
is more complex, in that
it allows to define target storage volumes. dam_v008
tries to control
its outflow so that the actual volume approximately equals the (potentially
seasonally varying) target volume. However, it cannot release arbitrary
low or high amounts of water to fulfil this task due to its priority to
release a predefined minimum amount of water (for ecological reasons) and
its second priority to not release to much water (for flood protection).
In this example, we activate these mechanisms through changing some related
parameter values (also see the documentation on method Calc_ActualRelease_V3
for more detailed examples, including the numerous corner cases):
>>> targetvolume(0.5)
>>> neardischargeminimumthreshold(0.1)
>>> allowedrelease(4.0)
>>> allowedwaterleveldrop(1.0)
Compared with the allowed release results of dam_v007
,
dam_v008
dampens the given flood event less efficiently. dam_v007
releases all initial inflow, while dam_v008
stores most of it until
it reaches the target volume of 0.5 million m³. After peak flow,
dam_v008
first releases its water as fast as allowed, but then again
tries to meet the target volume. The slow negative trend away from the
target value at the end of the simulation period results from the lack
of inflow while there is still the necessity to release at least 0.1 m³/s:
>>> test("dam_v008_target_volume")
Click to see the table
Click to see the graph
sharp transitions¶
Due to smoothing, the above results deviate from the ones one would expect from LARSIM simulations to some degree. However, if we set both “target range” parameters to zero (like one does not set the LARSIM option “TALSPERRE SOLLRANGE”) and both “tolerance” parameters to zero (to disable any smoothing), we should get more similar results:
>>> targetrangeabsolute(0.0)
>>> targetrangerelative(0.0)
>>> volumetolerance(0.0)
>>> dischargetolerance(0.0)
>>> test("dam_v008_sharp_transitions")
Click to see the table
Click to see the graph
higher accuracy¶
The first water volume calculated in the sharp transitions example is negative, which is the result of the limited numerical accuracy of the underlying integration algorithm. We can decrease such errors through defining smaller error tolerance values, but at the risk of relevant increases in computation times (especially in case one does apply zero smoothing values):
>>> solver.abserrormax(1e-6)
>>> test("dam_v008_higher_accuracy")
Click to see the table
Click to see the graph
target range¶
In the last example, the behaviour of the reservoir always changes abruptly
when the actual volume transcends the target volume. According to its
documentation, LARSIM then predicts unrealistic jumps in discharge.
To solve this issue, LARSIM offers the “TALSPERRE SOLLRANGE” option,
which ensures smoother transitions between 80 % and 120 % of the target
volume, accomplished by linear interpolation. dam_v008
should never
output similar jumps as it controls the correctness of its results.
As a drawback, correcting these jumps (which still occur “unseeable” and
possibly multiple times within each affected simulation time step) costs
computation time. Hence, at least when using small smoothing parameter
values, dam_v008
can also benefit from this approach. You can define
the range of interpolation freely via parameters TargetRangeAbsolute
and
TargetRangeRelative
depending on your specific needs. Setting the latter
to 0.2 corresponds to the original “TALSPERRE SOLLRANGE”-configuration:
>>> targetrangerelative(0.2)
>>> test("dam_v008_target_range")
Click to see the table
Click to see the graph
minimum volume¶
In all examples above, the dam would run dry entirely after a certain
amount of time to fulfil the downstream demand defined by parameter
NearDischargeMinimumThreshold
. Usually, this is neither desired
nor technically possible. The following example shows that the parameter
WaterVolumeMinimumThreshold
allows setting a minimum amount of water
below which no release occurs:
>>> watervolumeminimumthreshold(0.45)
>>> test("dam_v008_minimum_volume")
Click to see the table
Click to see the graph
-
class
hydpy.models.dam_v008.
Model
[source]¶ Bases:
hydpy.core.modeltools.ELSModel
Version 8 of HydPy-Dam.
- The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
Pic_Inflow_V1
Update the inlet link sequence.
- 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_AllowedDischarge_V2
Calculate the maximum discharge not leading to exceedance of the allowed water level drop.Calc_ActualRelease_V3
Calculate an actual water release that tries to change the water storage into the direction of the actual target volume without violating the required minimum and the allowed maximum flow.Calc_FloodDischarge_V1
Calculate the discharge during and after a flood event based on anSeasonalANN
describing the relationship(s) between discharge and water stage.Calc_Outflow_V1
Calculate the total outflow of the dam.
- 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):
Update_WaterVolume_V1
Update the actual water volume.
- The following “outlet update methods” are called in the given sequence at the end of each simulation step:
Pass_Outflow_V1
Update the outlet link sequenceQ
.
-
numconsts
: hydpy.core.modeltools.NumConstsELS¶
-
numvars
: hydpy.core.modeltools.NumVarsELS¶
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
WaterLevel()
Water level [m].SurfaceArea()
Surface area [million m²].AllowedDischarge()
Discharge threshold that should not be overcut by the actual discharge [m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
CatchmentArea()
Size of the catchment draining into the dam [km²].NearDischargeMinimumThreshold()
Discharge threshold of a cross section in the near of the dam that not be undercut by the actual discharge [m³/s].WaterVolumeMinimumThreshold()
The minimum operating water volume of the dam [million m³].WaterVolume2WaterLevel()
Artificial neural network describing the relationship between water level and water volume [-].WaterLevel2FloodDischarge()
Artificial neural network describing the relationship between flood discharge and water volume [-].AllowedWaterLevelDrop()
The highest allowed water level decrease [m/T].AllowedRelease()
The maximum water release not causing any harm downstream [m³/s].TargetVolume()
The desired volume of water to be stored within the dam at specific times of the year [Mio. m³].TargetRangeAbsolute()
The absolute interpolation range related to parameterTargetVolume
[Mio. m³].TargetRangeRelative()
The relative interpolation range related to parameterTargetVolume
[-].VolumeTolerance()
Smoothing parameter for volume related smoothing operations [Mio. m³].DischargeTolerance()
Smoothing parameter for discharge related smoothing operations [m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
TOY()
References thetimeofyear
index array provided by the instance of classIndexer
available in modulepub
. [-].Seconds()
Length of the actual simulation step size in seconds [s].VolumeSmoothParLog1()
Smoothing parameter to be derived fromVolumeTolerance
for smoothing kernelsmooth_logistic1()
[Mio. m³].VolumeSmoothParLog2()
Smoothing parameter to be derived fromVolumeTolerance
for smoothing kernelsmooth_logistic2()
[Mio. m³].DischargeSmoothPar()
Smoothing parameter to be derived fromDischargeTolerance
for smoothing kernelssmooth_min1()
andsmooth_max1()
[m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
Inflow()
Total inflow [m³/s].ActualRelease()
Actual water release thought for reducing drought events downstream [m³/s].FloodDischarge()
Water release associated with flood events [m³/s].Outflow()
Total outflow [m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
Q()
Discharge [m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- The following classes are selected:
Q()
Discharge [m³/s].
-
class
hydpy.models.dam_v008.
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_v008.
- 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_v008.
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_v008.
- The following classes are selected:
WaterVolume()
Water volume [million m³].