Skip to content
cfd-lab:~/zh/posts/2026-08-06-oblique-shock…online
NOTE #125DAY THU 유체역학DATE 2026.08.06READ 5 min read#Gas-Dynamics#Oblique-Shock#Supersonic-Inlet#Stagnation-Pressure#Flow-Phenomena

四道激波胜过一道 — 超声速进气道的斜激波串

连挨几道弱斜激波,总压损失反而小得多的原因

1944 年的哥廷根,Klaus Oswatitsch 正被超声速推进装置的进气道问题缠住。冲压发动机必须把进来的空气压缩,可在 Mach 3 下直接把气流刹停,三分之二的压力就没了。他给出的答案不是压得更狠,而是把压缩拆成几段。立几块斜面,每一块只把气流拧一点点。今天就从斜激波(斜着立起来的激波)的关系式出发,推出这笔账为什么算得通,再改变斜板的块数,亲手数一数恢复系数怎么走。

激波夺走的是什么

穿过激波,质量、动量、能量都守恒。滞止温度 T0T_0 也原样保留。消失的只有滞止压力(总压)p0p_0 这一个。

p02p01=exp ⁣(ΔsR)\frac{p_{02}}{p_{01}} = \exp\!\left(-\frac{\Delta s}{R}\right)

Δs\Delta s 是穿过激波后增加的熵,RR 是气体常数。熵增了多少,总压就被削掉多少。

为什么偏偏是总压。因为进气道能交给发动机的功,上限恰好就是总压。滞止压力砍掉一半,喷管里能榨出来的膨胀比也只剩一半。这正是把进气道的性能指标归结为恢复系数 πd=p0e/p0\pi_d = p_{0e}/p_{0\infty} 一个数的理由。

Mach 3 下立一道正激波,这个值是多少。正好是 0.3283。总压的 67% 化成了热散掉。

斜着切入,只剩法向分量

把激波相对气流斜着立起来,情况就变了。与波面平行的速度分量穿过激波不变。因为压力梯度只沿波面法向作用。

也就是说,斜激波是只承受法向分量的正激波。波角(wave angle)β\beta 一定,有效 Mach 数就是

M1n=M1sinβM_{1n} = M_1 \sin\beta

β\beta 越小,M1nM_{1n} 越贴近 1。哪怕来流是 Mach 3,只要 β=25.6°\beta = 25.6°,激波实际感受到的不过是 Mach 1.30 的一道弱激波。

气流的偏转角 θ\theta(deflection angle)与波角 β\beta 由下面这条关系绑在一起。

tanθ=2cotβM12sin2β1M12(γ+cos2β)+2\tan\theta = 2\cot\beta \, \frac{M_1^2 \sin^2\beta - 1}{M_1^2 (\gamma + \cos 2\beta) + 2}

γ\gamma 是比热比(空气取 1.4)。说这条式子就是本文的全部,也不算过分。

一个 θ–β–M,两个答案#

给定 M1M_1θ\theta 去解 β\beta,会得到两个根。波角小的那个是弱解(weak solution),大的那个是强解(strong solution)。弱解后方通常仍是超声速,强解后方则变成亚声速。

自然界几乎总是挑弱解。只要背压不是特别高,贴在楔面上的激波就是弱的那一支。

而且 θ\theta 一直加大,到某一刻根会彻底消失。每个 M1M_1 都有一个能拧到头的最大角 θmax\theta_{\max}

M1M_11.52.03.05.0
θmax\theta_{\max}12.1°23.0°34.1°41.1°

一旦 θ>θmax\theta > \theta_{\max},激波就贴不住物体,会朝前脱开,变成弯曲的脱体激波(bow shock)。脱开的瞬间,鼻锥正前方实际上就是一道正激波,恢复系数直线跳水。

在下面的模拟里亲手操作一下。

drag theta and watch the amber Vn arrow grow while the slate Vt arrow never changes — that is why p02/p01 falls. push theta past the amber thetamax line and the shock detaches. then drag M1: the whole theta-beta knee slides right, so a faster inlet can turn the flow harder.

M1M_1 滑块往上推,θ–β 曲线的拐点(knee)会向右移。意思是来流越快,能拧的角度越大。再把 θ\theta 推过 θmax\theta_{\max},看激波脱开的那一刻,同时盯住 p02/p01p_{02}/p_{01} 这个数字是怎么塌下去的。右图里的切向分量箭头,在激波前后长度完全一样 — 被削掉的只有法向分量。

损失按三次方缩小

这里有一个决定性的事实。弱激波的熵增并不正比于 M1n1M_{1n}-1。它正比于三次方。

ΔsR2γ3(γ+1)2(M1n21)3\frac{\Delta s}{R} \simeq \frac{2\gamma}{3(\gamma+1)^2}\left(M_{1n}^2 - 1\right)^3

γ=1.4\gamma = 1.4 时系数是 0.162。M1n21M_{1n}^2 - 1 减半,损失就变成八分之一。

正是这个三次方撑起了 Oswatitsch 的算盘。Mach 3 下一次性立起来,激波要扛的 Mn21M_n^2-1 是 8。把它切成四份,每一份扛的值小得多,损失按份数各自以三次方缩水。份数再多,乘起来的总和依然远小于原来那一个。

拿真实数字对一下。M1n=1.30M_{1n} = 1.30 一次的总压损失是 2.1%。同样的活拆成 M1n=1.15M_{1n} = 1.15 两次,每次只有 0.33%,加起来还不到 0.7%。激波数目翻倍,损失却只有原来的三分之一。

把 Mach 3 进气道切成几段#

按 8° 一块的斜板逐块增加、最后用一道正激波收尾的构型算了一遍。每一块斜板都要用穿过前一块之后的当地 Mach 数重新计算。

import math
 
GAMMA = 1.4
 
def stagnation_ratio(mn):
    """承受法向 Mach 数 mn 的激波的总压比 p02/p01"""
    g = GAMMA
    a = ((g + 1) * mn**2 / 2) / (1 + (g - 1) * mn**2 / 2)
    b = (g + 1) / (2 * g * mn**2 - (g - 1))
    return a ** (g / (g - 1)) * b ** (1 / (g - 1))
 
def downstream_normal_mach(mn):
    g = GAMMA
    return math.sqrt((1 + (g - 1) / 2 * mn**2) / (g * mn**2 - (g - 1) / 2))
 
def deflection(mach, beta):
    """给定波角 beta(rad) 所产生的偏转角 theta(rad)"""
    g = GAMMA
    num = mach**2 * math.sin(beta) ** 2 - 1
    den = mach**2 * (g + math.cos(2 * beta)) + 2
    return math.atan(2 / math.tan(beta) * num / den)
 
def wave_angle_weak(mach, theta):
    """产生 theta 的弱解 beta。拧不出来则返回 None"""
    lo, hi = math.asin(1 / mach), math.pi / 2
    grid = [lo + (hi - lo) * i / 4000 for i in range(4001)]
    peak = max(grid, key=lambda b: deflection(mach, b))
    if theta > deflection(mach, peak):
        return None
    a, b = lo, peak
    for _ in range(80):
        mid = 0.5 * (a + b)
        if deflection(mach, mid) < theta:
            a = mid
        else:
            b = mid
    return 0.5 * (a + b)
 
def inlet_recovery(mach_inf, n_ramps, ramp_deg):
    """穿过 n 块斜板 + 终端正激波之后的总压恢复系数"""
    theta = math.radians(ramp_deg)
    total, mach = 1.0, mach_inf
    for _ in range(n_ramps):
        beta = wave_angle_weak(mach, theta)
        if beta is None:
            break
        mn = mach * math.sin(beta)
        total *= stagnation_ratio(mn)
        mach = downstream_normal_mach(mn) / math.sin(beta - theta)
    return total * stagnation_ratio(mach)
 
for n in range(5):
    print(f"斜板 {n} 块: 恢复系数 {inlet_recovery(3.0, n, 8.0):.4f}")

输出是这样的。

斜板 0 块: 恢复系数 0.3283
斜板 1 块: 恢复系数 0.4497
斜板 2 块: 恢复系数 0.5808
斜板 3 块: 恢复系数 0.7101
斜板 4 块: 恢复系数 0.8235

四块 8° 斜板,就把恢复系数从 0.33 抬到 0.82,整整 2.5 倍。总偏转角只有 32°,额外加进去的东西不过是四张斜面。

换成 Mach 2.4 配 6° 斜板重跑一遍,趋势一样。0.5401 → 0.7440(2 块)→ 0.9096(4 块)。

把斜板数目推向无穷、每块的偏转角推向零,压缩就收敛到等熵。理论上恢复系数可以到 1。真实的 Concorde 和 SR-71 进气道之所以采用曲面斜板和可动中心锥,道理就在这里。

在下面亲手改一改斜板块数和偏转角。

keep M inf = 3.00 and delta = 8 deg, then drag N from 0 to 4 and watch the bottom number climb 0.3283 → 0.8235 while the red terminal shock bar gets visibly thinner. now push delta up: each ramp bites harder, the chain runs out of Mach, and it turns red.

把斜板数 NN 从 0 推到 5,看下方那根恢复系数柱是怎么往上爬的。接着把每块的偏转角推到 14°,到某一刻后面的斜板会变红。那是在提示:气流已经慢到那个程度,再按这个角度拧不动了。

切分并不是免费的

那立 20 块斜板不就行了。不这么做的理由有几条。

第一,长度。每多一块斜板,激波打到唇口(cowl lip)的位置就往后挪一截。进气道一长,重量和摩擦阻力就跟着上来。为了赚 3% 的恢复系数把机身拉长 1 m,这笔买卖多半是亏的。

第二,非设计点工况。斜板角度是按某个特定 Mach 数调的,要让所有激波正好汇到唇口(shock-on-lip)。一偏离那个 Mach 数,激波就错到唇口前面或里面,空气绕过进气道流走,产生溢流阻力(spillage drag)。斜板越多,对这种错位越敏感。

第三,边界层。每块斜板的激波都会撞上壁面边界层,让压力陡然升高。激波-边界层干扰一旦引起分离,纸面上的恢复系数就失去了意义。真实进气道在斜板附近开放气槽(bleed),正是为此。

第四,终端正激波去不掉。发动机压气机要求亚声速来流。总得有个地方必须穿过声速。斜板的作用是把撞上最后那道激波时的 Mach 数压低,而不是把它取消。上面的算例里,四块斜板那一档的终端激波发生在 Mach 1.67,仅这一道就拿走了 13%。

记住这三句

穿过激波丢掉的只有总压,而损失正比于 (M1n21)3(M_{1n}^2-1)^3 — 所以弱激波几乎是白拿的。

斜激波是只承受法向分量的正激波;θ\thetaβ\betaMM 关系有两个答案,一旦越过 θmax\theta_{\max} 就无解,激波随即脱体。

把同样的减速拆成几段,靠三次方,总损失骤降。Mach 3 下四块 8° 斜板把恢复系数从 0.33 拉到 0.82。代价是进气道长度,以及对偏离设计点的敏感度。

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