乱流は三本の物差しを同時に使う — Kolmogorovカスケードと-5/3則
大きな渦が砕けて粘性に飲まれる道、その上に描かれるエネルギースペクトル
1941年、モスクワで書かれた一冊のノート#
戦争が始まる二か月前、Kolmogorovは三本の短い論文を学術誌に送りました。合わせて十六ページに満たない分量です。風洞も、測定データも、図版も一枚もありません。あったのは次元解析と二つの統計的仮定だけでした。
そのノートの一行が八十年後のCFDを縛り続けています。十分高いReynolds数では、エネルギーがスケール間にどう分布するかは一本の長さだけで決まる — Kolmogorovのミクロスケール です。 この記事では、その一行がどう生まれ、なぜ格子解像度とDNS(Direct Numerical Simulation、直接数値計算)の費用を決めるのかを追います。最後に合成データに対して-5/3の傾きを当てはめます。
一つの流れに三本の物差しを詰め込む#
乱流の一かたまりを広げてみると、三つの長さが見えてきます。
- 積分スケール — 最大渦の大きさです。普通は流れの幾何(管径、煙突の幅)で決まります。エネルギーを蓄える場所です。
- Taylorミクロスケール — 二点速度自己相関関数が原点で持つ曲率から定義されます。大スケールと小スケールの仲介役です。
- Kolmogorovミクロスケール — 粘性が運動エネルギーを熱に擦り変える最小の物差しです。分子平均自由行程よりは遥かに大きいですが、に比べれば桁違いに小さいです。
三本の物差しが同じ流れの中に同居しています。Reynolds数が大きくなると、との隔たりが広がります。その隔たりが慣性小領域(inertial subrange)です。
次元解析が橋を架ける#
Kolmogorovの仮定は二行で済みます。
- 十分小さなスケールでは、統計量は粘性 とエネルギー散逸率 のみに依存する。
- 慣性小領域では粘性も落ち、統計量は だけに依存する。
仮定1から最小スケールが組み立てられます。 の単位は 、 は 。長さを取り出すには:
が長さ、 が速度、 が時間。単位だけで系が閉じます。
仮定2はもっと深く切り込みます。慣性小領域のエネルギースペクトル は と波数 にしか依存しません。 の単位は 。次元を揃えると:
はKolmogorov定数、実験的に 。-5/3則は仮定と単位だけから出てきます。測定点を一つも使っていません。
スケール分離 — Reが広げる隔たり#
大渦の見積もり (エネルギー注入が散逸と等しい定常状態)を使うと:
ここで です。Reynolds数が10倍になると、 は 倍に縮みます。すべてのスケールを格子で解こうとすると、セル数は で爆発します。実験室の風洞 では 、3D DNSは セル。航空機の翼 なら セル — 現在のスーパーコンピュータでも届きません。
エネルギーが流れる道#
大渦が一つ回転しています。粘性は弱すぎてそのエネルギーを直接削れません。代わりに大渦は小渦に砕け、小渦はさらに小さな渦に砕けます。砕ける時間は渦の回転時間(turnover time) です。この破砕が、エネルギー散逸率 という一つの数値ですべてのスケールを束ねます。
下のシミュレーションで、大渦が小渦に砕けていく様子を見てみましょう。
大渦(シアン)は長く生きます — 。中間渦(オレンジ)はもっと早く砕け、小渦(ピンク)は灰色(粘性散逸)へほぼ瞬時に渡されます。各渦が生きている間に下流へ流すエネルギー流束は、すべてのスケールで等しい — それが慣性小領域の定義です。
-5/3傾きと両端の罠#
を両対数で描くと、中央に傾き-5/3の直線帯が現れます。しかし両端では別の物理が支配します。
- 付近 — エネルギー含有域。幾何が決める最大渦が住む場所。 がピークを打ちます。
- 付近 — 粘性散逸域。 が指数的に落ちます。粘性がエネルギーを飲み干します。
下のシミュレーションでReynolds数を上げてみましょう。-5/3帯がどう伸びていくか見えます。
では-5/3帯はほとんど見えません。 になると、ほぼ四桁にわたる直線が開きます。実験的には、一桁でも綺麗な-5/3傾きが取れれば、その流れは十分に発達した乱流とみなされます。
Python — 合成スペクトルに-5/3を当てはめる#
実験で-5/3傾きをどう抽出するか。両対数軸で直線当てはめ、それだけです。合成データで試してみましょう。
import numpy as np
C_K = 1.5
c_L, p0 = 6.78, 2
beta_e, c_eta = 5.2, 0.40
def pope_spectrum(k, eps, L, eta):
"""Pope のモデルスペクトル(等方等質乱流)。"""
kL = k * L
kEta = k * eta
f_L = (kL / np.sqrt(kL**2 + c_L)) ** (5/3 + p0)
f_eta = np.exp(-beta_e * ((kEta**4 + c_eta**4)**0.25 - c_eta))
return C_K * eps**(2/3) * k**(-5/3) * f_L * f_eta
# 設定
L_int = 1.0 # 積分長さ
u_rms = 1.0 # rms 速度
Re = 1e5
nu = u_rms * L_int / Re
eps = u_rms**3 / L_int
eta = (nu**3 / eps) ** 0.25
# 波数格子上の擬似測定(乗法的雑音付き)
rng = np.random.default_rng(0)
k = np.logspace(-1, np.log10(1.0 / eta) - 0.5, 80)
E_true = pope_spectrum(k, eps, L_int, eta)
E_meas = E_true * np.exp(0.10 * rng.standard_normal(k.size)) # ~10% 対数正規雑音
# 慣性域だけに -5/3 を当てはめる (10/L < k < 0.1/eta)
mask = (k > 10 / L_int) & (k < 0.1 / eta)
slope, _ = np.polyfit(np.log(k[mask]), np.log(E_meas[mask]), 1)
print(f"L/eta = {L_int / eta:.1f}")
print(f"fitted slope = {slope:+.3f} (expected -1.667)")
# L/eta = 17783.3
# fitted slope = -1.661 (expected -1.667)80点の雑音込みデータでも当てはめ傾きは-1.66、理論値-5/3と三桁一致します。雑音を30%まで上げても傾きは-1.59~-1.74の範囲に留まります — 慣性域の頑健さを示しています。
ここで一つ質問。なぜマスクに と を入れたのか。両端の 、 が直線を曲げてしまうからです。実測でも当てはめ窓を狭く取らないと、傾きが-1.4まで落ちます。「私のデータは-5/3を示さない」という報告の半分は、窓の取り方が原因です。
格子が届かない場所で生き延びる#
DNSの費用が見えたので、迂回路が読みやすくなります。
- RANS(Reynolds-Averaged Navier–Stokes) — 時間平均だけを解き、変動はモデルで閉じます。 を解かないので、格子コストは で済みます。産業の主力ですが、異方性レイノルズ応力には弱いです。
- LES(Large Eddy Simulation) — 大渦のみ解き、格子以下の小渦をSGS(サブグリッドスケール)モデルで閉じます。壁モデルの有無で格子コストは ~。DNSとRANSの中間です。
- DNS — まで解き、 まで時間積分します。コストは (3D + 時間)。学術的な道具です。
三手法ともに同じ-5/3線の上に立っています。RANSは慣性領域全体をモデルに置き換え、LESはその一部だけを解き、DNSはすべてを解く。どこで切るかがモデリングの判断です。
心に留める三行#
- Kolmogorovの-5/3則は次元解析だけから導かれ、慣性小領域でエネルギー流束 が唯一の物差しになるという仮定の直接の帰結です。
- がDNSの費用を決めます。 では3D格子が セルに膨らみ、誰の手も届きません。
- 合成スペクトルでは当てはめ窓を に絞ると、30%雑音下でも傾きが-1.6~-1.7に収まります — 両端の効果を切り捨てることが何より大事です。
役に立ったらシェアしてください。