この記事は著者が韓国語で書いた原文の翻訳です。 原文(한국어)を読む
負の密度が漏れる場所 — 爆風波のためのPositivity保存フラックスリミッター
更新後の密度が床より上に残る範囲で、最大のθだけを残します。
午前2時27分です。Le Blanc衝撃管が0.003秒でNaNを吐きました。CFLを0.1まで下げても、格子を倍にしても、二本の曲線が一緒に崩れます。原因は単純でした。強い膨張波(rarefaction、圧力が急に下がる領域)の先頭で、一つのセルの密度が負に落ちていました。二ステップ後に音速がNaNになり、その次で領域全体が死にます。Hu・Adams・Shu(2013)のθブレンドは、その場で高次フラックスを一段階だけ後退させます。
右側密度ρ_Rを10⁻³より下げると、許容曲線が赤い領域に入り、その面のθは0.2を下回ります。
The cyan curve is ρn+1 after one Euler step as a function of how much central-flux we mix into the right face. The red zone is where ρ has crossed the floor 10⁻³. The yellow dot is the largest θ that still lands above the floor — that is the θ the per-face limiter picks. Drop ρR below 10⁻³ or push uR past 6 and θ collapses toward zero: the limiter falls back to first-order Lax–Friedrichs.
赤い領域は、次ステップの密度が床を割る側です。θがその境界で止まれば、その面は事実上一次のLax–Friedrichsです。
負の密度はどこで漏れるか
高次スキームは安定性と精度のあいだで揺れます。一次風上は衝撃を五セルほどにぼかします。二次中心差分は衝撃の両側にノコギリを植えます。揺れが軽ければ圧力が少し動くだけです。隣接セルの密度比が100:1を超えると — Le Blanc、Sedov爆発、超音速ノズルの後方 — 壊れ方が変わります。
セル の密度保存は次の形です。
は密度フラックスです。 のセル、つまり片側へ質量が多く抜けるセルでは、 が負になりえます。1D Eulerでは、強い衝撃の直後にある膨張の最初のセルがそこです。
負になると、先に音速が死にます。 で なら です。次のフラックスの がNaNを返します。一セルのNaNが両隣に広がり、二ステップ後には領域が終わります。
Lax–Friedrichs — ぼやけるが壊れない#
1954年にLaxが書いたLFフラックスは、この罠の外にいます。
は左右セルの最大信号速度、 は保存変数です。引く項が人工粘性です。隣を平均してノコギリを消します。着想は1950年に衝撃へわざと粘性を塗った処理と同じ場所にあります。LaxはCFL1のもとで を示しました。Hu et al. の定理1を簡略化した形です。衝撃が強くても弱くても、LFは崩れません。
代償は精度です。二セル幅の衝撃が五セルになり、接触不連続はステップごとに一セルずつぼけます。実務でLFだけを使う人はいません。それでも、その安全余裕がリミッターの出発点です。
θ ブレンド — 一段ずつだけ後退する
高次フラックス (WENO、MUSCL、中心差分)はLFより鋭い一方で、負の密度を作れます。Hu・Adams・Shuは二つのフラックスを一行に束ねます。
は面ごとの重みです。 なら純粋な高次、 なら純粋なLFです。リミッターの仕事は一つです。すべてのセルの次の密度が正に残る範囲で、最大の を選びます。領域の向こうまで退きません。一段だけです。
LFの結果が なので、補正 を足しても正のままになる の上限を面ごとに解きます。一つの面は両側のセルに触れます。両方とも床の上にいる必要があるので、小さい方が限界です。
先ほどρ_Rを下げたときθが0.2を下回ったのは、この上限です。その面は事実上一次LFで解かれます。
二段階制限 — 密度を先に、圧力を後で
密度が正でも、圧力が負ならソルバは同じように死にます。音速が虚数になるからです。Hu et al. はそこで二パスに分けます。
密度パス。 上式で を面ごとに決めます。すべてのセルの次の密度が 以上です。
圧力パス。 で密度フラックスを固定したあと、運動量とエネルギーのフラックスに を求めます。圧力の条件
は非線形です。一般には二次式です。 を小さい側に取る保守的な近似なら、一行で終わります。
一つの重み。 ですべての保存フラックスを混ぜます。一つの面、一つの です。保存量のあいだの一貫性が残ります。
NumPy 50 行 — Le Blanc 衝撃管で θ を自動決定#
Le Blancは 、 対 、 の強い衝撃管です。強い膨張が左へ進み、最初のセルの密度が負に落ちる試験です。
左右を割ると、密度比は 、圧力比は です。上で100:1を危険線の例にしましたが、この組の密度ジャンプはその下にあります。強いのは圧力の方です。 なら音速 で、左は 、右は です。比は できれいに割れます。
格子の数を式に入れると、時間刻みが原因ではないと分かります。 なので 、 です。 です。左の音速だけで測ったクーラン数は です。明け方にCFLを0.1まで下げても死んだことと合います。 でフラックス差が密度の余裕を超えると、ステップを縮めても床を割ります。
右の初期密度 から床 までの余裕は です。 を1に保つには、密度補正 が を超えてはいけません。 なら上限は です。余裕が まで縮むと、同じ で の上限は です。その面はほぼLFです。
ブレンドを重みで書き直すと です。 なら高次の取り分は53%です。 なら高次は2.8%だけで、残りはLFです。コードの上限は更新式と同じ不等式です。補正が密度を動かす量は で、右の余裕 を超えてはいけません。したがって です。 で等号が に届きます。
圧力の式も同じ読み方です。 で です。 と を固定すると、運動エネルギー1が圧力を0.4だけ削ります。右の は運動エネルギー で0に触れます。左の は同じ計算で まで持ちます。密度の床だけを守ると、密度は正のまま音速が虚数になる側へ漏れます。
import numpy as np
GAMMA = 1.4
RHO_FLOOR = 1e-3
N, NSTEP = 200, 220
dx = 1.0 / N
dt = 9.0e-5
def cons_to_prim(U):
rho, mu, E = U[0], U[1], U[2] # 保存 -> 原始変数
u = mu / rho
p = (GAMMA - 1.0) * (E - 0.5 * rho * u * u)
return u, p
def euler_flux(U):
u, p = cons_to_prim(U)
return np.array([U[1], U[1] * u + p, u * (U[2] + p)])
def alpha_face(UL, UR):
uL, pL = cons_to_prim(UL); uR, pR = cons_to_prim(UR)
aL = np.sqrt(GAMMA * max(pL, 0.0) / UL[0])
aR = np.sqrt(GAMMA * max(pR, 0.0) / UR[0])
return max(abs(uL) + aL, abs(uR) + aR)
def density_theta(U, dF, dt_dx):
"""面ごとの θ: ρ_LF を床より上に保つ最大値"""
theta = np.ones(N + 1)
for f in range(1, N):
d = dF[0, f] # 密度 anti-diffusion
if abs(d) < 1e-14: continue
rL_room = U[0, f - 1] - RHO_FLOOR # 左セルの余裕
rR_room = U[0, f] - RHO_FLOOR # 右セルの余裕
cap = (rL_room if d > 0 else rR_room) / (dt_dx * abs(d))
theta[f] = max(0.0, min(theta[f], cap))
return thetaドライバは一次LFが一パス、中心差分のanti-diffusionが一パス、θの決定が一パスです。220ステップ、200セルです。リミッターを切ると30ステップ付近でNaNになり、入れると最後まで残ります。
リミッターのスイッチを切ると、赤い曲線が30ステップ付近で密度を0より下へ引きずります。
Red is the raw centered scheme — its rarefaction tail dives below zero around t ≈ 0.006 and the solver blows up. Cyan is the same scheme blended with Lax–Friedrichs by a per-face θ ≤ θ_max so that ρ stays above the floor 10⁻³. Drag the time slider to watch the two solutions separate.
その交差が崩壊です。シアンは同じ時刻に の近くで平らになります。精度差は5%未満です。片方は生き、もう片方は死にます。
リミッターが奪うもの
が0まで落ちる面は一次LFで解かれます。衝撃の前面と強い膨張の先頭は、そこで鈍ります。その領域は領域全体の5%未満なので、大域の精度はほとんど動きません。平均のθは0.95から1.0のあいだを行き来します。
を のように低くしすぎると、リミッターの起動が遅れ、同じNaNが戻ります。実務では平均密度の 付近を床にします。RKの多段では、段ごとにリミッターをやり直す必要があります。最初の段だけを通すと、次の段でそのまま発散します。
床を1e-12まで下げると、リミッターはNaNのあとで目を覚ます#
は床ではなく飾りです。右状態の密度0.02から見ると余裕のほとんどがまだ残っていて、上の式のθ上限は1の近くに留まります。密度がすでに を下回ってから、上限が締まります。その前に音速の二乗 は符号を変えます。リミッターは、セルが死んだあとにLFへ退きます。
面のθが見ているのはセル平均だけです。平均は正なのに、セル内部の再構成が一点で負に折れると、この一行はその点を見ません。その穴を平均は正のまま、点で負に折れる再構成が別に塞ぐのかが、次の選択として残っています。
参考:X. Y. Hu, N. A. Adams, C.-W. Shu. Positivity-preserving method for high-order conservative schemes solving compressible Euler equations. J. Comput. Phys. 242 (2013) 169–180.
関連記事
役に立ったらシェアしてください。