Dieses Notebook fasst zwei zusammengehörige Aufgaben zusammen:
Hydraulische Vorbemessung des Wehrs (Poleni, (n‑1)‑Regel)
Tosbeckenbemessung (iterativer Workflow nach Bollrich / Peterka)
Lernziele:
Rechengänge sehen;
Kernannahmen verstehen;
Größenordnungen prüfen können;
Grenzen von Vereinfachungen erkennen.
import math
from scipy.optimize import brentq
from pprint import pprintTeil 1: Hydraulische Vorbemessung¶
Inhalte¶
Es wird eine überschlägige hydraulische Vorbemessung eines vollregelnden Wehrs durchgeführt:
Wahl eines plausiblen Bemessungsfalls
Vorbemessung der erforderlichen lichten Wehrbreite
Aufteilung in Wehrfelder
Nachweis der (n‑1)‑Regel (DIN 19700)
Grober Check von Freibord
Gegebene Daten und Notation¶
Poleni-Gleichung für den freien Überfall:
Effektive Überflussbreite (Einschnürung durch Pfeiler):
Herleitung: mit Pfeileräquivalenten
| Symbol | Bedeutung |
|---|---|
| Durchfluss (m³/s) | |
| wirksame Wehrbreite (m) | |
| Überfallhöhe (m) | |
| Abminderungsbeiwert bei unvollkommenem Überfall (–) | |
| Abflussbeiwert (–) | |
| zulässige Überfallhöhe bei BHQ₁ (m über Wehrkrone) | |
| höchster zulässiger Oberwasserstand bei BHQ₁ (m ü. NHN); | |
| erforderlicher Freibord (m) | |
| Anzahl Wehrfelder | |
| Breite eines Wehrfelds (m) | |
| Breite eines Pfeilers (m) | |
| Einschnürungsbeiwert (–) |
Eingangsgrößen¶
BHQ1 = 220.0 # m³/s Bemessungshochwasser 1 (Regelfall)
BHQ2 = 280.0 # m³/s Bemessungshochwasser 2 (Kontrollfall)
# h_ue_zul: zulässige Überfallhöhe über Wehrkrone bei BHQ1 (= z_H - z_Kr, relativ)
# Nicht zu verwechseln mit z_H (absolutem Oberwasserstand in m ü. NHN, vgl. Notation)
h_ue_zul = 1.0 # m
f = 1.0 # m Freibord (DIN 19700: f ≥ 0,5 m bei BHQ1)
mu = 0.5 # Abflussbeiwert (bewegliches Wehr, scharfkantig)
c = 1.0 # Abminderungsbeiwert (vollkommener Überfall, Anfangswert)
xi_pf = 0.10 # Einschnürungsbeiwert (abgerundete Pfeilerköpfe)
b_F = 10.0 # m gewählte Wehrfeldbreite (technisch bedingt)
b_pf = b_F * 0.225 # m Pfeilerbreite (Formel entspricht Drucksegmentverschlussmittel)
g = 9.81 # m/s²
print(f"Pfeilerbreite b_pf = {b_pf:.2f} m")Pfeilerbreite b_pf = 2.25 m
Poleni & erforderliche Wehrbreite¶
Entwurfsziel (DIN 19700, (n‑1)‑Regel):
Mit aktiven Wehrfeldern muss BHQ₁ abgeführt werden, ohne dass .
Auflösung der Poleni-Gleichung nach :
Auflösung nach (für gegebene Breite):
Hilfsfunktionen für Poleni-Solver¶
c_pol = (2/3) * mu * math.sqrt(2 * g) # kombinierter Poleni-Koeffizient ohne b und h_ue
def b_eff_von_Q(Q, h_ue, c_abd=1.0):
"""Erforderliche effektive Wehrbreite für gegebenen Durchfluss."""
return Q / (c_abd * c_pol * h_ue**1.5)
def h_ue_von_Q(Q, b_eff, c_abd=1.0):
"""Überfallhöhe bei gegebenem Durchfluss und effektiver Breite."""
return (Q / (c_abd * c_pol * b_eff))**(2/3)
def b_eff_n_felder(n_aktiv, h_ue):
"""Effektive Breite für n_aktiv nebeneinanderliegende Felder (Einschnürung berücksichtigt)."""
return n_aktiv * (b_F - 2 * xi_pf * h_ue)Erforderliche Breite und Anzahl Wehrfelder¶
# Gesamte b_eff für (n-1)-Fall muss b_eff_erf >= b_eff_von_Q(BHQ1, h_ue_zul) erfüllen
b_eff_erf = b_eff_von_Q(BHQ1, h_ue_zul, c)
b_F_eff = b_F - 2 * xi_pf * h_ue_zul # wirksame Feldbreite je Feld
n = 5 # Gesamtanzahl Wehrfelder
n_eff = n-1 # (n-1)-Regel
print(f"Kombinierter Poleni-Koeffizient c_pol = {c_pol:.4f}")
print(f"Erforderliche b_eff (n-1-Fall) = {b_eff_erf:.2f} m")
print(f"Wirksame Feldbreite b_F_eff = {b_F_eff:.2f} m")
print(f"Benötigte (n-1)-Felder = {n_eff}")
print(f"Gewählte Wehrfeldanzahl n = {n}")Kombinierter Poleni-Koeffizient c_pol = 1.4765
Erforderliche b_eff (n-1-Fall) = 149.00 m
Wirksame Feldbreite b_F_eff = 9.80 m
Benötigte (n-1)-Felder = 4
Gewählte Wehrfeldanzahl n = 5
Wehrabmessungen und Breite¶
n_pfeiler = n_eff - 1 # Zwischenpfeiler
b_licht = n_eff * b_F # lichte Gesamtbreite (nur Felder)
b_pfeiler = n_pfeiler * b_pf # Summe Pfeilerbreiten
b_gesamt = b_licht + b_pfeiler # Gesamtbreite inkl. Pfeiler
print(f"Anzahl Zwischenpfeiler : {n_pfeiler}")
print(f"Lichte Gesamtbreite : {b_licht:.1f} m")
print(f"Summe Pfeilerbreiten : {b_pfeiler:.2f} m")
print(f"Bauwerksbreite gesamt : {b_gesamt:.2f} m")Anzahl Zwischenpfeiler : 3
Lichte Gesamtbreite : 40.0 m
Summe Pfeilerbreiten : 6.75 m
Bauwerksbreite gesamt : 46.75 m
(n‑1) -- Nachweis -- hier: (n-2)¶
Bedingung: Mit aktiven Feldern muss gelten:
Zusätzlich werden BHQ₁ und BHQ₂ mit allen Feldern geprüft.
faelle = [
("BHQ1, n Felder", BHQ1, n),
("BHQ1, (n-1) Felder", BHQ1, n_eff),
("BHQ2, n Felder", BHQ2, n),
]
print(f"{'Fall':<28} {'n_akt':>5} {'b_eff':>8} {'h_ü':>7} {'≤ h_ü,zul?':>10}")
print("-" * 62)
for label, Q, n_akt in faelle:
h_ue_iter = h_ue_zul
for _ in range(20):
beff = b_eff_n_felder(n_akt, h_ue_iter)
h_ue_neu = h_ue_von_Q(Q, beff, c)
if abs(h_ue_neu - h_ue_iter) < 1e-6:
break
h_ue_iter = h_ue_neu
ok = "OK" if h_ue_iter <= h_ue_zul else "!!"
print(f"{label:<28} {n_akt:>5} {beff:>8.2f} {h_ue_iter:>7.3f} {ok:>10}")
print(f"\n h_ü,zul = {h_ue_zul:.2f} m (max. zulässige Überfallhöhe bei BHQ1)")
# h_ue bei BHQ1 mit allen n Feldern (für Zusammenfassung Teil 1)
h_ue_n = h_ue_zul
for _ in range(20):
beff_n = b_eff_n_felder(n, h_ue_n)
h_ue_n = h_ue_von_Q(BHQ1, beff_n, c)Fall n_akt b_eff h_ü ≤ h_ü,zul?
--------------------------------------------------------------
BHQ1, n Felder 5 47.87 2.132 !!
BHQ1, (n-1) Felder 4 38.01 2.486 !!
BHQ2, n Felder 5 47.48 2.517 !!
h_ü,zul = 1.00 m (max. zulässige Überfallhöhe bei BHQ1)
Freibord-Check¶
Kronenhöhe =
# h_ue bei BHQ1, (n-1)-Felder (konservativster Fall)
h_ue_n1 = h_ue_zul
for _ in range(20):
beff_n1 = b_eff_n_felder(n - 1, h_ue_n1)
h_ue_n1 = h_ue_von_Q(BHQ1, beff_n1, c)
freibord_errechnet = h_ue_zul - h_ue_n1
kronenhoehe = h_ue_zul + f
print(f"h_ü bei BHQ1, (n-1)-Felder : {h_ue_n1:.3f} m")
print(f"Freibord über h_ü bis h_ü,zul : {freibord_errechnet:.3f} m")
print(f"Kronenhöhe (= h_ü,zul + f) : {kronenhoehe:.2f} m über Wehrschwelle")
freibord_kriterium = 'OK' if f >= abs(freibord_errechnet) else 'Nicht erfüllt'
print(f"Freibordanforderung: " + freibord_kriterium)h_ü bei BHQ1, (n-1)-Felder : 2.486 m
Freibord über h_ü bis h_ü,zul : -1.486 m
Kronenhöhe (= h_ü,zul + f) : 2.00 m über Wehrschwelle
Freibordanforderung: Nicht erfüllt
Teil 2: Tosbeckenbemessung¶
Konzept¶
Ziel ist es, den Wechselsprung innerhalb des Tosbeckens zu erzwingen. Konstruktiver Freiheitsgrad: Tosbeckeneintiefung (in m).
Einstaugrad muss im Zielbereich liegen:
Iterativer Algorithmus (vgl. Vorlesungsfolie):
| Schritt | Inhalt |
|---|---|
| A | festlegen (Startwert) |
| B | , aus Bernoulli-Gleichung (Energiehöhe ) |
| C | |
| D | ? → Nein: anpassen |
| E | aus Manning–Strickler bzw. gemessen |
| F | (Bélanger) |
| G | ? → Nein: anpassen |
| + | und berechnen |
Zusätzliche Eingangsgrößen Tosbecken¶
Neben den Wehrparametern werden benötigt:
| Symbol | Bedeutung |
|---|---|
| Anzahl Wehrfelder in Teil 2 (Frage 2) | |
| Wehrhöhe über UW-Sohle (m) | |
| Strickler-Beiwert der UW-Strecke (m¹/³/s) | |
| Sohlgefälle der UW-Strecke (–) | |
| Breite der UW-Strecke (m) | |
| Gesamtenergielinie über Tosbeckensohle: |
Der Einheitsdurchfluss für die Tosbeckenbemessung wird konservativ aus dem -Felder-Fall berechnet (DIN 19700, (n‑1)‑Regel): Mit einem ausgefallenen Feld steigt je Feldbreite — das ist der maßgebende Lastfall für das Tosbecken.
w_wehr = 5.00 # m Wehrhöhe über UW-Sohle
k_st = 32.0 # m^1/3/s Strickler-Beiwert UW-Strecke
I_E = 4e-4 # - Sohlgefälle UW-Strecke
b_u = 150.0 # m Breite UW-Strecke (Rechteckprofil)
# Einheitsdurchfluss für Tosbecken: (n-1)-Fall (DIN 19700)
for _ in range(20):
beff_n1 = b_eff_n_felder(n_eff - 1, h_ue_zul)
h_ue_n1 = h_ue_von_Q(BHQ1, beff_n1, c)
q = BHQ1 / beff_n1 # m²/s Einheitsdurchfluss im (n-1)-Felder-Fall
print(f"Anzahl Wehrfelder (Teil 2): n_tos = {n_eff}")
print(f"(n_tos-1)-Wehrbreite (BHQ1): b_eff = {beff_n1:.2f} m, h_ü = {h_ue_zul:.3f} m")
print(f"Einheitsdurchfluss q = BHQ1 / b_eff = {q:.3f} m²/s")Anzahl Wehrfelder (Teil 2): n_tos = 4
(n_tos-1)-Wehrbreite (BHQ1): b_eff = 29.40 m, h_ü = 1.000 m
Einheitsdurchfluss q = BHQ1 / b_eff = 7.483 m²/s
Unterwassertiefe durch Manning-Strickler (Vorbereitung Schritt E)¶
Für ein Rechteckprofil gilt:
Ein numerischer 1D-Gleichungslöser für die Manning kann mittels folgender Funktion definiert und in der Folge aufgerufen werden:
def Q_manning(h, b, k, I):
A = b * h
R = (b * h) / (b + 2 * h)
return k * A * R**(2/3) * math.sqrt(I)
# brentq sucht h in [0.01, 20] m mit Q_manning(h) = BHQ1
h_u = brentq(lambda h: Q_manning(h, b_u, k_st, I_E) - BHQ1, 0.01, 20.0)
print(f"Unterwassertiefe h_u = {h_u:.3f} m")
print(f"Probe: Q_Manning = {Q_manning(h_u, b_u, k_st, I_E):.2f} m³/s (Soll: {BHQ1} m³/s)")Unterwassertiefe h_u = 1.659 m
Probe: Q_Manning = 220.00 m³/s (Soll: 220.0 m³/s)
Schritte A bis G: Iterative Tosbecken-Bemessung¶
Schritt B Herleitung von und ¶
Energiehöhe über Tosbeckensohle (Bernoulli, vernachlässige da 1,0 m/s):
Am schießenden Querschnitt 1 (Tosbeckeneinlauf):
Kodieren des Arbeitsablaufs¶
Der Arbeitsablauf (Workflow) der Tosbeckenbemessung sowie die Ermittlung des k-Faktor in Abhängigkeit der Froude-Zahl wird in zwei Funktionen definiert, mit als Eingangsvariable:
def tosbecken_check(e):
"""
Führt Schritte A-G des Tosbecken-Workflows für gegebene Eintiefung e durch.
Gibt (Fr1, epsilon, h1, h2, ok_Fr, ok_eps) zurück.
"""
# Schritt B: h1 aus Bernoulli (kleine, schießende Wurzel)
H_ges = h_ue_zul + w_wehr + e
# Suche h1 < h_grenz (kritische Tiefe) = (q**2/g)^(1/3)
h_krit = (q**2 / g)**(1/3)
h1 = brentq(lambda h: h + q**2 / (2 * g * h**2) - H_ges, 1e-4, h_krit)
v1 = q / h1
# Schritt C: Froude-Zahl
Fr1 = v1 / math.sqrt(g * h1)
# Schritt D: Fr1-Check
ok_Fr = 4.5 <= Fr1 < 9.0
# Schritt F: konjugierte Tiefe h2 (Belanger)
h2 = (h1 / 2) * (math.sqrt(1 + 8 * Fr1**2) - 1)
# Schritt G: Einstaugrad
eps = (h_u + e) / h2
ok_eps = 1.05 <= eps <= 1.15
return Fr1, eps, h1, h2, ok_Fr, ok_eps
# k-Faktor für Tosbeckenlänge (vgl. Peterka 1984 / USBR)
def k_faktor(Fr1):
if Fr1 < 2.4: return 4.8
elif Fr1 < 4.0: return 4.8 + (Fr1 - 2.4) / (4.0 - 2.4) * (5.8 - 4.8)
elif Fr1 < 5.0: return 5.8 + (Fr1 - 4.0) * (6.0 - 5.8)
elif Fr1 < 6.0: return 6.0
elif Fr1 <= 11.0: return 6.13
else: return 6.0Iterieren über ¶
Die Eintiefung kann nun mittels der zuvor definierten Funktionen berechnet werden, basierend auf einem Startwert und einem Wertebereich:
e_test = 2.0 # m Startwert (Schritt A)
e_min = 0.0 # m Suchbereich untere Grenze
e_max = 3.0 # m Suchbereich obere Grenze
iterationen = []
print(f"{'Iter':>4} {'e [m]':>7} {'Fr1':>6} {'Fr-OK':>6} {'h1 [m]':>8} {'h2 [m]':>8} {'ε':>6} {'ε-OK':>6}")
print("-" * 65)
for i in range(1, 15):
Fr1, eps, h1, h2, ok_Fr, ok_eps = tosbecken_check(e_test)
iterationen.append((e_test, Fr1, eps, h1, h2, ok_Fr, ok_eps))
fr_sym = "OK" if ok_Fr else "Nicht erfüllt"
eps_sym = "OK" if ok_eps else "Nicht erfüllt"
print(f"{i:>4} {e_test:>7.3f} {Fr1:>6.2f} {fr_sym:>6} {h1:>8.4f} {h2:>8.4f} {eps:>6.3f} {eps_sym:>6}")
if ok_Fr and ok_eps:
print("\n >>> Kriterien erfüllt: Iteration beendet.")
break
# Anpassungsstrategie (Bisektionslogik)
if not ok_Fr:
# Fr1 < 4.5 >>> e zu groß; Fr1 ≥ 9.0 >>> e zu klein
if Fr1 < 4.5:
e_max = e_test
else: # Fr1 >= 9.0
e_min = e_test
else:
# ok_Fr = True, aber ok_eps = False
if eps > 1.15: # zu viel Einstau >>> e verringern
e_max = e_test
else: # eps < 1.05 >>> zu wenig Einstau >>> e erhöhen
e_min = e_test
e_test = 0.5 * (e_min + e_max) # Bisektion
# Endwerte speichern
e_opt = e_test
Fr1_opt, eps_opt, h1_opt, h2_opt, _, eps_test = tosbecken_check(e_opt)Iter e [m] Fr1 Fr-OK h1 [m] h2 [m] ε ε-OK
-----------------------------------------------------------------
1 2.000 4.87 OK 0.6219 3.9846 0.918 Nicht erfüllt
2 2.500 5.13 OK 0.6011 4.0678 1.022 Nicht erfüllt
3 2.750 5.25 OK 0.5915 4.1076 1.073 OK
>>> Kriterien erfüllt: Iteration beendet.
Tosbeckenlänge und Kolkschutzlänge ¶
Nach Peterka (1958/1984):
| 2,4 | 4 | 5 | 6–11 | 14 | |
|---|---|---|---|---|---|
| 4,8 | 5,8 | 6 | 6,13 | 6 |
Tosbecken- und Kolkschutzlänge können durch Aufrufen der oben definierten Funktion für die Abschätzung des k-Faktors berechnet werden:
k = k_faktor(Fr1_opt)
l_T = k * h2_opt
l_K = 3.5 * l_T
print(f"Optimierte Eintiefung e = {e_opt:.3f} m")
print(f"Schießende Tiefe h1 = {h1_opt:.4f} m")
print(f"Froude-Zahl Fr1 = {Fr1_opt:.2f}")
print(f"Konjugierte Tiefe h2 = {h2_opt:.3f} m")
print(f"Unterwassertiefe h_u = {h_u:.3f} m")
print(f"Einstaugrad ε = {eps_opt:.3f} (Ziel: 1,05-1,15)")
print()
print(f"k-Faktor (Fr1={Fr1_opt:.1f}) k = {k:.2f}")
print(f"Tosbeckenlänge l_T = {l_T:.2f} m")
print(f"Kolkschutzlänge l_K = {l_K:.2f} m")Optimierte Eintiefung e = 2.750 m
Schießende Tiefe h1 = 0.5915 m
Froude-Zahl Fr1 = 5.25
Konjugierte Tiefe h2 = 4.108 m
Unterwassertiefe h_u = 1.659 m
Einstaugrad ε = 1.073 (Ziel: 1,05-1,15)
k-Faktor (Fr1=5.3) k = 6.00
Tosbeckenlänge l_T = 24.65 m
Kolkschutzlänge l_K = 86.26 m
Zusammenfassung der hydraulischen Durchbildung inkl. Tosbeckenbemessung¶
summary = {
"Hydraulik_Wehr": {
"BHQ1 (m3/s)": BHQ1,
"BHQ2 (m3/s)": BHQ2,
"h_ue_zul (m)": h_ue_zul,
"Freibord (m)": freibord_errechnet,
"Lichte Breite (m)": round(b_licht, 2),
"Gesamtbreite (m)": round(b_gesamt, 2),
"hü bei BHQ1 mit n Feldern (m)": round(h_ue_n, 3),
"hü bei BHQ1 mit (n-1) Feldern (m)": round(h_ue_n1, 3),
"Kronenhöhe (m)": round(kronenhoehe, 2),
"Nachweis Hochwassersicherheit": freibord_kriterium,
},
"Tosbecken": {
"hu (m)": round(h_u, 3),
"eopt (m)": round(e_opt, 3),
"h1 (m)": round(h1_opt, 4),
"h2 (m)": round(h2_opt, 3),
"Fr1": round(Fr1_opt, 2),
"epsilon": round(eps_opt, 3),
"k": round(k, 2),
"lT (m)": round(l_T, 2),
"lK (m)": round(l_K, 2),
"Energieumwandlung im Tosbecken": 'OK' if eps_test else 'Nicht erfüllt',
},
}
pprint(summary){'Hydraulik_Wehr': {'BHQ1 (m3/s)': 220.0,
'BHQ2 (m3/s)': 280.0,
'Freibord (m)': -1.4861232406301172,
'Gesamtbreite (m)': 46.75,
'Kronenhöhe (m)': 2.0,
'Lichte Breite (m)': 40.0,
'Nachweis Hochwassersicherheit': 'Nicht erfüllt',
'h_ue_zul (m)': 1.0,
'hü bei BHQ1 mit (n-1) Feldern (m)': 2.951,
'hü bei BHQ1 mit n Feldern (m)': 2.132},
'Tosbecken': {'Energieumwandlung im Tosbecken': 'OK',
'Fr1': 5.25,
'eopt (m)': 2.75,
'epsilon': 1.073,
'h1 (m)': 0.5915,
'h2 (m)': 4.108,
'hu (m)': 1.659,
'k': 6.0,
'lK (m)': 86.26,
'lT (m)': 24.65}}
Grenzen der Vereinfachung¶
Dieses Notebook ersetzt nicht:
standortbezogene Hydrologie (BHQ-Bestimmung)
1D/2D-Wasserstandsberechnungen für mehrere Abflüsse
die Rechteckannahme für das Unterwasser ist schwach und sollte durch genauere hydraulische und Geländedaten ersetzt werden
Nachweise für mehrere Last- und Ausfallfälle (a > 1, BHQ₂, ...)
geotechnische Nachweise
konstruktive Bemessung nach den jeweils einschlägigen Regeln
Nachweise für Fischdurchgängigkeit, Sedimentmanagement und Betriebssicherheit