HydPy-Manager-LWC (low water control management model)

The HydPy-Manager-LWC (low water control management model) base model provides features for implementing models that coordinate other models. Method features —————

class hydpy.models.manager.manager_model.Model[source]

Bases: AdHocModel

HydPy-Manager-LWC (low water control management model)

The following “receiver update methods” are called in the given sequence before performing a simulation step:
The following “run methods” are called in the given sequence during each simulation step:
The following “sender update methods” are called in the given sequence after performing a simulation step:
  • Pass_Request_V1 Pass the additional water release requests to the relevant sender sequences.

DOCNAME = ('Manager-LWC', 'low water control management model')
REUSABLE_METHODS = ()
class hydpy.models.manager.manager_model.Pick_LoggedDischarge_V1[source]

Bases: Method

Pick and memorise the target node’s current discharge value.

Used by the application model:

manager_lwc

Requires the derived parameter:

MemoryLength

Requires the receiver sequence:

Q

Calculates the log sequence:

LoggedDischarge

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> derived.memorylength(3)
>>> receivers.q = 3.0
>>> logs.loggeddischarge = 2.0, 4.0, 6.0
>>> model.pick_loggeddischarge_v1()
>>> logs.loggeddischarge
loggeddischarge(3.0, 2.0, 4.0)
class hydpy.models.manager.manager_model.Pick_LoggedWaterVolume_V1[source]

Bases: Method

Pick and memorise the water volume of all sources.

Used by the application model:

manager_lwc

Requires the derived parameter:

NmbSources

Requires the receiver sequence:

WaterVolume

Calculates the log sequence:

LoggedWaterVolume

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b", "c")
>>> receivers.watervolume.shape = 3
>>> receivers.watervolume = 1.0, 3.0, 2.0
>>> model.pick_loggedwatervolume_v1()
>>> logs.loggedwatervolume
loggedwatervolume(a=1.0, b=3.0, c=2.0)
class hydpy.models.manager.manager_model.Calc_FreeDischarge_V1[source]

Bases: Method

Extrapolate the “free discharge” that might occur without requesting additional water releases.

Used by the application model:

manager_lwc

Requires the control parameters:

TimeDelay TimeWindow

Requires the log sequences:

LoggedDischarge LoggedRequest

Calculates the flux sequence:

FreeDischarge

Basic equation:
\[ \begin{align}\begin{aligned}\begin{split}F = max \left (min \left(f(1), \, \min_{i=2}^W \big(f(1) + f(i) / i\big) \right), \, 0 \right) \\ f(i) = Q_i - R_{i+D}\end{split}\\\begin{split}\\ \\ F = FreeDischarge \\ Q = LoggedDischarge \\ R = LoggedRequest \\ W = TimeWindow \\ D = TimeDelay\end{split}\end{aligned}\end{align} \]

Examples:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> timedelay(1)
>>> timewindow(1)
>>> derived.memorylength.update()
>>> logs.loggeddischarge(3.0, nan)
>>> logs.loggedrequest(nan, 1.0)
>>> model.calc_freedischarge_v1()
>>> fluxes.freedischarge
freedischarge(2.0)
>>> timewindow(3)
>>> derived.memorylength.update()
>>> logs.loggeddischarge(2.0, 3.0, 4.0, nan)
>>> logs.loggedrequest(nan, 0.0, 1.0, 2.0)
>>> model.calc_freedischarge_v1()
>>> fluxes.freedischarge
freedischarge(2.0)
>>> logs.loggeddischarge[1] = 4.0
>>> model.calc_freedischarge_v1()
>>> fluxes.freedischarge
freedischarge(1.0)
>>> logs.loggeddischarge[1:3] = 3.0, 6.0
>>> model.calc_freedischarge_v1()
>>> fluxes.freedischarge
freedischarge(1.0)
>>> logs.loggeddischarge[2] = 10.0
>>> model.calc_freedischarge_v1()
>>> fluxes.freedischarge
freedischarge(0.0)
class hydpy.models.manager.manager_model.Calc_DemandTarget_V1[source]

Bases: Method

Estimate the demand for additional water releases.

Used by the application model:

manager_lwc

Requires the control parameter:

DischargeThreshold

Requires the derived parameter:

DischargeSmoothPar

Requires the flux sequence:

FreeDischarge

Calculates the flux sequence:

DemandTarget

Basic equation:
\[\begin{split}D = m(T - F, \, 0, \, S) \\ \\ D = Demand \\ F = FreeDischarge \\ T = DischargeThreshold \\ S = DischargeSmoothPar \\ m = smooth\_max1\end{split}\]
Used auxiliary method:

smooth_max1()

Examples:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> dischargethreshold(4.0)
>>> from hydpy import UnitTest
>>> test = UnitTest(
...     model,
...     model.calc_demandtarget_v1,
...     last_example=9,
...     parseqs=(fluxes.freedischarge, fluxes.demandtarget),
... )
>>> test.nexts.freedischarge = range(9)
>>> dischargetolerance(0.0)
>>> derived.dischargesmoothpar.update()
>>> test()
| ex. | freedischarge | demandtarget |
--------------------------------------
|   1 |           0.0 |          4.0 |
|   2 |           1.0 |          3.0 |
|   3 |           2.0 |          2.0 |
|   4 |           3.0 |          1.0 |
|   5 |           4.0 |          0.0 |
|   6 |           5.0 |          0.0 |
|   7 |           6.0 |          0.0 |
|   8 |           7.0 |          0.0 |
|   9 |           8.0 |          0.0 |
>>> dischargetolerance(1.0)
>>> derived.dischargesmoothpar.update()
>>> test()
| ex. | freedischarge | demandtarget |
--------------------------------------
|   1 |           0.0 |          4.0 |
|   2 |           1.0 |     3.000012 |
|   3 |           2.0 |     2.000349 |
|   4 |           3.0 |         1.01 |
|   5 |           4.0 |     0.205524 |
|   6 |           5.0 |         0.01 |
|   7 |           6.0 |     0.000349 |
|   8 |           7.0 |     0.000012 |
|   9 |           8.0 |          0.0 |
class hydpy.models.manager.manager_model.Calc_Alertness_V1[source]

Bases: Method

Determine the current need for low water control.

Used by the application model:

manager_lwc

Requires the control parameter:

DischargeThreshold

Requires the derived parameter:

DischargeSmoothPar

Requires the flux sequence:

FreeDischarge

Calculates the factor sequence:

Alertness

Basic equation:
\[\begin{split}A = l(T - F, \, 0, S) \\ \\ A = Alertness \\ F = FreeDischarge \\ T = DischargeThreshold \\ S = DischargeSmoothPar \\ l = smooth\_logistic1\end{split}\]
Used auxiliary method:

smooth_logistic1()

Examples:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> dischargethreshold(4.0)
>>> from hydpy import UnitTest
>>> test = UnitTest(
...     model,
...     model.calc_alertness_v1,
...     last_example=9,
...     parseqs=(fluxes.freedischarge, factors.alertness),
... )
>>> test.nexts.freedischarge = range(9)
>>> dischargetolerance(0.0)
>>> derived.dischargesmoothpar.update()
>>> test()
| ex. | freedischarge | alertness |
-----------------------------------
|   1 |           0.0 |       1.0 |
|   2 |           1.0 |       1.0 |
|   3 |           2.0 |       1.0 |
|   4 |           3.0 |       1.0 |
|   5 |           4.0 |       0.5 |
|   6 |           5.0 |       0.0 |
|   7 |           6.0 |       0.0 |
|   8 |           7.0 |       0.0 |
|   9 |           8.0 |       0.0 |
>>> dischargetolerance(1.0)
>>> derived.dischargesmoothpar.update()
>>> test()
| ex. | freedischarge | alertness |
-----------------------------------
|   1 |           0.0 |  0.999999 |
|   2 |           1.0 |   0.99996 |
|   3 |           2.0 |  0.998825 |
|   4 |           3.0 |  0.966837 |
|   5 |           4.0 |       0.5 |
|   6 |           5.0 |  0.033163 |
|   7 |           6.0 |  0.001175 |
|   8 |           7.0 |   0.00004 |
|   9 |           8.0 |  0.000001 |
class hydpy.models.manager.manager_model.Calc_DemandSources_V1[source]

Bases: Method

Calculate the water demand of all sources.

Used by the application model:

manager_lwc

Requires the control parameters:

Active VolumeThreshold

Requires the derived parameters:

NmbSources Seconds VolumeSmoothPar

Requires the factor sequence:

Alertness

Requires the log sequence:

LoggedWaterVolume

Calculates the flux sequence:

DemandSources

Basic equation:
\[\begin{split}D = \begin{cases} L \cdot 10^6/s \cdot m(T - V, \, 0, \, S) &|\ A \\ 0 &|\ \overline{A} \end{cases} \\ \\ A = Active \\ s = Seconds \\ D = DemandSources \\ L = Alertness \\ V = LoggedWaterVolume \\ S = VolumeSmoothPar \\ m = smooth\_max1\end{split}\]

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> derived.seconds(10**6 / 2.0)
>>> sources("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")
>>> volumethreshold(5.0)
>>> volumetolerance(0.0)
>>> active(True, True, True, True, True, True, True, True, True, False)
>>> derived.memorylength(1)
>>> derived.volumesmoothpar.update()
>>> logs.loggedwatervolume = 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0
>>> factors.alertness = 0.5
>>> model.calc_demandsources_v1()
>>> fluxes.demandsources
demandsources(a=4.0, b=3.0, c=2.0, d=1.0, e=0.0, f=0.0, g=0.0, h=0.0,
              i=0.0, j=0.0)
>>> volumetolerance(1.0)
>>> derived.volumesmoothpar.update()
>>> model.calc_demandsources_v1()
>>> fluxes.demandsources
demandsources(a=4.0, b=3.000012, c=2.000349, d=1.01, e=0.205524,
              f=0.01, g=0.000349, h=0.000012, i=0.0, j=0.0)
class hydpy.models.manager.manager_model.Calc_PossibleRelease_V1[source]

Bases: Method

Calculate the possible additional release of all sources.

Used by the application model:

manager_lwc

Requires the control parameters:

Active VolumeThreshold ReleaseMax

Requires the derived parameters:

NmbSources Seconds

Requires the log sequence:

LoggedWaterVolume

Calculates the flux sequence:

PossibleRelease

Basic equation:
\[\begin{split}P = \begin{cases} 10^6/s \cdot min(max(L - V, \, 0), \, R) &|\ A \\ 0 &|\ \overline{A} \end{cases} \\ \\ A = Active \\ s = Seconds \\ P = PossibleRelease \\ L = LoggedWaterVolume \\ V = VolumeMin \\ R = ReleaseMax\end{split}\]

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b", "c", "d", "e")
>>> volumethreshold(3.0, 3.0, 6.0, 3.0, 3.0)
>>> releasemax(6.0, 6.0, 6.0, 3.0, 6.0)
>>> active(True, True, True, True, False)
>>> derived.seconds(10**6 / 2.0)
>>> derived.memorylength(1)
>>> logs.loggedwatervolume = 4.0, 5.0, 5.0, 5.0, 5.0
>>> model.calc_possiblerelease_v1()
>>> fluxes.possiblerelease
possiblerelease(a=2.0, b=4.0, c=0.0, d=3.0, e=0.0)
class hydpy.models.manager.manager_model.Calc_Request_V1[source]

Bases: Method

Calculate the additional release request for all sources.

Used by the application model:

manager_lwc

Requires the control parameter:

Commission

Requires the derived parameters:

NmbSources Adjacency Order

Requires the flux sequences:

DemandTarget DemandSources PossibleRelease

Calculates the flux sequence:

Request

Examples:

As shown by the following example, the general principle of method Calc_Request_V1 is to distribute the target node’s demand proportionally to the directly neighbouring sources’ possible release. The determined requests serve as the relevant sources’ demands. Calc_Request_V1 then distributes these sources’ demands as requests to the following upstream sources, using the same rule. It repeats this behaviour often enough to reach even the most upstream sources.

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2001-01-01", "1d"
>>> from hydpy.models.manager import *
>>> parameterstep()
>>> commission("2000-01-01")
>>> sources("d_1", "d_1a", "d_2", "d_2a", "d_2b", "d_2b1")
>>> derived.adjacency([[True, False, False, False, False, False, False],
...                    [False, True, False, False, False, False, False],
...                    [True, False, False, False, False, False, False],
...                    [False, False, False, True, False, False, False],
...                    [False, False, False, True, False, False, False],
...                    [False, False, False, False, False, True, False]])
>>> derived.order.update()
>>> fluxes.demandtarget = 0.0
>>> fluxes.demandsources = 0.0
>>> fluxes.possiblerelease = 6.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=0.0, d_1a=0.0, d_2=0.0, d_2a=0.0, d_2b=0.0, d_2b1=0.0)
>>> fluxes.demandtarget = 10.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=5.0, d_1a=5.0, d_2=5.0, d_2a=2.5, d_2b=2.5, d_2b1=2.5)
>>> fluxes.possiblerelease[0] = 9.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=6.0, d_1a=6.0, d_2=4.0, d_2a=2.0, d_2b=2.0, d_2b1=2.0)
>>> fluxes.possiblerelease = 4.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=4.0, d_1a=4.0, d_2=4.0, d_2a=2.0, d_2b=2.0, d_2b1=2.0)
>>> fluxes.possiblerelease[0] = 0.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=0.0, d_1a=0.0, d_2=4.0, d_2a=2.0, d_2b=2.0, d_2b1=2.0)
>>> fluxes.possiblerelease[-3] = 1.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=0.0, d_1a=0.0, d_2=4.0, d_2a=0.8, d_2b=3.2, d_2b1=3.2)

If a source has its own demand, Calc_Request_V1 adds it to the request to the source’s upstream neighbours, from which it may be forwarded as described:

>>> fluxes.demandtarget = 1.0
>>> fluxes.demandsources[2] = 3.0
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=0.0, d_1a=0.0, d_2=1.0, d_2a=0.8, d_2b=3.2, d_2b1=3.2)

Before the commission date, Calc_Request_V1 sets all requests to zero:

>>> commission("2000-01-02")
>>> model.calc_request_v1()
>>> fluxes.request
request(d_1=0.0, d_1a=0.0, d_2=0.0, d_2a=0.0, d_2b=0.0, d_2b1=0.0)
class hydpy.models.manager.manager_model.Update_LoggedRequest_V1[source]

Bases: Method

Sum and memorise the requests to all source elements that are direct neighbours to the target node.

Used by the application model:

manager_lwc

Requires the derived parameters:

NmbSources MemoryLength Adjacency

Requires the flux sequence:

Request

Updates the log sequence:

LoggedRequest

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b", "c", "d")
>>> derived.memorylength(3)
>>> derived.adjacency([[True, False, False, False, False],
...                    [False, True, False, False, False],
...                    [True, False, False, False, False],
...                    [False, False, True, False, False]])
>>> fluxes.request = 1.0, nan, 2.0, nan
>>> logs.loggedrequest = 2.0, 4.0, 6.0
>>> model.update_loggedrequest_v1()
>>> logs.loggedrequest
loggedrequest(3.0, 2.0, 4.0)
class hydpy.models.manager.manager_model.Pass_Request_V1[source]

Bases: Method

Pass the additional water release requests to the relevant sender sequences.

Used by the application model:

manager_lwc

Requires the derived parameter:

NmbSources

Requires the flux sequence:

Request

Calculates the sender sequence:

Request

Example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b", "c")
>>> fluxes.request = 3.0, 1.0, 2.0
>>> senders.request.shape = 3
>>> model.pass_request_v1()
>>> senders.request
request(3.0, 1.0, 2.0)

Variable features

Variable tools

class hydpy.models.manager.manager_variables.MixinSources(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: Variable, ABC

Mixin class for 1-dimensional parameters and sequences that handle one value per source element.

We take parameter Active as an example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b")
>>> active.shape
(2,)

Redefining the same number of sources does not delete the already available data, while changing it does:

>>> active(a=True, b=False)
>>> sources("a", "b")
>>> active
active(a=True, b=False)
>>> sources("a", "b", "c")
>>> active
active(?)
NDIM: Final[Literal[1]] = 1
name = 'mixinsources'

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

class hydpy.models.manager.manager_variables.MixinSourceSequence(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: MixinSources, ABC

Extends MixinSources by a string representation that includes the source names.

We take the flux sequence Request as an example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b")
>>> fluxes.request = 1.0, 2.0
>>> fluxes.request
request(a=1.0, b=2.0)
name = 'mixinsourcesequence'

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

class hydpy.models.manager.manager_variables.MixinMemory(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: Variable, ABC

Mixin class for 1-dimensional sequences that handle one value per memorised simulation step.

We take the log sequence LoggedDischarge as an example:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> derived.memorylength(3)
>>> logs.loggeddischarge
loggeddischarge(nan, nan, nan)

Redefining the same memory length does not delete the already available data, while changing it does:

>>> logs.loggeddischarge = 1.0
>>> derived.memorylength(3)
>>> logs.loggeddischarge
loggeddischarge(1.0, 1.0, 1.0)
>>> derived.memorylength(2)
>>> logs.loggeddischarge
loggeddischarge(nan, nan)
NDIM: Final[Literal[1]] = 1
name = 'mixinmemory'

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

Parameter features

Parameter tools

class hydpy.models.manager.manager_parameters.ParameterSource(subvars: SubParameters[modeltools.Model])[source]

Bases: MixinSources, Parameter, ABC

Base class for parameters that handle individual values for all sources.

We take the parameter Active as an example, which requires (as all subclasses of ParameterSource) the relevant sources to be defined beforehand:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> active(c=True, a=False, b=True)
Traceback (most recent call last):
...
RuntimeError: While trying to set the values of parameter `active` of element `?`, the following error occurred: Parameter `sources` of element `?` does not know the names of the relevant sources so far.

As soon as the source names are known, you can assign their individual values via keyword arguments:

>>> sources("c", "a", "b")
>>> active
active(?)
>>> active(c=True, a=False, b=True)
>>> active
active(a=False, b=True, c=True)
>>> from hydpy import print_vector
>>> print_vector(active.values)
False, True, True

You can also provide a single general value for all sources.:

>>> active(True)
>>> active
active(True)
>>> print_vector(active.values)
True, True, True

Passing a vector of values as a positional argument also works (but may be prone to misallocations):

>>> active([False, True, True])
>>> active
active(a=False, b=True, c=True)
>>> print_vector(active.values)
False, True, True
>>> active(True, False, False)
>>> active
active(a=True, b=False, c=False)
>>> print_vector(active.values)
True, False, False

If you mix one positional argument with multiple keywords, the positional argument serves as a default value:

>>> active(True, a=False)
>>> active
active(a=False, b=True, c=True)
>>> active(True, a=False, b=True, c=False)
>>> active
active(a=False, b=True, c=False)

There can be only one default value:

>>> active(True, False, True, b=True)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `active` of element `?`, the following error occurred: Providing keyword arguments and more than one positional argument simultaneously is not supported.

Missing or unknown source names are reported as follows:

>>> active(c=True, a=False)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `active` of element `?`, the following error occurred: For the source `b`, no value is given.
>>> active(c=True)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `active` of element `?`, the following error occurred: For the sources `a` and `b`, no values are given.
>>> active(c=True, a=False, b=True, d=True)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `active` of element `?`, the following error occurred: The source `d` is unknown.
>>> active(c=True, a=False, b=True, d=True, e=False)
Traceback (most recent call last):
...
ValueError: While trying to set the values of parameter `active` of element `?`, the following error occurred: The sources `d` and `e` are unknown.
name = 'parametersource'

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

Control parameters

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

Bases: ControlParameters

Control parameters of model manager.

The following classes are selected:
  • Commission Commission date [-].

  • DischargeThreshold Discharge threshold for estimating release requests [m³/s].

  • DischargeTolerance Discharge tolerance for estimating release requests [m³/s].

  • TimeDelay Time delay (in terms of simulation steps) between the release of additional water and its effect on the target cross-section [-].

  • TimeWindow Time window (in terms of simulation steps) used for calculating multiple “free discharge” estimates [-].

  • Sources The sources (e.g. dams) that are instructible to release additional water.

  • VolumeThreshold Water volume below which the sources do not fulfil additional water release requests [million m³].

  • VolumeTolerance Water volume tolerance for determining the water demand of the individual sources [million m³].

  • ReleaseMax Maximum additional release of the individual sources [m³/s].

  • Active Flag to activate/deactivate sending requests to individual sources [-].

class hydpy.models.manager.manager_control.Commission(subvars: SubParameters[modeltools.Model])[source]

Bases: DateParameter

Commission date [-].

Required by the method:

Calc_Request_V1

Used by the application model:

manager_lwc

name = 'commission'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_control.DischargeThreshold(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Discharge threshold for estimating release requests [m³/s].

Required by the methods:

Calc_Alertness_V1 Calc_DemandTarget_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
TYPE

alias of float

SPAN = (0.0, None)
name = 'dischargethreshold'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_control.DischargeTolerance(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Discharge tolerance for estimating release requests [m³/s].

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
TYPE

alias of float

SPAN = (0.0, None)
name = 'dischargetolerance'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_control.TimeDelay(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Time delay (in terms of simulation steps) between the release of additional water and its effect on the target cross-section [-].

Required by the method:

Calc_FreeDischarge_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
TYPE

alias of int

SPAN = (0, None)
name = 'timedelay'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_control.TimeWindow(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Time window (in terms of simulation steps) used for calculating multiple “free discharge” estimates [-].

Required by the method:

Calc_FreeDischarge_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
TYPE

alias of int

SPAN = (1, None)
name = 'timewindow'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_control.Sources(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: SpecialParameter

The sources (e.g. dams) that are instructible to release additional water.

Used by the application model:

manager_lwc

Sources is a special parameter (see SpecialParameter) that handles the names of the elements that handle the relevant source models:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources
sources(?)
>>> sources.verify()
Traceback (most recent call last):
...
RuntimeError: Parameter `sources` of element `?` does not know the names of the relevant sources so far.

Sources expects the names of the elements which handle the relevant source models and sorts them alphabetically, if necessary:

>>> sources("c", "a", "b")
>>> sources
sources("a", "b", "c")
>>> sources.verify()

Sources provides the names of the individual sources by its property sourcenames and passes their number to the derived parameter NmbSources, which determines the shape of many other parameters and sequences:

>>> sources.sourcenames
('a', 'b', 'c')
>>> derived.nmbsources
nmbsources(3)
>>> active.shape
(3,)

Sources raises the following errors if the user gives no or invalid element names:

>>> sources()
Traceback (most recent call last):
...
ValueError: While trying to define the sources to be controlled by the model `manager` of element `?`, the following error occurred: Parameter `sources` requires the name of at least one element, but none is given.
>>> sources(3)
Traceback (most recent call last):
...
ValueError: While trying to define the sources to be controlled by the model `manager` of element `?`, the following error occurred: Parameter `sources` requires a list of the names of the elements which handle the relevant source models, but the argument `3` is not a valid element name.
>>> sources("not valid", "valid", " invalid")
Traceback (most recent call last):
...
ValueError: While trying to define the sources to be controlled by the model `manager` of element `?`, the following error occurred: Parameter `sources` requires a list of the names of the elements which handle the relevant source models, but the arguments `not valid` and ` invalid` are not valid element names.

In case of errors, the previous definitions remain unchanged:

>>> sources
sources("a", "b", "c")
property sourcenames: tuple[str, ...]

The names of the elements which handle the relevant source models.

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources.sourcenames
Traceback (most recent call last):
...
RuntimeError: Parameter `sources` of element `?` does not know the names of the relevant sources so far.
>>> sources("c", "a", "b")
>>> sources.sourcenames
('a', 'b', 'c')
verify() → None[source]

Raise a RuntimeError if the names of the sources are unknown.

name: str = 'sources'

Name of the variable in lowercase letters.

class hydpy.models.manager.manager_control.VolumeThreshold(subvars: SubParameters[modeltools.Model])[source]

Bases: ParameterSource

Water volume below which the sources do not fulfil additional water release requests [million m³].

Required by the methods:

Calc_DemandSources_V1 Calc_PossibleRelease_V1

Used by the application model:

manager_lwc

The documentation of the base class ParameterSource provides information on the different ways to set source-specific values.

TYPE

alias of float

SPAN = (0.0, None)
name = 'volumethreshold'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.manager.manager_control.VolumeTolerance(subvars: SubParameters[modeltools.Model])[source]

Bases: ParameterSource

Water volume tolerance for determining the water demand of the individual sources [million m³].

Used by the application model:

manager_lwc

The documentation of the base class ParameterSource provides information on the different ways to set source-specific values.

TYPE

alias of float

SPAN = (0.0, None)
name = 'volumetolerance'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.manager.manager_control.ReleaseMax(subvars: SubParameters[modeltools.Model])[source]

Bases: ParameterSource

Maximum additional release of the individual sources [m³/s].

Required by the method:

Calc_PossibleRelease_V1

Used by the application model:

manager_lwc

The documentation of the base class ParameterSource provides information on the different ways to set source-specific values.

TYPE

alias of float

SPAN = (0.0, None)
name = 'releasemax'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_control.Active(subvars: SubParameters[modeltools.Model])[source]

Bases: ParameterSource

Flag to activate/deactivate sending requests to individual sources [-].

Required by the methods:

Calc_DemandSources_V1 Calc_PossibleRelease_V1

Used by the application model:

manager_lwc

The documentation of the base class ParameterSource provides information on the different ways to set source-specific values.

TYPE

alias of bool

SPAN = (False, True)
name = 'active'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

Derived parameters

class hydpy.models.manager.DerivedParameters(master: Parameters[TM_co], cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: DerivedParameters

Derived parameters of model manager.

The following classes are selected:
class hydpy.models.manager.manager_derived.Seconds(subvars: SubParameters[modeltools.Model])[source]

Bases: SecondsParameter

Length of the actual simulation step size [s].

Required by the methods:

Calc_DemandSources_V1 Calc_PossibleRelease_V1

Used by the application model:

manager_lwc

name = 'seconds'

Name of the variable in lowercase letters.

unit = 's'

Unit of the variable.

class hydpy.models.manager.manager_derived.NmbSources(subvars: SubParameters[modeltools.Model])[source]

Bases: NmbParameter

The number of sources [-].

Calling the control parameter Sources sets NmbSources immediately. Method update() determines the same value:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b", "c")
>>> derived.nmbsources.update()
>>> derived.nmbsources
nmbsources(3)
SPAN = (1, None)
update() → None[source]

Determine the number of sources.

name = 'nmbsources'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_derived.DischargeSmoothPar(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Smoothing parameter related to DischargeTolerance [m³/s].

Required by the methods:

Calc_Alertness_V1 Calc_DemandTarget_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
TYPE

alias of float

SPAN = (0.0, None)
update() → None[source]

Calculate the smoothing parameter value.

The documentation on module smoothtools explains the following example in detail:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> dischargetolerance(0.0)
>>> derived.dischargesmoothpar.update()
>>> from hydpy.cythons.smoothutils import smooth_max1, smooth_min1
>>> from hydpy import round_
>>> round_(smooth_max1(4.0, 1.5, derived.dischargesmoothpar))
4.0
>>> round_(smooth_min1(4.0, 1.5, derived.dischargesmoothpar))
1.5
>>> dischargetolerance(2.5)
>>> derived.dischargesmoothpar.update()
>>> round_(smooth_max1(4.0, 1.5, derived.dischargesmoothpar))
4.01
>>> round_(smooth_min1(4.0, 1.5, derived.dischargesmoothpar))
1.49
name = 'dischargesmoothpar'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_derived.VolumeSmoothPar(subvars: SubParameters[modeltools.Model])[source]

Bases: ParameterSource

Smoothing parameter related to VolumeTolerance [m³/s].

Required by the method:

Calc_DemandSources_V1

Used by the application model:

manager_lwc

TYPE

alias of float

SPAN = (0.0, None)
update() → None[source]

Calculate the smoothing parameter value.

The documentation on module smoothtools explains the following example in detail:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b")
>>> volumetolerance(0.0, 2.5)
>>> derived.volumesmoothpar.update()
>>> from hydpy.cythons.smoothutils import smooth_max1, smooth_min1
>>> from hydpy import round_
>>> round_(smooth_max1(4.0, 1.5, derived.volumesmoothpar.values[0]))
4.0
>>> round_(smooth_min1(4.0, 1.5, derived.volumesmoothpar.values[0]))
1.5
>>> round_(smooth_max1(4.0, 1.5, derived.volumesmoothpar.values[1]))
4.01
>>> round_(smooth_min1(4.0, 1.5, derived.volumesmoothpar.values[1]))
1.49
name = 'volumesmoothpar'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_derived.MemoryLength(subvars: SubParameters[modeltools.Model])[source]

Bases: NmbParameter

Number of simulation steps to be covered by some log sequences [-].

Required by the methods:

Pick_LoggedDischarge_V1 Update_LoggedRequest_V1

Used by the application model:

manager_lwc

SPAN = (0, None)
update() → None[source]

Update the memory length according to \(MemoryLength = TimeDelay + TimeWindow\).

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> timedelay(2)
>>> timewindow(3)
>>> derived.memorylength.update()
>>> derived.memorylength
memorylength(5)
name = 'memorylength'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_derived.Adjacency(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

An (incomplete) adjacency matrix of the target node and all source elements [-].

Required by the methods:

Calc_Request_V1 Update_LoggedRequest_V1

Used by the application model:

manager_lwc

See method update() for more information.

Parameter Sources determines the shape of Adjacency (via the derived parameter NmbSources). The number of rows equals the number of sources, and the number of columns equals the number of sources plus one (for the target node):

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("a", "b")
>>> derived.adjacency.shape
(2, 3)
NDIM: Final[Literal[2]] = 2
TYPE

alias of bool

SPAN = (False, True)
update() → None[source]

Determine a directed subgraph that contains only the target node and all selected source elements.

We create the following setting where the sources d_1 and d_2 release their water toward the target node t, d_1a releases its water to d_1, d_2a and d_2b release their water to d_2, and d_2b1 releases its water to d_2b:

>>> from hydpy import Element, FusedVariable, Node, Nodes
>>> from hydpy.aliases import (
...     dam_observers_A,
...     dam_states_WaterVolume,
...     manager_senders_Request,
...     manager_receivers_WaterVolume,
... )
>>> t = Node("t")
>>> WaterVolume = FusedVariable(
...     "WaterVolume", dam_states_WaterVolume, manager_receivers_WaterVolume
... )
>>> v_1, v_1a, v_2, v_2a, v_2b, v_2b1 = Nodes(
...     "v_1", "v_1a", "v_2", "v_2a", "v_2b", "v_2b1",
...     defaultvariable=WaterVolume,
... )
>>> Request = FusedVariable("Request", dam_observers_A, manager_senders_Request)
>>> r_1, r_1a, r_2, r_2a, r_2b, r_2b1 = Nodes(
...     "r_1", "r_1a", "r_2", "r_2a", "r_2b", "r_2b1", defaultvariable=Request,
... )
>>> d_1 = Element("d_1", inlets="q_1a_1", outlets=t, observers=r_1, outputs=v_1)
>>> d_1a = Element("d_1a", outlets="q_1a_1", observers=r_1a, outputs=v_1a)
>>> d_2 = Element(
...     "d_2", inlets=("q_2a_2", "q_2b_2"),
...     outlets=t, observers=r_2, outputs=v_2,
... )
>>> d_2a = Element("d_2a", outlets="q_2a_2", observers=r_2a, outputs=v_2a)
>>> d_2b = Element(
...     "d_2b", inlets="q_2b1_2b",
...     outlets="q_2b_2", observers=r_2b, outputs=v_2b,
... )
>>> d_2b1 = Element("d_2b1", outlets="q_2b1_2b", observers=r_2b1, outputs=v_2b1)
>>> lwc = Element(
...     "lwc",
...     receivers=[t, v_1, v_1a, v_2, v_2a, v_2b, v_2b1],
...     senders=[r_1, r_1a, r_2, r_2a, r_2b, r_2b1],
... )

Method update() converts this setting into an adjacency matrix. The first column marks those sources (d1 and d_2) that release their water directly to the target node. The second column marks those sources (d_1a) that release their water to the first source (d1); the third column marks those sources (none) that release their water to the second source (d_1a), and so on. Note that the adjacency matrix is not square because we know that the target node does not release any water towards of the sources, which means we can omit the corresponding (first) row:

>>> from hydpy.models.manager_lwc import *
>>> parameterstep()
>>> sources("d_1", "d_1a", "d_2", "d_2a", "d_2b", "d_2b1")
>>> lwc.model = model
>>> derived.adjacency.update()
>>> derived.adjacency
adjacency([[True, False, False, False, False, False, False],
           [False, True, False, False, False, False, False],
           [True, False, False, False, False, False, False],
           [False, False, False, True, False, False, False],
           [False, False, False, True, False, False, False],
           [False, False, False, False, False, True, False]])

The adjacency matrix only represents the subgraph of the relevant source elements:

>>> sources("d_1a", "d_2", "d_2a", "d_2b1")
>>> derived.adjacency.update()
>>> derived.adjacency
adjacency([[True, False, False, False, False],
           [True, False, False, False, False],
           [False, False, True, False, False],
           [False, False, True, False, False]])

All source elements must, of course, lie upstream of the target node:

>>> d_3 = Element("d_3", outlets="q_3")
>>> sources("d_1", "d_2", "d_3")
>>> derived.adjacency.update()
Traceback (most recent call last):
...
RuntimeError: While trying to update parameter `adjacency` of element `lwc`, the following error occurred: There are no paths between the source element `d_3` and the target node `t`, but there must be exactly one.

A branching of the river network above the target node can mean trouble. update() thus searches for multiple paths between the target node and all source elements (this strategy might not cover all problematic cases and might also complain about some unproblematic ones - we might improve the algorithm later):

>>> sources("d_1", "d_1a", "d_2", "d_2a", "d_2b", "d_2b1")
>>> d_1a.outlets.add_device("b", force=True)
>>> d_2a.inlets.add_device("b", force=True)
>>> derived.adjacency.update()
Traceback (most recent call last):
...
RuntimeError: While trying to update parameter `adjacency` of element `lwc`, the following error occurred: There are two paths between the source element `d_1a` and the target node `t`, but there must be exactly one.
name = 'adjacency'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.manager.manager_derived.Order(subvars: SubParameters[modeltools.Model])[source]

Bases: MixinSources, Parameter

The processing order of all source elements [-].

Required by the method:

Calc_Request_V1

Used by the application model:

manager_lwc

See method update() for more information.

TYPE

alias of int

SPAN = (0, None)
update() → None[source]

Determine the processing order based on a (reversed) topological sort.

The following order ensures we do not process a source element before we have processed its downstream source elements:

>>> from hydpy.models.manager import *
>>> parameterstep()
>>> sources("d_1", "d_1a", "d_2", "d_2a", "d_2b", "d_2b1")
>>> derived.adjacency([[True, False, False, False, False, False, False],
...                    [False, True, False, False, False, False, False],
...                    [True, False, False, False, False, False, False],
...                    [False, False, False, True, False, False, False],
...                    [False, False, False, True, False, False, False],
...                    [False, False, False, False, False, True, False]])
>>> derived.order.update()
>>> derived.order
order(2, 4, 0, 5, 3, 1)
name = 'order'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

Sequence features

Factor sequences

class hydpy.models.manager.FactorSequences(master: Sequences[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FactorSequences

Factor sequences of model manager.

The following classes are selected:
  • Alertness The current need for low water control [-].

class hydpy.models.manager.manager_factors.Alertness(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: FactorSequence

The current need for low water control [-].

Calculated by the method:

Calc_Alertness_V1

Required by the method:

Calc_DemandSources_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
name = 'alertness'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

Flux sequences

class hydpy.models.manager.FluxSequences(master: Sequences[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FluxSequences

Flux sequences of model manager.

The following classes are selected:
  • DemandTarget The demand for additional water release at the target location [m³/s].

  • FreeDischarge The discharge at the target location that would have occurred without requesting additional water releases [m³/s].

  • DemandSources The demand for additional water release at the individual sources [m³/s].

  • PossibleRelease The possible additional water releases of the individual sources [m³/s].

  • Request The actual additional water release requested from the individual sources [m³/s].

class hydpy.models.manager.manager_fluxes.DemandTarget(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

The demand for additional water release at the target location [m³/s].

Calculated by the method:

Calc_DemandTarget_V1

Required by the method:

Calc_Request_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
name = 'demandtarget'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_fluxes.FreeDischarge(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

The discharge at the target location that would have occurred without requesting additional water releases [m³/s].

Calculated by the method:

Calc_FreeDischarge_V1

Required by the methods:

Calc_Alertness_V1 Calc_DemandTarget_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
name = 'freedischarge'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_fluxes.DemandSources(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: MixinSourceSequence, FluxSequence

The demand for additional water release at the individual sources [m³/s].

Calculated by the method:

Calc_DemandSources_V1

Required by the method:

Calc_Request_V1

Used by the application model:

manager_lwc

name = 'demandsources'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_fluxes.PossibleRelease(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: MixinSourceSequence, FluxSequence

The possible additional water releases of the individual sources [m³/s].

Calculated by the method:

Calc_PossibleRelease_V1

Required by the method:

Calc_Request_V1

Used by the application model:

manager_lwc

name = 'possiblerelease'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_fluxes.Request(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: MixinSourceSequence, FluxSequence

The actual additional water release requested from the individual sources [m³/s].

Calculated by the method:

Calc_Request_V1

Required by the methods:

Pass_Request_V1 Update_LoggedRequest_V1

Used by the application model:

manager_lwc

name = 'request'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Log sequences

class hydpy.models.manager.LogSequences(master: Sequences[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: LogSequences

Log sequences of model manager.

The following classes are selected:
  • LoggedDischarge Logged discharge values of the target location [m³/s].

  • LoggedRequest Logged sums of the additional release requests of all sources directly neighbouring the target location [m³/s].

  • LoggedWaterVolume Logged water volumes of the individual sources [million m³].

class hydpy.models.manager.manager_logs.LoggedDischarge(subvars: ModelSequences[modeltools.Model, ModelSequence, variabletools.FastAccess])[source]

Bases: MixinMemory, LogSequence

Logged discharge values of the target location [m³/s].

Calculated by the method:

Pick_LoggedDischarge_V1

Required by the method:

Calc_FreeDischarge_V1

Used by the application model:

manager_lwc

name = 'loggeddischarge'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_logs.LoggedRequest(subvars: ModelSequences[modeltools.Model, ModelSequence, variabletools.FastAccess])[source]

Bases: MixinMemory, LogSequence

Logged sums of the additional release requests of all sources directly neighbouring the target location [m³/s].

Updated by the method:

Update_LoggedRequest_V1

Required by the method:

Calc_FreeDischarge_V1

Used by the application model:

manager_lwc

name = 'loggedrequest'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_logs.LoggedWaterVolume(subvars: ModelSequences[modeltools.Model, ModelSequence, variabletools.FastAccess])[source]

Bases: MixinSourceSequence, LogSequence

Logged water volumes of the individual sources [million m³].

Calculated by the method:

Pick_LoggedWaterVolume_V1

Required by the methods:

Calc_DemandSources_V1 Calc_PossibleRelease_V1

Used by the application model:

manager_lwc

name = 'loggedwatervolume'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

Receiver sequences

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

Bases: ReceiverSequences

Receiver sequences of model manager.

The following classes are selected:
  • Q Discharge at the target location [m³/s].

  • WaterVolume The current water volume of the individual sources [million m³].

class hydpy.models.manager.manager_receivers.Q(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: ReceiverSequence

Discharge at the target location [m³/s].

Required by the method:

Pick_LoggedDischarge_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[0]] = 0
name = 'q'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.manager.manager_receivers.WaterVolume(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: ReceiverSequence

The current water volume of the individual sources [million m³].

Required by the method:

Pick_LoggedWaterVolume_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[1]] = 1
name = 'watervolume'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

Sender sequences

class hydpy.models.manager.SenderSequences(master: Sequences[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SenderSequences

Sender sequences of model manager.

The following classes are selected:
  • Request The actual additional water release requested from the individual sources [m³/s].

class hydpy.models.manager.manager_senders.Request(subvars: ModelIOSequences[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: SenderSequence

The actual additional water release requested from the individual sources [m³/s].

Calculated by the method:

Pass_Request_V1

Used by the application model:

manager_lwc

NDIM: Final[Literal[1]] = 1
name = 'request'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.