HydPy-Exch (base model)

The HydPy-Exch (base model) base model provides features to implement helper models that enable other models to exchange data more freely.

Method Features

class hydpy.models.exch.exch_model.Model[source]

Bases: AdHocModel, SubmodelInterface

HydPy-Exch (base model).

The following “receiver update methods” are called in the given sequence before performing a simulation step:
The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
The following “observer update methods” are called in the given sequence at the beginning of each simulation step:
  • Pick_X_V1 Pick the input data from multiple input nodes and sum it up.

The following “run methods” are called in the given sequence during each simulation step:
The following “outlet update methods” are called in the given sequence at the end of each simulation step:
The following interface methods are available to main models using the defined model as a submodel:
DOCNAME: DocName = ('Exch', 'base model')
OBSERVER_METHODS: ClassVar[tuple[type[Method], ...]] = (<class 'hydpy.models.exch.exch_model.Pick_X_V1'>,)
REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()
class hydpy.models.exch.exch_model.Pick_LoggedWaterLevel_V1[source]

Bases: Method

Pick the logged water level from a single receiver node.

Requires the receiver sequence:

WaterLevel

Calculates the log sequence:

LoggedWaterLevel

Basic equation:

\(LoggedWaterLevel = WaterLevel\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> receivers.waterlevel = 2.0
>>> model.pick_loggedwaterlevel_v1()
>>> logs.loggedwaterlevel
loggedwaterlevel(2.0)
class hydpy.models.exch.exch_model.Pick_LoggedWaterLevels_V1[source]

Bases: Method

Pic the logged water levels from two receiver nodes.

Requires the receiver sequence:

WaterLevels

Calculates the log sequence:

LoggedWaterLevels

Basic equation:

\(LoggedWaterLevels = WaterLevels\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> receivers.waterlevels.shape = 2
>>> receivers.waterlevels = 2.0, 4.0
>>> model.pick_loggedwaterlevels_v1()
>>> logs.loggedwaterlevels
loggedwaterlevels(2.0, 4.0)
class hydpy.models.exch.exch_model.Pick_X_V1[source]

Bases: Method

Pick the input data from multiple input nodes and sum it up.

Required by the method:

Determine_Y_V1

Requires the control parameter:

ObserverNodes

Calculates the factor sequence:

X

Basic equation:

\(X_{factors} = \sum X_{observers}\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> observernodes("n1", "n2")
>>> observers.x = 1.0, 2.0
>>> model.pick_x_v1()
>>> factors.x
x(3.0)
class hydpy.models.exch.exch_model.Update_WaterLevels_V1[source]

Bases: Method

Update the factor sequence WaterLevels.

Requires the log sequence:

LoggedWaterLevels

Calculates the factor sequence:

WaterLevels

Basic equation:

\(WaterLevels = LoggedWaterLevel\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> logs.loggedwaterlevels = 2.0, 4.0
>>> model.update_waterlevels_v1()
>>> factors.waterlevels
waterlevels(2.0, 4.0)
class hydpy.models.exch.exch_model.Calc_DeltaWaterLevel_V1[source]

Bases: Method

Calculate the effective difference of both water levels.

Requires the control parameter:

CrestHeight

Requires the factor sequence:

WaterLevels

Calculates the factor sequence:

DeltaWaterLevel

Basic equation:

\(DeltaWaterLevel = max(WaterLevel_0, CrestHeight) - max(WaterLevel_1, CrestHeight)\)

Examples:

“Effective difference” means that only the height above the crest counts. The first example illustrates this for fixed water levels and a variable crest height:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> from hydpy import UnitTest
>>> test = UnitTest(model=model,
...                 method=model.calc_deltawaterlevel_v1,
...                 last_example=5,
...                 parseqs=(control.crestheight, factors.deltawaterlevel))
>>> test.nexts.crestheight = 1.0, 2.0, 3.0, 4.0, 5.0
>>> factors.waterlevels = 4.0, 2.0
>>> test()
| ex. | crestheight | deltawaterlevel |
---------------------------------------
|   1 |         1.0 |             2.0 |
|   2 |         2.0 |             2.0 |
|   3 |         3.0 |             1.0 |
|   4 |         4.0 |             0.0 |
|   5 |         5.0 |             0.0 |

Method Calc_DeltaWaterLevel_V1 modifies the basic equation given above to also work for an inverse gradient:

>>> factors.waterlevels = 2.0, 4.0
>>> test()
| ex. | crestheight | deltawaterlevel |
---------------------------------------
|   1 |         1.0 |            -2.0 |
|   2 |         2.0 |            -2.0 |
|   3 |         3.0 |            -1.0 |
|   4 |         4.0 |             0.0 |
|   5 |         5.0 |             0.0 |
class hydpy.models.exch.exch_model.Calc_PotentialExchange_V1[source]

Bases: Method

Calculate the potential exchange that strictly follows the weir formula without taking any other limitations into account.

Requires the control parameters:

CrestWidth FlowCoefficient FlowExponent

Requires the factor sequence:

DeltaWaterLevel

Calculates the flux sequence:

PotentialExchange

Basic equation:

\(PotentialExchange = FlowCoefficient \cdot CrestWidth \cdot DeltaWaterLevel ^ {FlowExponent}\)

Examples:

Method Calc_PotentialExchange_V1 modifies the above basic equation to work for positive and negative gradients:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> crestwidth(3.0)
>>> flowcoefficient(0.5)
>>> flowexponent(2.0)
>>> factors.deltawaterlevel = 2.0
>>> model.calc_potentialexchange_v1()
>>> fluxes.potentialexchange
potentialexchange(6.0)
>>> factors.deltawaterlevel = -2.0
>>> model.calc_potentialexchange_v1()
>>> fluxes.potentialexchange
potentialexchange(-6.0)
class hydpy.models.exch.exch_model.Calc_ActualExchange_V1[source]

Bases: Method

Calculate the actual exchange.

Requires the control parameter:

AllowedExchange

Requires the flux sequence:

PotentialExchange

Calculates the flux sequence:

ActualExchange

Basic equation:

\(ActualExchange = min(PotentialExchange, AllowedExchange)\)

Examples:

Method Calc_ActualExchange_V1 modifies the given basic equation to work for positive and negative gradients:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> allowedexchange(2.0)
>>> fluxes.potentialexchange = 1.0
>>> model.calc_actualexchange_v1()
>>> fluxes.actualexchange
actualexchange(1.0)
>>> fluxes.potentialexchange = 3.0
>>> model.calc_actualexchange_v1()
>>> fluxes.actualexchange
actualexchange(2.0)
>>> fluxes.potentialexchange = -1.0
>>> model.calc_actualexchange_v1()
>>> fluxes.actualexchange
actualexchange(-1.0)
>>> fluxes.potentialexchange = -3.0
>>> model.calc_actualexchange_v1()
>>> fluxes.actualexchange
actualexchange(-2.0)
class hydpy.models.exch.exch_model.Pass_ActualExchange_V1[source]

Bases: Method

Pass the actual exchange to an outlet node.

Requires the flux sequence:

ActualExchange

Calculates the outlet sequence:

Exchange

Basic equation:

\(Exchange = ActualExchange\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> fluxes.actualexchange = 2.0
>>> outlets.exchange.shape = 2
>>> model.pass_actualexchange_v1()
>>> outlets.exchange
exchange(-2.0, 2.0)
class hydpy.models.exch.exch_model.Pick_OriginalInput_V1[source]

Bases: Method

Update OriginalInput based on Total.

Requires the inlet sequence:

Total

Calculates the flux sequence:

OriginalInput

Basic equation:

\(OriginalInput = \sum Total\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> inlets.total.shape = 2
>>> inlets.total = 2.0, 4.0
>>> model.pick_originalinput_v1()
>>> fluxes.originalinput
originalinput(6.0)
class hydpy.models.exch.exch_model.Calc_AdjustedInput_V1[source]

Bases: Method

Adjust the original input data.

Requires the control parameters:

Delta Minimum

Requires the derived parameter:

MOY

Requires the flux sequence:

OriginalInput

Calculates the flux sequence:

AdjustedInput

Basic equation:

\(AdjustedInput = max(OriginalInput + Delta, \ Minimum)\)

Examples:

The degree of the input adjustment may vary monthly. Hence, we must define a concrete initialisation period for the following examples:

>>> from hydpy import pub
>>> pub.timegrids = "2000-03-30", "2000-04-03", "1d"
>>> from hydpy.models.exch import *
>>> parameterstep()
>>> derived.moy.update()

Negative Delta values correspond to decreasing input:

>>> delta.mar = -1.0
>>> minimum(0.0)
>>> model.idx_sim = pub.timegrids.init["2000-03-31"]
>>> fluxes.originalinput = 1.5
>>> model.calc_adjustedinput_v1()
>>> fluxes.adjustedinput
adjustedinput(0.5)

The adjusted input values are never smaller than the threshold value defined by parameter Minimum:

>>> minimum(1.0)
>>> model.calc_adjustedinput_v1()
>>> fluxes.adjustedinput
adjustedinput(1.0)

Positive Delta values correspond to increasing input:

>>> model.idx_sim = pub.timegrids.init["2000-04-01"]
>>> delta.apr = 1.0
>>> fluxes.originalinput = 0.5
>>> model.calc_adjustedinput_v1()
>>> fluxes.adjustedinput
adjustedinput(1.5)
class hydpy.models.exch.exch_model.Calc_Outputs_V1[source]

Bases: Method

Calculate the output via interpolation or extrapolation.

Requires the control parameters:

XPoints YPoints

Requires the derived parameters:

NmbPoints NmbBranches

Requires the flux sequence:

AdjustedInput

Calculates the flux sequence:

Outputs

Examples:

For example, assume a weir directing all discharge into branch1 until reaching the capacity limit of 2 m³/s. exch_branch_hbv96 redirects the discharge exceeding this threshold to branch2:

>>> from hydpy.models.exch_branch_hbv96 import *
>>> parameterstep()
>>> xpoints(0.0, 2.0, 4.0)
>>> ypoints(branch1=[0.0, 2.0, 2.0],
...         branch2=[0.0, 0.0, 2.0])
>>> derived.nmbbranches.update()
>>> derived.nmbpoints.update()

Low discharge example (linear interpolation between the first two supporting point pairs):

>>> fluxes.adjustedinput = 1.
>>> model.calc_outputs_v1()
>>> fluxes.outputs
outputs(branch1=1.0,
        branch2=0.0)

Medium discharge example (linear interpolation between the second two supporting point pairs):

>>> fluxes.adjustedinput = 3.0
>>> model.calc_outputs_v1()
>>> print(fluxes.outputs)
outputs(branch1=2.0,
        branch2=1.0)

High discharge example (linear extrapolation beyond the second two supporting point pairs):

>>> fluxes.adjustedinput = 5.0
>>> model.calc_outputs_v1()
>>> fluxes.outputs
outputs(branch1=2.0,
        branch2=3.0)

Non-monotonous relationships and balance violations are allowed:

>>> xpoints(0.0, 2.0, 4.0, 6.0)
>>> ypoints(branch1=[0.0, 2.0, 0.0, 0.0],
...         branch2=[0.0, 0.0, 2.0, 4.0])
>>> derived.nmbbranches.update()
>>> derived.nmbpoints.update()
>>> fluxes.adjustedinput = 7.0
>>> model.calc_outputs_v1()
>>> fluxes.outputs
outputs(branch1=0.0,
        branch2=5.0)
class hydpy.models.exch.exch_model.Calc_Y_V1[source]

Bases: Method

Use an interpolation function to calculate the result.

Required by the method:

Determine_Y_V1

Requires the control parameter:

X2Y

Requires the factor sequence:

X

Calculates the factor sequence:

Y

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> from hydpy import PPoly
>>> x2y(PPoly.from_data([0.0, 1.0], [2.0, 4.0]))
>>> factors.x = 0.5
>>> model.calc_y_v1()
>>> factors.y
y(3.0)
class hydpy.models.exch.exch_model.Pass_Outputs_V1[source]

Bases: Method

Update Branched based on Outputs.

Requires the derived parameter:

NmbBranches

Requires the flux sequence:

Outputs

Calculates the outlet sequence:

Branched

Basic equation:

\(Branched_i = Outputs_i\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> derived.nmbbranches(2)
>>> fluxes.outputs.shape = 2
>>> fluxes.outputs = 2.0, 4.0
>>> outlets.branched.shape = 2
>>> model.pass_outputs_v1()
>>> outlets.branched
branched(2.0, 4.0)
class hydpy.models.exch.exch_model.Pass_Y_V1[source]

Bases: Method

Pass the result data to an arbitrary number of sender nodes.

Requires the factor sequence:

Y

Calculates the sender sequence:

Y

Basic equation:

\(Y_{senders} = Y_{factors}\)

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> factors.y = 3.0
>>> senders.y.shape = 2
>>> model.pass_y_v1()
>>> senders.y
y(3.0, 3.0)
class hydpy.models.exch.exch_model.Get_WaterLevel_V1[source]

Bases: Method

Return the water level in m.

Requires the log sequence:

LoggedWaterLevel

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> logs.loggedwaterlevel = 2.0
>>> from hydpy import round_
>>> round_(model.get_waterlevel_v1())
2.0
class hydpy.models.exch.exch_model.Determine_Y_V1[source]

Bases: AutoMethod

Interface method for determining the result.

Required submethods:

Pick_X_V1 Calc_Y_V1

Requires the control parameters:

ObserverNodes X2Y

Calculates the factor sequences:

X Y

class hydpy.models.exch.exch_model.Get_Y_V1[source]

Bases: Method

Return the result.

Requires the factor sequence:

Y

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> factors.y = 2.0
>>> model.get_y_v1()
2.0

Parameter Features

Control parameters

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

Bases: SubParameters

Control parameters of model exch.

The following classes are selected:
  • CrestHeight() Crest height [m].

  • CrestWidth() Crest width [m].

  • FlowCoefficient() Flow coefficient [-].

  • FlowExponent() Flow exponent [-].

  • AllowedExchange() The highest water exchange allowed [m³/s].

  • Delta() Monthly varying difference for increasing or decreasing the input [e.g. m³/s].

  • Minimum() The allowed minimum value of the adjusted input [e.g. m³/s].

  • XPoints() Supporting points for the independent input variable [e.g. m³/s].

  • YPoints() Supporting points for the dependent output variables [e.g. m³/s].

  • ObserverNodes() The number of the considered observer nodes [-].

  • X2Y() An interpolation function describing the relationship between arbitrary properties [-].

class hydpy.models.exch.exch_control.CrestHeight(subvars: SubParameters)[source]

Bases: Parameter

Crest height [m].

Required by the method:

Calc_DeltaWaterLevel_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0.0, None)
name: str = 'crestheight'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_control.CrestWidth(subvars: SubParameters)[source]

Bases: Parameter

Crest width [m].

Required by the method:

Calc_PotentialExchange_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0.0, None)
name: str = 'crestwidth'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_control.FlowCoefficient(subvars: SubParameters)[source]

Bases: Parameter

Flow coefficient [-].

Required by the method:

Calc_PotentialExchange_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0.0, None)
INIT: int | float | bool | None = 0.62
name: str = 'flowcoefficient'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

class hydpy.models.exch.exch_control.FlowExponent(subvars: SubParameters)[source]

Bases: Parameter

Flow exponent [-].

Required by the method:

Calc_PotentialExchange_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0.0, None)
INIT: int | float | bool | None = 1.5
name: str = 'flowexponent'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

class hydpy.models.exch.exch_control.AllowedExchange(subvars: SubParameters)[source]

Bases: Parameter

The highest water exchange allowed [m³/s].

Required by the method:

Calc_ActualExchange_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0.0, None)
INIT: int | float | bool | None = 1.5
name: str = 'allowedexchange'

Name of the variable in lowercase letters.

unit: str = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.Delta(subvars: SubParameters)[source]

Bases: MonthParameter

Monthly varying difference for increasing or decreasing the input [e.g. m³/s].

Required by the method:

Calc_AdjustedInput_V1

TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (None, None)
INIT: int | float | bool | None = 0.0
name: str = 'delta'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.Minimum(subvars: SubParameters)[source]

Bases: Parameter

The allowed minimum value of the adjusted input [e.g. m³/s].

Required by the method:

Calc_AdjustedInput_V1

NDIM: int = 0
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (None, None)
INIT: int | float | bool | None = 0.0
name: str = 'minimum'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.XPoints(subvars: SubParameters)[source]

Bases: Parameter

Supporting points for the independent input variable [e.g. m³/s].

Required by the method:

Calc_Outputs_V1

There must be at least two supporting points, and they must be strictly monotonous. If not, XPoints raises the following errors:

>>> from hydpy.models.exch_branch_hbv96 import *
>>> parameterstep()
>>> xpoints(1.0, 2.0)
>>> xpoints
xpoints(1.0, 2.0)
>>> xpoints(1.0)
Traceback (most recent call last):
...
ValueError: Branching via linear interpolation requires at least two supporting points, but parameter `xpoints` of element `?` received 1 value(s).
>>> xpoints(1.0, 2.0, 2.0, 3.0)
Traceback (most recent call last):
...
ValueError: The values of parameter `xpoints` of element `?` must be arranged strictly monotonously, which is not the case for the given values `1.0, 2.0, 2.0, and 3.0`.
NDIM: int = 1
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (None, None)
name: str = 'xpoints'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.YPoints(subvars: SubParameters)[source]

Bases: Parameter

Supporting points for the dependent output variables [e.g. m³/s].

Required by the method:

Calc_Outputs_V1

Preparing parameter YPoints requires consistency with parameter XPoints and the currently available Node objects.

>>> from hydpy.models.exch_branch_hbv96 import *
>>> parameterstep("1d")
>>> ypoints
ypoints(?)

You need to prepare parameter XPoints first:

>>> ypoints(1.0, 2.0)
Traceback (most recent call last):
...
RuntimeError: The shape of parameter `ypoints` of element `?` depends on the shape of parameter `xpoints`, which is not defined so far.
>>> xpoints(1.0, 2.0, 3.0)

Supply the names of the output Node objects as keyword arguments:

>>> ypoints(1.0, 2.0)
Traceback (most recent call last):
...
ValueError: For parameter `ypoints` of element `?`, no branches are defined.  Do this via keyword arguments, as explained in the documentation.

The number of x and y supporting points must be identical for all branches.:

>>> ypoints(branch1=[1.0, 2.0],
...         branch2=[2.0, 4.0])
Traceback (most recent call last):
...
ValueError: Each branch requires the same number of supporting points as given for parameter `xpoints`, which is 3, but for branch `branch1` of parameter `ypoints` of element `?`, 2 values are provided.
>>> xpoints(1.0, 2.0)

When working on an actual project (indicated by a predefined project name), each branch name must correspond to a Node name:

>>> from hydpy import pub, Nodes
>>> pub.projectname = "test"
>>> nodes = Nodes("branch1")
>>> ypoints(branch1=[1.0, 2.0],
...         branch2=[2.0, 4.0])
Traceback (most recent call last):
...
RuntimeError: Parameter `ypoints` of element `?` is supposed to branch to node `branch2`, but such a node is not available.

We use the following general exception message for some unexpected errors:

>>> nodes = Nodes("branch1", "branch2")
>>> ypoints(branch1=[1.0, 2.0],
...         branch2="xy")
Traceback (most recent call last):
...
ValueError: While trying to set the values for branch `branch2` of parameter `ypoints` of element `?`, the following error occurred: could not convert string to float: 'xy'

Changing the number of branches during runtime might result in erroneous connections to the Node objects:

>>> ypoints(branch1=[1.0, 2.0],
...         branch2=[2.0, 4.0])
>>> ypoints
ypoints(branch1=[1.0, 2.0],
        branch2=[2.0, 4.0])
>>> ypoints(branch1=[1.0, 2.0])
Traceback (most recent call last):
...
RuntimeError: The number of branches of the exch model should not be changed during runtime.  If you really need to do this, first initialise a new "branched" sequence and connect it to the respective outlet nodes properly.
NDIM: int = 2
TYPE

alias of float

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (None, None)
name: str = 'ypoints'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.ObserverNodes(subvars: SubParameters)[source]

Bases: Parameter

The number of the considered observer nodes [-].

Required by the methods:

Determine_Y_V1 Pick_X_V1

Parameter ObserverNodes requires the names of all observer nodes that need consideration:

>>> from hydpy.models.exch_interp import *
>>> parameterstep()
>>> observernodes(2)
Traceback (most recent call last):
...
ValueError: Parameter `observernodes` of element `?` requires the names of all relevant observation nodes, but the first given value is of type `int`.
>>> observernodes
observernodes(?)

When receiving this information, it automatically prepares the observer sequence X:

>>> observernodes("node_1", "node_2")
>>> observers.x.shape
(2,)
>>> observers.x.observernodes
('node_1', 'node_2')
>>> observernodes
observernodes("node_1", "node_2")
>>> observernodes.value
2
NDIM: int = 0
TYPE

alias of int

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (0, None)
name: str = 'observernodes'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

class hydpy.models.exch.exch_control.X2Y(subvars: SubParameters)[source]

Bases: SimpleInterpolator

An interpolation function describing the relationship between arbitrary properties [-].

Required by the methods:

Calc_Y_V1 Determine_Y_V1

XLABEL = 'X'
YLABEL = 'Y'
name: str = 'x2y'

Class name in lowercase letters.

Derived parameters

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

Bases: SubParameters

Derived parameters of model exch.

The following classes are selected:
  • MOY() References the “global” month of the year index array [-].

  • NmbBranches() The number of branches [-].

  • NmbPoints() The number of supporting points for linear interpolation [-].

class hydpy.models.exch.exch_derived.MOY(subvars: SubParameters)[source]

Bases: MOYParameter

References the “global” month of the year index array [-].

Required by the method:

Calc_AdjustedInput_V1

name: str = 'moy'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

class hydpy.models.exch.exch_derived.NmbBranches(subvars: SubParameters)[source]

Bases: Parameter

The number of branches [-].

Required by the methods:

Calc_Outputs_V1 Pass_Outputs_V1

NDIM: int = 0
TYPE

alias of int

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (1, None)
update()[source]

Determine the number of branches.

name: str = 'nmbbranches'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

class hydpy.models.exch.exch_derived.NmbPoints(subvars: SubParameters)[source]

Bases: Parameter

The number of supporting points for linear interpolation [-].

Required by the method:

Calc_Outputs_V1

NDIM: int = 0
TYPE

alias of int

TIME: bool | None = None
SPAN: tuple[int | float | bool | None, int | float | bool | None] = (2, None)
update()[source]

Determine the number of points.

name: str = 'nmbpoints'

Name of the variable in lowercase letters.

unit: str = '-'

Unit of the variable.

Sequence Features

Factor sequences

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

Bases: FactorSequences

Factor sequences of model exch.

The following classes are selected:
  • WaterLevels() The water level at two locations [m].

  • DeltaWaterLevel() Effective difference of the two water levels [m].

  • X() Arbitrary kind of input data [?].

  • Y() Arbitrary kind of result data [?].

class hydpy.models.exch.exch_factors.WaterLevels(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: MixinFixedShape, FactorSequence

The water level at two locations [m].

Calculated by the method:

Update_WaterLevels_V1

Required by the method:

Calc_DeltaWaterLevel_V1

After each simulation step, the value of WaterLevels corresponds to the value of the LoggedWaterLevels of the previous simulation step.

NDIM: int = 1
SHAPE: tuple[int, ...] = (2,)
name: str = 'waterlevels'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_factors.DeltaWaterLevel(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FactorSequence

Effective difference of the two water levels [m].

Calculated by the method:

Calc_DeltaWaterLevel_V1

Required by the method:

Calc_PotentialExchange_V1

After each simulation step, the value of DeltaWaterLevel corresponds to the value of the LoggedWaterLevels of the previous simulation step.

NDIM: int = 0
name: str = 'deltawaterlevel'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_factors.X(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FactorSequence

Arbitrary kind of input data [?].

Calculated by the methods:

Determine_Y_V1 Pick_X_V1

Required by the method:

Calc_Y_V1

NDIM: int = 0
name: str = 'x'

Name of the variable in lowercase letters.

unit: str = '?'

Unit of the variable.

class hydpy.models.exch.exch_factors.Y(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FactorSequence

Arbitrary kind of result data [?].

Calculated by the methods:

Calc_Y_V1 Determine_Y_V1

Required by the methods:

Get_Y_V1 Pass_Y_V1

NDIM: int = 0
name: str = 'y'

Name of the variable in lowercase letters.

unit: str = '?'

Unit of the variable.

Flux sequences

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

Bases: FluxSequences

Flux sequences of model exch.

The following classes are selected:
class hydpy.models.exch.exch_fluxes.PotentialExchange(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

The potential bidirectional water exchange [m³/s].

Calculated by the method:

Calc_PotentialExchange_V1

Required by the method:

Calc_ActualExchange_V1

NDIM: int = 0
NUMERIC: bool = False
name: str = 'potentialexchange'

Name of the variable in lowercase letters.

unit: str = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.ActualExchange(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

The actual bidirectional water exchange [m³/s].

Calculated by the method:

Calc_ActualExchange_V1

Required by the method:

Pass_ActualExchange_V1

NDIM: int = 0
NUMERIC: bool = False
name: str = 'actualexchange'

Name of the variable in lowercase letters.

unit: str = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.OriginalInput(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

Unadjusted total input [e.g. m³/s].

Calculated by the method:

Pick_OriginalInput_V1

Required by the method:

Calc_AdjustedInput_V1

NDIM: int = 0
NUMERIC: bool = False
name: str = 'originalinput'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.AdjustedInput(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

Adjusted total input [e.g. m³/s].

Calculated by the method:

Calc_AdjustedInput_V1

Required by the method:

Calc_Outputs_V1

NDIM: int = 0
NUMERIC: bool = False
name: str = 'adjustedinput'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.Outputs(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: FluxSequence

Branched outputs [e.g. m³/s].

Calculated by the method:

Calc_Outputs_V1

Required by the method:

Pass_Outputs_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'outputs'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

Log sequences

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

Bases: LogSequences

Log sequences of model exch.

The following classes are selected:
class hydpy.models.exch.exch_logs.LoggedWaterLevel(subvars: ModelSequences[ModelSequence, FastAccess])[source]

Bases: LogSequenceFixed

Logged water level [m].

Calculated by the method:

Pick_LoggedWaterLevel_V1

Required by the method:

Get_WaterLevel_V1

NUMERIC: bool = False
SHAPE: int = 1
name: str = 'loggedwaterlevel'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_logs.LoggedWaterLevels(subvars: ModelSequences[ModelSequence, FastAccess])[source]

Bases: LogSequenceFixed

Logged water levels [m].

Calculated by the method:

Pick_LoggedWaterLevels_V1

Required by the method:

Update_WaterLevels_V1

NUMERIC: bool = False
SHAPE: int = 2
name: str = 'loggedwaterlevels'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

Inlet sequences

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

Bases: InletSequences

Inlet sequences of model exch.

The following classes are selected:
  • Total() Total input [e.g. m³/s].

class hydpy.models.exch.exch_inlets.Total(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: InletSequence

Total input [e.g. m³/s].

Required by the method:

Pick_OriginalInput_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'total'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

Outlet sequences

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

Bases: OutletSequences

Outlet sequences of model exch.

The following classes are selected:
class hydpy.models.exch.exch_outlets.Exchange(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: OutletSequence

Bidirectional water exchange [m³/s].

Calculated by the method:

Pass_ActualExchange_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'exchange'

Name of the variable in lowercase letters.

unit: str = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_outlets.Branched(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: OutletSequence

Branched outputs [e.g. m³/s].

Calculated by the method:

Pass_Outputs_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'branched'

Name of the variable in lowercase letters.

unit: str = 'e.g. m³/s'

Unit of the variable.

Observer sequences

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

Bases: ObserverSequences

Observer sequences of model exch.

The following classes are selected:
  • X() Arbitrary kind of input data [?].

class hydpy.models.exch.exch_observers.X(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: ObserverSequence

Arbitrary kind of input data [?].

Required by the methods:

Determine_Y_V1 Pick_X_V1

NDIM: int = 1
NUMERIC: bool = False
property observernodes: tuple[str, ...]

The relevant observer node’s names.

If necessary, the following error message tries to clarify the usual way of specifying the relevant observer nodes:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> observers.x.observernodes
Traceback (most recent call last):
...
RuntimeError: The observer sequence `x` of element `?` does not know the names of the observer nodes it should be connected with.  Consider providing this information via the control parameter `observernodes`.
>>> observernodes("gauge_1", "gauge_2")
>>> observers.x.observernodes
('gauge_1', 'gauge_2')
connect_to_nodes(group: Literal['inlets', 'receivers', 'inputs', 'outlets', 'senders', 'observers'], available_nodes: list[Node], applied_nodes: list[Node], report_noconnect: bool) None[source]

Establish pointer connections with the relevant observer nodes.

The selection of the observer nodes relies on the nodes’ names instead of their variable types. We demonstrate this by using dam_detention as an example base model, which can handle an arbitrary number of exch_interp submodels:

>>> from hydpy.models.dam_detention import *
>>> parameterstep()

We start with defining an element not connected to any observer nodes and a dam_detention model not handling any submodels and so not any observation series:

>>> from hydpy import Element, PPoly, print_vector
>>> basin = Element("basin", inlets="inflow", outlets="outflow")
>>> nmbsafereleasemodels(0)
>>> basin.model = model

After adding a single submodel that wants to be connected to the still missing observer node gauge_1, connect_to_nodes() raises the following error:

>>> nmbsafereleasemodels(1)
>>> with model.add_safereleasemodel("exch_interp", position=0):
...     observernodes("gauge_1")
...     x2y(PPoly.from_data(xs=[0.0], ys=[0.0]))
>>> basin.model.connect()
Traceback (most recent call last):
...
RuntimeError: While trying to build the node connection of the `observer` sequences of the model handled by element `basin`, the following error occurred: The following node is unavailable: gauge_1.

Adding a node named gauge_1 as an inlet node makes no difference:

>>> basin.inlets = "gauge_1"
>>> basin.model.connect()
Traceback (most recent call last):
...
RuntimeError: While trying to build the node connection of the `observer` sequences of the model handled by element `basin`, the following error occurred: The following node is unavailable: gauge_1.

After also adding gauge_1 as an observer node, connect_to_nodes() builds a proper connection to it without interfering with the general functionality, which also establishes a connection between this node and the main model’s inlet sequence Q:

>>> basin.observers = "gauge_1"
>>> basin.model.connect()
>>> basin.observers.gauge_1.sequences.sim.value = 1.0
>>> basin.model.update_inlets()
>>> print_vector(basin.model.sequences.inlets.q.value)
1.0, 0.0
>>> safereleasemodel = basin.model.safereleasemodels[0]
>>> safereleasemodel.update_observers()
>>> print_vector(safereleasemodel.sequences.observers.x.value)
1.0

The following two examples demonstrate that both the error reporting and the connection mechanism work in more complex cases as well:

>>> basin.observers = "gauge_3"
>>> nmbsafereleasemodels(2)
>>> with model.add_safereleasemodel("exch_interp", position=0):
...     observernodes("gauge_1")
...     x2y(PPoly.from_data(xs=[0.0], ys=[0.0]))
>>> with model.add_safereleasemodel("exch_interp", position=1):
...     observernodes("gauge_2", "gauge_3", "gauge_4")
...     x2y(PPoly.from_data(xs=[0.0], ys=[0.0]))
>>> basin.model.connect()
Traceback (most recent call last):
...
RuntimeError: While trying to build the node connection of the `observer` sequences of the model handled by element `basin`, the following error occurred: The following nodes are unavailable: gauge_2 and gauge_4.
>>> from hydpy import print_vector
>>> basin.observers = ("gauge_2", "gauge_4")
>>> basin.model.connect()
>>> basin.observers.gauge_1.sequences.sim.value = 1.0
>>> basin.observers.gauge_2.sequences.sim.value = 4.0
>>> basin.observers.gauge_3.sequences.sim.value = 3.0
>>> basin.observers.gauge_4.sequences.sim.value = 2.0
>>> safereleasemodel = basin.model.safereleasemodels[0]
>>> safereleasemodel.update_observers()
>>> print_vector(safereleasemodel.sequences.observers.x.value)
1.0
>>> safereleasemodel = basin.model.safereleasemodels[1]
>>> safereleasemodel.update_observers()
>>> print_vector(safereleasemodel.sequences.observers.x.values)
4.0, 3.0, 2.0

The error reporting on the existence of non-connectible nodes works as usual:

>>> basin.observers = "gauge_5"
>>> basin.model.connect()
Traceback (most recent call last):
...
RuntimeError: While trying to build the node connection of the `observer` sequences of the model handled by element `basin`, the following error occurred: The following nodes have not been connected to any sequences: gauge_5.
name: str = 'x'

Name of the variable in lowercase letters.

unit: str = '?'

Unit of the variable.

Receiver sequences

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

Bases: ReceiverSequences

Receiver sequences of model exch.

The following classes are selected:
  • WaterLevel() The water level at a single remote location [m].

  • WaterLevels() The water level at multiple remote locations [m].

class hydpy.models.exch.exch_receivers.WaterLevel(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: ReceiverSequence

The water level at a single remote location [m].

Required by the method:

Pick_LoggedWaterLevel_V1

NDIM: int = 0
NUMERIC: bool = False
name: str = 'waterlevel'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

class hydpy.models.exch.exch_receivers.WaterLevels(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: ReceiverSequence

The water level at multiple remote locations [m].

Required by the method:

Pick_LoggedWaterLevels_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'waterlevels'

Name of the variable in lowercase letters.

unit: str = 'm'

Unit of the variable.

Sender sequences

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

Bases: SenderSequences

Sender sequences of model exch.

The following classes are selected:
  • Y() Arbitrary kind of result data [?].

class hydpy.models.exch.exch_senders.Y(subvars: ModelIOSequences[ModelIOSequence, FastAccessIOSequence])[source]

Bases: SenderSequence

Arbitrary kind of result data [?].

Calculated by the method:

Pass_Y_V1

NDIM: int = 1
NUMERIC: bool = False
name: str = 'y'

Name of the variable in lowercase letters.

unit: str = '?'

Unit of the variable.

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

Bases: SubParameters

Control parameters of model exch.

The following classes are selected:
  • CrestHeight() Crest height [m].

  • CrestWidth() Crest width [m].

  • FlowCoefficient() Flow coefficient [-].

  • FlowExponent() Flow exponent [-].

  • AllowedExchange() The highest water exchange allowed [m³/s].

  • Delta() Monthly varying difference for increasing or decreasing the input [e.g. m³/s].

  • Minimum() The allowed minimum value of the adjusted input [e.g. m³/s].

  • XPoints() Supporting points for the independent input variable [e.g. m³/s].

  • YPoints() Supporting points for the dependent output variables [e.g. m³/s].

  • ObserverNodes() The number of the considered observer nodes [-].

  • X2Y() An interpolation function describing the relationship between arbitrary properties [-].

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

Bases: SubParameters

Derived parameters of model exch.

The following classes are selected:
  • MOY() References the “global” month of the year index array [-].

  • NmbBranches() The number of branches [-].

  • NmbPoints() The number of supporting points for linear interpolation [-].

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

Bases: FactorSequences

Factor sequences of model exch.

The following classes are selected:
  • WaterLevels() The water level at two locations [m].

  • DeltaWaterLevel() Effective difference of the two water levels [m].

  • X() Arbitrary kind of input data [?].

  • Y() Arbitrary kind of result data [?].

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

Bases: FluxSequences

Flux sequences of model exch.

The following classes are selected:
class hydpy.models.exch.InletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InletSequences

Inlet sequences of model exch.

The following classes are selected:
  • Total() Total input [e.g. m³/s].

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

Bases: LogSequences

Log sequences of model exch.

The following classes are selected:
class hydpy.models.exch.ObserverSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: ObserverSequences

Observer sequences of model exch.

The following classes are selected:
  • X() Arbitrary kind of input data [?].

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

Bases: OutletSequences

Outlet sequences of model exch.

The following classes are selected:
class hydpy.models.exch.ReceiverSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: ReceiverSequences

Receiver sequences of model exch.

The following classes are selected:
  • WaterLevel() The water level at a single remote location [m].

  • WaterLevels() The water level at multiple remote locations [m].

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

Bases: SenderSequences

Sender sequences of model exch.

The following classes are selected:
  • Y() Arbitrary kind of result data [?].