Skip to content
cfd-lab:~/zh/posts/2026-04-28-rankine-vorte…● online

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

NOTE #025DAY TUE 유체역학DATE 2026.04.28UPDATED 2026.10.19READ 4 min read#Vortex#Vorticity#Fluid-Dynamics#Flow-Phenomena#Helmholtz

漩涡的两副面孔 — 自由涡、强迫涡与亥姆霍兹

叶片始终把同一面朝向排水口时,那一段只有公转。2ω的自转留在黄色核心里。

拔掉浴缸塞子,水会一圈圈地转。这一幕常被叫成"水在旋转"。流体力学面对这片区域的大部分时,说法反过来:这里没有旋转(irrotational)。两句话看似矛盾,涡(vortex)的样子就藏在里面。同一幅图里住着自由涡(free vortex,速度按 1/r1/r)和强迫涡(forced vortex,速度按 ωr\omega r)。涡量(vorticity,流体微团自转角速度的两倍)量的就是这两者之差。亥姆霍兹定理接着问,这样的涡为什么不容易灭。

浴缸漩涡真的是"旋转"吗

"旋转"这一个词里叠着两层。一层是 公转,围着某个点做圆周运动。另一层是 自转,微团绕自己的轴转。

浴缸漩涡里,水的微团确实公转。远离排水口的自转几乎没有。一片小叶子沿着圆走,身体并不转,始终把同一面对着排水口。

流体力学里的"旋转"指自转。所以自由涡除了奇异的中心,整片区域都是无旋。

把核心半径 RR 调小,黄色自转区就变窄;把 Umax⁡U_{\max} 调大,核心涡量 2Umax⁡/R2U_{\max}/R 跟着变大。

Yellow tracers sit inside the forced-vortex core and rotate as a solid body (ω = 2U/R). Blue tracers outside follow u_θ = ΓR/r — circular streamlines but zero local spin. The Rankine combined vortex is the simplest model for a bath-tub drain or tornado.

黄色粒子在原地自转。蓝色粒子保持朝向排水口的那一面,只做公转。右上角曲线在 r≤Rr \le R 是直线,外面是 1/r1/r。

强迫涡与自由涡:同一幅画,不同的灵魂

在旋转容器里把水搅久了,整桶水会像刚体一样一起转。这叫 强迫涡。每一个微团既公转也自转。

uθ(r)=ω ru_\theta(r) = \omega \, r

其中 uθu_\theta 是切向速度,ω\omega 是刚体角速度,rr 是到中心的距离。速度与半径成正比。

忽略粘性的理想流体里自然形成的漩涡,是 自由涡(势涡)。

uθ(r)=Γ2πru_\theta(r) = \frac{\Gamma}{2\pi r}

Γ\Gamma 是 环量(circulation),沿闭合曲线的速度线积分。速度按 1/r1/r 衰减,到中心发散。真实流体里,粘性把这个奇点驯服。

强迫涡自由涡
速度ωr\omega rΓ/2πr\Gamma / 2\pi r
自转有无
能量输入持续不断仅在最初一次
日常例子搅动的杯水浴缸、龙卷风

同样的圆形流动,自转的有无却相反。把这一差异收成一个标量的,就是涡量。

涡量度量了什么

涡量 ω\boldsymbol{\omega} 是速度场的旋度(curl)。

ω=∇×u\boldsymbol{\omega} = \nabla \times \mathbf{u}

二维情形里只剩 zz 分量:

ωz=∂v∂x−∂u∂y\omega_z = \frac{\partial v}{\partial x} - \frac{\partial u}{\partial y}

其中 u,vu, v 分别是 x,yx, y 方向的速度。这个值正好等于 流体微团自转角速度的两倍。

代入强迫涡,ωz=2ω\omega_z = 2\omega,是常数,整片区域都在自转。代入自由涡,除中心外处处 ωz=0\omega_z = 0。流线一样圆,自转却相反。

兰金组合涡 — 龙卷风的蓝图

真实漩涡不会只听一种法则。靠近中心时粘性强,流体像刚体一样转;远处粘性可以忽略,自由涡接管。把两者拼起来的模型就是 兰金组合涡。

uθ(r)={Umax⁡R r,r≤RUmax⁡ Rr,r>Ru_\theta(r) = \begin{cases} \dfrac{U_{\max}}{R}\, r, & r \le R \\[6pt] \dfrac{U_{\max}\, R}{r}, & r > R \end{cases}

RR 是核心半径,Umax⁡U_{\max} 是核心边界处的最大切向速度。两段在 r=Rr = R 光滑相接。龙卷风风速、翼尖涡、排水口上方的吸入涡,都接近这一形状。核心内是有旋区,核心外是无旋区。

把代码里的默认值直接代进公式。Umax⁡=1U_{\max} = 1,R=0.5R = 0.5。在 r=Rr = R 处,内外两式都给出 uθ=1u_\theta = 1。r=0.25r = 0.25 时内侧是 Umax⁡r/R=0.5U_{\max} r / R = 0.5。r=1r = 1 时外侧是 Umax⁡R/r=0.5U_{\max} R / r = 0.5。离中心一样远,速度数字相同,斜率相反。

外圈环量不随半径变大。r>Rr > R 时 uθ=Umax⁡R/ru_\theta = U_{\max} R / r,所以 Γ=2πruθ=2πRUmax⁡\Gamma = 2\pi r u_\theta = 2\pi R U_{\max}。代入数字是 2π×0.5×1=π2\pi \times 0.5 \times 1 = \pi。核心涡量 ωz=2Umax⁡/R=4\omega_z = 2 U_{\max}/R = 4。核心面积 πR2=π/4\pi R^2 = \pi/4,乘上涡量得 4×π/4=π4 \times \pi/4 = \pi。面积积分和回路积分收在同一个环量上。粘性把中心奇点抹开以后,远处一条回路量到的仍是这一个 Γ=π\Gamma = \pi。代码注释里的 2Umax⁡/R2 U_{\max}/R 指的就是核心内的 44,不是网格另造的数。这个 Γ\Gamma 怎样变成升力,接在 旋转的球 里。

亥姆霍兹定理 — 涡的不灭

无粘流体里,微团上的力只有压力,压力指向微团中心,产生不了力矩。所以 此前不自转的微团不会开始自转,正在自转的微团不会停下。这是亥姆霍兹涡定理的一行。

更精确的说法是 开尔文定理:沿一条闭合物质曲线测得的环量 Γ\Gamma 不随时间变化。

DΓDt=0\frac{D\Gamma}{Dt} = 0

D/DtD/Dt 是物质导数,跟着流体微团走。涡管不能被切断,也不能被分开,拉长以后转得更快,和花样滑冰收臂是同一件事。真实流体有粘性,涡终究会扩散,但在水或空气里能活好几天。飞机航迹上的凝结涡能久久可见,就是这个缘故。

速度势打开的那扇门

在无旋(ω=0\boldsymbol{\omega} = 0)区域,向量恒等式直接给出一行:

∇×u=0⟹u=∇ϕ\nabla \times \mathbf{u} = 0 \quad \Longrightarrow \quad \mathbf{u} = \nabla \phi

标量 ϕ\phi 称为 速度势。若再满足不可压缩 ∇⋅u=0\nabla \cdot \mathbf{u} = 0,则

∇2ϕ=0\nabla^2 \phi = 0

这是拉普拉斯方程。无粘、无旋、不可压缩流可以由一个标量完全描述。十九世纪能用解析方法处理翼型升力和源汇,窍门在这里。自由涡本身写成 ϕ=(Γ/2π) θ\phi = (\Gamma / 2\pi)\, \theta,一个与角度 θ\theta 成正比的势。

用代码看这两种涡

把兰金涡的速度和离散涡量画出来,差别很清楚。

import numpy as np
 
def rankine_speed(r, R_core, U_max):
    """兰金组合涡的切向速度"""
    speed = np.where(r <= R_core,
                     U_max * r / R_core,
                     U_max * R_core / np.maximum(r, 1e-9))
    return speed
 
def vorticity_field(u, v, dx, dy):
    """二维离散旋度: omega_z = dv/dx - du/dy"""
    dvdx = (v[1:-1, 2:] - v[1:-1, :-2]) / (2 * dx)
    dudy = (u[2:, 1:-1] - u[:-2, 1:-1]) / (2 * dy)
    return dvdx - dudy
 
# 在 200x200 网格上采样
N, L = 200, 2.0
x = np.linspace(-L, L, N)
y = np.linspace(-L, L, N)
X, Y = np.meshgrid(x, y)
R = np.hypot(X, Y)
THETA = np.arctan2(Y, X)
 
U_max, R_core = 1.0, 0.5
u_theta = rankine_speed(R, R_core, U_max)
u =  -u_theta * np.sin(THETA)
v =   u_theta * np.cos(THETA)
 
dx = dy = x[1] - x[0]
omega = vorticity_field(u, v, dx, dy)
 
# 核心内外的平均涡量
mask_in  = R[1:-1, 1:-1] <  R_core
mask_out = R[1:-1, 1:-1] >  1.5 * R_core
print(f"核心内平均 omega_z ~ {omega[mask_in].mean():.3f}")   # ~ 2 * U_max / R_core
print(f"核心外平均 omega_z ~ {omega[mask_out].mean():.3f}")  # ~ 0

核心内 ωz≈2Umax⁡/R\omega_z \approx 2 U_{\max}/R 几乎是常数,核心外接近零。同样的圆形流动里,分开"转"与"不转"的边界正好画在 r=Rr = R 上。

网格用的是同一组数字。N=200N = 200,L=2L = 2,区域从 −2-2 到 22,间距是 4/1994/199。核心半径 0.50.5 大约是离中心二十五格。外侧掩膜从 1.5R=0.751.5 R = 0.75 打开。RR 和 0.750.75 之间不进平均,因为中心差分的模板一旦跨过边界,ωz\omega_z 就既不是 44 也不是 00。注释里的期望值是核心内 44、外面 00。间距 4/1994/199 约是 0.0200.020,半径 0.50.5 因此落在离中心约二十五格处,掩膜从 0.750.75 才开始计入平均。

核心半径留在哪里

核心切得太小,2Umax⁡/R2U_{\max}/R 会超出网格。Umax⁡=1U_{\max} = 1、R=0.5R = 0.5 时涡量是 44。把 RR 减半,同一公式给出 88。跨过边界的中心差分会把平均值污染成既非 44 也非 88 的数。外侧掩膜从 1.5R1.5R 打开,就是为了躲开这一格。

把核心推到区域边缘,1/r1/r 的尾巴就没了。环量 Γ=2πRUmax⁡\Gamma = 2\pi R U_{\max} 还可以写下来,但树叶保持同一朝向的无旋段消失了。这条尾巴上伯努利常数跨流线是否还均匀,要看 总压下降而耗散为零的那次计算。

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