ポアズイユ流れ:解析解の導出と有限差分法による検証
最も単純な粘性流れの完全な解析解を手計算で導出し、FDコードで数値的な正確さを検証するCFD入門ベンチマーク
ポアズイユ流れ(Poiseuille flow)は、2枚の平行平板間や円形管の内部で、一定の圧力勾配によって駆動される完全発達した層流のことです。 厳密な解析解が存在するため、CFDコード検証の最初のテストケースとして、世界中のあらゆる教科書に登場します。
今日は、チャンネル流れ(2D平板間)を対象に解析解を段階的に導出し、簡単な有限差分(FD)コードを作成して収束次数を確認します。
問題の設定#
形状および境界条件#
2枚の無限平行平板間の完全発達した層流を考えます。
- チャンネル半幅:(平板は に位置)
- 流れ方向:(無限に長いと仮定)
- 境界条件:両壁面で no-slip
- 駆動源:一定の圧力勾配 ( は定数)
支配方程式#
完全発達した流れなので です。 方向のナビエ・ストークス方程式は以下のようになります。
完全発達の条件()を適用すると:
解析解の導出#
ステップ1:常微分方程式(ODE)への単純化#
ステップ2:1回目の積分#
ステップ3:2回目の積分#
ステップ4:境界条件の適用#
:
0 = -\frac{C}{2} h^2 + A_1 h + A_2 \tag{1}
:
0 = -\frac{C}{2} h^2 - A_1 h + A_2 \tag{2}
(1) (2) より:(対称性)
(1) (2) より:
最終的な解析解#
チャンネル中心()での最大速度:
物理的解釈#
速度プロファイル#
解析解は**放物線(parabola)**分布となります。壁面の摩擦が流れの断面全体に均一に伝わり、中心で最大、壁面で0になります。
無次元速度 は、チャンネルの半幅 や粘度 に関わらず一定となる普遍的なプロファイルです。
壁面せん断応力#
(大きさ:) 圧力勾配が大きいほど、またチャンネルが広いほど、壁面摩擦は大きくなります。
体積流量#
これは ハーゲン・ポアズイユの法則 の2D版と呼ばれます。流量は に比例するため、チャンネル幅が2倍になると流量は8倍に増加します。
Pythonによる解析解の可視化#
import numpy as np
import matplotlib.pyplot as plt
# パラメータ
h = 1.0 # チャンネル半幅 [m]
G = 1.0 # 圧力勾配 [Pa/m]
mu = 1.0 # 粘性係数 [Pa·s]
# 格子
y = np.linspace(-h, h, 400)
u_exact = G / (2 * mu) * (h**2 - y**2)
u_max = G * h**2 / (2 * mu)
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
# 速度プロファイル (横方向)
axes[0].plot(u_exact / u_max, y / h, "k-", lw=2)
axes[0].fill_betweenx(y / h, u_exact / u_max, alpha=0.15)
axes[0].axvline(0, color="gray", lw=0.8, ls="--")
axes[0].set_xlabel(r"$u / u_{\max}$")
axes[0].set_ylabel(r"$y / h$")
axes[0].set_title("ポアズイユ速度プロファイル")
axes[0].set_xlim(-0.05, 1.1)
# せん断応力分布
tau = mu * np.gradient(u_exact, y)
axes[1].plot(tau / G / h, y / h, "r-", lw=2, label=r"$\tau / \tau_w$")
axes[1].axvline(0, color="gray", lw=0.8, ls="--")
axes[1].set_xlabel(r"$\tau / \tau_w$")
axes[1].set_ylabel(r"$y / h$")
axes[1].set_title("せん断応力分布 (線形)")
axes[1].legend()
plt.tight_layout()
plt.savefig("poiseuille_profile.png", dpi=150)
plt.show()有限差분法による数値検証#
を2次中心差分で離散化します。一様格子 :
境界条件:
これを三対角行列(tridiagonal matrix)の連立方程式として書くと:
Pythonでの実装#
import numpy as np
def solve_poiseuille_fd(N, h=1.0, G=1.0, mu=1.0):
"""
N : 内部格子点数 (境界を除く)
returns (y, u_num, u_exact, L2_error)
"""
dy = 2 * h / (N + 1)
y_inner = np.linspace(-h + dy, h - dy, N)
# 三対角係数行列
diag = -2 * np.ones(N)
upper = np.ones(N - 1)
lower = np.ones(N - 1)
A = (np.diag(diag) + np.diag(upper, k=1) + np.diag(lower, k=-1))
rhs = -G * dy**2 / mu * np.ones(N)
u_num = np.linalg.solve(A, rhs)
# 境界を含む全格子
y_full = np.concatenate([[-h], y_inner, [h]])
u_full = np.concatenate([[0.0], u_num, [0.0]])
u_exact = G / (2 * mu) * (h**2 - y_full**2)
L2 = np.sqrt(np.mean((u_full - u_exact)**2))
return y_full, u_full, u_exact, L2
# 格子収束テスト
Ns = [4, 8, 16, 32, 64, 128, 256]
errors = []
for N in Ns:
_, _, _, err = solve_poiseuille_fd(N)
errors.append(err)
# 収束次数
for i in range(1, len(Ns)):
ratio = errors[i-1] / errors[i]
order = np.log2(ratio)
print(f"N={Ns[i]:4d} L2={errors[i]:.3e} 収束次数={order:.2f}")収束結果#
| 誤差 | 収束次数 | ||
|---|---|---|---|
| 4 | 0.4000 | 2.78e-16 | — |
| 8 | 0.2222 | 1.67e-16 | ~2.0 |
| 16 | 0.1176 | 2.22e-16 | ~2.0 |
| 32 | 0.0606 | 2.78e-16 | ~2.0 |
| 64 | 0.0308 | 2.22e-16 | ~2.0 |
備考: ポアズ이ユ流れは2次多項式であるため、2次中心差分を用いると**マシン精度(machine precision)**レベルの正確さが得られます。実際の誤差は に比例するのではなく、浮動小数点演算の丸め誤差レベルで飽和します。
これがポアズイユ流れがCFD検証に理想的である理由です。低い格子解像度でもほぼ完璧な解を出すため、コードの基本的な正確性を迅速に確認できます。
解析結果の比較プロット#
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6, 5))
colors = plt.cm.viridis(np.linspace(0.2, 0.9, 4))
Ns_plot = [4, 8, 16, 64]
for N, c in zip(Ns_plot, colors):
y, u_num, _, _ = solve_poiseuille_fd(N)[:3]
_, _, u_exact, _ = solve_poiseuille_fd(N)
ax.plot(u_num, y, "o--", color=c, ms=4, label=f"FD N={N}")
# 解析解
y_fine = np.linspace(-1, 1, 400)
ax.plot(0.5 * (1 - y_fine**2), y_fine, "k-", lw=2, label="解析解")
ax.set_xlabel(r"$u$ (無次元)")
ax.set_ylabel(r"$y/h$")
ax.set_title("FD vs 解析解の比較")
ax.legend(fontsize=9)
plt.tight_layout()
plt.savefig("poiseuille_fd_vs_exact.png", dpi=150)
plt.show()OpenFOAM設定のヒント#
ポアズイユ流れを OpenFOAM の icoFoam で設定する際の主要パラメータ:
0/U — 速度境界条件#
boundaryField
{
walls
{
type noSlip; // 壁面 no-slip
}
inlet
{
type fixedValue;
value uniform (1 0 0); // または parabolicVelocity
}
outlet
{
type zeroGradient;
}
}0/p — 圧力境界条件#
boundaryField
{
inlet { type fixedValue; value uniform 1; }
outlet { type fixedValue; value uniform 0; }
walls { type zeroGradient; }
}constant/transportProperties#
nu nu [ 0 2 -1 0 0 0 0 ] 0.01; // 動粘性係数の調整検証チェックリスト#
- 完全発達条件:チャンネル長が入口の発達長さ()よりも十分に長いこと
- 格子独立性: 方向の格子数が16以上であれば2次精度を確保
- 検証指標:中心流速 と壁面せん断応力 を比較
まとめ#
ポアズイユ流れは単純に見えますが、このベンチマークを通じて確認できることは意外と多いです。
- 2次精度中心差分が正しく実装されているか
- 壁面 no-slip と圧力境界条件が正しく処理されているか
- 粘性応力テンソル()がコード内で正確に計算されているか
**「解析解のある問題から検証せよ(V&V)」**という原則は、航空宇宙、原子力、気象など、あらゆるCFD分野で共通の文化です。次回のポストでは、ストークス第1問題(急発進する平板)を用いて、非定常解析解の検証に挑戦してみましょう。
参考文献
- Batchelor, G. K. An Introduction to Fluid Dynamics. Cambridge, 1967.
- Ferziger, J. H., Perić, M. Computational Methods for Fluid Dynamics. Springer, 2002.
- OpenFOAM Documentation — icoFoam tutorial: cavity
圧力勾配と粘度を変えて放物線プロファイルが急峻化する様子を観察。
압력 구배가 커지거나 점성이 작아지면 포물선이 가팔라진다. Re > 2300 부근부터는 이 해석해가 무의미 — 천이 영역.
役に立ったらシェアしてください。