HydPy-WQ-Table-Strickler (free geometry river profile submodel including Strickler-based calculations)

wq_table_strickler is a stateless submodel that requires information on the current water level or depth from its main model (usually a routing model). It returns the corresponding discharge and related properties, such as the kinematic wave celerity. We implemented it to make HydPy’s routing features compatible with LARSIM’s PROFILE EXTERN option.

Basically, wq_table_strickler works much like wq_widths_strickler. However, while wq_widths_strickler requires only cross-section width and internally calculates other geometric data based on simple geometric assumptions, wq_table_strickler also requires external information on the wetted area and wetted perimeter. This lets users provide data from cross-section measurements without accuracy loss. However, please note that wq_table_strickler does not know the real geometry. Hence, its interpolation results can be more or less inconsistent for different geometrical properties, depending on the vertical distance between subsequent measurements and how much the real cross section deviates from the simple trapezoidal shape. Inconsistent input data is likely to increase this interpolation uncertainty as well. It depends on the selected routing model how much these problems actually affect simulation results. As a rule of thumb, simple methods which only query basic information from wq_table_strickler should have little or no trouble at all. More complex models which, for example, also rely on estimated wave velocity, are likely to be affected more heavily.

Integration tests

Note

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

We repeat some of the examples of wq_widths_strickler to show that wq_table_strickler yields the same results for strictly trapezoidal cross-section geometries, and add a test showing how deviations from a trapezoidal shape affect simulation results.

>>> from hydpy import Element, IntegrationTest, Nodes, pub
>>> pub.timegrids = "2000-01-01", "2000-01-05", "30m"
>>> nodes = Nodes("input1", "input2", "output")
>>> stream = Element("stream", inlets=["input1", "input2"], outlets="output")
>>> import numpy
>>> q_base = 100.0
>>> q_peak = 900.0
>>> t_peak = 24.0
>>> beta = 16.0
>>> ts = pub.timegrids.init.to_timepoints()
>>> series = (q_peak - q_base) * ((ts / t_peak) * numpy.exp(1.0 - ts / t_peak)) ** beta

Musk-MCT

We use the same data as in the Musk-MCT configuration of wq_widths_strickler and call the methods approximate() of class FlowAreas, approximate() of class TotalAreas, and approximate() of class FlowPerimeters to calculate the missing values in a trapezoidal manner:

>>> import numpy
>>> from hydpy.models.musk_mct import *
>>> parameterstep()
>>> stream.model = model
>>> length(100.0)
>>> nmbsegments(4)
>>> bottomslope(0.00025)
>>> catchmentarea(25000.0)
>>> with model.add_wqmodel_v1("wq_table_strickler") as submodel:
...     control = submodel.parameters.control
...     control.nmbwidths(3)
...     control.nmbsectors(1)
...     control.heights(0.0, 6.0, 100.0)
...     control.flowwidths(15.0, 75.0, 1015.0)
...     control.totalwidths(15.0, 75.0, 1015.0)
...     control.flowareas.approximate()
...     control.totalareas.approximate()
...     control.flowperimeters.approximate()
...     control.stricklercoefficients(1.0/0.035)
...     control.calibrationfactors(1.0)
>>> IntegrationTest.plotting_options.axis1 = (states.discharge,)
>>> test = IntegrationTest(stream)
>>> nodes.input1.sequences.sim.series = q_base
>>> nodes.input2.sequences.sim.series = series

Long segments

The following results are, as expected, identical to those in the Long segments example of wq_widths_strickler:

>>> model.prepare_states(100.0)
>>> test("wq_table_strickler_musk_mct_long_segments")
Click to see the table

Poorly defined rectangles

Now, we modify the wetted and total areas and the wetted perimeter extremely without adjusting the cross-section widths. wq_table_strickler still assumes a pattern of stacked trapezoids for interpolation, but the real areas and perimeters belong to a pattern of stacked rectangles. Clearly, this is not a very satisfying configuration and does likely not lead to accurate results, but at least the following show no obvious signs of numerical problems:

>>> model.wqmodel.parameters.control.totalareas(0, 450.0, 95860.0)
>>> model.wqmodel.parameters.control.flowareas(0, 450.0, 95860.0)
>>> model.wqmodel.parameters.control.flowperimeters(15.0, 87.0, 1215.0)
>>> model.wqmodel.update_parameters()
>>> model.prepare_states(100.0)
>>> test("wq_table_strickler_musk_mct_poorly_defined_rectangles")
Click to see the table

No-flow areas

wq_table_strickler realises the idea of no-flow areas like wq_widths_strickler does. Hence, after increasing the cross-section’s total width and refreshing the wetted areas and perimeters o match trapezoidal geometries, we achieve the same results as in the No-flow areas example of wq_widths_strickler:

>>> model.wqmodel.parameters.control.totalwidths(15.0, 75.0, 2015.0)
>>> model.wqmodel.parameters.control.flowareas.approximate()
>>> model.wqmodel.parameters.control.totalareas.approximate()
>>> model.wqmodel.parameters.control.flowperimeters.approximate()
>>> model.wqmodel.update_parameters()
>>> model.prepare_states(100.0)
>>> test("wq_table_strickler_musk_mct_no_flow_areas")
Click to see the table

KinW-Implicit-Euler

Next, we also use kinw_impl_euler as the main model to repeat the remaining examples of wq_widths_strickler to show that wq_table_strickler handles sharp transitions equally well:

>>> from hydpy import reverse_model_wildcard_import
>>> reverse_model_wildcard_import()
>>> from hydpy.models.kinw_impl_euler import *
>>> parameterstep()
>>> stream.model = model
>>> length(100.0)
>>> nmbsegments(8)
>>> with model.add_wqmodel_v1("wq_table_strickler") as submodel:
...     control = submodel.parameters.control
...     control.nmbwidths(5)
...     control.nmbsectors(3)
...     control.heights(0.0, 6.0, 6.0, 8.0, 10.0)
...     control.flowwidths(15.0, 75.0, 275.0, 315.0, 715.0)
...     control.totalwidths(15.0, 75.0, 275.0, 315.0, 715.0)
...     control.flowareas.approximate()
...     control.totalareas.approximate()
...     control.flowperimeters.approximate()
...     control.bottomslope(0.00025)
...     control.transitions(1, 3)
...     control.stricklercoefficients(1.0/0.035, 10.0, 10.0)
...     control.calibrationfactors(1.0)
>>> IntegrationTest.plotting_options.axis1 = (
...     fluxes.inflow, fluxes.internalflow, fluxes.outflow
... )
>>> test = IntegrationTest(stream)
>>> nodes.input1.sequences.sim.series = q_base
>>> nodes.input2.sequences.sim.series = series

Overbank flow

Because the configuration is practically identical, the following results match those of the Overbank flow example of wq_widths_strickler:

>>> model.prepare_states(100.0)
>>> test("wq_table_strickler_kinw_impl_euler_overbank_flow")
Click to see the table

No-flow areas

For strictly trapezoidal geometries, sudden differences between the cross-section’s total width and flow widths are also handled identically, which you can check by comparing the following results with those of the No-flow areas example of wq_widths_strickler:

>>> model.wqmodel.parameters.control.totalwidths(15.0, 75.0, 375.0, 415.0, 815.0)
>>> model.wqmodel.parameters.control.totalareas.approximate()
>>> model.prepare_states(100.0)
>>> test("wq_table_strickler_kinw_impl_euler_no_flow_areas")
Click to see the table
class hydpy.models.wq_table_strickler.Model[source]

Bases: WidthsModel, CrossSectionModel_V1

HydPy-WQ-Table-Strickler (free geometry river profile submodel including Strickler-based calculations).

The following interface methods are available to main models using the defined model as a submodel:
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 = ('WQ-Table-Strickler', 'free geometry river profile submodel including Strickler-based calculations')
prepare_bottomslope

Set the bottom’s slope (in the longitudinal direction) [-].

>>> from hydpy.models.wq_table_strickler import *
>>> parameterstep()
>>> model.prepare_bottomslope(0.01)
>>> bottomslope
bottomslope(0.01)
REUSABLE_METHODS = ()
class hydpy.models.wq_table_strickler.AideSequences(master: Sequences[TM_co], cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: AideSequences

Aide sequences of model wq_table_strickler.

The following classes are selected:
  • Index() Index of the measured height directly below the current height [-].

  • Excess() Difference between the current height and the next-lower measured height [m].

  • Weight() Linear weighting factor that is zero if the current height equals the next-lower measured height and one if it equals the next-higher measured height [-].

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

Bases: ControlParameters

Control parameters of model wq_table_strickler.

The following classes are selected:
  • NmbWidths() Number of widths that define the cross section [-].

  • NmbSectors() Number of the separately calculated sectors of the cross section [-].

  • Heights() The measurement heights of the widths defining the cross section [m].

  • FlowWidths() The widths of those subareas of the cross section involved in water routing [m].

  • TotalWidths() The widths of the total cross section [m].

  • FlowAreas() The wetted areas of the cross section involved in water routing [m²].

  • TotalAreas() The wetted areas of the total cross section [m].

  • FlowPerimeters() The wetted perimeters of the cross section involved in water routing [m].

  • Transitions() Indexes that mark the transitions between separately calculated cross-section sectors [m].

  • StricklerCoefficients() Manning-Strickler coefficient for each trapezium or sector [m^(1/3)/s].

  • CalibrationFactors() Calibration factor for each trapezium or sector [-].

  • BottomSlope() Bottom slope [-].

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

Bases: DerivedParameters

Derived parameters of model wq_table_strickler.

The following classes are selected:
  • SectorFlowWidths() The sector-specific widths of those subareas of the cross section involved in water routing [m].

  • SectorTotalWidths() The sector-specific widths of the total cross section [m].

  • SectorFlowAreasFromTable() The sector-specific wetted areas of those subareas of the cross section involved in water routing [m²].

  • SectorTotalAreasFromTable() The sector-specific wetted areas of the total cross section [m²].

  • FlowAreaAdjustments() Factors for adjusting flow areas calculated by assuming trapezoidal geometries to externally defined flow areas [-].

  • TotalAreaAdjustments() Factors for adjusting total wetted areas calculated by assuming trapezoidal geometries to externally defined total wetted areas [-].

  • SectorFlowPerimetersFromTable() The sector-specific wetted perimeters of those subareas of the cross section involved in water routing [m].

  • SectorFlowPerimeterDerivativesFromTable() Sector-specific changes in the wetted perimeters of the subareas of the cross section involved in water routing with respect to water-level increases [m].

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

Bases: FactorSequences

Factor sequences of model wq_table_strickler.

The following classes are selected:
  • WaterDepth() Water depth [m].

  • WaterLevel() Water level [m].

  • FlowAreas() The sector-specific wetted areas of those subareas of the cross section involved in water routing [m²].

  • FlowArea() The total wetted area of those subareas of the cross section involved in water routing [m²].

  • TotalAreas() The sector-specific wetted areas of the total cross section [m²].

  • TotalArea() The total wetted area of the total cross section [m²].

  • FlowPerimeters() The sector-specific wetted perimeters of those subareas of the cross section involved in water routing [m].

  • FlowPerimeterDerivatives() The sector-specific wetted perimeters of those subareas of the cross section involved in water routing [m].

  • FlowWidths() The sector-specific widths of those subareas of the cross section involved in water routing [m].

  • TotalWidths() The sector-specific widths of the total cross section [m].

  • TotalWidth() The total width of the total cross section [m].

  • DischargeDerivatives() Discharge change of each trapezoidal range with respect to a water level increase [m²/s].

  • DischargeDerivative() Total discharge change with respect to a water level increase [m²/s].

  • Celerity() Kinematic celerity (wave speed) [m/s].

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

Bases: FluxSequences

Flux sequences of model wq_table_strickler.

The following classes are selected: