Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Wechselsprungkonstruktion

Run this notebook in your web browser: Open in marimo

Der Link öffnet hydraulic-jump.py als interaktives marimo Notebook, das vollständig in Ihrem Webbrowser läuft, ohne etwas zu installieren.

  1. Warten Sie einen Moment, bis Python im Browser geladen ist (das dauert nur am ersten Start länger).

  2. Klicken Sie auf die gelbe Starttaste (▶, unten rechts) um alle Zellen auszuführen.

  3. Bearbeiten und re-run jede Codezelle zu experimentieren: marimo automatisch aktualisiert alle Zellen, die davon abhängig sind.

  4. Ihre Bearbeitungen bleiben nur im Browser-Tab. Um sie zu halten, speichern Sie das Notizbuch durch das Menü (≠, oben rechts) > Export... > Python.

Diese Übung ** orientiert sich am Clyde Dam, am Clutha River / Mata-Au in Central Otago, ist Neuseelands größter Beton-Schwerkraftdamm: 490 m breit, bis zu 60 m hoch über dem alten Flussbett und beschlagnahmender Lake Dunstan. Seine gated Überlauf hat vier radiale Tore, jeweils 15 m hoch und 10 m breit, entworfen, um eine Entladung von 3200 m3^3s (0,2% AEP) auf einem Seehöhe von 195.1 m zu führen. Das Wasser, das den Überlauf passiert, steigt eine Rutsche auf der Dammseite ab. Der hochenergetische Fluss an der Zehe dieser Rutsche muss in einem Tosbecken abgeführt werden, damit das Flussbett stromabwärts nicht durchgeschwemmt wird.

Schülerherausforderung: Größe der Beckengeometrie, so dass sich der Wechselsprung innerhalb des Beckens bildet und dort gehalten wird, und dadurch das Durchforsten stromabwärts des Damms vermieden wird.

Struktur der Berechnungsvorlage

Übersicht

Wer macht die Arbeit? |----------- | I Der Fluss, der am Becken ankommt: Entladung der Einheit, Energiekopf an der Rutsche und der Tiefe des Schwanzwassers | **gegeben ** - führen Sie die Zellen und lesen Sie die Ergebnisse | | II | Tosbecken & Wechselsprungdesign | student -- Workflow ist gegeben, Wechselsprunggleichungen müssen eingegeben werden |

Einzelheiten

Teil I legt die Größen fest, auf die der Wechselsprung und damit das Becken ausgelegt ist: die Entladung QQ und die Einheitsentladung qq, der Energiekopf H0H_0 oberhalb des unversenkten Beckens invertiert und die Schwanzwassertiefe htwh_{tw} erhalten aus der Manning-Gleichung.

Part II contains three short functions, marked Task 1 to Task 3. Each is a single equation from the lecture. The numerics around them, that is the root finding, the search over the basin depth and the plots, are given, so that an incorrect equation produces an incorrect number rather than a traceback. The equation at the centre of the exercise is the sequent-depth (Bélanger) equation of Task 2; the other two establish the state it is applied to and the criterion by which the result is judged. On completing Part II you should be able to:

  • die Energie-, Kontinuitäts- und Impulsverhältnisse ausdrücken, die einen Wechselsprung als Code festlegen;

  • Bestimmen, ob ein bestimmter Unterwasserspiegel einen Wechselsprung in einem Becken behält oder stromabwärts streicht;

  • die Tiefe, die Länge und den Scheuerschutz eines Beckens vor diesen Beziehungen zu bestimmen.

Notation

Tiefen werden als hh bezeichnet und Köpfe HH, in der Vorlesung und hier gleichermaßen. Der Retentionsgrad wird als rtr_{\mathrm{t}} und nicht als ε\varepsilon des deutschen Arbeitsbeispiels bezeichnet, aus dem dieser Workflow angepasst wird, da ε\varepsilon die turbulente Dissipationsrate in der Vorlesung bezeichnet.

| Symbol | Bedeutung | Einheit | |----------- | QQ | spillway design flow | m3^3s | | ww | Breite des Tosbeckens | m | | wtww_{tw} | Tailwater River Breite | m | qq | Entladung pro Einheitsbreite, q=Q/wq = Q/w | m2^2/s | | H0H_0 | Energie Kopf über dem unversenkten Becken invertiert | m | | db\mathbf{d_b} | Tiefe des Beckenbodens unter dem flussabwärts gelegenen Bett | m | | HH | Energie Kopf über dem Beckenboden, H=H0+dbH = H_0 + \mathbf{d_b} | m | | h1h_1, v1v_1, Fr1Fr_1 | Tiefe, Geschwindigkeit und Froude-Zahl am Eingang des Beckens (überkritisch) | m, m/s, -- | | h2h_2 | konjugierte (sequente) Tiefe des Wechselsprungs | m | | htwh_{tw} | Schwanzwassertiefe im flussabwärts gelegenen Bereich | m | | nMn_M | Manning Rauheitskoeffizient der Downstream-Reichweite | s/m1/3^{1/3} | rtr_{\mathrm{t}} | Retention Ratio, (htw+db)/h2(h_{tw} + \mathbf{d_b})/h_2 | -- | | S0,twS_{0,tw} | Längsbettneigung des stromabwärts gelegenen Bereichs | -- | | ΔH\Delta H | Kopfverlust über den Wechselsprung | m | | flf_{l} | Peterka Basin-Längen-Multiplikator, gelesen von Fr1Fr_1 | -- | | lbl_b, lsl_s | Beckenlänge und Scheuerschutzlänge | m |

Die folgende Zelle importiert die Python-Pakete und die für die Figuren verwendeten Farben. Diese Zellen dienen der Funktionsweise der Berechnungsvorlage und tragen keine Lerninhalte.

import math
from dataclasses import dataclass

import matplotlib.patheffects as pe
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import brentq

# Physical constants used throughout.
G = 9.81  # gravitational acceleration [m/s2]

# The lecture palette, so that figures and slides read as one piece.
NAVY, BLUE, CYAN, GREEN, WARN, GREY = (
    "#0C0C48", "#00467F", "#00CAEF", "#167D61", "#C74B2A", "#4A4A4C",
)

plt.rcParams.update({
    "figure.figsize": (8.4, 4.2),
    "figure.dpi": 110,
    "axes.spines.top": False,
    "axes.spines.right": False,
    "axes.titleweight": "bold",
    "axes.labelcolor": NAVY,
    "axes.edgecolor": NAVY,
    "text.color": NAVY,
    "xtick.color": NAVY,
    "ytick.color": NAVY,
    "font.size": 9,
})

Teil I: Randbedingungen für die Wechselsprungkonstruktion

Alles in diesem Teil ist gegeben. Führen Sie die Zellen aus und beachten Sie die Mengen, die an Teil II weitergegeben werden. Hier wird keine hydraulische Stoßberechnung durchgeführt.

Anmerkung: nur die Entladung, die zugehörige Seehöhe und die Gate-Dimensionen werden veröffentlichte Zahlen; der Rest wird angenommen. Die eigentliche Struktur ist nicht so einfach. Eine Gate-gesteuerte Schleuse mit einem Nennwert von 1500 m3^3/s grenzt an den Abfluss und die beiden passieren gemeinsam die größte erwartete Flut von 6820 m3^3/s. Die Energiedissipation am Zehen wurde auf physikalischen Modellen vom Ministerium für Arbeit und Entwicklung anstatt aus einer geschlossenen Form Berechnung entwickelt. Diese Übung stellt daher den ersten Schritt dar, den Ingenieure typischerweise vor einer detaillierten Designstudie mit physikalischen oder numerischen Modellen absolvieren; sie ist kein Ersatz für eine solche Studie.

| Menge | Wert | Bemerkung | |---------- | QQ, spillway design flow | 3200 m3^3/s | veröffentlicht, auf einem Seeniveau von 195.1 m | | ww, Breite der Rutsche und Becken | 40 m | vier 10 m Torbuchten, idealisiert als eine rechteckige Rutsche mit den Toren ignoriert | | H0H_0, Energiekopf über dem unsunk Becken invert | 50.00 m | angenommen: der Designflutstand steht ca. 60 m über dem Flussbett, von dem ca. 10 m als verlorener Schacht genommen wird | |wtww_{tw}, nMn_M, S0,twS_{0,tw} des Clutha nach dem Damm | 60 m, 0.045 s/m1/3^{1/3}, 0.0006 | angenommen |

In der neuseeländischen Praxis werden Einfang-Design-Überschwemmungen als jährliche Überschreitungswahrscheinlichkeit angegeben, so dass die 100-jährige Überschwemmung das 1% AEP-Ereignis ist und die 500-jährige Überschwemmung, die für Clyde angegeben wird, das 0.2% AEP-Ereignis ist; das ältere durchschnittliche Wiederauftreten (ARI) bedeutet dasselbe. Ein Damm-Spillway ist jedoch nicht auf ein Einzugs-AEP ausgelegt: Unter den NZSOLD * New Zealand Dam Safety Guidelines* folgt die Zufluss-Design-Flosse aus der Potential Impact Classification des Damms und für einen Hochkonsequenz-Demm bis zur wahrscheinlichen maximalen Flut.

Die folgende Zelle definiert diese hydrologischen, hydraulischen und geometrischen Randbedingungen.

# --- the design discharge ----------------------------------------------------
Q_design = 3200.0  # m3/s   Clyde Dam spillway design flow at lake level 195.1 m
                   #        (published; the 500-year, 0.2% AEP flood)

# --- the chute toe and the stilling basin below it ---------------------------
w_chute = 40.0     # m      four 10 m gate bays, idealised as one rectangle
H0 = 50.00         # m      energy head above the un-sunk basin invert (assumed)

# --- the Clutha River below the dam (assumed) --------------------------------
n_manning = 0.045   # s/m^(1/3)  Manning roughness of the downstream reach
slope = 6.0e-4      # -          bed slope of the downstream reach
w_tw = 60.0         # m          width of the downstream reach (rectangular idealisation)
h_tw = 19.060       # m          tailwater depth of that reach in uniform flow

print(f"spillway design flow Q  = {Q_design:7.1f} m3/s")
print(f"chute and basin width w = {w_chute:7.2f} m")
print(f"head at the invert   H0 = {H0:7.2f} m")
spillway design flow Q  =  3200.0 m3/s
chute and basin width w =   40.00 m
head at the invert   H0 =   50.00 m

Grenzberechnung

Einheitsentladung

Für die Berechnung des Wechselsprungs ist eine Entladung pro Meter Breite erforderlich:

q=Qwq = \frac{Q}{w}

The chute delivers this flow supercritically, which is the condition for a jump to form. The critical depth printed below is the upper bound on the entry depth h1h_1, and Part II uses it as the bracket when solving the energy equation.

q_unit = Q_design / w_chute
h_crit = (q_unit**2 / G)**(1 / 3)

print(f"unit discharge   q = Q / w   = {q_unit:7.3f} m2/s")
print(f"critical depth   h_c         = {h_crit:7.3f} m")
print(f"critical velocity            = {q_unit / h_crit:7.3f} m/s")
unit discharge   q = Q / w   =  80.000 m2/s
critical depth   h_c         =   8.673 m
critical velocity            =   9.224 m/s

Wassertiefe htwh_{tw}

Die Tiefe in der stromabwärtigen Reichweite bestimmt, ob der Wechselsprung zurückgehalten oder gefegt wird, und wird durch die Reichweite selbst und nicht durch den Überlauf eingestellt. Für einen rechteckigen Kanal in gleichmäßigem Fluss gibt die Manning-Gleichung

Q=1nM A R2/3 S0,tw,A=wtw htw,R=wtw htwwtw+2 htwQ = \frac{1}{n_M}\,A\,R^{2/3}\,\sqrt{S_{0,tw}}, \qquad A = w_{tw}\,h_{tw}, \qquad R = \frac{w_{tw}\,h_{tw}}{w_{tw} + 2\,h_{tw}}

Evaluating this for the reach above gives htw=19.060h_{tw} = 19.060 m, which is assigned directly in the cell below and used from there on.

Note: Natural channels are not rectangular, and htwh_{tw} enters the retention ratio directly. In practice the tailwater rating curve is obtained from gauging, a numerical model, or terrain data, and a range of tailwater levels is tested rather than a single value.

Die Zelle unten druckt auch die kritische Tiefe des stromabwärts gelegenen Bereichs, da ein Wechselsprung nur im Unterwasser enden kann, während dieser Bereich unterkritisch ist.

h_crit_tw = ((Q_design / w_tw)**2 / G)**(1 / 3)

print(f"tailwater depth h_tw = {h_tw:.3f} m   (given, from the reach above)")
print(f"critical depth of the reach = {h_crit_tw:.3f} m"
      f"   -> {'subcritical' if h_tw > h_crit_tw else 'SUPERCRITICAL'}")
tailwater depth h_tw = 19.060 m   (given, from the reach above)
critical depth of the reach = 6.619 m   -> subcritical

Definieren von Datenstrukturen und Standardwerten

Der folgende Codeblock baut die erforderlichen Datenstrukturen auf und setzt Standardwerte für den Kernteil II.

@dataclass(frozen=True)
class DesignData:
    Q: float       # spillway design flow [m3/s]
    q: float       # discharge per unit width [m2/s]
    H0: float      # energy head above the un-sunk basin invert [m]
    h_tw: float    # tailwater depth [m]
    w: float       # width the basin has to cover [m]


DESIGN = DesignData(
    Q=Q_design,
    q=q_unit,
    H0=H0,
    h_tw=h_tw,
    w=w_chute,
)

print(f"Q      = {DESIGN.Q:8.1f} m3/s   spillway design flow")
print(f"q      = {DESIGN.q:8.3f} m2/s   unit discharge")
print(f"H0     = {DESIGN.H0:8.2f} m      energy head above the un-sunk invert")
print(f"h_tw   = {DESIGN.h_tw:8.3f} m      tailwater depth")
print(f"w      = {DESIGN.w:8.2f} m      width the basin has to cover")
Q      =   3200.0 m3/s   spillway design flow
q      =   80.000 m2/s   unit discharge
H0     =    50.00 m      energy head above the un-sunk invert
h_tw   =   19.060 m      tailwater depth
w      =    40.00 m      width the basin has to cover

Teil II: Tosbecken & Wechselsprungkonstruktion

Die sequente Tiefe (Bélanger) Gleichung

Für einen horizontalen, rechteckigen Kanal folgen die Lage und die Größe des Wechselsprunges von der Impulserhaltung, den hydrostatischen Druckkräften und der Kontinuität. Da die spezifische Kraft stromaufwärts (1) und stromabwärts (2) des Wechselsprungs, d.h. M1=M2M_1 = M_2 mit M=q2/(g h)+h2/2M = q^2/(g\,h) + h^2/2, gleich ist, wird das Tiefenverhältnis durch die sequent-tiefe Gleichung von Bélanger berechnet:

  h2h1=12(1+8 Fr12−1)  \boxed{\;\frac{h_2}{h_1} = \frac{1}{2}\left(\sqrt{1 + 8\,Fr_1^{2}} - 1\right)\;}

Bestimmt sind h1h_1 und h2h_2 die sequent (conjugate) Tiefen. Jede nachfolgende Menge in dieser Übung ergibt sich aus h2h_2: dem Rückhalteverhältnis, das anzeigt, ob der Wechselsprung im Becken, der Beckenlänge und der erforderlichen Länge des nachgeschalteten Geruchsschutzes bleibt.

Design Problem

Die Position des Wechselsprunges wird nicht durch den Ablauf festgelegt. Sie wird von der tailwater Tiefe gesteuert: ein Wechselsprung bildet, in dem die nachgeschaltete Tiefe der konjugierten Tiefe h2h_2 entspricht, die dem ankommenden überkritischen Zustand entspricht. Wenn das Schwanzwasser zu flach ist, ist der Wechselsprung ** ausgeschleust ** auf ungeschützten nachgeschalteten Flussbett; wo es zu tief ist, ist der Wechselsprung ** entführt** und weniger.

Die einheitliche Gestaltungsfreiheit ist die ** Grundtiefe*db\mathbf{d_b}, mit der der Beckenboden unterhalb des nachgeschalteten Flussbetts liegt. Erhöhen db\mathbf{d_b} wirkt in zwei entgegengesetzte Richtungen:

  1. Er erhöht den Energiekopf H=H0+dbH = H_0 + \mathbf{d_b} über dem Boden, so dass der Eintrittsfluss schneller und flacher ist, was Fr1Fr_1 und damit h2h_2 anhebt;

  2. es erhöht die über dem Boden verfügbare Tiefe, nämlich htw+dbh_{tw} + \mathbf{d_b}.

Ein akzeptables Design ist eine Beckentiefe, bei der beide technischen Ziele gleichzeitig erfüllt werden:

4.5≤Fr1<9.0and1.05≤rt=htw+dbh2≤1.154.5 \le Fr_1 < 9.0 \qquad\text{and}\qquad 1.05 \le r_{\mathrm{t}} = \frac{h_{tw} + \mathbf{d_b}}{h_2} \le 1.15

Das erste technische Ziel ist der Stillsprung, der zu 45 % bis 70 % Kopfverlust führt, und kein oszillierender Anstieg zur Ermüdung der Struktur. Das zweite technische Ziel erfordert, dass das Becken etwas mehr Wasser als die Wechselsprunganforderungen hält, so dass der Wechselsprung mit einem kleinen Rand ohne Ertrinken gehalten wird.

Der Workflow

Die Schritte laufen in der Reihenfolge der Tabelle, und jeder ist entweder gegeben oder eine der drei Aufgaben:

Inhalt | Hinweis | |------| | Wählen Sie eine Testbeckentiefe db\mathbf{d_b} | hier: 1.0 m (gegeben) | | h1h_1 und v1v_1 aus der Energiegleichung am Eingang | angegeben | | Fr1=v1/g h1Fr_1 = v_1/\sqrt{g\,h_1} | Task 1 | | ist 4.5≤Fr1<9.04.5 \le Fr_1 < 9.0? wenn nicht, anpassen db\mathbf{d_b} | angegebene | | die Konjugattiefe h2h_2 aus der Bélanger Gleichung | Task 2 | | ist 1.05≤rt≤1.151.05 \le r_{\mathrm{t}} \le 1.15 wenn nicht, anpassen db\mathbf{d_b} | Task 3 + angegeben | | Beckenlänge lbl_b und Scour-Protection Länge lsl_s | angegeben | | Kopfverlust ΔH\Delta H | angegeben |

Die drei Aufgaben

Jede Aufgabe ist eine Gleichung aus dem Vortrag.

** Ersetzen Sie die raise NotImplementedError(...)-Linie mit einer return-Anweisung.**

Die Funktionsnamen und ihre Argumente dürfen nicht geändert werden, da der Workflow unten sie anruft.

Important: Nach Abschluss jeder Aufgabe, führen Sie die *self-check Zelle. Es markiert jede Funktion [OK] oder [XX] gegen die Vorlesungswerte.

Vorgestellt: Energiekopf über dem Beckenboden

Neglecting the approach velocity, the energy head available above the basin floor is H=H0+dbH = H_0 + \mathbf{d_b}. At the basin entrance, that is, cross section 1, that head is split between depth and velocity head. With continuity v=q/hv = q/h for a rectangular section,

H=h+v22g=h+q22g h2H = h + \frac{v^2}{2g} = h + \frac{q^2}{2g\,h^2}

Die rechte Seite wird unten in Abhängigkeit von hh und qq codiert. Lesen Sie es, denn der Eintrittszustand jeder Testbeckentiefe kommt daraus: Der angegebene Soldat entry_depth weiter unten wählt die flache, überkritische Wurzel von energy_head(h, q) == H, die der Zweig der Schacht ist.

def energy_head(h, q, g=G):
    '''
    Given: specific energy head of a rectangular section [m].

    Parameters
    ----------
    h : water depth [m]
    q : discharge per unit width [m2/s]

    Returns
    -------
    the energy head h + q^2 / (2 g h^2) [m]
    '''
    return h + q**2 / (2 * g * h**2)

Aufgabe 1: Froud-Nummer

The Froude number compares the flow velocity with the shallow-water wave speed c=ghc = \sqrt{g h}:

Fr=vg hFr = \frac{v}{\sqrt{g\,h}}

Erinnern Sie sich daran, dass Fr>1Fr > 1 überkritische und Fr<1Fr < 1unterkritischer Fluss bedeutet. Dieser Schritt des Workflows berechnet nur den Wert der Froude-Zahl (hier: Fr1Fr_1) für den späteren Vergleich mit dem stationären Fenster:

def froude_number(v, h, g=G):
    '''
    Task 1: Froude number of a rectangular section [-].

    Parameters
    ----------
    v : depth-averaged velocity [m/s]
    h : water depth [m]
    '''
    # >>> YOUR CODE HERE
    raise NotImplementedError("Task 1: return the Froude number")

Aufgabe 2: Sequenztiefe (Bélanger) Gleichung

** Dies ist die zentrale Gleichung der Übung. ** Implementieren Sie das Tiefenverhältnis an den Querschnitten 2 (h2h_2) und 1 (h1h_1):

h2h1=12(1+8 Fr12−1)\frac{h_2}{h_1} = \frac{1}{2}\left(\sqrt{1 + 8\,Fr_1^{2}} - 1\right)

Note: This equation describes neither the roller between the cross sections nor the internal structure of the jump. Everything the design requires after this point, that is the retention ratio, the basin length and the scour-protection length, follows from the h2h_2 sequent depth equation returns.

def conjugate_depth(h1, Fr1):
    '''
    Task 2: conjugate (sequent) depth downstream of the jump [m].

    Parameters
    ----------
    h1  : supercritical depth upstream of the jump [m]
    Fr1 : Froude number at section 1 [-]
    '''
    # >>> YOUR CODE HERE
    raise NotImplementedError("Task 2: return the conjugate depth h2")

Aufgabe 3: Retentionsverhältnis

Die Wassertiefe über dem Beckenboden ist die Unterwassertiefe plus die Beckentiefe. Vergleicht man es mit der Tiefe, die der Wechselsprung fordert, ergibt sich das Retentionsverhältnis:

rt=htw+dbh2r_{\mathrm{t}} = \frac{h_{tw} + \mathbf{d_b}}{h_2}

rt<1r_{\mathrm{t}} < 1 bedeutet, dass das Becken die Konjugattiefe nicht liefern kann und der Wechselsprung stromabwärts geschwommen wird; rtr_{\mathrm{t}} gut über 1 bedeutet, dass der Wechselsprung ertrunken ist. Der Retentionscheck bittet um 1.05≤rt≤1.151.05 \le r_{\mathrm{t}} \le 1.15.

def retention_ratio(h_tw, d_b, h2):
    '''
    Task 3: retention ratio of the basin [-].

    Parameters
    ----------
    h_tw : tailwater depth in the downstream reach [m]
    d_b  : depth of the basin floor below the downstream bed [m]
    h2   : conjugate depth required by the jump [m]
    '''
    # >>> YOUR CODE HERE
    raise NotImplementedError("Task 3: return the retention ratio")

Vorgestellt: Becken- und Geruchsschutzlängen

To empirically derive the required stilling basin length lbl_b, Peterka (USBR Engineering Monograph 25) measured the length of the jump in six test flumes and plotted it against the Froude number as a ready reckoner (his Figure 7, free jump on a horizontal apron). The curve gives a factor (here: flf_l), which is read off at the Froude number of cross section 1 (Fr1Fr_1) and multiplied by the conjugate depth (h2h_2):

| Fr1Fr_1 | 2.4 | 4 | 5 | 6 bis 11 | 14

| flf_{l} | 4.8 | 5.8 | 6.0 | 6.13 | 6.0

Die Funktion peterka_f unten liest diese Tabelle (keine Intervention erforderlich) und gibt flf_{l} zurück. Es passt nichts: np.interp interpoliert linear zwischen den tabellarisierten Punkten einer gemessenen Kurve, und diese Kurve ist keine gerade Linie.

def peterka_f(Fr1):
    '''Given: basin-length multiplier after Peterka (USBR EM 25), interpolated [-].'''
    knots_Fr = [2.4, 4.0, 5.0, 6.0, 11.0, 14.0]
    knots_f = [4.8, 5.8, 6.0, 6.13, 6.13, 6.0]
    return float(np.interp(Fr1, knots_Fr, knots_f))


print(f"f_l at Fr1 = 5.0 : {peterka_f(5.0):.3f}")
print(f"f_l at Fr1 = 8.0 : {peterka_f(8.0):.3f}")
f_l at Fr1 = 5.0 : 6.000
f_l at Fr1 = 8.0 : 6.130

Next, calculate the required basin length lbl_b to contain the jump with the peterka_f function. Because the flow leaving the jump (and the basin end sill) is still turbulent, the riverbed immediately downstream of the basin has to be armoured over a length lsl_s:

lb=fl(Fr1)h2,ls=3.5lbl_b = f_{l}(Fr_1) h_2, \qquad l_s = 3.5 l_b

Beide Längen sind unten codiert, basin_lengths rufen peterka_f für den Multiplikator an.

def basin_lengths(h2, Fr1):
    '''
    Given: basin length and scour-protection length [m].

    Parameters
    ----------
    h2  : conjugate depth downstream of the jump [m]
    Fr1 : Froude number at section 1, which selects the multiplier [-]

    Returns
    -------
    (l_b, l_s) : basin length and scour-protection length [m]
    '''
    l_b = peterka_f(Fr1) * h2
    return l_b, 3.5 * l_b

Hinweis: Für einen stetigen Wechselsprung ist lbl_b in der Nähe der Faustregel lj≈l_j \approx6 h2h_2, und die Zellen in diesem Notizbuch drucken sowohl ljl_j als auch lbl_b. Andere Designhandbücher würden jedoch unterschiedliche Faktoren angeben, was einer der Gründe ist, warum ein detailliertes Design mit einem physikalischen oder numerischen Modell entscheidend ist.

Selbstkontrolle

Führen Sie diese Zelle nach Abschluss jeder Aufgabe aus. Die Referenzwerte sind die ungefähren Ergebnisse, die in den Vorlesungsschiebern vorgestellt werden, so [OK] auf jeder Zeile angibt, dass die drei Aufgaben die Dias wiedergeben.

CHECKS = [
    ("Task 1  froude_number(31.623, 2.5298)",
     lambda: froude_number(31.623, 2.5298), (6.348,), "-"),
    ("Task 2  conjugate_depth(2.5298, 6.348)",
     lambda: conjugate_depth(2.5298, 6.348), (21.481,), "m"),
    ("Task 3  retention_ratio(19.060, 3.5, 21.481)",
     lambda: retention_ratio(19.060, 3.5, 21.481), (1.050,), "-"),
]


def check_tasks(tolerance=5e-3, verbose=True):
    '''Compare each task against the worked values from the lecture.'''
    passed = 0
    for label, call, expected, unit in CHECKS:
        try:
            value = call()
        except NotImplementedError:
            if verbose:
                print(f"[ ] {label:<46} not implemented yet")
            continue
        got = value if isinstance(value, tuple) else (value,)
        ok = (len(got) == len(expected) and
              all(abs(g - e) <= tolerance * max(1.0, abs(e))
                  for g, e in zip(got, expected)))
        passed += ok
        if verbose:
            mark = "OK" if ok else "XX"
            shown = ", ".join(f"{g:.3f}" for g in got)
            wanted = ", ".join(f"{e:.3f}" for e in expected)
            print(f"[{mark}] {label:<46} {shown:>19} {unit:<3}"
                  f" (expected {wanted})")
    if verbose:
        print("-" * 78)
        print(f"{passed} of {len(CHECKS)} tasks correct.")
    return passed == len(CHECKS)


TASKS_DONE = check_tasks()
[ ] Task 1  froude_number(31.623, 2.5298)          not implemented yet
[ ] Task 2  conjugate_depth(2.5298, 6.348)         not implemented yet
[ ] Task 3  retention_ratio(19.060, 3.5, 21.481)   not implemented yet
------------------------------------------------------------------------------
0 of 3 tasks correct.

Workflow-Implementierung: die Suche über die Beckentiefe

**Der Rest der Berechnungen von Teil II wird angegeben (die Antworten auf die Folgefragen sind nicht). **

Die Funktion basin_state evaluiert das Ende eines Testbeckens und ruft die oben geschriebenen Funktionen an; search_basin_depth wählt die Testtiefen aus, indem Sie db\mathbf{d_b}by-bisection anpassen, bis es die shallowest Tiefe gefunden hat, in der beide Engineering-Ziele erfüllt sind. Die Bisection-Logik sollte vor Ablauf der Zelle gelesen werden.

Fr1Fr_1 and rtr_{\mathrm{t}} increase with db\mathbf{d_b}, which is what allows one to use a single bracket for both tests: too shallow a basin does not supply the depth the jump demands and sweeps it downstream, but too deep a basin supplies more than the jump requires and drowns it. Each failed trial therefore indicates which half of the bracket to retain, and in the present case the search fails in both directions before converging.

** Reservierungen:** Der Such-Workflow beginnt mit einem ersten Test von db\mathbf{d_b} = 1,0 m. Dieser Prozess erfüllt das stetige Stoßfenster, Fr1Fr_1 = 6.1 ist bereits ein stetiger Wechselsprung und versäumt das Rückhaltefenster, der Wechselsprung wird ausgeschwemmt. Die Bissektion vertieft dann das Becken auf 10,5 m, das den Wechselsprung ertrinkt, und arbeitet zurück. Eine akzeptable Tiefe ist nicht das Ende der Suche: Weil ein tieferes Becken Kosten Ausgrabung für keinen Nutzen, hält die Klammer geschlossen, bis die *shallowest akzeptable Tiefe gefunden wird, und dieser Wert wird auf die nächsten 0,25 m für eine konstruktive Figur abgerundet. Das Ergebnis hängt noch von der Breite des Bügels ab, so sollte ein Bericht angeben, welche Klammer es produziert.

FR_WINDOW = (4.5, 9.0)     # steady-jump range
RT_WINDOW = (1.05, 1.15)   # retention window


@dataclass(frozen=True)
class BasinState:
    d_b: float     # trial basin depth [m]
    H: float       # energy head above the basin floor [m]
    h1: float      # supercritical entry depth [m]
    v1: float      # entry velocity [m/s]
    Fr1: float     # entry Froude number [-]
    h2: float      # conjugate depth [m]
    Rt: float      # retention ratio [-]

    @property
    def fr_ok(self):
        return FR_WINDOW[0] <= self.Fr1 < FR_WINDOW[1]

    @property
    def rt_ok(self):
        return RT_WINDOW[0] <= self.Rt <= RT_WINDOW[1]


def critical_depth(q, g=G):
    '''Critical depth of a rectangular section [m]; the bracket for the entry depth.'''
    return (q**2 / g)**(1 / 3)


def entry_depth(H, q):
    '''
    The shallow, supercritical root of energy_head(h, q) = H [m].

    Both roots satisfy the energy equation. The supercritical one lies below the
    critical depth, and it is the branch the spillway delivers, so the bracket is
    closed at the critical depth.
    '''
    return brentq(lambda h: energy_head(h, q) - H, 1e-4, critical_depth(q))


def basin_state(d_b, design=None):
    '''The workflow evaluated for one trial basin depth d_b.'''
    design = design or DESIGN
    H = design.H0 + d_b                          # head above the basin floor
    h1 = entry_depth(H, design.q)                # supercritical root
    v1 = design.q / h1                           # continuity
    Fr1 = froude_number(v1, h1)                  # Task 1
    h2 = conjugate_depth(h1, Fr1)                # Task 2
    Rt = retention_ratio(design.h_tw, d_b, h2)   # Task 3
    return BasinState(d_b=d_b, H=H, h1=h1, v1=v1, Fr1=Fr1, h2=h2, Rt=Rt)
def search_basin_depth(db_start=1.0, db_min=0.0, db_max=20.0, max_iter=25,
                       tol=0.005, grid=0.25, verbose=True):
    '''
    Bisection on the basin depth d_b for the SHALLOWEST depth at which both
    engineering objectives are met, rounded up to the next `grid` metres.

    Returns the accepted BasinState and the full iteration history.
    '''
    d_b = db_start
    history = []
    if verbose:
        print(f"{'iter':>4}{'d_b [m]':>9}{'Fr1':>8}{'h1 [m]':>9}{'h2 [m]':>9}"
              f"{'Rt':>8}   verdict")
        print("-" * 66)

    for i in range(1, max_iter + 1):
        state = basin_state(d_b)
        history.append(state)
        if verbose:
            flags = []
            if not state.fr_ok:
                flags.append("Fr1 low" if state.Fr1 < FR_WINDOW[0] else "Fr1 high")
            if not state.rt_ok:
                flags.append("swept out" if state.Rt < RT_WINDOW[0] else "drowned")
            print(f"{i:>4}{state.d_b:>9.3f}{state.Fr1:>8.2f}{state.h1:>9.4f}"
                  f"{state.h2:>9.4f}{state.Rt:>8.3f}   "
                  f"{'accepted' if not flags else ', '.join(flags)}")

        # A deeper basin raises H, so the entry flow is shallower and faster: Fr1 and Rt increase monotonically with d_b. One bracket therefore serves both criteria, and each verdict says which way to move: a jump that is too gentle or swept out wants a deeper basin, one that is too fierce or drowned wants a shallower one. An acceptable trial is not the end of the search either, because a deeper basin than necessary costs excavation for no benefit, so it too narrows the bracket from above.
        if not state.fr_ok:
            if state.Fr1 < FR_WINDOW[0]:
                db_min = d_b  # jump too gentle: deepen the basin
            else:
                db_max = d_b  # jump too fierce: raise the floor
        elif state.Rt < RT_WINDOW[0]:
            db_min = d_b      # swept out: deeper basin
        else:
            db_max = d_b      # accepted or drowned: try a shallower one

        if db_max - db_min < tol:
            break
        d_b = 0.5 * (db_min + db_max)
    else:
        raise RuntimeError("no acceptable basin depth found in the search range")

    # db_max is the shallowest depth known to work; round it up to a buildable one.
    d_b = math.ceil(db_max / grid) * grid
    state = basin_state(d_b)
    history.append(state)
    if not (state.fr_ok and state.rt_ok):
        raise RuntimeError(f"rounding up to {d_b:.2f} m no longer meets the engineering objectives")
    if verbose:
        print(f"{'->':>4}{state.d_b:>9.3f}{state.Fr1:>8.2f}{state.h1:>9.4f}"
              f"{state.h2:>9.4f}{state.Rt:>8.3f}   shallowest, rounded up")
    return state, history


if TASKS_DONE:
    DESIGN_STATE, HISTORY = search_basin_depth()
    print(f"\naccepted basin depth d_b = {DESIGN_STATE.d_b:.3f} m")
else:
    DESIGN_STATE, HISTORY = None, []
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Kopfverlust über den Wechselsprung

Der Kopfverlust quantifiziert die Arbeit, die das Becken leistet. Dies ist keine Aufgabe: Die Designentscheidung wurde bereits von den beiden oben genannten Engineering-Zielen getroffen. Der Verlust wird hier berechnet, weil es der Grund ist, warum das Becken existiert. Die Kombination der Energiegleichung mit der konjugierten Tiefenbeziehung auf einem horizontalen Bett ergibt den Kopfverlust in geschlossener Form,

ΔH=H1−H2=(h2−h1)34h1h2>0\Delta H = H_1 - H_2 = \frac{(h_2 - h_1)^3}{4 h_1 h_2} > 0

ΔH\Delta H ist ein Verlust von Kopf und nicht von Energie: Es stellt die irreversible Umwandlung von mechanischer Mittelflussenergie in Turbulenzen und letztendlich in innere Energie dar, wobei die Gesamtenergie durchweg konserviert wird.

def head_loss(h1, h2):
    '''Given: head loss across the jump [m].'''
    return (h2 - h1)**3 / (4 * h1 * h2)


if TASKS_DONE:
    delta_H = head_loss(DESIGN_STATE.h1, DESIGN_STATE.h2)
    H1 = energy_head(DESIGN_STATE.h1, DESIGN.q)

    print(f"head loss           dH        = {delta_H:8.3f} m")
    print(f"energy head at 1    H1        = {H1:8.3f} m")
    print(f"relative loss       dH / H1   = {delta_H / H1:8.1%}")
else:
    delta_H = H1 = None
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Länge des Beckens und Scheuerschutz

Die angegebenen basin_lengths, die im angenommenen Design zusammen mit der Daumenregel (lj≈l_j \approx 6 h2h_2) bewertet wurden, gegen die die Beckenlänge überprüft werden kann.

if TASKS_DONE:
    f_peterka = peterka_f(DESIGN_STATE.Fr1)
    l_b, l_s = basin_lengths(DESIGN_STATE.h2, DESIGN_STATE.Fr1)

    print(f"Peterka multiplier  f_l  = {f_peterka:7.2f}  (at Fr1 = {DESIGN_STATE.Fr1:.2f})")
    print(f"basin length        l_b  = {l_b:7.2f} m   <- given")
    print(f"rule of thumb     6 h_2  = {6 * DESIGN_STATE.h2:7.2f} m"
          f"   ({abs(6 * DESIGN_STATE.h2 / l_b - 1):.1%} from l_b)")
    print(f"scour protection    l_s  = {l_s:7.2f} m   <- given")
else:
    f_peterka = l_b = l_s = None
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Ergebnisbewertungsflächen

Prüfung der technischen Zielsetzung

Die beiden Engineering-Ziele werden hier grafisch als Funktion der Beckentiefe db\mathbf{d_b} bewertet. Die schattierten Bänder in den Plots sind die Ziele und die gestrichelte vertikale Linie ist das akzeptierte Design. Nur ein Kriterium ist entscheidend: Fr1Fr_1 bleibt in seinem Band über alle Tests hinweg, aber rtr_{\mathrm{t}} tritt in sein Band ein und lässt es innerhalb von etwa 2,5 m Beckentiefe, zwischen 6,79 m und 9,31 m, wieder. Das Retentionskriterium wählt daher db\mathbf{d_b} aus, und es ist das Kriterium, das von der gegebenen Unterwassertiefe htwh_{tw} abhängt.

if TASKS_DONE:
    db_range = np.linspace(0.2, 20.0, 240)
    states = [basin_state(float(x)) for x in db_range]
    Fr_curve = np.array([s.Fr1 for s in states])
    Rt_curve = np.array([s.Rt for s in states])

    fig, axes = plt.subplots(1, 2, figsize=(9.4, 3.6), sharex=True)

    axes[0].axhspan(*FR_WINDOW, color=CYAN, alpha=0.18, lw=0)
    axes[0].plot(db_range, Fr_curve, color=BLUE, lw=2.2)
    axes[0].set_ylabel("$Fr_1$ at the basin entrance [-]")
    axes[0].set_title("Steady-jump window")
    axes[0].set_ylim(4.3, 9.3)
    axes[0].annotate("steady jump\n$4.5 \\leq Fr_1 < 9$", (0.8, 8.4),
                     color=BLUE, fontsize=8.5)

    axes[1].axhspan(Rt_curve.min(), RT_WINDOW[0], color=WARN, alpha=0.10, lw=0)
    axes[1].axhspan(*RT_WINDOW, color=CYAN, alpha=0.18, lw=0)
    axes[1].axhspan(RT_WINDOW[1], Rt_curve.max(), color=GREY, alpha=0.10, lw=0)
    axes[1].axhline(1.0, color=GREY, lw=0.8, ls=":")
    axes[1].plot(db_range, Rt_curve, color=BLUE, lw=2.2)
    axes[1].set_ylabel("retention ratio $r_\\mathrm{t}$ [-]")
    axes[1].set_title("Retention window")
    axes[1].set_ylim(Rt_curve.min(), Rt_curve.max())
    axes[1].annotate("jump swept out", (4.2, 0.83), color=WARN, fontsize=8.5)
    axes[1].annotate("retained", (0.8, 1.09), color=BLUE, fontsize=8.5)
    axes[1].annotate("jump drowned", (0.8, 1.42), color=GREY, fontsize=8.5)

    for ax in axes:
        ax.axvline(DESIGN_STATE.d_b, color=WARN, lw=1.4, ls="--")
        # the design variable is the one symbol set apart from the notation:
        # bold and in the warn colour, on the slides and here alike
        ax.set_xlabel("basin depth $\\mathbf{d_b}$ [m]", color=WARN)
        ax.set_xlim(0.2, 20.0)

    axes[0].plot([DESIGN_STATE.d_b], [DESIGN_STATE.Fr1], "o", color=WARN, ms=6, zorder=3)
    axes[1].plot([DESIGN_STATE.d_b], [DESIGN_STATE.Rt], "o", color=WARN, ms=6, zorder=3)
    axes[0].annotate(f"design\n$\\mathbf{{d_b}} = {DESIGN_STATE.d_b:.2f}$ m,"
                     f"  $Fr_1 = {DESIGN_STATE.Fr1:.2f}$",
                     (DESIGN_STATE.d_b, DESIGN_STATE.Fr1), textcoords="offset points",
                     xytext=(-104, 34), color=WARN, fontsize=8.5,
                     arrowprops=dict(arrowstyle="-", color=WARN, lw=0.8))
    axes[1].annotate(f"$r_\\mathrm{{t}} = {DESIGN_STATE.Rt:.3f}$",
                     (DESIGN_STATE.d_b, DESIGN_STATE.Rt), textcoords="offset points",
                     xytext=(40, -58), color=WARN, fontsize=8.5,
                     arrowprops=dict(arrowstyle="-", color=WARN, lw=0.8))

    fig.tight_layout()
    plt.show()
else:
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Längsabschnitt des Tosbeckens

Das angenommene Design wird in dem folgenden Codeblock zur Skala gezogen, mit dem nachgeschalteten Flussbett als Datum. Zwei Tiefen sind über dem Tosbeckenboden markiert, und der Unterschied zwischen ihnen ist Gegenstand der Retentionsprüfung:

  • Verfügbar ist die Tiefe, die durch das Versenkwasser und die Tiefe des Beckens bereitgestellt wird, htw+dbh_{tw} + \mathbf{d_b}.

  • Erforderlich ist die für den Wechselsprung erforderliche Tiefe, d.h. die konjugierte Tiefe h2h_2.

Their ratio is rtr_{\mathrm{t}}, and the surplus is the margin by which the jump is retained within the basin rather than on the bed downstream. Only the end depths of the jump follow from the 1d relations, so the surface drawn between cross sections 1 and 2 is indicative.

if TASKS_DONE:
    s = DESIGN_STATE
    floor = -s.d_b                       # basin floor, below the downstream riverbed
    h_avail = DESIGN.h_tw + s.d_b        # depth available over the floor
    h_need = floor + s.h2                # level the jump demands, above the datum
    top = DESIGN.H0                      # energy head above the un-sunk invert
    u = l_b / 24.8                       # one drawing unit, so the layout scales

    x_face, x_toe, x_end = -7.0 * u, 0.0, l_b
    x_tail = x_end + 0.6 * l_b
    x_j0, x_j1 = 0.26 * l_b, 0.62 * l_b

    # every label gets a white glow, so that one crossing a line stays readable
    glow = [pe.withStroke(linewidth=2.6, foreground="white")]

    fig, ax = plt.subplots(figsize=(9.4, 3.4))

    # --- structure and bed ---------------------------------------------------
    # the chute face descends from the spillway crest to the basin floor,
    # then the floor runs to the end sill and the river bed continues downstream
    ax.plot([x_face - 2.0 * u, x_face, x_face + 3.2 * u, x_toe, x_end, x_end, x_tail],
            [top, top, top, floor, floor, 0.0, 0.0],
            color=NAVY, lw=2.4, solid_joinstyle="round")

    # --- water body ----------------------------------------------------------
    xs = np.linspace(x_toe, x_tail, 500)
    bed = np.where(xs <= x_end, floor, 0.0)
    ramp = np.clip((xs - x_j0) / (x_j1 - x_j0), 0.0, 1.0)
    surface = (floor + s.h1) + (DESIGN.h_tw - floor - s.h1) * (
        0.5 - 0.5 * np.cos(math.pi * ramp))
    # a small crest at the end of the jump, so that the roller reads as a roller
    # rather than as a smooth asymptote; it is schematic, like the ramp itself
    surface = surface + 0.04 * (DESIGN.h_tw - floor - s.h1) * np.exp(
        -((xs - x_j1) / (0.09 * l_b))**2)

    ax.fill_between(xs, surface, bed, color=CYAN, alpha=0.30, lw=0)
    ax.plot(xs, surface, color=BLUE, lw=2.0)

    # --- dimensions ----------------------------------------------------------
    def dim(x, y0, y1, label, colour=NAVY, dx=0.7 * u, ha="left", frac=0.5,
            outside=False, ext=0.4 * u):
        '''
        A dimension between two levels, with a tick at each end so that what it
        measures from and to is unambiguous. outside=True puts the two heads
        beyond the span, pointing in, for a span too short to hold them.
        '''
        for y in (y0, y1):
            ax.plot([x - 0.5 * u, x + 0.5 * u], [y, y], color=colour, lw=0.8)
        if outside:
            ax.annotate("", (x, y0), (x, y0 - ext),
                        arrowprops=dict(arrowstyle="->", color=colour, lw=1.1))
            ax.annotate("", (x, y1), (x, y1 + ext),
                        arrowprops=dict(arrowstyle="->", color=colour, lw=1.1))
        else:
            ax.annotate("", (x, y0), (x, y1),
                        arrowprops=dict(arrowstyle="<->", color=colour, lw=1.1))
        if label:
            ax.text(x + dx, y0 + frac * (y1 - y0), label, color=colour,
                    fontsize=8.2, va="center", ha=ha, path_effects=glow)

    # the level the jump demands, carried downstream so that it can be compared
    # with the water surface; it starts right of the jump arrow, never under it
    ax.plot([0.48 * x_end, x_end + 6.0 * u], [h_need] * 2,
            color=WARN, lw=1.0, ls="--")
    dim(0.50 * x_end, floor, h_need,
        f"required\n$h_2 \\approx {s.h2:.1f}$ m", colour=WARN, dx=-0.7 * u,
        ha="right", frac=0.86)
    dim(0.86 * x_end, floor, DESIGN.h_tw,
        f"available\n$h_{{tw}}+\\mathbf{{d_b}} \\approx {h_avail:.1f}$ m",
        dx=-0.7 * u, ha="right")

    # the surplus is 1.1 m on a 22 m bar, so it is named rather than left to the eye
    x_gap = x_end + 4.6 * u
    dim(x_gap, h_need, DESIGN.h_tw, "", colour=WARN, outside=True)
    ax.annotate(f"surplus $\\approx {h_avail - s.h2:.1f}$ m\n"
                f"(water above the level $h_2$ demands)",
                (x_gap, DESIGN.h_tw + 0.6 * u), textcoords="offset points",
                xytext=(0, 32), color=WARN, fontsize=8.2, ha="center",
                arrowprops=dict(arrowstyle="->", color=WARN, lw=0.9),
                path_effects=glow)

    ax.annotate(f"$h_1 \\approx {s.h1:.1f}$ m",
                (x_toe + 3.2 * u, floor + 0.5 * s.h1), textcoords="offset points",
                xytext=(2, 54), color=NAVY, fontsize=8.2,
                arrowprops=dict(arrowstyle="->", color=NAVY, lw=0.9),
                path_effects=glow)
    dim(x_end + 2.4 * u, floor, 0.0,
        f"$\\mathbf{{d_b}} \\approx {s.d_b:.1f}$ m", colour=WARN, outside=True,
        ext=0.8 * u, dx=1.2 * u)
    dim(x_end + 9.0 * u, 0.0, DESIGN.h_tw,
        f"$h_{{tw}} \\approx {DESIGN.h_tw:.1f}$ m")

    ax.annotate("", (x_toe, floor - 0.365 * s.h2), (x_end, floor - 0.365 * s.h2),
                arrowprops=dict(arrowstyle="<->", color=NAVY, lw=1.1))
    ax.text(0.5 * x_end, floor - 0.62 * s.h2,
            f"basin length $l_b \\approx {l_b:.1f}$ m",
            color=NAVY, fontsize=8.2, ha="center", path_effects=glow)

    # --- labels --------------------------------------------------------------
    ax.axhline(0.0, color=GREY, lw=0.7, ls=":")
    # the arrow points at the crest of the roller, and stays above the dashed
    # level line so that it can cross neither that line nor the "required" label
    x_jump = x_j1
    y_jump = float(np.interp(x_jump, xs, surface))
    ax.text(x_jump, y_jump + 1.75 * u, "hydraulic jump", color=NAVY, fontsize=9,
            ha="center", style="italic", path_effects=glow)
    ax.annotate("", (x_jump, y_jump + 0.25 * u), (x_jump, y_jump + 1.45 * u),
                arrowprops=dict(arrowstyle="->", color=NAVY, lw=0.9))
    ax.text(x_face - 1.6 * u, top + 0.12 * s.h2,
            f"from the spillway chute,  $H_0 \\approx {top:.1f}$ m",
            color=NAVY, fontsize=8.2, path_effects=glow)

    ax.set_xlim(x_face - 2.5 * u, x_tail + 1.0 * u)
    ax.set_ylim(floor - 0.75 * s.h2, top + 0.55 * s.h2)
    ax.set_aspect("equal")
    ax.set_xlabel("distance along the basin [m]")
    ax.set_ylabel("level above the\ndownstream bed [m]")
    ax.spines["left"].set_visible(True)
    fig.tight_layout()
    plt.show()
else:
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Entwurfszusammenfassung

if TASKS_DONE:
    s = DESIGN_STATE
    rows = [
        ("given", "spillway design flow", "Q", DESIGN.Q, "m3/s"),
        ("given", "unit discharge", "q", DESIGN.q, "m2/s"),
        ("given", "energy head above the invert", "H0", DESIGN.H0, "m"),
        ("given", "tailwater depth", "h_tw", DESIGN.h_tw, "m"),
        ("design", "basin depth", "d_b", s.d_b, "m"),
        ("design", "energy head above the floor", "H", s.H, "m"),
        ("design", "entry depth", "h1", s.h1, "m"),
        ("design", "entry velocity", "v1", s.v1, "m/s"),
        ("design", "entry Froude number", "Fr1", s.Fr1, "-"),
        ("design", "conjugate depth", "h2", s.h2, "m"),
        ("design", "retention ratio", "Rt", s.Rt, "-"),
        ("result", "head loss", "dH", delta_H, "m"),
        ("result", "relative head loss", "dH/H1", 100 * delta_H / H1, "%"),
        ("result", "basin length", "l_b", l_b, "m"),
        ("result", "scour protection length", "l_s", l_s, "m"),
    ]

    print(f"{'':8}{'quantity':<34}{'symbol':<14}{'value':>10}  unit")
    group = None
    for kind, name, symbol, value, unit in rows:
        if kind != group:
            print("-" * 70)
            group = kind
        print(f"{kind:<8}{name:<34}{symbol:<14}{value:>10.3f}  {unit}")

    print("=" * 70)
    print(f"windows: Fr1 in [{FR_WINDOW[0]}, {FR_WINDOW[1]}) -> "
          f"{'met' if s.fr_ok else 'NOT met'};  "
          f"Rt in [{RT_WINDOW[0]}, {RT_WINDOW[1]}] -> "
          f"{'met' if s.rt_ok else 'NOT met'}")
else:
    print("Complete Tasks 1 to 3, then re-run this cell.")
Complete Tasks 1 to 3, then re-run this cell.

Weitere Fragen

Jeder der folgenden erfordert eine einzige Änderung an einem Eingang des oben geschriebenen Codes, um zu untersuchen, wie Unsicherheiten und Änderungen in den Randbedingungen auf den Wechselsprung wirken, und damit auf die Tosbeckenkonstruktion.

  1. Was passiert, wenn die Schwanzwassertiefe niedriger ist? Recompute mit der um 2 m reduzierten Schwalbenwassertiefe und alles andere unverändert, d.h. handbasin_state a DesignData, dessen h_tw 2 m kleiner ist. Bestimmen Sie den Effekt auf rtr_{\mathrm{t}} und seine Folge für das nachgeschaltete Flussbett und identifizieren Sie, wie sich die Wechselsprungposition ändert.

  2. ** Wie verhalten sich die Sprünge unter verschiedenen Entladungssszenarien?** Das Becken ist für eine 500-jährige Überschwemmung konzipiert, arbeitet aber meist mit viel geringeren Entladungen. So re-evaluieren Sie basin_state mit einer DesignData, deren qhalbiert ist, und bestimmen Sie, ob der Wechselsprung stabil bleibt und bleibt erhalten.

Einschränkungen der Vereinfachung

Diese Berechnungsvorlage verwendet vereinfachte 1d-Gleichungen, und ihre Ergebnisse unterliegen daher einer erheblichen Unsicherheit, bezogen auf (aber nicht auf):

  • Hydralogie, das ist die Ableitung der Designflut;

  • die Schwalbenwasser-Ratingkurve anstelle der rechteckigen Manning-Optimierung;

  • Last- und Ausfallszenarien, einschließlich Überschwemmungen, die die Entleerung des Ablaufs des Ablaufs des Ablaufs des Ablaufs, den Teil-Gate-Betrieb und die Schleusentore neben dem Ablauf des Ablaufs übersteigen;

  • Kavitation, Luftentnahme, Auftrieb, schwankende Drücke und Ermüdung der Struktur;

  • stromabwärts der geschützten Länge eine Beurteilung der Geruchs- und Flussbettstabilität;

  • geotechnische Analyse und Konstruktion;

  • Fischpassage und Sedimentmanagement.

Quellen