HydPy-Dam-V3 (dam model, version 3)¶
dam_v003
is quite similar to dam_v002
. Both application models provide the same
flood retention functionalities. Also, both try to meet the water demand at a remote
location. The difference is that dam_v002
expects this demand to occur in the
channel downstream (usually to increase low discharge values). Instead, dam_v003
supplies water to a different location (such as a drinking water treatment plant).
Hence, dam_v002
releases its water via a single output path while dam_v003
divides
it into two separate paths.
The following explanations focus on this difference. For further information on using
dam_v003
, please read the documentation on dam_v001
and dam_v002
.
Integration tests¶
Note
When new to HydPy, consider reading section Integration Tests first.
To illustrate the functionalities of dam_v003
, we refer back to those examples of
the comprehensive documentation on application model dam_v001
we also revisited when
discussing dam_v002
. In contrast to the comparison between dam_v001
and
dam_v002
, we cannot define settings for dam_v003
that lead to identical results
in cases of remote demand. In all other situations, dam_v003
works like dam_v001
and dam_v002
. Hence, most examples serve more to confirm the correctness of the
model’s implementation than explaining new features.
The time-related setup is identical to the ones of dam_v001
and dam_v002
:
>>> from hydpy import pub, Node, Element
>>> pub.timegrids = "01.01.2000", "21.01.2000", "1d"
dam_v003
requires connections to four instead of three Node
objects. Instead of
one outlet node, there must be two outlet nodes. Node outflow corresponds to the
outflow node of the documentation on dam_v001
and dam_v002
and passes the
received outflow into the channel immediately downstream of the dam. Node
actual_supply is new and serves to supply a different location with water. Node
required_supply is equivalent to node demand of the documentation on dam_v002
.
It delivers the same information but from a different location:
>>> inflow = Node("inflow", variable="Q")
>>> outflow = Node("outflow", variable="Q")
>>> actual_supply = Node("actual_supply", variable="S")
>>> required_supply = Node("required_supply", variable="S")
>>> dam = Element("dam",
... inlets=inflow,
... outlets=(outflow, actual_supply),
... receivers=required_supply)
>>> from hydpy.models.dam_v003 import *
>>> parameterstep("1d")
>>> dam.model = model
dam_v001
releases water via two outlet sequences, Q
and S
,
and needs to know which one corresponds to which outlet node. It gathers this
information when building the connection with its Element
object dam in the last
assignment above. Therefore, it inspects the variable
attribute of each outlet
node. In our example, we use the string literals “Q” and “S” to enable the correct
allocation. See the documentation on method connect()
for alternatives and more
detailed explanations.
We define the configuration of the IntegrationTest
object, the initial conditions,
the input time series, and the parameter values exactly as for dam_v002
:
>>> 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.loggedrequiredremoterelease, 0.005))
>>> inflow.sequences.sim.series = 1.0
>>> 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)
Now, we prepare the two additional parameters, WaterLevelMinimumRemoteThreshold
and
WaterLevelMinimumRemoteTolerance
:
>>> waterlevelminimumremotethreshold(0.0)
>>> waterlevelminimumremotetolerance(0.0)
smooth near minimum¶
This example corresponds to the smooth near minimum example of
application model dam_v001
and the smooth near minimum example of
application model dam_v002
. We again use the same remote demand:
>>> required_supply.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]
Due to the separate output paths, there are relevant differences to the results of
dam_v001
and dam_v002
. dam_v001
and dam_v002
can use the same water to both
meet the near and the remote demand, which is not possible for dam_v003
. Hence, it
must release a larger total amount of water:
>>> test("dam_v003_smooth_near_minimum")
Click to see the table
Click to see the graph
restriction enabled¶
This example corresponds to the restriction enabled example of
application model dam_v001
and the restriction enabled example of
application model dam_v002
. We update the time series of the inflow and the required
remote release accordingly:
>>> inflow.sequences.sim.series[10:] = 0.1
>>> required_supply.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 results show that the restriction on releasing water during low inflow conditions only concerns the release into the channel downstream:
>>> test("dam_v003_restriction_enabled")
Click to see the table
Click to see the graph
smooth stage minimum¶
This example corresponds to the smooth stage minimum example of
application model dam_v001
and the smooth stage minimum example of
application model dam_v002
. We update parameters WaterLevelMinimumThreshold
and
WaterLevelMinimumTolerance
, as well as the time series of the inflow and the required
remote release, accordingly, but keep the old value of NearDischargeMinimumThreshold
:
>>> waterlevelminimumtolerance(0.01)
>>> waterlevelminimumthreshold(0.005)
>>> inflow.sequences.sim.series = numpy.linspace(0.2, 0.0, 20)
>>> required_supply.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]
>>> neardischargeminimumthreshold
neardischargeminimumthreshold(0.2)
Additionally, we illustrate the control parameters unknown to dam_v001
and
dam_v002
, WaterLevelMinimumRemoteThreshold
, and WaterLevelMinimumRemoteTolerance
.
Separate water level-related threshold values for the near demand
(WaterLevelMinimumThreshold
) and the remote demand
(WaterLevelMinimumRemoteThreshold
) and their smoothing parameters allow for a
distinct configuration of both output paths in situations when the available storage is
limited. Here, we set WaterLevelMinimumRemoteThreshold
to a higher value than
WaterLevelMinimumThreshold
. Hence, the release into the channel downstream has
priority over the supply to the remote location:
>>> waterlevelminimumremotetolerance(0.01)
>>> waterlevelminimumremotethreshold(0.01)
>>> test("dam_v003_smooth_stage_minimum")
Click to see the table
Click to see the graph
evaporation¶
This example corresponds to the evaporation example of application model
dam_v001
and the evaporation example of application model dam_v002
.
We add an evap_ret_io
submodel and update the required remote release time series
accordingly:
>>> 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]
>>> required_supply.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]
Due to the remaining differences regarding remote demand, the following results differ
from those of dam_v001
and dam_v002
. However, detailed comparisons show the same
patterns for adjusting potential evaporation and its conversion to actual evaporation
under water scarcity:
>>> test("dam_v003_evaporation")
Click to see the table
Click to see the graph
>>> del model.pemodel
flood retention¶
This example repeats the flood retention example of application model
dam_v001
and the flood retention example of application model
dam_v002
. We use the same parameter and input time series configuration:
>>> neardischargeminimumthreshold(0.0)
>>> neardischargeminimumtolerance(0.0)
>>> waterlevelminimumthreshold(0.0)
>>> waterlevelminimumtolerance(0.0)
>>> waterlevelminimumremotethreshold(0.0)
>>> waterlevelminimumremotetolerance(0.0)
>>> waterlevel2flooddischarge(PPoly.from_data(xs=[0.0, 1.0], ys=[0.0, 2.5]))
>>> 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]
>>> 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]
>>> required_supply.sequences.sim.series = 0.0
>>> test.inits.loggedrequiredremoterelease = 0.0
The following results demonstrate that dam_v003
calculates the same outflow values as
dam_v001
and dam_v002
if there is no relevant remote demand:
>>> test("dam_v003_flood_retention")
Click to see the table
Click to see the graph
- class hydpy.models.dam_v003.Model[source]¶
Bases:
Main_PrecipModel_V2
,Main_PEModel_V1
HydPy-Dam-V3 (dam model, version 3).
- The following “receiver update methods” are called in the given sequence before performing a simulation step:
Pic_LoggedRequiredRemoteRelease_V2
Update the receiver sequenceLoggedRequiredRemoteRelease
.
- The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
Calc_Precipitation_V1
If available, let a submodel that complies with thePrecipModel_V2
interface determine precipitation.Calc_PotentialEvaporation_V1
If available, let a submodel that complies with thePETModel_V1
interface determine potential evaporation.Calc_AdjustedEvaporation_V1
Adjust the given potential evaporation.Pic_Inflow_V1
Update the inlet sequenceInflow
.Calc_RequiredRemoteRelease_V2
Get the required remote release of the last simulation step.Calc_RequiredRelease_V2
Calculate the water release (immediately 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_V1
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_ActualRemoteRelease_V1
Calculate the actual remote water release that can be supplied by the dam considering the required remote 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_V2
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
.Pass_ActualRemoteRelease_V1
Update the outlet link sequenceS
.
- 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.
- 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.
- REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()¶
- class hydpy.models.dam_v003.ControlParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Control parameters of model dam_v003.
- The following classes are selected:
SurfaceArea()
Average size of the water surface [km²].CatchmentArea()
Size of the catchment draining into the dam [km²].CorrectionPrecipitation()
Precipitation correction factor [-].CorrectionEvaporation()
Evaporation correction factor [-].WeightEvaporation()
Time weighting factor for evaporation [-].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].WaterLevelMinimumRemoteThreshold()
The minimum operating water level of the dam regarding remote water supply [m].WaterLevelMinimumRemoteTolerance()
A tolerance value for the minimum operating water level regarding remote water supply [m].WaterVolume2WaterLevel()
An interpolation function that describes the relationship between water level and water volume [-].WaterLevel2FloodDischarge()
An interpolation function that describesg the relationship between flood discharge and water volume [-].
- class hydpy.models.dam_v003.DerivedParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Derived parameters of model dam_v003.
- 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.NearDischargeMinimumSmoothPar1()
Smoothing parameter to be derived fromNearDischargeMinimumThreshold
for smoothing kernelsmooth_logistic1()
[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].WaterLevelMinimumRemoteSmoothPar()
Smoothing parameter to be derived fromWaterLevelMinimumRemoteTolerance
[m].
- class hydpy.models.dam_v003.FactorSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
FactorSequences
Factor sequences of model dam_v003.
- The following classes are selected:
WaterLevel()
Water level [m].
- class hydpy.models.dam_v003.FluxSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
FluxSequences
Flux sequences of model dam_v003.
- The following classes are selected:
Precipitation()
Precipitation [mm].AdjustedPrecipitation()
Adjusted precipitation [m³/s].PotentialEvaporation()
Potential evaporation [mm/T].AdjustedEvaporation()
Adjusted evaporation [m³/s].ActualEvaporation()
Actual evaporation [m³/s].Inflow()
Total inflow [m³/s].RequiredRemoteRelease()
Water release considered appropriate to reduce drought events at cross-sections far downstream [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].ActualRemoteRelease()
Actual water release thought for arbitrary “remote” purposes [m³/s].FloodDischarge()
Water release associated with flood events [m³/s].Outflow()
Total outflow [m³/s].
- class hydpy.models.dam_v003.InletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
InletSequences
Inlet sequences of model dam_v003.
- The following classes are selected:
Q()
Inflow [m³/s].
- class hydpy.models.dam_v003.LogSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
LogSequences
Log sequences of model dam_v003.
- The following classes are selected:
LoggedAdjustedEvaporation()
Logged adjusted evaporation [m³/s].LoggedRequiredRemoteRelease()
Logged required discharge values computed by another model [m³/s].
- class hydpy.models.dam_v003.OutletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
OutletSequences
Outlet sequences of model dam_v003.
- class hydpy.models.dam_v003.ReceiverSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
ReceiverSequences
Receiver sequences of model dam_v003.
- The following classes are selected:
S()
Required water supply [m³/s].
- class hydpy.models.dam_v003.SolverParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
SubParameters
Solver parameters of model dam_v003.
- 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_v003.StateSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)¶
Bases:
StateSequences
State sequences of model dam_v003.
- The following classes are selected:
WaterVolume()
Water volume [million m³].