import math
import numpy as np
import matplotlib.pyplot as plt
n = 0.02 # Manning の祖度係数
So = 1 / 1000 # 河床勾配
B = 200 # 川幅 [m]
Q = 2000 # 流量 [cu.m/s]
h = 5 # 下流端の水深 [m]
z = 0 # 下流端の河床高 [m]
dx = 500 # 計算距離刻み [m]
L = 5000 # 流路長 [m]
sz = L // dx + 1
xs = np.linspace(0, L, sz)
zs = xs * So
Hs = np.empty(sz)
# 汎用変数
p = 10 / 3
qq = (Q / B)**2
qq_2g = qq / 19.6
K = n * n * qq * dx / 2
# 境界条件
H = z + h; Hs[0] = H
cnst = H + qq_2g / (h * h) + K / math.pow(h, p)
for i, z in zip(range(1, sz), zs[1:]):
cnst -= z
# 水深の初期推定値として直下の計算点の水深を当てる
while True:
vv_2g = qq_2g / (h * h) # 速度水頭
Sfdx_2 = K / math.pow(h, p) # 損失水頭
er = h + vv_2g - Sfdx_2 - cnst # 残差
if abs(er) < 1e-4: break
# ニュートン法による補正
h -= er / (1 + (p * Sfdx_2 - 2 * vv_2g) / h)
H = h + z; Hs[i] = H
cnst = H + vv_2g + Sfdx_2
plt.plot(xs, zs, label="$z_b$")
plt.plot(xs, Hs, label="$H$")
plt.xlabel("$x$ (m)")
plt.ylabel("$z_b, H$ (m)")
plt.legend()
plt.grid()
plt.show()
print("|$x$<br>[m]|$z$<br>[m]|$H$<br>[m]|")
print("|---|---|---|")
for i in range(sz):
print(f"|{xs[i]:.0f}|{zs[i]:.1f}|{Hs[i]:.3f}|")
download