Skip to content
cfd-lab:~/ja/posts/2026-06-21-asymptotic-pr…● online

この記事は著者が韓国語で書いた原文の翻訳です。 原文(한국어)を読む

NOTE #079DAY SUN 논문리뷰DATE 2026.06.21UPDATED 2026.10.19READ 5 min read#CFD#Paper-Review#Low-Mach#Asymptotic-Preserving#IMEX

[論文レビュー] 低マッハで音を殺さない方法 — AP-IMEX波動スキーム

この出力のステップ数は M=128/ε で、対数減衰 0.154/ε が explicit 列をほぼ再現します。

低マッハ(low Mach)の流れを圧縮性コードに入れると、音速が速いほど絵が鮮明になりそうに思えます。逆です。マッハ数が下がるほど、標準の風上(upwind)は健全な波を格子から消します。Arun・Das Gupta・Samantaray(2019)は線形波動方程式系でその崩壊を切り分け、IMEX-RK でマッハ数に依らない安定な漸近保存(AP)スキームを組みました。音響演算子を陰的に解く理由は、下の数字に出ています。

ε\varepsilon のスライダーを左へ動かすと、赤い風上曲線は傾き −1-1 で立ち上がり、シアンの AP 曲線は平らなままです。

0.010.111010010000.0010.010.11Mach number ε (log scale)effective diffusion (log)explicit upwind ∝ 1/εAP / implicit (flat)
D_explicit ≈ 0.078
D_AP ≈ 7.8e-3
ratio ≈ 10.0×

ε=10−3\varepsilon=10^{-3} では二つの曲線の比が数百倍まで開きます。マッハ数を下げて大きくなるのは波ではなく、風上の数値粘性です。

ε が 0 に近づくと格子が波を食べる#

スケールを整えた等エントロピー Euler 方程式には、小さな数が一つ入っています。マッハ数 ε\varepsilon です。圧力項は運動量方程式に ∇p/ε2\nabla p / \varepsilon^2 として入ります。

∂tρ+∇⋅(ρu)=0,∂t(ρu)+∇⋅(ρu⊗u)+∇pε2=0\partial_t \rho + \nabla\cdot(\rho \mathbf{u}) = 0, \qquad \partial_t (\rho\mathbf{u}) + \nabla\cdot(\rho\mathbf{u}\otimes\mathbf{u}) + \frac{\nabla p}{\varepsilon^2} = 0

ρ\rho は密度、u\mathbf{u} は速度、p=ργp=\rho^\gamma は圧力です。ε\varepsilon は基準速度を基準音速で割った値です。

ε→0\varepsilon \to 0 で解は非圧縮極限へ向かいます。特異摂動(singular perturbation)です。著者らは解析を短くするため、線形波動系を使います。

∂tϱ+(u⋅∇)ϱ+aε∇⋅u=0,∂tu+(u⋅∇)u+aε∇ϱ=0\partial_t \varrho + (\mathbf{u}\cdot\nabla)\varrho + \frac{a}{\varepsilon}\nabla\cdot\mathbf{u} = 0, \qquad \partial_t \mathbf{u} + (\mathbf{u}\cdot\nabla)\mathbf{u} + \frac{a}{\varepsilon}\nabla\varrho = 0

ϱ\varrho は線形化した密度摂動、aa はその状態の音速です。実効音速は c=a/εc=a/\varepsilon です。マッハ数が小さくなると、この音響速度が爆発します。

well-prepared 空間 — 生き残るべき解#

極限 ε→0\varepsilon\to 0 で解は好きな方向へ漏れません。準備の整った(well-prepared)空間に集まります。密度は定数、速度の発散は 0 です。

ϱ(0)=const,∇⋅u(0)=0\varrho^{(0)} = \text{const}, \qquad \nabla\cdot\mathbf{u}^{(0)} = 0

この空間が音響演算子 L(U)=(a∇⋅u, a∇ϱ)L(U)=(a\nabla\cdot\mathbf{u},\,a\nabla\varrho) の核(kernel)です。離散解も同じ場所へ着地すべきです。Dellacherie(2010)は、この不変性を破るスキームが低マッハで精度を失うことを示しました。核を保てば漸近精度(AA)です。安定制限が ε\varepsilon に依らなければ漸近保存(AP)です。

風上粘性は音速に比例して大きくなる

犯人は風上の数値粘性です。波動系を特性変数で対角化すると、速度 ±c\pm c のスカラー移流が二つになります。各モードに Rusanov 風上を掛けると、1ステップの増幅が出ます。

∣g∣2=(1−ν(1−cos⁡θ))2+ν2sin⁡2θ,ν=c ΔtΔx,  θ=kΔx|g|^2 = \big(1 - \nu(1-\cos\theta)\big)^2 + \nu^2\sin^2\theta, \qquad \nu = \frac{c\,\Delta t}{\Delta x},\ \ \theta = k\Delta x

ν\nu は音響 CFL、θ\theta はセルあたりの位相、kk は波数です。

1ステップの損失は小さいです。積み上がる方が問題です。物理時間 TT まで行くには音響ステップが M=T/Δt=Tc/(νΔx)M = T/\Delta t = T c /(\nu\Delta x) 回必要です。θ\theta が小さいとき 1ステップの減衰は 12ν(1−ν)θ2\tfrac{1}{2}\nu(1-\nu)\theta^2 で、MM 回重ねると対数減衰はこうなります。

M⋅12ν(1−ν)θ2  =  12 T c (1−ν) k2Δx  ∝  c  ∝  1εM\cdot\tfrac{1}{2}\nu(1-\nu)\theta^2 \;=\; \tfrac{1}{2}\,T\,c\,(1-\nu)\,k^2\Delta x \;\propto\; c \;\propto\; \frac{1}{\varepsilon}

マッハ数を一桁下げると、実効粘性も一桁大きくなります。上の図で赤い曲線の傾きが −1-1 なのは、この比例です。

演算子分割 — 対流は陽的に、音響は陰的に

方程式を時間スケールで割ると、演算子は二つです。

∂tU+H(U)+1εL(U)=0\partial_t U + H(U) + \frac{1}{\varepsilon}L(U) = 0

HH は時間スケール O(1)O(1) の対流です。L/εL/\varepsilon は時間スケール O(ε)O(\varepsilon) の音響です。硬さ(stiffness)はすべて L/εL/\varepsilon にあります。その部分だけ陰的に解きます。対流は陽的に残します。この混合が IMEX(Implicit-Explicit)です。同じ分離をマッハ 0 まで持っていったとき時間刻みが持つかは、IMEX TVD の再現が続けて扱います。

音響を陰的にすれば中心差分でも安定です。風上粘性は外れます。Δt\Delta t を決めるのは速い音響ではなく遅い対流です。このモデルの中では、ε\varepsilon が小さくても刻みを縮める理由がありません。

IMEX-RK が硬さを受け止める#

時間積分は IMEX ルンゲ・クッタ(IMEX-RK)です。陽的表 (A~,b~)(\tilde A,\tilde b) が HH を、陰的表 (A,b)(A,b) が L/εL/\varepsilon を受け持ちます。各ステージで音響は、密度に対する楕円型方程式へ凝縮されます。圧力ポアソンに似た形です。

ϱ−β2Δt2 a2∇2ϱ=(陽的な項)\varrho - \beta^2 \Delta t^2\, a^2 \nabla^2 \varrho = (\text{陽的な項})

β\beta は IMEX 表の対角係数、∇2\nabla^2 はラプラシアンです。この楕円問題の可逆性は、変分の鞍点(saddle point)で保証されます。離散では循環行列(circulant matrix)が同じ結論を与えます。一意解、ε\varepsilon に依らない一様安定、well-prepared 空間の不変性。三つです。

Python — 1モードの振幅減衰を再現する#

下のコードはフーリエモード一つの風上増幅を計算し、物理時間 TT の後に残る振幅をマッハ数ごとに出します。陰的スキームはモードを保存するので、振幅は 1 です。

import numpy as np
 
a  = 1.0        # 線形化音速
k  = 2 * np.pi  # [0,1] 上の単一フーリエモード
T  = 1.0        # 固定物理終了時刻
nu = 0.5        # 音響CFL数
 
def upwind_amp_factor(eps, N):
    """波動系Rusanovにおける1特性モードの増幅 |g|。"""
    c  = a / eps              # 音響速度 c = a/ε
    dx = 1.0 / N
    th = k * dx               # セルあたり位相 θ = kΔx
    re = 1.0 - nu * (1.0 - np.cos(th))
    im = nu * np.sin(th)
    return np.hypot(re, im)   # |g| <= 1
 
def retained_amplitude(eps, N):
    """物理時間 T 後のモード振幅(風上 vs 陰的)。"""
    c  = a / eps
    dx = 1.0 / N
    dt = nu * dx / c          # 音響CFLステップ
    M  = T / dt               # 陽的ステップ数
    explicit = upwind_amp_factor(eps, N) ** M
    implicit = 1.0            # 中心-陰的はモードを保存
    return M, explicit, implicit
 
if __name__ == "__main__":
    N = 64
    print(f"{'eps':>8} {'steps M':>10} {'explicit':>12} {'AP':>6}")
    for eps in [0.4, 0.2, 0.1, 0.05, 0.02, 0.01]:
        M, ex, ap = retained_amplitude(eps, N)
        print(f"{eps:8.3f} {M:10.0f} {ex:12.3e} {ap:6.2f}")

出力はこうなります。

     eps    steps M     explicit     AP
   0.400        320    6.804e-01   1.00
   0.200        640    4.629e-01   1.00
   0.100       1280    2.143e-01   1.00
   0.050       2560    4.591e-02   1.00
   0.020       6400    4.430e-04   1.00
   0.010      12800    1.980e-07   1.00

Mach ε\varepsilon を下げると、赤い振幅は物理時間 T=1T=1 に届く前に床へ着きます。CFL ν\nu を 1 側へ寄せると ν(1−ν)\nu(1-\nu) が小さくなり、減衰は一瞬和らぎます。ε\varepsilon をさらに下げると、その利得は 1/ε1/\varepsilon の累積に埋もれます。NN を大きくしても θ2∝N−2\theta^2\propto N^{-2} と Δx∝N−1\Delta x\propto N^{-1} は一部しか打ち消し合いません。

コードの数を式へ入れると、ステップ数は閉じた形になります。a=1a=1、T=1T=1、ν=0.5\nu=0.5、N=64N=64 なら Δx=1/64\Delta x=1/64 で c=1/εc=1/\varepsilon です。Δt=νΔx/c\Delta t=\nu\Delta x/c なので M=T/Δt=128/εM=T/\Delta t=128/\varepsilon です。表の 320、640、1280、2560、6400、12800 は、ε=0.4,0.2,0.1,0.05,0.02,0.01\varepsilon=0.4,0.2,0.1,0.05,0.02,0.01 をこの式に入れた値です。ε\varepsilon を半分にすると MM は 2 倍です。10 分の 1 にすると MM も 10 倍です。

対数減衰 12Tc(1−ν)k2Δx\tfrac12 T c(1-\nu)k^2\Delta x に同じ数を入れると、指数は 0.154/ε0.154/\varepsilon です。k=2πk=2\pi だから係数がそうなります。ε=0.4\varepsilon=0.4 で指数は 0.386、e−0.386=0.680\mathrm{e}^{-0.386}=0.680 です。出力の 6.804×10−16.804\times 10^{-1} と小数三位まで一致します。ε=0.1\varepsilon=0.1 では e−1.542=0.214\mathrm{e}^{-1.542}=0.214 で、出力の 2.143×10−12.143\times 10^{-1} と合います。ε=0.01\varepsilon=0.01 で指数は 15.4 です。e−15.4\mathrm{e}^{-15.4} は 2.0×10−72.0\times 10^{-7} の近くで、出力は 1.980×10−71.980\times 10^{-7} です。θ=kΔx=2π/64≈0.098\theta=k\Delta x=2\pi/64\approx 0.098 なので、小さな角度の仮定は表の一番下まで正確ではありません。表の端が近似より少し余計に死ぬ理由です。ν=0.5\nu=0.5 は ν(1−ν)=0.25\nu(1-\nu)=0.25 で、この積が最大になる CFL です。だからこの列は、1ステップの減衰がいちばん強い条件の記録です。

漸近保存(AP)と漸近精度(AA)#

二つは別の問いです。AP は、離散スキームの ε→0\varepsilon\to 0 極限が極限方程式の正しい離散化かを問います。安定制限は ε\varepsilon に依ってはいけません。AA はもう一歩です。格子は有限で、ε\varepsilon は小さいが 0 ではないとき、解が well-prepared 空間の近くに留まるかです。風上は両方に失敗します。IMEX の陰解法は両方を通ります。分かれる場所は空間差分の次数ではなく、時間離散化です。

ν=0.5 の最悪減衰でも AP 列は 1.00 です#

この表の AP 列は六行とも 1.00 です。陰解法が風上粘性を外すので、指数 0.154/ε0.154/\varepsilon が振幅に掛からないからです。ν=0.5\nu=0.5 は 1ステップの減衰因子が最大なのに、M=128/εM=128/\varepsilon 回積んだあとも 1.00 です。この線形波動系では、L/εL/\varepsilon だけを陰的にする選択が合っています。

その選択が低マッハの方程式すべてへそのまま移るわけではありません。音響を陰的に入れても、時間刻みが再び大きく縮む系があります。相対速度に二つ目の 1/M21/M^2 が残る場所は、エンタルピーに残った硬さに書いてあります。

役に立ったらシェアしてください。