Skip to content
cfd-lab:~/zh/posts/2026-05-23-chamarthi-202…● online

本文译自作者的韩语原文。 阅读原文(한국어)

NOTE #050DAY SAT 논문리뷰DATE 2026.05.23UPDATED 2026.10.19READ 6 min read#Paper-Review#Interface-Capturing#THINC#Multicomponent#Compressible#Shock-Capturing

[论文评论] 一种方案无法处理所有波 — Chamarthi (2025)

ψ低于 0.35 的接触用 THINC,激波仍用 MP5,粘性切向速度在 Ducros 未触发时走中心差分。

第一次跑 HLLC 时,激波很干净,落在两个网格内。同样的网格上,接触间断(contact discontinuity,只有密度跳变、压力与法向速度连续的波)却模糊了十个格子。同样的格式、同样的网格、同样的时间步,两种波的表现却截然不同。Chamarthi (2025) 给出了简短的答案 — 一种格式无法处理所有波。本文将跟随该论文的核心算法,亲手复现新的接触传感器与 THINC sigmoid(可微的阶梯函数)。

拨动密度比和压力比,ψ\psi 会在界面处落到 0.35 以下。两侧压力取齐也一样。

Two-gas shock tube · contact-discontinuity sensor ψᵢ on s = p/ργ

The cyan curve is ρ(x) at t = 0; the yellow curve is ψᵢ on s = p/ργ. Red shading marks cells where ψᵢ falls below 0.35 — those are the ones that switch from MP5 to THINC reconstruction. Currently 4 of 120 cells trigger THINC. Match pL to pR and the sensor still fires at the interface, because the jump in s comes from the change of γ even when pressure is balanced.

只改 γ\gamma,ss 就会跳。压力比拉到 10:1,标记仍主要落在接触面上。

论文信息

  • 作者: Amareshwara Sainadh Chamarthi (Caltech, Engineering and Applied Science)
  • 期刊: Computers and Fluids, 2025
  • DOI: 10.1016/j.compfluid.2025.106856 (S0045-7930(25)00318-4)
  • 题目: Physics appropriate interface capturing reconstruction approach for viscous compressible multicomponent flows

两种波,同一把尺 — 1990 年代的习惯#

WENO、MP5、MUSCL 对任何变量都用同一套规则重构。激波(密度·压力·法向速度都跳)用五阶多项式,材料界面(只有密度·体积分数跳)同样用五阶多项式。激波被锐利捕捉,接触间断却做不到。

原因很简单。激波处 Lax 熵条件让跳跃自我陡化(self-steepening),任何被扩散抹掉的部分会被重建回来。接触间断没有自我陡化。一旦被模糊,接触间断不会再变锐。用同样的多项式重构,时间一长,界面会越变越厚。

Harten 早在 1989 年用 subcell resolution 走了另一条路。Huynh 加入了 slope steepening。两人得出同样的结论 — 接触间断需要不同的处理。Chamarthi (2025) 把这一直觉提升到了多组分五方程模型。

寻找接触间断的新尺度 — s=p/ργs = p/\rho^\gamma#

以往的界面探测依赖体积分数(volume fraction)α\alpha。当 ϵ<α<1−ϵ\epsilon < \alpha < 1-\epsilon 时判定为界面。有两个弱点。第一,单组分内部的接触间断(例如 Sod 激波管)无法识别。第二,当三种以上组分共存时,必须检查每个 αk\alpha_k。

Chamarthi 用一个类似熵的标量代替它:

s=pργ,ρ=ρ1α1+ρ2α2s = \frac{p}{\rho^\gamma}, \qquad \rho = \rho_1 \alpha_1 + \rho_2 \alpha_2

其中 pp 是压力、ρ\rho 是混合密度、γ\gamma 是混合比热比。在接触波(entropy wave)上,pp 与法向速度连续,但 ρ\rho 与 γ\gamma 都跳,所以 ss 也跳。在激波上 ss 也跳,但其跳跃在 WENO smoothness indicator 中呈现不同的形态。

传感器复用 WENO 的 β0\beta_0 与 β2\beta_2 指标,去掉平方改用绝对值:

ψi=2ab+εa2+b2+ε\psi_i = \frac{2 a b + \varepsilon}{a^2 + b^2 + \varepsilon} a=1312∣si−2−2si−1+si∣+14∣si−2−4si−1+3si∣a = \tfrac{13}{12} |s_{i-2} - 2 s_{i-1} + s_i| + \tfrac{1}{4} |s_{i-2} - 4 s_{i-1} + 3 s_i| b=1312∣si−2si+1+si+2∣+14∣3si−4si+1+si+2∣b = \tfrac{13}{12} |s_i - 2 s_{i+1} + s_{i+2}| + \tfrac{1}{4} |3 s_i - 4 s_{i+1} + s_{i+2}|

ψi\psi_i 衡量左右模板粗糙度的一致性(coherence)。光滑区域 ψi→1\psi_i \to 1;一侧不光滑则 ψi→0\psi_i \to 0。低于阈值 ψc=0.35\psi_c = 0.35 的格点就是今天的 THINC 候选。

上面的图已经显示这一点。无论改变气体 1 与气体 2 的密度比,还是让两侧压力相等,传感器总是在界面位置低于阈值。这是因为 γ\gamma 的变化本身就让 ss 跳跃。有趣的是,即便把压力比拉到 10:1(即 Sod 激波管初始条件),传感器主要仍指向接触面。激波上的 ss 跳跃是平滑发展的,而界面的 ss 跳跃在初始条件中就存在。

THINC sigmoid — 单个格子内的阶梯#

THINC (Tangent of Hyperbola for INterface Capturing) 不是多项式,而是可微的 sigmoid 函数:

q(ξ)=qmin⁡+qmax⁡2+qmax⁡−qmin⁡2tanh⁡ ⁣[β(ξ−ξ0)]q(\xi) = \frac{q_{\min} + q_{\max}}{2} + \frac{q_{\max} - q_{\min}}{2} \tanh\!\left[\beta(\xi - \xi_0)\right]

ξ\xi 是格内坐标 [0,1][0,1],β\beta 是陡度(steepness)参数,ξ0\xi_0 是跳跃位置。给定格平均后,ξ0\xi_0 是唯一确定的。β=1.8\beta = 1.8 时跳跃约落在 4 格内,β=2.0\beta = 2.0 则更陡。

论文给出的左右界面值闭式如下:

qi+1/2L=ua+ud⋅K1+K2/K11+K2,qi−1/2R=ua−ud⋅K1−K2/K11−K2q^{L}_{i+1/2} = u_a + u_d \cdot \frac{K_1 + K_2/K_1}{1 + K_2}, \quad q^{R}_{i-1/2} = u_a - u_d \cdot \frac{K_1 - K_2/K_1}{1 - K_2}

其中 ua=(qi+1+qi−1)/2u_a = (q_{i+1} + q_{i-1})/2,ud=(qi+1−qi−1)/2u_d = (q_{i+1} - q_{i-1})/2,αi=(qi−ua)/ud\alpha_i = (q_i - u_a)/u_d,K1=tanh⁡(β/2)K_1 = \tanh(\beta/2),K2=tanh⁡(αiβ/2)K_2 = \tanh(\alpha_i \beta / 2)。当单调性条件 (qi+1−qi)(qi−qi−1)>0(q_{i+1} - q_i)(q_i - q_{i-1}) > 0 不成立时,公式退回到一阶迎风 qiq_i。

在同一网格上把 THINC 与 MUSCL+minmod 摆在一起。两者都稳定,都遵守 L∞L^\infty 界限。差异在于界面厚度。挑选跳变更小的候选,是 MUSCL-THINC-BVD 的做法。

Periodic advection · square pulse · 120 cells · CFL = 0.4 · forward Euler

Same advection step, two reconstructions. The green MUSCL+minmod profile smears the contact within ~6 cells after each cycle. The cyan THINC profile stays within 2–3 cells because the sigmoid keeps the jump steep across the cell. Lowering β below 1.5 makes THINC almost as diffusive as MUSCL; pushing β past 2.2 invites overshoots at the leading edge.

在 CFL = 0.4 的设置下,跑完周期域一圈后,MUSCL+minmod 把方波边缘抹成约 6 格宽,THINC 保持在 2–3 格。把 β\beta 降到 1.5 以下,THINC 会变得几乎和 MUSCL 一样耗散。把 β\beta 推到 2.2 以上,前沿会出现轻微 overshoot。这就是论文推荐 β=1.8\beta = 1.8–1.91.9 的原因。

Ducros 传感器 — 在粘性模拟中重新登场的名字#

粘性流动中,切向速度(tangential velocity)是连续的。Batchelor 的教科书自 1967 年就这样说。然而多数无粘代码对所有变量使用同一套迎风方案,把跳跃假设带进了粘性计算。

Chamarthi 的第二项贡献是让 Ducros 传感器 重新登场。Ducros 传感器能识别激波,但识别不了接触间断:

Ωi=(∇⋅u)2(∇⋅u)2+∣∇×u∣2⋅Ri\Omega_i = \frac{(\nabla \cdot \mathbf{u})^2}{(\nabla \cdot \mathbf{u})^2 + |\nabla \times \mathbf{u}|^2} \cdot R_i

RiR_i 是压力的四阶差分比,首项衡量压缩 vs 旋转模态的比例。激波是强压缩,Ωi→1\Omega_i \to 1;剪切层是强旋转,Ωi→0\Omega_i \to 0。Ducros 看不见接触间断,这一点就是关键。切向速度只要 Ducros 未触发,就始终用中心差分处理。粘性流动中,这是正确的规则。

比较矩阵 — 三种算法

变量·波传统 MP5/WENOHY-THINC (无粘)HY-THINC-D (粘性)
声波 (W1,W6W_1, W_6)MP5MP5MP5
接触波 (W2,W3W_2, W_3)MP5THINC if ψi<ψc\psi_i < \psi_cTHINC if ψi<ψc\psi_i < \psi_c
剪切波 (W4W_4)MP5MP5中心差分 if Ω<0.01\Omega < 0.01
体积分数 (W5W_5)MP5THINC if ψi<ψc\psi_i < \psi_cTHINC if ψi<ψc\psi_i < \psi_c

五方程模型的六个特征变量,各自被赋予不同的重构规则。同样的网格、同样的时间步、同样的 HLLC 黎曼求解器,只是在何处用哪个函数发生了变化。

Python — 在多组分激波管上比较两种算法#

下面的代码复现论文 Example 4.1 的 Abgrall–Karni 两气激波管。我们没有写完整的五方程模型,而是削减到对比所需的最小形式,直接实现接触传感器 ψi\psi_i 与 THINC 重构。

import numpy as np
 
GAMMA = 1.4
PSI_C = 0.35
XI = 1e-2
EPS = 0.9 * PSI_C / (1.0 - 0.9 * PSI_C) * XI
 
def contact_sensor_psi(s):
    """式(32-33)。s = p / rho^gamma,长度 N 数组。"""
    N = len(s)
    psi = np.ones(N)
    for i in range(2, N - 2):
        a = (13/12) * abs(s[i-2] - 2*s[i-1] + s[i]) \
            + 0.25 * abs(s[i-2] - 4*s[i-1] + 3*s[i])
        b = (13/12) * abs(s[i] - 2*s[i+1] + s[i+2]) \
            + 0.25 * abs(3*s[i] - 4*s[i+1] + s[i+2])
        psi[i] = (2*a*b + EPS) / (a*a + b*b + EPS)
    return psi
 
def thinc_face(qm, qi, qp, beta=1.8):
    """式(30)。返回 i+1/2 的左态值。"""
    if (qp - qi) * (qi - qm) <= 0:
        return qi
    u_a = 0.5 * (qp + qm)
    u_d = 0.5 * (qp - qm)
    if abs(u_d) < 1e-12:
        return qi
    alpha = (qi - u_a) / u_d
    if abs(alpha) >= 1.0:
        return qi
    K1 = np.tanh(beta / 2.0)
    K2 = np.tanh(alpha * beta / 2.0)
    return u_a + u_d * (K1 + K2 / K1) / (1.0 + K2)
 
def mp_face(qm2, qm, qi, qp, qp2):
    """线性 5 阶迎风(为简洁起见省略 MP 限幅)。"""
    return (2*qm2 - 13*qm + 47*qi + 27*qp - 3*qp2) / 60.0
 
def wave_appropriate_recon(s, q_alpha, q_other, beta=1.8):
    """每个界面根据传感器决定使用 THINC 或 MP5。"""
    N = len(s)
    psi = contact_sensor_psi(s)
    q_alpha_L = np.zeros(N)
    q_other_L = np.zeros(N)
    for i in range(2, N - 2):
        sensor_min = min(psi[i-1], psi[i], psi[i+1])
        if sensor_min < PSI_C:
            q_alpha_L[i] = thinc_face(q_alpha[i-1], q_alpha[i], q_alpha[i+1], beta)
        else:
            q_alpha_L[i] = mp_face(q_alpha[i-2], q_alpha[i-1], q_alpha[i],
                                   q_alpha[i+1], q_alpha[i+2])
        q_other_L[i] = mp_face(q_other[i-2], q_other[i-1], q_other[i],
                               q_other[i+1], q_other[i+2])
    return q_alpha_L, q_other_L
 
# 在 Sod 激波管上检查 psi 分布
N = 200
x = np.linspace(0, 1, N)
rho = np.where(x < 0.5, 1.0, 0.125)
p   = np.where(x < 0.5, 1.0, 0.1)
s   = p / rho**GAMMA
print(f"trigger cells: {(contact_sensor_psi(s) < PSI_C).sum()} / {N}")
# 输出: trigger cells: 3 / 200  ←  仅接触面附近 3 格切换到 THINC

200 格的网格里,落入阈值之下的格子只有三个。剩下的 197 格仍走 MP5。"局部切换"是恰当的形容。

这些数已经写在代码和正文里。N=200N=200,γ=1.4\gamma=1.4,ψc=0.35\psi_c=0.35,ξ=10−2\xi=10^{-2}。左侧 ρ=1\rho=1,p=1p=1。右侧 ρ=0.125\rho=0.125,p=0.1p=0.1。s=p/ργs=p/\rho^{\gamma},接触上 ss 跳跃,阈值之下 3 格,其余 197 格仍是 MP5。EPS 就是代码里的 0.9 ψc/(1−0.9 ψc)⋅ξ0.9\,\psi_c/(1-0.9\,\psi_c)\cdot\xi。不是新测的数。

THINC 在 β=1.8\beta=1.8 时把跳跃收进大约 4 个格子。β=2.0\beta=2.0 更陡。CFL =0.4=0.4 走完一个周期,MUSCL+minmod 的拐角摊成 6 格,THINC 保持 2–3 格。β\beta 低于 1.5,THINC 也朝那 6 格变糊。超过 2.2,前缘出现过冲。论文给的窗口是 1.81.8–1.91.9。传感器里的 13/1213/12 和 1/41/4 是 WENO 光滑指示子的系数,平方换成了绝对值。压力比 10:1 时标记仍留在接触上,因为激波的 ss 跳跃随时间摊开,界面的 ss 跳跃就是初始条件本身。

复现过程中遇到的三个陷阱

记录三个论文没有明说的细节。

  1. ε\varepsilon 依赖变量尺度。推荐的 ξ=10−2\xi = 10^{-2} 需要根据变量 ss 的数量级重新调整。若流动里 s∼10−3s \sim 10^{-3},ξ\xi 也要相应缩小。论文没讨论跨尺度的情况。

  2. 关闭 MP 限幅会失去五阶精度。上面的 Python 只用了线性 MP5。完整的 Suresh–Huynh MP limit 还需要 50 多行代码,而这 50 行承担了一半的稳定性。逐行迁移时务必小心。

  3. HLLC vs HLLC-LM。Chamarthi 默认使用 HLLC。低马赫数情况下,HLLC 的人工耗散会作用到接触波,部分抵消 THINC 刚锐化的界面。当流动同时具有低马赫数与强接触间断时,需要 HLLC-LM 或单独的低马赫修正。

OpenFOAM 的 interFoam 与 Ansys Fluent 的 VOF 走的是另一条路 — 几何重构体积分数。THINC 是代数(algebraic)方法,能以较小修改移植到非结构网格,但有观察显示在网格未对齐界面时会有累积性损失。

这篇论文提出的新问题

Chamarthi 的结论是 二阶精度配上正确物理,胜过五阶精度配上错误物理。周期性双剪切层算例支持了这一判断。随之而来的新问题是 — 我们能否给"物理适配度"一个更明确的定义?波依赖的方案在非结构网格、非牛顿流体、磁流体力学(MHD)中是否同样有效?合上本文后下一篇可读的论文 — 同作者的 Wave-appropriate multidimensional upwinding (JCP 2025),即多维扩展。

把 β 放在 1.8,还是换掉 HLLC#

只看界面厚度,β\beta 放在 1.81.8–1.91.9。低于 1.5,拐角退回 6 格的 MUSCL。超过 2.2,前缘过冲。200 格里切到 THINC 的只有 3 格。另外 197 格留在 MP5。这个比例就是局部切换。

低马赫又有强接触时,HLLC 会把这 3 格重新抹糊。那时该换 HLLC-LM。只求激波锐利,MP5 加 HLLC 就够。小涡也要留下来,是 TENO 用另一套指示子在问的事。不按波换函数,接触会再次摊到十个格子。

如果对您有帮助,请分享。