HydPy-WQ-Widths-Strickler (tabulated widths river profile submodel including Strickler-based calculations)

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

wq_widths_strickler is very similar to wq_trapeze_strickler but more flexible and thus a little more complicated. The first difference is that it relies on defining individual height/width pairs, which can be grouped into separate sectors by marking the transitions between all neighbouring sectors. The documentation on method plot() of the base class WidthsModel visualises this based on some trapeze-based profiles.

The second difference is that only wq_widths_strickler distinguishes between those parts of a cross-section that are actively involved in water routing and those that are not but still play a role due to providing storage volume. This feature can help to model retention effects of goyles or structured overbanks. It is also visualised in the documentation on method plot() and some of the following integration tests show how it modifies 1-dimensional floodwave routing.

Integration tests

Note

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

We use two different main models, musk_mct and kinw_impl_euler, to emphasise different aspects of wq_widths_strickler. The following setting and input time series stem from the integration tests of these models (that rely on wq_trapeze_strickler), which allows for direct comparisons:

>>> 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 create the same channel configuration as used in the Long segments example. Note that the first two height/width pairs would principally suffice for representing the same simple trapezoidal channel profile. However, we prefer to add a third pair at an extreme height to ensure the vertical orientation of the cross section’s-outlines above the highest height does not cause deviations from the original example’s results:

>>> 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_widths_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.stricklercoefficients(1.0/0.035)
>>> IntegrationTest.plotting_options.axis1 = (states.discharge,)
>>> test = IntegrationTest(stream)
>>> nodes.input1.sequences.sim.series = q_base
>>> nodes.input2.sequences.sim.series = series

Please also note that, due to the presence of the third height/width pair given, the second pair has absolutely no effect on the results, because (1) it lies in the direct line between the first and the last pair and (2) we do define a single sector, which is why the Manning-Strickler equation (and so the same friction coefficient) is always applied on the complete cross-section.

Long segments

The following results are identical to the ones of the Long segments example (as to be expected due to the quasi-identical configuration):

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

No-flow areas

Next, we demonstrate the effect of introducing “no-flow areas” by widening the total profile width in the channel’s upper range but not the flow width (which marks those areas that actively contribute to water routing). musk_mct can react a little sensitive to strong discontinuities, so we prefer introduce this change smoothly by letting the difference between both widths continually grow, beginning at the second height/width pair. Hence, the resulting more pronounced retention effect shows only after the water level exceeds the second pair’s measuring height:

>>> model.wqmodel.parameters.control.totalwidths(15.0, 75.0, 2015.0)
>>> model.prepare_states(100.0)
>>> test("wq_widths_strickler_musk_mct_no_flow_areas")
Click to see the table
Click to see the graph

KinW-Implicit-Euler

Next, we use kinw_impl_euler as the main model. Its better stability regarding discontinuous channel profiles eases defining more comlex cross sections. Hence, we can reuse the test configuration of the overbank flow example:

>>> 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_widths_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.bottomslope(0.00025)
...     control.transitions(1, 3)
...     control.stricklercoefficients(1.0/0.035, 10.0, 10.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

Due to the practically identical configuration, the following results are equal to those of the overbank flow example:

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

No-flow areas

In this example, we demonstrate the effect of a more sudden difference between the cross-section’s total width and flow width, which comes into play as soon as the water depth exceeds the main channel’s depth:

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

Bases: WidthsModel, CrossSectionModel_V1

HydPy-WQ-Widths-Strickler (tabulated widths 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: DocName = ('WQ-Widths-Strickler', 'tabulated widths river profile submodel including Strickler-based calculations')
OBSERVER_METHODS: ClassVar[tuple[type[Method], ...]] = ()
prepare_bottomslope

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

>>> from hydpy.models.wq_widths_strickler import *
>>> parameterstep()
>>> model.prepare_bottomslope(0.01)
>>> bottomslope
bottomslope(0.01)
REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()
cymodel: CyModelProtocol | None
parameters: parametertools.Parameters
sequences: sequencetools.Sequences
masks: masktools.Masks
class hydpy.models.wq_widths_strickler.AideSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: AideSequences

Aide sequences of model wq_widths_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_widths_strickler.ControlParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Control parameters of model wq_widths_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].

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

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

  • BottomSlope() Bottom slope [-].

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

Bases: SubParameters

Derived parameters of model wq_widths_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].

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

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

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

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

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

Bases: FactorSequences

Factor sequences of model wq_widths_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 trapeze 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_widths_strickler.FluxSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FluxSequences

Flux sequences of model wq_widths_strickler.

The following classes are selected: