HydPy-KinW-Williams-Ext (Williams routing based on an externally calculated volume-discharge relationship)

kinw_williams_ext is a computationally more efficient alternative to the application model kinw_williams. The higher efficiency is due to not calculating discharges based on channel geometries but preprocessed relationships between velocity and storage, similar to the “V/Q-BEZIEHUNG EXTERN” option of LARSIM.

The “parameter” VG2FG describes this relationship. You can configure it using a piecewise linear, a spline, or a neural network-based interpolation technique. See modules anntools and ppolytools for further information. Principally, VG2FG can fit any relationship provided by kinw_williams very accurately. However, high accuracy might require a considerable number of polynomials or neurons. At least the latter can come with a relevant performance cost.

For simple use cases, one can assign a single value to parameter VG2FG, either a constant flow velocity or a constant delay time. kinw_williams_ext then works like the often-applied linear storage cascade.

Integration tests

Note

When new to HydPy, consider reading section Integration Tests first.

main channel flow

The following integration test repeats the main channel flow example of the documentation on application model kinw_williams. The spatial and temporal settings are identical:

>>> from hydpy import ANN, pub, Nodes, Element
>>> pub.timegrids = "2000-01-01", "2000-01-05", "30m"
>>> from hydpy.models.kinw_williams_ext import *
>>> parameterstep("30m")
>>> nodes = Nodes("input1", "input2", "output")
>>> stream = Element("stream",
...                  inlets=["input1", "input2"],
...                  outlets="output")
>>> stream.model = model

We again divide a channel of 100 km into eight subsections:

>>> laen(100.0)
>>> gts(8)
>>> ek(1.0)

Next, we define a relatively small neural network of three neurons in a single hidden layer. This network roughly approximates the flow velocity calculated by the Gauckler-Manning-Strickler equation on the triple trapezoid profile defined in the main channel flow example:

>>> vg2fg(ANN(nmb_neurons=(3,),
...           weights_input=[[1.239962, 8.434961, 0.116195]],
...           weights_output=[[28.031913],
...                           [22.114402],
...                           [85.802384]],
...           intercepts_hidden=[[4.346762, 4.553889, 4.197525]],
...           intercepts_output=[-134.031566]))

In contrast to application model kinw_williams, kinw_williams_ext uses the stored water volume (VG) as its state variable instead of the water stage (H). Hence, we now must set VG to a value resulting in an initial outflow of 100 m³/s for the defined parameterisation of VG2FG, which holds for 1.55884384 million m³:

>>> from hydpy.core.testtools import IntegrationTest
>>> IntegrationTest.plotting_options.activated = fluxes.qz, fluxes.qa
>>> test = IntegrationTest(stream, inits=[[states.vg, 1.55884384]])

Finally, we define two identical inflow time series:

>>> import numpy
>>> q_base = 100.0
>>> q_peak = 900.0
>>> t_peak = 24.0
>>> beta = 16.0
>>> ts = pub.timegrids.init.to_timepoints()
>>> nodes.input1.sequences.sim.series = q_base
>>> nodes.input2.sequences.sim.series = (
...     (q_peak-q_base)*((ts/t_peak)*numpy.exp(1.0-ts/t_peak))**beta)

Our approximation of the velocity-storage relationship is far from perfect. Still, at least in the range relevant to the selected event, it is sufficient to reproduce the original results of application model kinw_williams with reasonable accuracy (for example, peak flow is 659.6 m³/s instead of 659.0 m³/s):

>>> test("kinw_williams_ext_main_channel_flow")
Click to see the table
Click to see the graph

linear storage cascade

This example shows using kinw_williams_ext like a simple linear storage cascade. Therefore, you must assign a constant flow velocity to parameter VG2FG via the keyword argument velocity in m/s. Alternatively, you can define the number of hours it takes for a flood wave to travel through the whole channel via the keyword argument timedelay.

When defining a constant flow velocity, be aware that this is also the wave celerity due to the assumed linearity. Hence, we set a velocity of 1.5 m/s, which is higher than the average flow velocity in the main channel flow example but leads to comparable results.

Note that, even when used as a linear storage cascade, kinw_williams_ext still relies on the numerical integration of its differential equations. Hence, it is computationally less efficient than Unit Hydrograph based approaches like those implemented in application model arma_rimorido, especially for short channels and high numbers of channel subsections. On the other hand, kinw_williams_ext only requires the actual water volume stored in the subsections to describe its current state, which is more concise and understandable than the logged values of arma_rimorido and can simplify the coupling with data assimilation approaches.

>>> vg2fg(velocity=1.5)
>>> test.inits.vg = 0.83333333
>>> test("kinw_williams_ext_linear_storage_cascade")
Click to see the table
Click to see the graph

directly forwarded runoff

If you need to forward the runoff directly (as if the channel length would be zero), set the number of subchannels to zero:

>>> laen(0.0)
>>> gts(0)
>>> test("kinw_williams_ext_directly_forwarded_runoff")
Click to see the table
Click to see the graph
class hydpy.models.kinw_williams_ext.Model[source]

Bases: ELSModel

HydPy-KinW-Williams-Ext (Williams routing based on an externally calculated volume-discharge relationship).

The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
  • Pick_Q_V1 Query the current inflow from all inlet nodes.

The following methods define the relevant components of a system of ODE equations (e.g. direct runoff):
  • Calc_QZA_V1 Calculate the current inflow into the channel.

  • Calc_QG_V2 Calculate the discharge of the total cross-section based on an interpolated flow velocity.

  • Calc_QA_V1 Query the actual outflow.

The following methods define the complete equations of an ODE system (e.g. change in storage of fast water due to effective precipitation and direct runoff):
The following “outlet update methods” are called in the given sequence at the end of each simulation step:
  • Pass_Q_V1 Pass the outflow to the outlet node.

DOCNAME: DocName = ('KinW-Williams-Ext', 'Williams routing based on an externally calculated volume-discharge relationship')
REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()
class hydpy.models.kinw_williams_ext.ControlParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Control parameters of model kinw_williams_ext.

The following classes are selected:
  • Laen() Flusslänge (channel length) [km].

  • GTS() Anzahl Gewässerteilstrecken (number of channel subsections) [-].

  • VG2FG() Flexibler Interpolator zur Berechnung der Fließgeschwindigkeit in Abhängigkeit zur aktuellen Wasserspeicherung einer Gewässerteilstrecke (flexible interpolator describing the relationship between the flow velocity and the water storage of individual channel subsections) [m/s].

  • EK() Kalibrierfaktor (calibration factor) [-].

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

Bases: SubParameters

Derived parameters of model kinw_williams_ext.

The following classes are selected:
  • Sek() Sekunden im Simulationszeitschritt (Number of seconds of the selected simulation time step) [s].

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

Bases: FluxSequences

Flux sequences of model kinw_williams_ext.

The following classes are selected:
  • QZ() Mittlerer Zufluss in Gerinnestrecke (average inflow into the channel) [m³/s].

  • QZA() Aktueller Zufluss in Gerinnestrecke (current inflow into the channel) [m³/s].

  • QG() Durchfluss gesamt (total discharge) [m³/s].

  • QA() Abfluss aus Gerinnestrecke (outflow out of the channel) [m³/s].

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

Bases: InletSequences

Inlet sequences of model kinw_williams_ext.

The following classes are selected:
  • Q() Abfluss (runoff) [m³/s].

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

Bases: OutletSequences

Outlet sequences of model kinw_williams_ext.

The following classes are selected:
  • Q() Abfluss (runoff) [m³/s].

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

Bases: SubParameters

Solver parameters of model kinw_williams_ext.

The following classes are selected:
  • AbsErrorMax() Absolute numerical error tolerance [m³/s].

  • RelErrorMax() Relative numerical error tolerance [-].

  • RelDTMin() Smallest relative integration time step size allowed [-].

  • RelDTMax() Largest relative integration time step size allowed [-].

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

Bases: StateSequences

State sequences of model kinw_williams_ext.

The following classes are selected:
  • VG() Wasservolumen (water volume) [million m³].