TabulatedRatingCurve

A TabulatedRatingCurve determines outflow from a Basin by looking up the flow rate that corresponds to the current upstream level from a rating curve. The TabulatedRatingCurve takes a rating curve as input. Use it for instance to model flow over a weir.

1 Tables

1.1 Static

column type unit restriction
node_id Int32 - sorted
control_state String - (optional) sorted per node_id
active Bool - (optional, default true)
max_downstream_level Float64 \(\text{m}\) (optional)
level Float64 \(\text{m}\) sorted per control_state, unique
flow_rate Float64 \(\text{m}^3/\text{s}\) start at 0, increasing

Thus a single rating curve can be given by the following table:

node_id flow_rate level
2 0.0 -0.10
2 0.0001 0.09
2 0.01 0.29
2 0.9 20.09

Below the lowest given level of -0.10, the flow rate is kept at 0. Between given levels the flow rate is interpolated linearly. Above the maximum given level of 20.09, the flow rate keeps increases linearly according to the slope of the last segment.

1.1.1 Interpolation

The \(Q(h)\) relationship of a tabulated rating curve is defined as a linear interpolation.

Code
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, Markdown

np.random.seed(0)
fontsize = 15

N = 10
level = np.cumsum(np.random.rand(N))
flow = level**2 + np.random.rand(N)
flow[0] = 0.0
fig, ax = plt.subplots()
ax.set_xticks([])
ax.set_yticks([0])
ax.scatter(level, flow, label = "data")
ax.plot(level, flow, label = "interpolation", color = "C0")
ax.plot([level[0] - 1, level[0]], [0, 0], label = "extrapolation", linestyle = "dashed")
ax.legend()
ax.set_xlabel("level", fontsize = fontsize)
ax.set_ylabel("flow", fontsize = fontsize)

level_extrap = 2 * level[-1] - level[-2]
flow_extrap = 2 * flow[-1] - flow[-2]
ax.plot([level[-1], level_extrap], [flow[-1], flow_extrap], color = "C0", linestyle = "dashed")
ax.set_xlim(level[0] - 0.5, (level[-1] + level_extrap)/2)

markdown_table = pd.DataFrame(
        data = {
            "level" : level,
            "flow" : flow
        }
    ).to_markdown(index = False)

display(Markdown(markdown_table))
level flow
0.548814 0
1.264 2.1266
1.86677 4.05286
2.41165 6.74165
2.8353 8.10999
3.4812 12.2059
3.91879 15.3771
4.81056 23.9741
5.77422 34.1198
6.15766 38.7868

Here it is validated that the flow starts at \(0\) and is non-decreasing. The flow is extrapolated as \(0\) backward and linearly forward.

1.2 Time

This table is the transient form of the TabulatedRatingCurve table. The only difference is that a time column is added. The table must by sorted by time, and per time it must be sorted by node_id. With this the rating curves can be updated over time. Note that a node_id can be either in this table or in the static one, but not both.

column type unit restriction
node_id Int32 - sorted
time DateTime - sorted per node_id
level Float64 \(\text{m}\) sorted per node_id per time
flow_rate Float64 \(\text{m}^3/\text{s}\) non-negative
max_downstream_level Float64 \(\text{m}\) (optional)

2 Equations

The TabulatedRatingCurve is a tabulation of a Basin’s discharge behavior. It describes a piecewise linear relationship between the Basin’s level and its discharge. It can be understood as an empirical description of a Basin’s properties. This can include a weir, but also the lumped hydraulic behavior of the upstream channels.

\[ Q = \phi f(h) \]

Where:

  • \(h\) is the upstream water level
  • \(f\) is a piecewise linear function describing the given rating curve \(Q(h)\)
  • \(\phi\) is the reduction factor, which smoothly reduces flow based on all of these criteria:
    • The upstream volume is below \(10 m^3\).
    • The upstream level is less than \(0.02 m\) above the downstream level.
    • The downstream level is above max_downstream_level - \(0.02 m\)