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:
  • Get_WaterLevel_V1 Return the water level in m.

  • Determine_Y_V1 Interface method for determining the result.

  • Get_Y_V1 Return the result.

  • Determine_Transfer_V1 Interface method for determining the water transfer based on the current water volume and the main model’s allowed discharge.

  • Get_Transfer_V1 Interface method for querying the effective water transfer in m³/s.

  • Set_Transfer_V1 Interface method to receive the final effective water transfer and pass the actual transfer to the outlet node.

The following “additional methods” might be called by one or more of the other methods or are meant to be directly called by the user:
DOCNAME = ('Exch', 'base model')
nodenames: list[str] = []
targetnames: tuple[str, ...] = ()
REUSABLE_METHODS = ()
class hydpy.models.exch.exch_model.Pick_LoggedWaterLevel_V1[source]

Bases: Method

Pick the logged water level from a single receiver node.

Used by the application model:

exch_waterlevel

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

Pick the logged water levels from two receiver nodes.

Used by the application model:

exch_weir_hbv96

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

Used by the application model:

exch_interp

Requires the derived parameter:

NmbObserverNodes

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.

Used by the application model:

exch_weir_hbv96

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 between both water levels.

Used by the application model:

exch_weir_hbv96

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.

Used by the application model:

exch_weir_hbv96

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.

Used by the application model:

exch_weir_hbv96

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.

Used by the application model:

exch_weir_hbv96

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.

Used by the application model:

exch_branch_hbv96

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.Pick_Input_V1[source]

Bases: Method

Sum all individual input values.

Used by the application model:

exch_branch_rules

Requires the inlet sequence:

Total

Calculates the flux sequence:

Input_

Basic equation:

\(Input = \sum Total\)

Example:

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

Bases: Method

Sum all individual inflow values.

Used by the application model:

exch_branch_io

Requires the inlet sequence:

Inflow

Calculates the flux sequence:

Inflow

Basic equation:
\[Inflow_{fluxes} = \sum Inflow_{inputs}\]

Example:

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

Bases: Method

Adjust the original input data.

Used by the application model:

exch_branch_hbv96

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.

Used by the application model:

exch_branch_hbv96

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.core.exceptiontools import ignore_deprecations
>>> from hydpy.models.exch_branch_hbv96 import *
>>> with ignore_deprecations():
...     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.Return_AllowedTransfer_V1[source]

Bases: Method

Restrict withdrawals to the allowed discharge without turning them into supplies.

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

Used auxiliary methods:

smooth_min1() smooth_max1()

Basic (discontinuous) equation:
\[\begin{split}T_{new} = \begin{cases} T_{old} &|\ T_{old} \leq 0 \\ max \big(min(T_{old}, \, A), \, 0\big) &|\ T_{old} > 0 \end{cases} \\ \\ T = transfer \\ A = alloweddischarge\end{split}\]

Return_AllowedTransfer_V1 applies the strategy of method Fix_Min1_V1 of base model dam (with an “absolute” smoother) to ensure the result is never negative and never exceeds the given transfer or the allowed discharge.

Examples:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> from hydpy import round_
>>> def test(smoothpar):
...     for transfer, alloweddischarge in ((-1.0, -1.0), (2.0, -1.0),
...                                        (2.0, 0.0), (2.0, 1.0), (2.0, 2.0),
...                                        (2.0, 3.0), (2.0, inf)):
...         result = model.return_allowedtransfer_v1(
...             transfer, alloweddischarge, smoothpar
...         )
...         print(transfer, alloweddischarge, end=": ")
...         round_(result)

Without smoothing, the restriction is a simple (discontinuous) minimum with a lower bound of zero, which does not affect supplies (negative values):

>>> test(0.0)
-1.0 -1.0: -1.0
2.0 -1.0: 0.0
2.0 0.0: 0.0
2.0 1.0: 1.0
2.0 2.0: 2.0
2.0 3.0: 2.0
2.0 inf: 2.0

With smoothing, the results stay within the same bounds:

>>> test(0.5)
-1.0 -1.0: -1.0
2.0 -1.0: 0.0
2.0 0.0: 0.0
2.0 1.0: 0.935724
2.0 2.0: 1.653426
2.0 3.0: 1.936536
2.0 inf: 2.0
class hydpy.models.exch.exch_model.Determine_Transfer_V1[source]

Bases: Method

Interface method for determining the water transfer based on the current water volume and the main model’s allowed discharge.

Used by the application model:

exch_water_transfer_io

Required submethod:

Return_AllowedTransfer_V1

Requires the control parameters:

MinVol MaxVol VolTransferRules

Requires the derived parameters:

TOY VolSmoothPar QSmoothPar

Requires the input sequence:

RequestedTransfer

Calculates the aide sequence:

EffectiveTransfer

Used auxiliary method:

smooth_logistic1()

Basic equations:
\[\begin{split}E = f_{AT}(E', \, A, \, S_Q) \\ \\ E' = \begin{cases} f_T(V) &|\ R \in \{nan, \, -\infty, \, \infty\} \\ R \cdot f_{s1}(V - V_{n}, \, S_V) &|\ 0 \leq R < \infty \\ R \cdot f_{s1}(V_{x} - V, \, S_V) &|\ -\infty < R < 0 \end{cases} \\ \\ E = EffectiveTransfer \\ R = RequestedTransfer \\ V = watervolume \\ A = alloweddischarge \\ f_{AT} = Return\_AllowedTransfer\_V1 \\ f_T = VolTransferRules \\ f_{s1} = smooth\_logistic1 \\ V_{n} = MinVol \\ V_{x} = MaxVol \\ S_V = VolSmoothPar \\ S_Q = QSmoothPar\end{split}\]

Examples:

We prepare exch_water_transfer_io for a single day and define a fallback rule returning 0.5 m³/s per million m³ of stored water:

>>> from hydpy import pub, round_
>>> pub.timegrids = "2000-01-01", "2000-01-02", "1d"
>>> from hydpy.models.exch import *
>>> parameterstep()
>>> voltransferrules(PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]))
>>> minvol(1.0)
>>> maxvol(3.0)
>>> voltol(0.0)
>>> qtol(0.0)
>>> derived.toy.update()
>>> derived.volsmoothpar.update()
>>> derived.qsmoothpar.update()
>>> model.idx_sim = 0

The following test function prints the effective transfer for some water volumes (assuming the main model’s allowed discharge is unrestricted):

>>> def test():
...     for watervolume in (0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0):
...         model.determine_transfer_v1(watervolume, inf)
...         print(watervolume, end=": ")
...         round_(aides.effectivetransfer.value)

Without an external transfer request (nan or inf values), Determine_Transfer_V1 applies the fallback rule and does not consider the thresholds MinVol and MaxVol:

>>> inputs.requestedtransfer = nan
>>> test()
0.0: 0.0
0.5: 0.25
1.0: 0.5
1.5: 0.75
2.0: 1.0
2.5: 1.25
3.0: 1.5
3.5: 1.75
4.0: 2.0

Otherwise, without smoothing, requested withdrawals (positive values) drop to zero below MinVol and are halved exactly at MinVol:

>>> inputs.requestedtransfer = 2.0
>>> test()
0.0: 0.0
0.5: 0.0
1.0: 1.0
1.5: 2.0
2.0: 2.0
2.5: 2.0
3.0: 2.0
3.5: 2.0
4.0: 2.0

Likewise, Determine_Transfer_V1 reduces supplies (negative values) when the water volume approaches MaxVol:

>>> inputs.requestedtransfer = -2.0
>>> test()
0.0: -2.0
0.5: -2.0
1.0: -2.0
1.5: -2.0
2.0: -2.0
2.5: -2.0
3.0: -1.0
3.5: 0.0
4.0: 0.0

Positive VolTol values smooth the transition: the reduction factor is 0.5 at the threshold and 0.99 and 0.01 at a distance of VolTol on the permitted and the forbidden side, respectively:

>>> voltol(0.5)
>>> derived.volsmoothpar.update()
>>> test()
0.0: -2.0
0.5: -2.0
1.0: -2.0
1.5: -1.999998
2.0: -1.999796
2.5: -1.98
3.0: -1.0
3.5: -0.02
4.0: -0.000204
>>> inputs.requestedtransfer = 2.0
>>> test()
0.0: 0.000204
0.5: 0.02
1.0: 1.0
1.5: 1.98
2.0: 1.999796
2.5: 1.999998
3.0: 2.0
3.5: 2.0
4.0: 2.0

Finally, Determine_Transfer_V1 restricts all withdrawals (requested or rule-based) to the main model’s allowed discharge (for example, the discharge that complies with the allowed water level drop of dam_llake), whereby it never turns withdrawals into supplies (see method Return_AllowedTransfer_V1 for more information). QTol controls the smoothness of this restriction:

>>> voltol(0.0)
>>> derived.volsmoothpar.update()
>>> qtol(0.5)
>>> derived.qsmoothpar.update()
>>> def test(requestedtransfer):
...     inputs.requestedtransfer = requestedtransfer
...     for alloweddischarge in (-1.0, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, inf):
...         model.determine_transfer_v1(2.0, alloweddischarge)
...         print(alloweddischarge, end=": ")
...         round_(aides.effectivetransfer.value)
>>> test(2.0)
-1.0: 0.0
0.0: 0.0
0.5: 0.495101
1.0: 0.994812
1.5: 1.488475
2.0: 1.877957
2.5: 1.99
inf: 2.0
>>> test(nan)
-1.0: 0.0
0.0: 0.0
0.5: 0.488475
1.0: 0.877957
1.5: 0.99
2.0: 0.9994
2.5: 0.999965
inf: 1.0
>>> test(-2.0)
-1.0: -2.0
0.0: -2.0
0.5: -2.0
1.0: -2.0
1.5: -2.0
2.0: -2.0
2.5: -2.0
inf: -2.0
class hydpy.models.exch.exch_model.Get_Transfer_V1[source]

Bases: Method

Interface method for querying the effective water transfer in m³/s.

Used by the application model:

exch_water_transfer_io

Requires the aide sequence:

EffectiveTransfer

Example:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> aides.effectivetransfer = 2.0
>>> from hydpy import round_
>>> round_(model.get_transfer_v1())
2.0
class hydpy.models.exch.exch_model.Set_Transfer_V1[source]

Bases: Method

Interface method to receive the final effective water transfer and pass the actual transfer to the outlet node.

Used by the application model:

exch_water_transfer_io

Requires the control parameter:

KeepWaterBalance

Requires the input sequence:

RequestedTransfer

Calculates the outlet sequence:

ActualTransfer

Basic equation:
\[\begin{split}A = \begin{cases} T &|\ R \in \{nan, \, -\infty, \, \infty\} \ \lor \ K \\ R &|\ R \notin \{nan, \, -\infty, \, \infty\} \ \land \ \overline{K} \end{cases} \\ \\ A = ActualTransfer \\ T = transfer \\ R = RequestedTransfer \\ K = KeepWaterBalance\end{split}\]

Examples:

The main model must pass the effective transfer it calculated for the whole simulation step:

>>> from hydpy.models.exch import *
>>> parameterstep()
>>> def test(transfer):
...     model.set_transfer_v1(transfer)
...     print(outlets.actualtransfer)

Without an external request (that is, for transfers calculated by the fallback rule VolTransferRules), the actual transfer always equals the effective transfer, regardless of KeepWaterBalance:

>>> keepwaterbalance(False)
>>> inputs.requestedtransfer = nan
>>> test(1.0)
actualtransfer(1.0)

With an external request, the actual transfer equals the effective transfer if KeepWaterBalance is True and the requested one otherwise:

>>> inputs.requestedtransfer = 2.0
>>> keepwaterbalance(True)
>>> test(1.0)
actualtransfer(1.0)
>>> keepwaterbalance(False)
>>> test(1.0)
actualtransfer(2.0)

Main models like dam_llake pass zero effective transfers before their commission date. If KeepWaterBalance is False, Set_Transfer_V1 nevertheless passes externally requested transfers to the outlet node during this period:

>>> test(0.0)
actualtransfer(2.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

Used by the application model:

exch_interp

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(xs=[0.0, 1.0], ys=[2.0, 4.0]))
>>> factors.x = 0.5
>>> model.calc_y_v1()
>>> factors.y
y(3.0)
class hydpy.models.exch.exch_model.Pass_ActualTransfer_StreamOutflow_V1[source]

Bases: Method

Calculate the actual water transfer and remaining stream outflow based on external transfer requests (if available) or based on internal transfer calculations (as a fallback).

Used by the application model:

exch_branch_io

Requires the control parameters:

MinStream MaxStream KeepWaterBalance FlowTransferRules

Requires the derived parameters:

TOY StreamIndex

Requires the input sequence:

RequestedTransfer

Requires the flux sequence:

Inflow

Calculates the outlet sequences:

ActualTransfer StreamOutflow

Basic equations:
\[ActualTransfer = RequestedTransfer \ StreamOutflow = Inflow - ActualTransfer\]

Examples:

We prepare a 15-day simulation period and set up a UnitTest instance to automatically use method Pass_ActualTransfer_StreamOutflow_V1 with the corresponding input values (each example refers to the next day, starting with January 1):

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2000-01-16", "1d"
>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> derived.toy.update()
>>> from hydpy import UnitTest
>>> test = UnitTest(
...     model,
...     model.pass_actualtransfer_streamoutflow_v1,
...     last_example=14,
...     parseqs=(
...         fluxes.inflow,
...         inputs.requestedtransfer,
...         outlets.actualtransfer,
...         outlets.streamoutflow,
...     ),
...     first_idx_sim=0,
... )

In all of the following examples, the inflow increases linearly from -4 to 9 m³/s:

>>> test.nexts.inflow = range(-4, 10)

For the first example, we set all requested transfer values to nan or inf (the latter, positive and negative):

>>> test.nexts.requestedtransfer = 12 * [nan] + [inf, -inf]

All of the given values have similar meaning. They either indicate that information about the requested transfer is missing (typical meaning nan) or that it is intentionally not passed (we use this interpretation for inf here). The choice between them might matter in applications, for example when loading affected time series with the checkseries option enabled. However, Pass_ActualTransfer_StreamOutflow_V1 reacts the same way by falling back to its internal transfer calculations.

We now configure these calculations by defining the target nodes and their season-dependent interpolation rules, which determine which target node gets which proportion of the available inflow (see the documentation on the parameters Targets and FlowTransferRules for more explanations and configuration options):

>>> targets(stream="river", transfer="diversion")
>>> flowtransferrules(
...     toy_01_01_12=PPoly(xs=[-1.0, 0.0, 1.0], ys=[0.0, 0.0, 0.5]),
...     toy_01_04_12=PPoly(xs=[-1.0, 0.0, 1.0], ys=[0.0, 0.0, 0.5]),
...     toy_01_14_12=PPoly(xs=[0.0], ys=[0.0]),
... )
>>> derived.streamindex.update()

Note that the first interpolation rule, which solely applies for the first four days (due to its double definition) lets “negative inflow” (reverse flow) pass unhindered through the main stream and transfers half of the “positive inflow” (normal flow). Between the fourth and fourteenth day, the second rule, which does not order any water transfer, becomes gradually more important. Because of the “normal” way to configure FlowTransferRules via PPoly instances instead of PPolys instances, the water balance (\(Inflow = ActualTransfer + StreamOutflow\)) is automatically kept:

>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |               nan |            0.0 |          -4.0 |
|   2 |   -3.0 |               nan |            0.0 |          -3.0 |
|   3 |   -2.0 |               nan |            0.0 |          -2.0 |
|   4 |   -1.0 |               nan |            0.0 |          -1.0 |
|   5 |    0.0 |               nan |            0.0 |           0.0 |
|   6 |    1.0 |               nan |            0.4 |           0.6 |
|   7 |    2.0 |               nan |            0.7 |           1.3 |
|   8 |    3.0 |               nan |            0.9 |           2.1 |
|   9 |    4.0 |               nan |            1.0 |           3.0 |
|  10 |    5.0 |               nan |            1.0 |           4.0 |
|  11 |    6.0 |               nan |            0.9 |           5.1 |
|  12 |    7.0 |               nan |            0.7 |           6.3 |
|  13 |    8.0 |               inf |            0.4 |           7.6 |
|  14 |    9.0 |              -inf |            0.0 |           9.0 |

As soon as we provide external transfer requests, parameter FlowTransferRules becomes obsolete (positive transfers correspond to withdrawals from the stream and negative transfers correspond to supplies to the stream):

>>> test.nexts.requestedtransfer = 7 * [4.0, -4.0]

Instead, parameters MinStream and MaxStream come into play, restricting withdrawals and supplies, respectively (note that they do not affect the fallback calculations based on FlowTransferRules). We first set them to minus infinity and infinity, so the transfer is completely unrestricted:

>>> minstream(-numpy.inf)
>>> maxstream(numpy.inf)

Without restrictions, the basic equation applies without modification:

>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |               4.0 |            4.0 |          -8.0 |
|   2 |   -3.0 |              -4.0 |           -4.0 |           1.0 |
|   3 |   -2.0 |               4.0 |            4.0 |          -6.0 |
|   4 |   -1.0 |              -4.0 |           -4.0 |           3.0 |
|   5 |    0.0 |               4.0 |            4.0 |          -4.0 |
|   6 |    1.0 |              -4.0 |           -4.0 |           5.0 |
|   7 |    2.0 |               4.0 |            4.0 |          -2.0 |
|   8 |    3.0 |              -4.0 |           -4.0 |           7.0 |
|   9 |    4.0 |               4.0 |            4.0 |           0.0 |
|  10 |    5.0 |              -4.0 |           -4.0 |           9.0 |
|  11 |    6.0 |               4.0 |            4.0 |           2.0 |
|  12 |    7.0 |              -4.0 |           -4.0 |          11.0 |
|  13 |    8.0 |               4.0 |            4.0 |           4.0 |
|  14 |    9.0 |              -4.0 |           -4.0 |          13.0 |

For the remaining examples, we want the water transfer not to cause stream outflow values below 3 and above 6 m³/s:

>>> minstream(3.0)
>>> maxstream(6.0)

First, we focus on positive transfers (withdrawals), so that only parameter MinStream is used:

>>> test.nexts.requestedtransfer = 14 * [2.0]

The exact behaviour of preventing excessive withdrawals depends on parameter KeepWaterBalance. If it is True, the actual transfer is limited to the inflow exceeding MinStream. However, inflow values already below MinStream are not automatically increased by supplies, meaning ActualTransfer is at most decreased to zero and not to negative values:

>>> keepwaterbalance(True)
>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |               2.0 |            0.0 |          -4.0 |
|   2 |   -3.0 |               2.0 |            0.0 |          -3.0 |
|   3 |   -2.0 |               2.0 |            0.0 |          -2.0 |
|   4 |   -1.0 |               2.0 |            0.0 |          -1.0 |
|   5 |    0.0 |               2.0 |            0.0 |           0.0 |
|   6 |    1.0 |               2.0 |            0.0 |           1.0 |
|   7 |    2.0 |               2.0 |            0.0 |           2.0 |
|   8 |    3.0 |               2.0 |            0.0 |           3.0 |
|   9 |    4.0 |               2.0 |            1.0 |           3.0 |
|  10 |    5.0 |               2.0 |            2.0 |           3.0 |
|  11 |    6.0 |               2.0 |            2.0 |           4.0 |
|  12 |    7.0 |               2.0 |            2.0 |           5.0 |
|  13 |    8.0 |               2.0 |            2.0 |           6.0 |
|  14 |    9.0 |               2.0 |            2.0 |           7.0 |

If KeepWaterBalance is False, StreamOutflow is reduced when necessary, but ActualTransfer is always identical to RequestedTransfer (see the explanation in the documentation of parameter KeepWaterBalance):

>>> keepwaterbalance(False)
>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |               2.0 |            2.0 |          -4.0 |
|   2 |   -3.0 |               2.0 |            2.0 |          -3.0 |
|   3 |   -2.0 |               2.0 |            2.0 |          -2.0 |
|   4 |   -1.0 |               2.0 |            2.0 |          -1.0 |
|   5 |    0.0 |               2.0 |            2.0 |           0.0 |
|   6 |    1.0 |               2.0 |            2.0 |           1.0 |
|   7 |    2.0 |               2.0 |            2.0 |           2.0 |
|   8 |    3.0 |               2.0 |            2.0 |           3.0 |
|   9 |    4.0 |               2.0 |            2.0 |           3.0 |
|  10 |    5.0 |               2.0 |            2.0 |           3.0 |
|  11 |    6.0 |               2.0 |            2.0 |           4.0 |
|  12 |    7.0 |               2.0 |            2.0 |           5.0 |
|  13 |    8.0 |               2.0 |            2.0 |           6.0 |
|  14 |    9.0 |               2.0 |            2.0 |           7.0 |

The restriction of StreamOutflow to MaxStream for negative transfer requests (supplies) is exactly the opposite:

>>> test.nexts.requestedtransfer = 14 * [-2.0]
>>> keepwaterbalance(True)
>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |              -2.0 |           -2.0 |          -2.0 |
|   2 |   -3.0 |              -2.0 |           -2.0 |          -1.0 |
|   3 |   -2.0 |              -2.0 |           -2.0 |           0.0 |
|   4 |   -1.0 |              -2.0 |           -2.0 |           1.0 |
|   5 |    0.0 |              -2.0 |           -2.0 |           2.0 |
|   6 |    1.0 |              -2.0 |           -2.0 |           3.0 |
|   7 |    2.0 |              -2.0 |           -2.0 |           4.0 |
|   8 |    3.0 |              -2.0 |           -2.0 |           5.0 |
|   9 |    4.0 |              -2.0 |           -2.0 |           6.0 |
|  10 |    5.0 |              -2.0 |           -1.0 |           6.0 |
|  11 |    6.0 |              -2.0 |            0.0 |           6.0 |
|  12 |    7.0 |              -2.0 |            0.0 |           7.0 |
|  13 |    8.0 |              -2.0 |            0.0 |           8.0 |
|  14 |    9.0 |              -2.0 |            0.0 |           9.0 |
>>> keepwaterbalance(False)
>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |              -2.0 |           -2.0 |          -2.0 |
|   2 |   -3.0 |              -2.0 |           -2.0 |          -1.0 |
|   3 |   -2.0 |              -2.0 |           -2.0 |           0.0 |
|   4 |   -1.0 |              -2.0 |           -2.0 |           1.0 |
|   5 |    0.0 |              -2.0 |           -2.0 |           2.0 |
|   6 |    1.0 |              -2.0 |           -2.0 |           3.0 |
|   7 |    2.0 |              -2.0 |           -2.0 |           4.0 |
|   8 |    3.0 |              -2.0 |           -2.0 |           5.0 |
|   9 |    4.0 |              -2.0 |           -2.0 |           6.0 |
|  10 |    5.0 |              -2.0 |           -2.0 |           6.0 |
|  11 |    6.0 |              -2.0 |           -2.0 |           6.0 |
|  12 |    7.0 |              -2.0 |           -2.0 |           7.0 |
|  13 |    8.0 |              -2.0 |           -2.0 |           8.0 |
|  14 |    9.0 |              -2.0 |           -2.0 |           9.0 |

MinStream and MaxStream can be identical:

>>> minstream(4.0)
>>> maxstream(4.0)
>>> keepwaterbalance(True)
>>> test.nexts.requestedtransfer = 7 * [2.0, -2.0]
>>> test()
| ex. | inflow | requestedtransfer | actualtransfer | streamoutflow |
---------------------------------------------------------------------
|   1 |   -4.0 |               2.0 |            0.0 |          -4.0 |
|   2 |   -3.0 |              -2.0 |           -2.0 |          -1.0 |
|   3 |   -2.0 |               2.0 |            0.0 |          -2.0 |
|   4 |   -1.0 |              -2.0 |           -2.0 |           1.0 |
|   5 |    0.0 |               2.0 |            0.0 |           0.0 |
|   6 |    1.0 |              -2.0 |           -2.0 |           3.0 |
|   7 |    2.0 |               2.0 |            0.0 |           2.0 |
|   8 |    3.0 |              -2.0 |           -1.0 |           4.0 |
|   9 |    4.0 |               2.0 |            0.0 |           4.0 |
|  10 |    5.0 |              -2.0 |            0.0 |           5.0 |
|  11 |    6.0 |               2.0 |            2.0 |           4.0 |
|  12 |    7.0 |              -2.0 |            0.0 |           7.0 |
|  13 |    8.0 |               2.0 |            2.0 |           6.0 |
|  14 |    9.0 |              -2.0 |            0.0 |           9.0 |
class hydpy.models.exch.exch_model.Pass_Outputs_V1[source]

Bases: Method

Update Branched based on Outputs.

Used by the application model:

exch_branch_hbv96

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_Branched_V1[source]

Bases: Method

Branch the current input by applying the (seasonally varying) interpolation rules.

Used by the application model:

exch_branch_rules

Requires the control parameter:

Rules

Requires the derived parameter:

TOY

Requires the flux sequence:

Input_

Calculates the outlet sequence:

Branched

Basic equation:

\(Branched_i = Rules_i(Input)\)

Example:

We define two different branching rules for January 1 and 2 (see the documentation on parameter Rules for more information):

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2000-01-03", "1d"
>>> from hydpy.models.exch_branch_rules import *
>>> parameterstep()
>>> rules(
...     toy_01_01_12=PPolys(
...         a=PPoly(xs=[0.0, 1.0], ys=[0.0, 1.0]),
...         b=PPolys.REST,
...     ),
...     toy_01_02_12=PPolys(
...         a=PPolys.REST,
...         b=PPoly(xs=[0.0], ys=[1.0]),
...     ),
... )
>>> derived.toy.update()
>>> outlets.branched.shape = 2
>>> fluxes.input_ = 3.0
>>> model.idx_sim = pub.timegrids.init["2000-01-01"]
>>> model.pass_branched_v1()
>>> outlets.branched
branched(3.0, 0.0)
>>> model.idx_sim = pub.timegrids.init["2000-01-02"]
>>> model.pass_branched_v1()
>>> outlets.branched
branched(2.0, 1.0)
class hydpy.models.exch.exch_model.Pass_Y_V1[source]

Bases: Method

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

Used by the application model:

exch_interp

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.

Used by the application model:

exch_waterlevel

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.

Used by the application model:

exch_interp

Required submethods:

Pick_X_V1 Calc_Y_V1

Requires the control parameter:

X2Y

Requires the derived parameter:

NmbObserverNodes

Calculates the factor sequences:

X Y

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

Bases: Method

Return the result.

Used by the application model:

exch_interp

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[TM_co], cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: ControlParameters

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].

  • Targets() Target nodes.

  • MinStream() Minimum stream outflow that externally requested withdrawals must not undercut [m³/s].

  • MaxStream() Maximum stream outflow that externally requested supplies must not exceed [m³/s].

  • KeepWaterBalance() Flag to indicate if too-high requested transfers should be reduced [-].

  • FlowTransferRules() Seasonally varying interpolation rules for branching the (adjusted) inflow [-].

  • Rules() Seasonally varying interpolation rules for branching the input [-].

  • MinVol() Minimum water volume that externally requested withdrawals should not undercut [million m³].

  • MaxVol() Maximum water volume that externally requested supplies should not exceed [million m³].

  • VolTol() Tolerance for smoothing the reduction of externally requested transfers at the water volume thresholds MinVol and MaxVol [million m³].

  • QTol() Tolerance for smoothing the reduction of withdrawals to the main model’s allowed discharge [m³/s].

  • VolTransferRules() Seasonally varying interpolation rules for calculating the water transfer based on the current water volume [m³/s].

  • ObserverNodes() The names of the considered observer nodes.

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

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

Bases: Parameter

Crest height [m].

Required by the method:

Calc_DeltaWaterLevel_V1

Used by the application model:

exch_weir_hbv96

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

alias of float

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

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

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

Bases: Parameter

Crest width [m].

Required by the method:

Calc_PotentialExchange_V1

Used by the application model:

exch_weir_hbv96

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

alias of float

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

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

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

Bases: Parameter

Flow coefficient [-].

Required by the method:

Calc_PotentialExchange_V1

Used by the application model:

exch_weir_hbv96

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

alias of float

SPAN = (0.0, None)
INIT = 0.62
name = 'flowcoefficient'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: Parameter

Flow exponent [-].

Required by the method:

Calc_PotentialExchange_V1

Used by the application model:

exch_weir_hbv96

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

alias of float

SPAN = (0.0, None)
INIT = 1.5
name = 'flowexponent'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: Parameter

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

Required by the method:

Calc_ActualExchange_V1

Used by the application model:

exch_weir_hbv96

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

alias of float

SPAN = (0.0, None)
INIT = 1.5
name = 'allowedexchange'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

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

Bases: MonthParameter

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

Required by the method:

Calc_AdjustedInput_V1

Used by the application model:

exch_branch_hbv96

TYPE

alias of float

INIT = 0.0
name = 'delta'

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: Parameter

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

Required by the method:

Calc_AdjustedInput_V1

Used by the application model:

exch_branch_hbv96

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

alias of float

INIT = 0.0
name = 'minimum'

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: Parameter

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

Required by the method:

Calc_Outputs_V1

Used by the application model:

exch_branch_hbv96

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

>>> from hydpy.core.exceptiontools import ignore_deprecations
>>> from hydpy.models.exch_branch_hbv96 import *
>>> with ignore_deprecations():
...     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: Final[Literal[1]] = 1
TYPE

alias of float

name = 'xpoints'

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: Parameter

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

Required by the method:

Calc_Outputs_V1

Used by the application model:

exch_branch_hbv96

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

>>> from hydpy.core.exceptiontools import ignore_deprecations
>>> from hydpy.models.exch_branch_hbv96 import *
>>> with ignore_deprecations():
...     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])

Redefining the supporting points without changing the number of branches does not affect existing values:

>>> fluxes.outputs = 1.0, 2.0
>>> ypoints(branch1=[1.0, 3.0],
...         branch2=[2.0, 5.0])
>>> fluxes.outputs
outputs(branch1=1.0,
        branch2=2.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: Final[Literal[2]] = 2
TYPE

alias of float

name = 'ypoints'

Name of the variable in lowercase letters.

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

Unit of the variable.

class hydpy.models.exch.exch_control.Targets(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: SpecialParameter

Target nodes.

Used by the application model:

exch_branch_io

Targets is a special parameter (see SpecialParameter) that serves to define the names of both target nodes, which is necessary for creating the required connections. “stream” refers to the node reflecting the main riverbed; “transfer” refers to the node to which some of the water is branched (or supplied from):

>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> targets
targets(?)
>>> targets.verify()
Traceback (most recent call last):
...
RuntimeError: For parameter `targets` of element `?`, the names of the target nodes are still unknown.
>>> targets(stream="river", transfer="diversion")
>>> targets
targets(stream="river", transfer="diversion")
>>> targets.verify()

Both target nodes must have different names:

>>> targets(stream="river", transfer="river")
Traceback (most recent call last):
...
ValueError: You must not assign the same target node name (`river`) to both the keyword arguments `stream` and `transfer` of parameter `targets` of element `?` (remember that node names serve as unique identifiers).
>>> targets
targets(stream="river", transfer="diversion")
verify() → None[source]

Raise a RuntimeError if the names of the target nodes are unknown.

name: str = 'targets'

Name of the variable in lowercase letters.

class hydpy.models.exch.exch_control.MinStream(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Minimum stream outflow that externally requested withdrawals must not undercut [m³/s].

Required by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

MinStream only restricts positive values of RequestedTransfer (withdrawals). It neither affects the transfers calculated by the fallback parameter FlowTransferRules nor triggers supplies when the inflow is already below MinStream. Set it to minus inf to allow arbitrary withdrawals. See the documentation on method Pass_ActualTransfer_StreamOutflow_V1 and parameter KeepWaterBalance for further information.

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

alias of float

SPAN = (-inf, inf)
INIT = 0.0
trim(lower: float | Sequence[float] | ndarray[tuple[int], dtype[float64]] | Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]] | Sequence[Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]]] | ndarray[tuple[int, int, int], dtype[float64]] | None = None, upper: float | Sequence[float] | ndarray[tuple[int], dtype[float64]] | Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]] | Sequence[Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]]] | ndarray[tuple[int, int, int], dtype[float64]] | None = None) → bool[source]

Trim upper values in accordance with \(MinStream \leq MaxStream\).

>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> maxstream.value = 2.0
>>> minstream(1.0)
>>> minstream
minstream(1.0)
>>> minstream(2.0)
>>> minstream
minstream(2.0)
>>> minstream(3.0)
>>> minstream
minstream(2.0)
name = 'minstream'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.MaxStream(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Maximum stream outflow that externally requested supplies must not exceed [m³/s].

Required by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

MaxStream only restricts negative values of RequestedTransfer (supplies). It neither affects the transfers calculated by the fallback parameter FlowTransferRules nor triggers withdrawals when the inflow is already above MaxStream. Set it to inf to allow arbitrary supplies. See the documentation on method Pass_ActualTransfer_StreamOutflow_V1 and parameter KeepWaterBalance for further information.

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

alias of float

SPAN = (-inf, inf)
INIT = inf
trim(lower: float | Sequence[float] | ndarray[tuple[int], dtype[float64]] | Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]] | Sequence[Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]]] | ndarray[tuple[int, int, int], dtype[float64]] | None = None, upper: float | Sequence[float] | ndarray[tuple[int], dtype[float64]] | Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]] | Sequence[Sequence[Sequence[float] | ndarray[tuple[int], dtype[float64]]] | ndarray[tuple[int, int], dtype[float64]]] | ndarray[tuple[int, int, int], dtype[float64]] | None = None) → bool[source]

Trim lower values in accordance with \(MinStream \leq MaxStream\).

>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> minstream.value = 2.0
>>> maxstream(3.0)
>>> maxstream
maxstream(3.0)
>>> maxstream(2.0)
>>> maxstream
maxstream(2.0)
>>> maxstream(1.0)
>>> maxstream
maxstream(2.0)
name = 'maxstream'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_control.KeepWaterBalance(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Flag to indicate if too-high requested transfers should be reduced [-].

Required by the methods:

Pass_ActualTransfer_StreamOutflow_V1 Set_Transfer_V1

Used by the application models:

exch_branch_io exch_water_transfer_io

There are two lines of reasoning:

  • If the requested water transfer is 2 m³/s (withdrawal) but only 1 m³/s is available, one must reduce the transfer to 1 m³/s: set KeepWaterBalance to True.

  • The requested water transfer is measured and thus very certain and should always be maintained: set KeepWaterBalance to False (at the cost of violating the water balance).

The same thoughts apply to negative water transfers (supplies) that exceed a given threshold.

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

alias of bool

SPAN = (False, True)
INIT = True
name = 'keepwaterbalance'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: SeasonalInterpolator

Seasonally varying interpolation rules for branching the (adjusted) inflow [-].

Required by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

FlowTransferRules is a fallback parameter that is only relevant for periods without available RequestedTransfer time series data.

Please prepare parameter Targets before configuring parameter FlowTransferRules:

>>> from hydpy import ANN, PPoly, PPolys, pub
>>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"
>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> flowtransferrules
flowtransferrules(?)
>>> flowtransferrules(PPoly(xs=[0.0, 1.0], ys=[0.0, 2.0]))
Traceback (most recent call last):
...
RuntimeError: While trying to set the interpolation rules of parameter `flowtransferrules` of element `?`, the following error occurred: The names of the target nodes are still unknown.  Please define them via parameter `targets` first.

If there is no seasonality, assign a single PPoly instance that interpolates water transfer based on the (adjusted) inflow:

>>> targets(stream="river", transfer="diversion")
>>> flowtransferrules(PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]))
>>> flowtransferrules
flowtransferrules(
    PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    )
)

Behind the scenes, parameter FlowTransferRules converts this PPoly instance to a PPolys instance that applies the given interpolation rule to calculate the water transfer and leaves the rest for the main stream (note that PPolys sorts the target nodes alphabetically, which is why derived parameter StreamIndex is required to identify the main stream’s outflow):

>>> flowtransferrules.toy_01_01_00_00
PPolys(
    diversion=PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    ),
    river=PPolys.REST,
)

The same mechanism applies when passing multiple PPoly instances to introduce seasonal patterns:

>>> flowtransferrules(
...     toy_01_01_12=PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]),
...     toy_01_03_12=PPoly(xs=[0.0], ys=[0.0]),
... )
>>> flowtransferrules
flowtransferrules(
    toy_1_1_12_0_0=PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    ),
    toy_1_3_12_0_0=PPoly(
        xs=[0.0],
        ys=[0.0],
    ),
)
>>> flowtransferrules.toy_01_01_12_00
PPolys(
    diversion=PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    ),
    river=PPolys.REST,
)

You are allowed to interpolate the water transfer and rest flow independently by directly assigning one or multiple PPolys instances, which requires explicit mentioning of the respective target nodes’ names (note that this changes the water balance, and so is only useful if you are aware of certain water losses or gains bound to specific flow regimes):

>>> flowtransferrules(
...     PPolys(
...         river=PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]),
...         diversion=PPoly(xs=[0.0, 2.0], ys=[0.0, 2.0]),
...     )
... )
>>> flowtransferrules
flowtransferrules(
    PPolys(
        diversion=PPoly(
            xs=[0.0, 2.0],
            ys=[0.0, 2.0],
        ),
        river=PPoly(
            xs=[0.0, 2.0],
            ys=[0.0, 1.0],
        ),
    )
)

Using wrong target names results in the following error:

>>> flowtransferrules(
...     PPolys(
...         stream=PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]),
...         diversion=PPoly(xs=[0.0, 2.0], ys=[0.0, 2.0]),
...     )
... )
Traceback (most recent call last):
...
ValueError: While trying to set the interpolation rules of parameter `flowtransferrules` of element `?`, the following error occurred: When defining the node-specific interpolation rules of parameter `PPolys` manually, you must use the target nodes' names defined by parameter `Targets`, which are `river and diversion` instead of `diversion and stream`.

Configuring parameter FlowTransferRules based on other interpolation methods is currently not supported:

>>> flowtransferrules(ANN(nmb_inputs=1, nmb_outputs=2, nmb_neurons=(10,)))
Traceback (most recent call last):
...
TypeError: While trying to set the interpolation rules of parameter `flowtransferrules` of element `?`, the following error occurred: Parameter `flowtransferrules` currently only supports interpolation via `PPolys` instances.  Best practice is to configure them indirectly via `PPoly` instances (see the documentation).
XLABEL = 'inflow [m³/s]'
YLABEL = 'outflow [m³/s]'
name: str = 'flowtransferrules'

Name of the variable in lowercase letters.

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

Bases: SeasonalInterpolator

Seasonally varying interpolation rules for branching the input [-].

Required by the method:

Pass_Branched_V1

Used by the application model:

exch_branch_rules

Rules accepts one or multiple PPolys instances, which must all address the same target nodes:

>>> from hydpy import ANN, PPoly, PPolys, pub
>>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"
>>> from hydpy.models.exch_branch_rules import *
>>> parameterstep()
>>> rules(
...     toy_01_01_12=PPolys(
...         river=PPolys.REST,
...         diversion=PPoly(xs=[0.0], ys=[1.0]),
...     ),
...     toy_01_03_12=PPolys(
...         diversion=PPoly(xs=[0.0], ys=[2.0]),
...         river=PPolys.REST,
...     ),
... )

PPolys sorts its interpolation functions by the target nodes’ names, so each output always belongs to the same target node, regardless of the order of the keyword arguments:

>>> model.targetnames
('diversion', 'river')
>>> rules
rules(
    toy_1_1_12_0_0=PPolys(
        diversion=PPoly(
            xs=[0.0],
            ys=[1.0],
        ),
        river=PPolys.REST,
    ),
    toy_1_3_12_0_0=PPolys(
        diversion=PPoly(
            xs=[0.0],
            ys=[2.0],
        ),
        river=PPolys.REST,
    ),
)

Using different target names for different seasons results in the following error:

>>> rules(
...     toy_01_01_12=PPolys(river=PPolys.REST, diversion=PPoly(xs=[0.0], ys=[1.0])),
...     toy_01_03_12=PPolys(river=PPolys.REST, channel=PPoly(xs=[0.0], ys=[2.0])),
... )
Traceback (most recent call last):
...
ValueError: While trying to set the interpolation rules of parameter `rules` of element `?`, the following error occurred: All `PPolys` instances must address the same target nodes, but `channel and river` differs from `diversion and river`.

Configuring parameter Rules based on other interpolation methods is currently not supported:

>>> rules(ANN(nmb_inputs=1, nmb_outputs=2, nmb_neurons=(10,)))
Traceback (most recent call last):
...
TypeError: While trying to set the interpolation rules of parameter `rules` of element `?`, the following error occurred: Parameter `rules` currently only supports interpolation via `PPolys` instances.
XLABEL = 'input [e.g. m³/s]'
YLABEL = 'outputs [e.g. m³/s]'
name: str = 'rules'

Name of the variable in lowercase letters.

class hydpy.models.exch.exch_control.MinVol(subvars)[source]

Bases: SeasonalParameter

Minimum water volume that externally requested withdrawals should not undercut [million m³].

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

MinVol only affects positive RequestedTransfer values (withdrawals), not the VolTransferRules fallback. Set it to -inf to disable it (see Determine_Transfer_V1).

NDIM: Final[Literal[1]] = 1
INIT = 0.0
name = 'minvol'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.exch.exch_control.MaxVol(subvars)[source]

Bases: SeasonalParameter

Maximum water volume that externally requested supplies should not exceed [million m³].

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

MaxVol only affects negative RequestedTransfer values (supplies), not the VolTransferRules fallback. Set it to inf to disable it (see Determine_Transfer_V1).

NDIM: Final[Literal[1]] = 1
INIT = inf
name = 'maxvol'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.exch.exch_control.VolTol(subvars)[source]

Bases: SeasonalParameter

Tolerance for smoothing the reduction of externally requested transfers at the water volume thresholds MinVol and MaxVol [million m³].

Used by the application model:

exch_water_transfer_io

Zero values cause discontinuities that might hamper the main model’s numerical integration (see Determine_Transfer_V1).

NDIM: Final[Literal[1]] = 1
SPAN = (0.0, None)
INIT = 0.0
name = 'voltol'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.exch.exch_control.QTol(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Tolerance for smoothing the reduction of withdrawals to the main model’s allowed discharge [m³/s].

Used by the application model:

exch_water_transfer_io

Zero values cause discontinuities that might hamper the main model’s numerical integration (see Determine_Transfer_V1).

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

alias of float

SPAN = (0.0, None)
INIT = 0.0
name = 'qtol'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

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

Bases: SeasonalInterpolator

Seasonally varying interpolation rules for calculating the water transfer based on the current water volume [m³/s].

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

VolTransferRules is a fallback parameter that is only relevant for periods without available RequestedTransfer time series data.

You can define a single interpolation rule:

>>> from hydpy import ANN, PPoly, pub
>>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"
>>> from hydpy.models.exch_water_transfer_io import *
>>> parameterstep()
>>> voltransferrules(PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]))
>>> voltransferrules
voltransferrules(
    PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    )
)

Or multiple interpolation rules for different times of the year:

>>> voltransferrules(
...     toy_01_01_12=PPoly(xs=[0.0, 2.0], ys=[0.0, 1.0]),
...     toy_01_03_12=PPoly(xs=[0.0], ys=[0.0]),
... )
>>> voltransferrules
voltransferrules(
    toy_1_1_12_0_0=PPoly(
        xs=[0.0, 2.0],
        ys=[0.0, 1.0],
    ),
    toy_1_3_12_0_0=PPoly(
        xs=[0.0],
        ys=[0.0],
    ),
)

Note that each interpolator must have exactly one input (the water volume) and one output (the water transfer):

>>> voltransferrules(ANN(nmb_inputs=1, nmb_neurons=(1,), nmb_outputs=2))
Traceback (most recent call last):
...
ValueError: While trying to set the interpolation rules of parameter `voltransferrules` of element `?`, the following error occurred: Parameter `voltransferrules` requires interpolators with exactly one input and one output, but the given one has one input and two outputs.
XLABEL = 'water volume [million m³]'
YLABEL = 'transfer [m³/s]'
name: str = 'voltransferrules'

Name of the variable in lowercase letters.

class hydpy.models.exch.exch_control.ObserverNodes(subvars: SubVariables[Any, Any, Any, Any])[source]

Bases: SpecialParameter

The names of the considered observer nodes.

Used by the application model:

exch_interp

ObserverNodes is a special parameter (see SpecialParameter) that requires the names of all observer nodes that need consideration:

>>> from hydpy.models.exch_interp import *
>>> parameterstep()
>>> observernodes
observernodes(?)
>>> observernodes.verify()
Traceback (most recent call last):
...
RuntimeError: For parameter `observernodes` of element `?`, the names of the observer nodes are still unknown.
>>> 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 and the derived parameter NmbObserverNodes:

>>> observernodes("node_1", "node_2")
>>> observers.x.observernodes
('node_1', 'node_2')
>>> derived.nmbobservernodes
nmbobservernodes(2)
>>> observernodes
observernodes("node_1", "node_2")
>>> observernodes.verify()
verify() → None[source]

Raise a RuntimeError if the names of the observer nodes are unknown.

name: str = 'observernodes'

Name of the variable in lowercase letters.

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

Bases: SimpleInterpolator

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

Required by the methods:

Calc_Y_V1 Determine_Y_V1

Used by the application model:

exch_interp

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

Name of the variable in lowercase letters.

Derived parameters

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

Bases: DerivedParameters

Derived parameters of model exch.

The following classes are selected:
  • TOY() References the timeofyear index array provided by the instance of class Indexer available in module pub [-].

  • MOY() References the “global” month of the year index array [-].

  • NmbObserverNodes() The number of observer nodes [-].

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

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

  • StreamIndex() The index of the stream node’s output among the outputs of parameter FlowTransferRules [-].

  • VolSmoothPar() Smoothing parameter to be derived from VolTol for smoothing kernel smooth_logistic1() [million m³].

  • QSmoothPar() Smoothing parameter to be derived from QTol for smoothing kernels smooth_min1() and smooth_max1() [m³/s].

class hydpy.models.exch.exch_derived.TOY(subvars: SubParameters[modeltools.Model])[source]

Bases: TOYParameter

References the timeofyear index array provided by the instance of class Indexer available in module pub [-].

name = 'toy'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: MOYParameter

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

Required by the method:

Calc_AdjustedInput_V1

Used by the application model:

exch_branch_hbv96

name = 'moy'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.exch.exch_derived.NmbObserverNodes(subvars: SubParameters[modeltools.Model])[source]

Bases: NmbParameter

The number of observer nodes [-].

Required by the methods:

Determine_Y_V1 Pick_X_V1

Used by the application model:

exch_interp

Calling the control parameter ObserverNodes sets NmbObserverNodes immediately. Method update() determines the same value:

>>> from hydpy.models.exch_interp import *
>>> parameterstep()
>>> observernodes("node_1", "node_2", "node_3")
>>> derived.nmbobservernodes(1)
>>> derived.nmbobservernodes.update()
>>> derived.nmbobservernodes
nmbobservernodes(3)
SPAN = (0, None)
update() → None[source]

Determine the number of observer nodes.

name = 'nmbobservernodes'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: Parameter

The number of branches [-].

Required by the methods:

Calc_Outputs_V1 Pass_Outputs_V1

Used by the application model:

exch_branch_hbv96

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

alias of int

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

Determine the number of branches.

name = 'nmbbranches'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

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

Bases: Parameter

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

Required by the method:

Calc_Outputs_V1

Used by the application model:

exch_branch_hbv96

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

alias of int

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

Determine the number of points.

name = 'nmbpoints'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.exch.exch_derived.StreamIndex(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

The index of the stream node’s output among the outputs of parameter FlowTransferRules [-].

Required by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

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

alias of int

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

Determine the index of the stream node’s output.

PPolys sorts its outputs alphabetically by the target nodes’ names. Hence, the stream node’s output comes first if its name is “smaller” than the name of the transfer node:

>>> from hydpy.models.exch_branch_io import *
>>> parameterstep()
>>> targets(stream="channel", transfer="diversion")
>>> derived.streamindex.update()
>>> derived.streamindex
streamindex(0)

Otherwise, it comes second:

>>> targets(stream="river", transfer="diversion")
>>> derived.streamindex.update()
>>> derived.streamindex
streamindex(1)
name = 'streamindex'

Name of the variable in lowercase letters.

unit = '-'

Unit of the variable.

class hydpy.models.exch.exch_derived.VolSmoothPar(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Smoothing parameter to be derived from VolTol for smoothing kernel smooth_logistic1() [million m³].

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

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

alias of float

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

Calculate the smoothing parameter values.

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

>>> from hydpy import pub
>>> pub.timegrids = "2000-01-01", "2000-01-03", "1d"
>>> from hydpy.models.exch_water_transfer_io import *
>>> parameterstep()
>>> voltol(0.0)
>>> voltol.values[1] = 2.5
>>> derived.volsmoothpar.update()
>>> from hydpy.cythons.smoothutils import smooth_logistic1
>>> from hydpy import round_
>>> round_(smooth_logistic1(0.1, derived.volsmoothpar[0]))
1.0
>>> round_(smooth_logistic1(2.5, derived.volsmoothpar[1]))
0.99
name = 'volsmoothpar'

Name of the variable in lowercase letters.

unit = 'million m³'

Unit of the variable.

class hydpy.models.exch.exch_derived.QSmoothPar(subvars: SubParameters[modeltools.Model])[source]

Bases: Parameter

Smoothing parameter to be derived from QTol for smoothing kernels smooth_min1() and smooth_max1() [m³/s].

Required by the method:

Determine_Transfer_V1

Used by the application model:

exch_water_transfer_io

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 some detail:

>>> from hydpy.models.exch_water_transfer_io import *
>>> parameterstep()
>>> qtol(0.0)
>>> derived.qsmoothpar.update()
>>> from hydpy.cythons.smoothutils import smooth_min1
>>> from hydpy import round_
>>> round_(smooth_min1(4.0, 1.5, derived.qsmoothpar))
1.5
>>> qtol(2.5)
>>> derived.qsmoothpar.update()
>>> round_(smooth_min1(4.0, 1.5, derived.qsmoothpar))
1.49
name = 'qsmoothpar'

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Sequence Features

Input sequences

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

Bases: InputSequences

Input sequences of model exch.

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

Bases: InputSequence

Externally requested water transfer [m³/s].

Positive values are withdrawals, and negative values are supplies. nan or inf (positive or negative) means that no external request is available.

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Factor sequences

class hydpy.models.exch.FactorSequences(master: Sequences[TM_co], 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[TM_co, 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

Used by the application model:

exch_weir_hbv96

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

SHAPE = (2,)
name = 'waterlevels'

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

class hydpy.models.exch.exch_factors.DeltaWaterLevel(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_weir_hbv96

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

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

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

class hydpy.models.exch.exch_factors.X(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_interp

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

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

class hydpy.models.exch.exch_factors.Y(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_interp

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

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

Flux sequences

class hydpy.models.exch.FluxSequences(master: Sequences[TM_co], 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[TM_co, 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

Used by the application model:

exch_weir_hbv96

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.ActualExchange(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_weir_hbv96

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

class hydpy.models.exch.exch_fluxes.OriginalInput(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_branch_hbv96

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

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: FluxSequence

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

Calculated by the method:

Pick_Input_V1

Required by the method:

Pass_Branched_V1

Used by the application model:

exch_branch_rules

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

Name of the variable in lowercase letters.

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

Unit of the variable.

class hydpy.models.exch.exch_fluxes.AdjustedInput(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_branch_hbv96

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

Name of the variable in lowercase letters.

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

Unit of the variable.

class hydpy.models.exch.exch_fluxes.Outputs(subvars: ModelIOSequences[TM_co, 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

Used by the application model:

exch_branch_hbv96

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

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: FluxSequence

Inflow [m³/s].

Calculated by the method:

Pick_Inflow_V1

Required by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Log sequences

class hydpy.models.exch.LogSequences(master: Sequences[TM_co], 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[modeltools.Model, ModelSequence, variabletools.FastAccess])[source]

Bases: LogSequenceFixed

Logged water level [m].

Calculated by the method:

Pick_LoggedWaterLevel_V1

Required by the method:

Get_WaterLevel_V1

Used by the application model:

exch_waterlevel

SHAPE = 1
name = 'loggedwaterlevel'

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

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

Bases: LogSequenceFixed

Logged water levels [m].

Calculated by the method:

Pick_LoggedWaterLevels_V1

Required by the method:

Update_WaterLevels_V1

Used by the application model:

exch_weir_hbv96

SHAPE = 2
name = 'loggedwaterlevels'

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

Inlet sequences

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

Bases: InletSequences

Inlet sequences of model exch.

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

Bases: InletSequence

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

Required by the methods:

Pick_Input_V1 Pick_OriginalInput_V1

Used by the application models:

exch_branch_hbv96 exch_branch_rules

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

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: InletSequence

Inflow [m³/s].

Required by the method:

Pick_Inflow_V1

Used by the application model:

exch_branch_io

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Outlet sequences

class hydpy.models.exch.OutletSequences(master: Sequences[TM_co], 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[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: OutletSequence

Bidirectional water exchange [m³/s].

Calculated by the method:

Pass_ActualExchange_V1

Used by the application model:

exch_weir_hbv96

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

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

Bases: OutletSequence

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

Calculated by the methods:

Pass_Branched_V1 Pass_Outputs_V1

Used by the application models:

exch_branch_hbv96 exch_branch_rules

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

Name of the variable in lowercase letters.

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

Unit of the variable.

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

Bases: OutletSequence

Actual water transfer [m³/s].

Calculated by the methods:

Pass_ActualTransfer_StreamOutflow_V1 Set_Transfer_V1

Used by the application models:

exch_branch_io exch_water_transfer_io

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

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

Bases: OutletSequence

Mainstream outflow [m³/s].

Calculated by the method:

Pass_ActualTransfer_StreamOutflow_V1

Used by the application model:

exch_branch_io

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

Observer sequences

class hydpy.models.exch.ObserverSequences(master: Sequences[TM_co], 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[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: ObserverSequence

Arbitrary kind of input data [?].

Required by the methods:

Determine_Y_V1 Pick_X_V1

Used by the application model:

exch_interp

Parameter ObserverNodes determines the length of X (via the derived parameter NmbObserverNodes):

>>> from hydpy.models.exch_interp import *
>>> parameterstep()
>>> observernodes("node_1", "node_2")
>>> observers.x.shape
(2,)

To prevent losing information, ObserverNodes changes the shape of X only when necessary:

>>> observers.x = 1.0, 2.0
>>> observernodes("node_3", "node_4")
>>> observers.x
x(1.0, 2.0)
>>> observernodes("node_1")
>>> observers.x
x(nan)
NDIM: Final[Literal[1]] = 1
property observernodes: tuple[str, ...]

The relevant observer node 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 by 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(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(xs=[0.0], ys=[0.0]))
>>> with model.add_safereleasemodel("exch_interp", position=1):
...     observernodes("gauge_2", "gauge_3", "gauge_4")
...     x2y(PPoly(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 = 'x'

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

Receiver sequences

class hydpy.models.exch.ReceiverSequences(master: Sequences[TM_co], 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[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: ReceiverSequence

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

Required by the method:

Pick_LoggedWaterLevel_V1

Used by the application model:

exch_waterlevel

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

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

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

Bases: ReceiverSequence

The water level at multiple remote locations [m].

Required by the method:

Pick_LoggedWaterLevels_V1

Used by the application model:

exch_weir_hbv96

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

Name of the variable in lowercase letters.

unit = 'm'

Unit of the variable.

Sender sequences

class hydpy.models.exch.SenderSequences(master: Sequences[TM_co], 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[TM_co, ModelIOSequence, FastAccessIOSequence])[source]

Bases: SenderSequence

Arbitrary kind of result data [?].

Calculated by the method:

Pass_Y_V1

Used by the application model:

exch_interp

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

Name of the variable in lowercase letters.

unit = '?'

Unit of the variable.

Aide sequences

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

Bases: AideSequences

Aide sequences of model exch.

The following classes are selected:
class hydpy.models.exch.exch_aides.EffectiveTransfer(subvars: ModelSequences[modeltools.Model, ModelSequence, variabletools.FastAccess])[source]

Bases: AideSequence

Water transfer that affects the water balance of the main model [m³/s].

Calculated by the method:

Determine_Transfer_V1

Required by the method:

Get_Transfer_V1

Used by the application model:

exch_water_transfer_io

Positive values indicate withdrawals; negative values indicate supplies.

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

Name of the variable in lowercase letters.

unit = 'm³/s'

Unit of the variable.

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

Bases: AideSequences

Aide sequences of model exch.

The following classes are selected:
class hydpy.models.exch.ControlParameters(master: Parameters[TM_co], cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: ControlParameters

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].

  • Targets() Target nodes.

  • MinStream() Minimum stream outflow that externally requested withdrawals must not undercut [m³/s].

  • MaxStream() Maximum stream outflow that externally requested supplies must not exceed [m³/s].

  • KeepWaterBalance() Flag to indicate if too-high requested transfers should be reduced [-].

  • FlowTransferRules() Seasonally varying interpolation rules for branching the (adjusted) inflow [-].

  • Rules() Seasonally varying interpolation rules for branching the input [-].

  • MinVol() Minimum water volume that externally requested withdrawals should not undercut [million m³].

  • MaxVol() Maximum water volume that externally requested supplies should not exceed [million m³].

  • VolTol() Tolerance for smoothing the reduction of externally requested transfers at the water volume thresholds MinVol and MaxVol [million m³].

  • QTol() Tolerance for smoothing the reduction of withdrawals to the main model’s allowed discharge [m³/s].

  • VolTransferRules() Seasonally varying interpolation rules for calculating the water transfer based on the current water volume [m³/s].

  • ObserverNodes() The names of the considered observer nodes.

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

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

Bases: DerivedParameters

Derived parameters of model exch.

The following classes are selected:
  • TOY() References the timeofyear index array provided by the instance of class Indexer available in module pub [-].

  • MOY() References the “global” month of the year index array [-].

  • NmbObserverNodes() The number of observer nodes [-].

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

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

  • StreamIndex() The index of the stream node’s output among the outputs of parameter FlowTransferRules [-].

  • VolSmoothPar() Smoothing parameter to be derived from VolTol for smoothing kernel smooth_logistic1() [million m³].

  • QSmoothPar() Smoothing parameter to be derived from QTol for smoothing kernels smooth_min1() and smooth_max1() [m³/s].

class hydpy.models.exch.FactorSequences(master: Sequences[TM_co], 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[TM_co], 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[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InletSequences

Inlet sequences of model exch.

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

Bases: InputSequences

Input sequences of model exch.

The following classes are selected:
class hydpy.models.exch.LogSequences(master: Sequences[TM_co], 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[TM_co], 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[TM_co], 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[TM_co], 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[TM_co], 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 [?].