dam_v005¶
Version 5 application model of HydPy-Dam.
Application model dam_v005
extends dam_v001
with two features enabling
collaboration with other dam models for better drought and flood prevention.
Like dam_v001
, dam_v005
tries to increase the discharge at a remote location in the
channel downstream during low flow conditions and sometimes fails due to its limited
storage content. One additional feature of dam_v005
is that it passes the information
on its anticipated failure to another remote location. This information enables other
models to jump in when necessary.
The second additional feature of dam_v005
is that it receives input from two
additional inlet nodes, one passing “supply discharge” and the other one “relief
discharge”. We understand “supply discharge” as water delivered from a remote location
to increase the storage content of dam_v005
when necessary (during droughts). In
contrast, relief discharge serves to relieve the other location (possibly another dam)
during floods. dam_v005
calculates both the desirable supply discharge and the
acceptable relief discharge and passes that information to a single or two separate
remote locations.
The following explanations focus on these differences. For further information on using
dam_v005
, please read the documentation on model dam_v001
. Besides that, see the
documentation on dam_v002
and dam_v004
, which are possible counterparts for
dam_v005
.
Integration tests¶
Note
When new to HydPy, consider reading section How to understand integration tests? first.
The following integration tests build on some of the examples demonstrating the
functionality of model dam_v001
. To achieve comparability, we define identical
parameter values, initial conditions, and input time series. The following
explanations focus on the differences between applications models dam_v005
and
dam_v001
.
The following time-related setup is identical to the one of dam_v001
:
>>> from hydpy import pub
>>> pub.timegrids = "01.01.2000", "21.01.2000", "1d"
Due to the high complexity of dam_v005
and our test setting, which includes two
instances of another model type (arma_v1
), we need to define lots of Node
objects:
>>> from hydpy import Node
>>> inflow = Node("inflow", variable="Q")
>>> outflow = Node("outflow", variable="Q")
>>> natural = Node("natural", variable="Q")
>>> remote = Node("remote", variable="Q")
>>> actual_supply = Node("actual_supply", variable="S")
>>> required_supply = Node("required_supply", variable="S")
>>> allowed_relief = Node("allowed_relief", variable="R")
>>> actual_relief = Node("actual_relief", variable="R")
>>> demand = Node("demand", variable="D")
>>> from hydpy import Element
>>> dam = Element("dam",
... inlets=(inflow, actual_supply, actual_relief),
... outlets=outflow,
... receivers=remote,
... senders=(demand, required_supply, allowed_relief))
>>> stream1 = Element("stream1", inlets=outflow, outlets=remote)
>>> stream2 = Element("stream2", inlets=natural, outlets=remote)
The nodes inflow and outflow handle the “normal” discharge into and out of the dam.
Node outflow passes its values to the routing element stream1. The second routing
element, stream2, represents a natural tributary and receives the “natural” discharge
of the subcatchment downstream of the dam provided by the natural node. Both routing
elements give their outflow to node remote, representing the cross-section downstream
where discharge should not undercut a certain threshold. So far, the setting is
identical to the one of the documentation on dam_v001
.
dam_v005
needs to connect to two additional inlet nodes and also to three sender
nodes. The input nodes actual_supply and actual_relief handle the actual supply
and relief discharge from remote locations. The sender nodes required_supply and
allowed_relief inform other models of the currently required supply and the allowed
relief. The sender node demand tells other models about the estimated demand for
water at the cross-section downstream that it cannot currently release itself.
To enable dam_v005
to connect the different involved sequences and nodes correctly,
we need to give suitable variable
values to the Node
instances. We use the
string literal “Q” for the inflow and the outflow node, “S” for both supply nodes, “R”
for both relief nodes, and “D” for node demand. See the documentation on method
connect()
for alternatives and more detailed explanations.
As mentioned above, dam_v002
and dam_v004
are good counterparts for dam_v005
.
Including them in the following examples would lead to a better agreement with typical
use cases of dam_v005
. However, we do not want to bloat up the already scenario
setting further. Hence, instead of dynamically calculating the remote locations’
discharges, we prefer to apply predefined discharge time series.
We configure both arma_v1
models, the IntegrationTest
object, and the initial
conditions precisely as in the dam_v001
examples:
>>> from hydpy import prepare_model
>>> stream2.model = prepare_model("arma_v1")
>>> stream2.model.parameters.control.responses(((), (1.0,)))
>>> stream2.model.parameters.update()
>>> stream1.model = prepare_model("arma_v1")
>>> stream1.model.parameters.control.responses(((), (0.2, 0.4, 0.3, 0.1)))
>>> stream1.model.parameters.update()
>>> from hydpy.models.dam_v005 import *
>>> parameterstep("1d")
>>> dam.model = model
>>> 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
>>> test.inits=((states.watervolume, 0.0),
... (logs.loggedadjustedevaporation, 0.0),
... (logs.loggedtotalremotedischarge, 1.9),
... (logs.loggedoutflow, 0.0),
... (stream1.model.sequences.logs.login, 0.0))
The following control parameters are common to both models. We apply the same values:
>>> 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)
>>> nmblogentries(1)
>>> remotedischargeminimum(1.4)
>>> remotedischargesafety(0.5)
>>> 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)
dam_v005
implements six additional control parameters, three for calculating the
required supply (HighestRemoteSupply
, WaterLevelSupplyThreshold
, and
WaterLevelSupplyTolerance
) and three for calculating the allowed relief
(HighestRemoteRelief
, WaterLevelReliefThreshold
, and WaterLevelReliefTolerance
):
>>> highestremotesupply(1.0)
>>> waterlevelsupplythreshold(0.2)
>>> waterlevelsupplytolerance(0.05)
>>> highestremoterelief(5.0)
>>> waterlevelreliefthreshold(0.5)
>>> waterlevelrelieftolerance(0.05)
We define identical time series for Precipitation
,
Evaporation
, and the subcatchment’s discharge time series:
>>> inputs.precipitation.series = 0.0
>>> inputs.evaporation.series = 0.0
>>> natural.sequences.sim.series = [1.8, 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, 1.1, 1.0, 1.0,
... 1.0, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8]
In the initial examples on dam_v001
, the model receives a constant inflow of 1.0 m³/s
from its single inlet node. To work with the same input sum and prove that all node
connections work correctly, we set the “normal” inflow, the actual supply, and the
actual relief discharge to a constant value of 1/3 m³/s:
>>> inflow.sequences.sim.series = 1.0/3.0
>>> actual_supply.sequences.sim.series = 1.0/3.0
>>> actual_relief.sequences.sim.series = 1.0/3.0
smooth near minimum¶
This example extends the smooth near minimum example of application
model dam_v001
.
All results achieved for the water level and the outflow agree exactly, confirming
that dam_v005
captures the relevant functionalities of dam_v001
correctly. From
the results specific to dam_v005
, inspecting those of sequence RequiredRemoteSupply
is most insightful. At the beginning of the simulation period, they reflect the value
of parameter HighestRemoteSupply
(1.0 m³/s). When the water level reaches the value
of parameter WaterLevelSupplyThreshold
(0.2 m, which corresponds to a water volume of
0.8 million m³), the required remote release decreases and finally reaches 0.0 m³/s.
This transition happens over a relatively long period due to the large value of the
smoothing parameter WaterLevelSupplyTolerance
(0.05 m):
>>> test("dam_v005_smooth_near_minimum")
Click to see the table
Click to see the graph
restriction enabled¶
This example extends the restriction enabled example of application
model dam_v001
. It confirms that the restriction on releasing water when there is
little inflow works as explained for model dam_v001
. In addition, it shows that
dam_v005
uses sequence MissingRemoteRelease
to indicate when the ActualRelease
is
smaller than the estimated RequiredRemoteRelease
and passes this information the
demand node:
>>> inflow.sequences.sim.series[:10] = 1.0
>>> inflow.sequences.sim.series[10:] = 0.1
>>> actual_supply.sequences.sim.series = 0.0
>>> actual_relief.sequences.sim.series = 0.0
>>> neardischargeminimumtolerance(0.0)
>>> test("dam_v005_restriction_enabled")
Click to see the table
Click to see the graph
smooth stage minimum¶
This example extends the smooth stage minimum example of application
model dam_v001
. We update parameters WaterLevelMinimumThreshold
and
WaterLevelMinimumTolerance
, as well as the time series of the “normal” inflow,
accordingly:
>>> neardischargeminimumthreshold(0.0)
>>> waterlevelminimumtolerance(0.01)
>>> waterlevelminimumthreshold(0.005)
>>> inflow.sequences.sim.series = numpy.linspace(0.2, 0.0, 20)
There is also a perfect agreement between dam_v001
and dam_v005
for the given case
where the available water storage is too limited for releasing enough discharge:
>>> test("dam_v005_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 accordingly:
>>> inputs.evaporation.series = 10 * [1.0] + 10 * [5.0]
All internal evaporation-related results agree with the ones of dam_v001
exactly:
>>> test("dam_v005_evaporation")
Click to see the table
Click to see the graph
flood retention¶
This example repeats the flood retention example of application model
dam_v001
. We use the same parameter and input time series configuration:
>>> remotedischargeminimum(0.0)
>>> remotedischargesafety(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]
>>> inputs.evaporation.series = 0.0
>>> test.inits.loggedtotalremotedischarge = 1.0
>>> natural.sequences.sim.series = 1.0
The following test results show that dam_v005
reproduces the water levels and outflow
values calculated by dam_v001
precisely. Furthermore, they illustrate the estimation
of AllowedRemoteRelief
based on the current water level, which is functionally
similar to the one of RequiredRemoteSupply
discussed in the
smooth near minimum example:
>>> test("dam_v005_flood_retention")
Click to see the table
Click to see the graph
- class hydpy.models.dam_v005.Model[source]¶
Bases:
ELSModel
Version 5 of HydPy-Dam.
- The following “receiver update methods” are called in the given sequence before performing a simulation step:
Pic_TotalRemoteDischarge_V1
Update the receiver sequenceTotalRemoteDischarge
.Update_LoggedTotalRemoteDischarge_V1
Log a new entry of the discharge at a cross-section far downstream.
- The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
Calc_AdjustedEvaporation_V1
Adjust the given potential evaporation.Pic_Inflow_V2
Update the inlet sequenceInflow
.Calc_NaturalRemoteDischarge_V1
Estimate the natural discharge of a cross-section far downstream based on the last few simulation steps.Calc_RemoteDemand_V1
Estimate the discharge demand of a cross-section far downstream.Calc_RemoteFailure_V1
Estimate the shortfall of actual discharge under the required discharge of a cross section far downstream.Calc_RequiredRemoteRelease_V1
Guess the required release necessary to not fall below the threshold value at a cross section far downstream with a certain level of certainty.Calc_RequiredRelease_V1
Calculate the total water release (immediately and far downstream) required for reducing drought events.Calc_TargetedRelease_V1
Calculate the targeted water release for reducing drought events, taking into account both the required water release and the actual inflow into the dam.
- The following methods define the relevant components of a system of ODE equations (e.g. direct runoff):
Calc_AdjustedPrecipitation_V1
Adjust the given precipitation.Pic_Inflow_V2
Update the inlet sequenceInflow
.Calc_WaterLevel_V1
Determine the water level based on an interpolation approach approximating the relationship between water volume and water level.Calc_ActualEvaporation_V1
Calculate the actual evaporation.Calc_ActualRelease_V1
Calculate the actual water release that can be supplied by the dam considering the targeted release and the given water level.Calc_FloodDischarge_V1
Calculate the discharge during and after a flood event based on seasonally varying interpolation approaches approximating 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:
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 sequenceQ
.Update_LoggedOutflow_V1
Log a new entry of discharge at a cross section far downstream.
- The following “sender update methods” are called in the given sequence after performing a simulation step:
Calc_MissingRemoteRelease_V1
Calculate the portion of the required remote demand that could not be met by the actual discharge release.Pass_MissingRemoteRelease_V1
Update the outlet link sequenceD
.Calc_AllowedRemoteRelief_V2
Calculate the allowed maximum relief that another location is allowed to discharge into the dam.Pass_AllowedRemoteRelief_V1
Update the outlet link sequenceR
.Calc_RequiredRemoteSupply_V1
Calculate the supply required from another location.Pass_RequiredRemoteSupply_V1
Update the outlet link sequenceS
.
- class hydpy.models.dam_v005.ControlParameters(master: Parameters, cls_fastaccess: Type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Control parameters of model dam_v005.
- The following classes are selected:
SurfaceArea()
Average size of the water surface [km²].CatchmentArea()
Size of the catchment draining into the dam [km²].NmbLogEntries()
Number of log entries for certain variables [-].CorrectionPrecipitation()
Precipitation correction factor [-].CorrectionEvaporation()
Evaporation correction factor [-].WeightEvaporation()
Time weighting factor for evaporation [-].RemoteDischargeMinimum()
Discharge threshold of a cross-section far downstream not to be undercut by the actual discharge [m³/s].RemoteDischargeSafety()
Safety factor for reducing the risk to release not enough water [m³/s].NearDischargeMinimumThreshold()
Discharge threshold of a cross-section near the dam not to be undercut by the actual discharge [m³/s].NearDischargeMinimumTolerance()
A tolerance value for the “near discharge minimum” [m³/s].RestrictTargetedRelease()
A flag indicating whether low flow variability has to be preserved or not [-].WaterLevelMinimumThreshold()
The minimum operating water level of the dam [m].WaterLevelMinimumTolerance()
A tolerance value for the minimum operating water level [m].ThresholdEvaporation()
The water level at which actual evaporation is 50 % of potential evaporation [m].ToleranceEvaporation()
A tolerance value defining the steepness of the transition of actual evaporation between zero and potential evaporation [m].HighestRemoteRelief()
The highest possible relief discharge from another location [m³/s].WaterLevelReliefThreshold()
The threshold water level of the dam regarding the allowed relief discharge from another location [m].WaterLevelReliefTolerance()
A tolerance value for parameterWaterLevelReliefThreshold
[m].HighestRemoteSupply()
The highest possible supply discharge from another location [m³/s].WaterLevelSupplyThreshold()
The threshold water level of the dam regarding the required supply discharge from another location [m].WaterLevelSupplyTolerance()
A tolerance value for parameterWaterLevelSupplyThreshold
[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 [-].
- class hydpy.models.dam_v005.DerivedParameters(master: Parameters, cls_fastaccess: Type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Derived parameters of model dam_v005.
- 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 [s].InputFactor()
Factor for converting meteorological input from mm/T to million m³/s.RemoteDischargeSmoothPar()
Smoothing parameter to be derived fromRemoteDischargeSafety
[m³/s].NearDischargeMinimumSmoothPar1()
Smoothing parameter to be derived fromNearDischargeMinimumThreshold
for smoothing kernelsmooth_logistic1()
[m³/s].NearDischargeMinimumSmoothPar2()
Smoothing parameter to be derived fromNearDischargeMinimumThreshold
for smoothing kernelsmooth_logistic2()
[m³/s].WaterLevelMinimumSmoothPar()
Smoothing parameter to be derived fromWaterLevelMinimumTolerance
for smoothing kernelsmooth_logistic1()
[m].SmoothParEvaporation()
Smoothing parameter to be derived fromToleranceEvaporation
for smoothing kernelsmooth_logistic1()
[m].WaterLevelReliefSmoothPar()
Smoothing parameter to be derived fromWaterLevelReliefTolerance
for smoothing kernelsmooth_logistic1()
[m³/s].WaterLevelSupplySmoothPar()
Smoothing parameter to be derived fromWaterLevelSupplyTolerance
for smoothing kernelsmooth_logistic1()
[m³/s].
- class hydpy.models.dam_v005.FactorSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
FactorSequences
Factor sequences of model dam_v005.
- The following classes are selected:
WaterLevel()
Water level [m].
- class hydpy.models.dam_v005.FluxSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
FluxSequences
Flux sequences of model dam_v005.
- The following classes are selected:
AdjustedPrecipitation()
Adjusted precipitation [m³/s].AdjustedEvaporation()
Adjusted evaporation [m³/s].ActualEvaporation()
Actual evaporation [m³/s].Inflow()
Total inflow [m³/s].TotalRemoteDischarge()
Total discharge at a cross-section far downstream [m³/s].NaturalRemoteDischarge()
Natural discharge at a cross-section far downstream [m³/s].RemoteDemand()
Discharge demand at a cross-section far downstream [m³/s].RemoteFailure()
Difference between the actual and the required discharge at a cross-section far downstream [m³/s].RequiredRemoteRelease()
Water release considered appropriate to reduce drought events at cross-sections far downstream [m³/s].AllowedRemoteRelief()
Allowed discharge to relieve a dam during high flow conditions [m³/s].RequiredRemoteSupply()
Required water supply, for example, to fill a dam during low water conditions [m³/s].RequiredRelease()
Required water release for reducing drought events downstream [m³/s].TargetedRelease()
The targeted water release for reducing drought events downstream after taking both the required release and additional low flow regulations into account [m³/s].ActualRelease()
Actual water release thought for reducing drought events downstream [m³/s].MissingRemoteRelease()
Amount of the required remote demand not met by the actual release [m³/s].FloodDischarge()
Water release associated with flood events [m³/s].Outflow()
Total outflow [m³/s].
- class hydpy.models.dam_v005.InletSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
InletSequences
Inlet sequences of model dam_v005.
- class hydpy.models.dam_v005.InputSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
InputSequences
Input sequences of model dam_v005.
- The following classes are selected:
Precipitation()
Precipitation [mm].Evaporation()
Potential evaporation [mm].
- class hydpy.models.dam_v005.LogSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
LogSequences
Log sequences of model dam_v005.
- The following classes are selected:
LoggedTotalRemoteDischarge()
Logged discharge values from somewhere else [m3/s].LoggedOutflow()
Logged discharge values from the dam itself [m3/s].LoggedAdjustedEvaporation()
Logged adjusted evaporation [m3/s].
- class hydpy.models.dam_v005.OutletSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
OutletSequences
Outlet sequences of model dam_v005.
- The following classes are selected:
Q()
Outflow [m³/s].
- class hydpy.models.dam_v005.ReceiverSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
ReceiverSequences
Receiver sequences of model dam_v005.
- The following classes are selected:
Q()
Remote discharge [m³/s].
- class hydpy.models.dam_v005.SenderSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SenderSequences
Sender sequences of model dam_v005.
- class hydpy.models.dam_v005.SolverParameters(master: Parameters, cls_fastaccess: Type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Solver parameters of model dam_v005.
- 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_v005.StateSequences(master: Sequences, cls_fastaccess: Type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
StateSequences
State sequences of model dam_v005.
- The following classes are selected:
WaterVolume()
Water volume [million m³].