風下差分法(Downwind scheme / 前進差分)は c > 0 の移流問題では無条件不安定であり、 格子やΔtの値に関わらず解が発散します。 本コードは安定な風上差分法との比較のために「なぜ風下差分を使ってはいけないか」を視覚的に示す教育目的のコードです。
1次元移流方程式を風下差分法(Downwind scheme)で解くコード。 空間差分に前進差分(q[j+1]−q[j])を用いる点が風上差分法と唯一の違いで、 それ以外の設定(CFL=0.5 固定、3段階の格子細分化)は 風上差分_2 と完全に同じである。 格子を細かくしても発散が止まらないことから、 スキームの安定性は離散化方向に依存することが直感的に理解できる。
| ライブラリ | 用途 |
|---|---|
| numpy | 配列演算・初期条件の構築 |
| matplotlib.pyplot | グラフ描画(subplots による横並び比較) |
対象方程式は1次元線形移流方程式:
移流速度 c > 0 のとき、情報は 上流(左)から下流(右) へ伝わる。 差分スキームが安定であるためには、情報が伝わってくる方向(上流側)のデータを使う必要がある。
風下差分のフォン・ノイマン安定性解析では増幅率 G が:
CFL > 0 かつ θ ≠ 0 のとき常に |G| > 1 となり、CFL の値や格子の細かさに関わらず無条件不安定。
| スキーム | 差分式 | 安定性 |
|---|---|---|
| 風上差分(Upwind) | q[j]n+1 = q[j]n − c·Δt/Δx · (q[j]n − q[j-1]n) | CFL ≤ 1 で安定 |
| 風下差分(Downwind) | q[j]n+1 = q[j]n − c·Δt/Δx · (q[j+1]n − q[j]n) | 無条件不安定 |
コード上の違いは 1文字:qold[j-1] → qold[j+1]
| ケース | Δt | Δx | 格子点数 jmax | CFL | 結果 |
|---|---|---|---|---|---|
| 粗い格子 | 0.1 | 0.2 | 11 | 0.5 | 発散 |
| 中間格子 | 0.025 | 0.05 | 41 | 0.5 | 発散 |
| 細かい格子 | 0.01 | 0.02 | 101 | 0.5 | 発散 |
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 29 16:21:27 2026
@author: kishu
"""
import numpy as np
import matplotlib.pyplot as plt
c=1
#dt=0.05
fig, axes = plt.subplots(1, 3, figsize=(21, 7), dpi=100)
plt.rcParams["font.size"]=25
for ax, dt, dx, jmax, nmax in zip(axes, [0.1, 0.025, 0.01], [0.2, 0.05, 0.02], [11, 41, 101], [600, 600, 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
plot_times = [0.1, 0.2, 0.3]
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+1]-qold[j])/(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()
全3ケース(CFL=0.5)で発散。格子を細かくしても不安定性は解消されない。 風上差分_2 と同一パラメータだが、差分方向を変えるだけで挙動が正反対になることが確認できる。