1次元移流方程式(線形移流方程式)を風上差分法(Upwind scheme)で解くコード。 空間差分は1次精度の風上差分、時間差分は前進オイラー法(陽的1次精度)を用いる。 Δt を 0.05 / 0.1 / 0.2 の3種類に変えてクーラン数(Courant数)が解の安定性に与える影響を横並びグラフで比較する。
| ライブラリ | 用途 |
|---|---|
| numpy | 配列演算・初期条件の構築 |
| matplotlib.pyplot | グラフ描画(subplots による横並び比較) |
対象方程式は1次元線形移流方程式(スカラー輸送方程式):
この方程式は流体中のスカラー量(温度・濃度・放射性核種等)が速度 c で上流から下流へ流れる現象を表す。 解析解は初期波形が形を変えずに x 方向へ速度 c で平行移動するものとなる。
風上差分法の安定条件は CFL 条件で与えられる:
| 項目 | 内容 |
|---|---|
| 空間差分 | 1次精度風上差分(後退差分):(q[j] − q[j-1]) / Δx |
| 時間積分 | 前進オイラー法(陽的1次精度) |
| 空間格子 | Δx = 0.1、格子点数 jmax = 21 |
| 初期条件 | ステップ関数(x < 1.0 で q=1、x ≥ 1.0 で q=0) |
| 境界条件 | 両端固定(ループ外で更新なし) |
| 比較ケース | Δt = 0.05(CFL=0.5)、0.1(CFL=1.0)、0.2(CFL=2.0) |
import numpy as np
import matplotlib.pyplot as plt
c=1
#dt=0.05
dx=0.1
jmax=21
nmax=600
x=np.linspace(0,dx*(jmax-1),jmax)
q_init=np.zeros(jmax)
for j in range(jmax):
if(j<jmax/2):
q_init[j]=1
else:
q_init[j]=0
fig, axes = plt.subplots(1, 3, figsize=(21, 7), dpi=100)
plt.rcParams["font.size"]=25
plot_times = [0.2, 0.4, 0.6]
for ax, dt in zip(axes, [0.05, 0.1, 0.2]):
q=q_init.copy()
ax.plot(x,q,marker='o',lw=2,label='t=0.0')
for n in range(1,1+nmax):
qold=q.copy()
for j in range(1,jmax-1):
q[j]=qold[j]-dt*c*(qold[j]-qold[j-1])/(dx)
if any(np.isclose(n*dt, pt) for pt in plot_times):
ax.plot(x,q,marker='o',lw=2,label=f't={n*dt:.2g}')
ax.grid(color='black',linestyle='dashed',linewidth=0.5)
ax.set_xlabel('x')
ax.set_ylabel('q')
ax.set_ylim([0,1.5])
ax.set_title(f'dt = {dt},Courant={dt*c/dx:.2g}')
ax.legend()
plt.tight_layout()
plt.show()
左:CFL=0.5(Δt=0.05)安定・数値拡散あり / 中:CFL=1.0(Δt=0.1)安定・数値拡散最小 / 右:CFL=2.0(Δt=0.2)不安定・発散