Skip to content
cfd-lab:~/zh/posts/2026-05-21-complex-poten…online
NOTE #050DAY THU 유체역학DATE 2026.05.21READ 4 min readWORDS 1,895#유체역학#Potential-Flow#Complex-Potential#Cauchy-Riemann#d-Alembert#유동현상

两个函数相加,一个圆柱便出现了 — 复势与达朗贝尔佯谬

在均匀流上叠加一个小点,绕圆柱流动便自动浮现的原因。

只是把两个函数相加,一个圆柱就凭空出现了。取一道均匀流,在其上叠加一个点状偶极子,中央便会浮起一个完整的圆 — 而没有人画过这个圆。本文要讲的是,这一戏法其实正是十九世纪复变函数论的一行而已。我们将沿着柯西–黎曼方程为何成为二维无粘流动骨架的脉络,看一行 W=Uz+m/zW=Uz+m/z 如何精确给出圆柱绕流,以及它怎样导出 1752 年让达朗贝尔陷入困境的"零阻力"佯谬。最后用 60 行 NumPy 重画这幅图。

流线与等势线为何处处正交#

二维不可压缩、无粘、无旋流动中同时定义着两个标量场:速度势 ϕ\phi 与流函数 ψ\psi。速度把两者联结起来。

u=ϕx=ψy,v=ϕy=ψxu = \frac{\partial \phi}{\partial x} = \frac{\partial \psi}{\partial y}, \qquad v = \frac{\partial \phi}{\partial y} = -\frac{\partial \psi}{\partial x}

等势线 ϕ=const.\phi=\text{const.} 的斜率为 u/v-u/v,流线 ψ=const.\psi=\text{const.} 的斜率为 v/uv/u。两者乘积为 1-1两族曲线处处正交。

这一正交格栅并非装饰,而是正则函数实部与虚部所固有的性质。一句"复导数对任何接近方向给出相同值",便将这两个标量场绑在一起,成为一对。

复速度势 — 柯西与黎曼架的桥#

z=x+iyz = x + iy,考虑 W(z)=ϕ(x,y)+iψ(x,y)W(z) = \phi(x,y) + i\psi(x,y)WW 在复意义下可微,要求从任何方向逼近 zz 都给出同一极限。沿实轴与虚轴分别取极限并令其相等,得到两式。

ϕx=ψy,ϕy=ψx\frac{\partial \phi}{\partial x} = \frac{\partial \psi}{\partial y}, \qquad \frac{\partial \phi}{\partial y} = -\frac{\partial \psi}{\partial x}

这就是柯西–黎曼关系。而它们正是我们刚才为速度写下的方程。**把二维无旋流动的 ϕ\phiψ\psi 装进同一个复函数,这个复函数就是正则的。**称 W(z)W(z)复速度势

它的复导数也带含义。由 dW=(uiv)dzdW = (u - iv)\, dz

dWdz=uiv\frac{dW}{dz} = u - iv

这是 复速度,即速度向量的共轭,两个分量完整保留。

一行 — W=Uz+m/zW = Uz + m/z 画出圆柱#

从最简单的两块基本流谈起。均匀流 W=UzW = Uz。分实虚部得 ϕ=Ux\phi = Uxψ=Uy\psi = Uy。等势是垂直线,流线是水平线。偶极子(源汇相靠拢至重合的极限)W=m/zW = m/z。极坐标下 W=(m/r)(cosθisinθ)W = (m/r)(\cos\theta - i\sin\theta),即 ϕ=(m/r)cosθ\phi = (m/r)\cos\theta,ψ=(m/r)sinθ\psi = -(m/r)\sin\theta

把它们相加。

W(z)=Uz+mzW(z) = Uz + \frac{m}{z}

极坐标下化简为

ψ(r,θ)=U ⁣(rR2r)sinθ,RmU\psi(r,\theta) = U\!\left(r - \frac{R^2}{r}\right)\sin\theta, \qquad R \equiv \sqrt{\tfrac{m}{U}}

其中 RR 是由偶极子强度与均匀流之比决定的长度尺度。寻找 ψ=0\psi = 0 的位置:要么 sinθ=0\sin\theta = 0(xx 轴),要么 r=Rr = R。后者是关键。半径为 RR 的整圈,就是一条流线。

在无粘假设下,任何流线都可换成固体壁,而圆外流动不变。于是把 r=Rr = R 当作圆柱壁面。均匀流加一个偶极子 — 两项最简单函数的和 — 便是均匀来流中圆柱绕流的精确无粘解。没有人画圆,圆却被数学画了出来。

在下面的可视化中亲自试一下。

W(z) = Uz + m/z + iΓ/(2π)·ln(z). When Γ=0 the picture is symmetric — d'Alembert's zero drag. Slide Γ to break the symmetry and lift appears (Kutta–Joukowski).

Um 同步增大,半径 R=m/UR = \sqrt{m/U} 随之变化。把 Γ 从 0 移开,上下对称即被打破 — 这正是下一节升力的机制。同时打开 streamequipotential,两族曲线在各处正交的网格便清晰可见。

加一行环量,升力就出现了#

圆柱表面的速度分布上下对称。由伯努利方程,压力也对称,合力为零。这就是下一节将谈到的达朗贝尔佯谬。打破对称,需要 环量(表面绕一周的切向速度积分)。点涡的复势为 W=i(Γ/2π)lnzW = -i(\Gamma/2\pi)\ln z。把它再叠上去。

W(z)=Uz+mziΓ2πlnzW(z) = Uz + \frac{m}{z} - i\,\frac{\Gamma}{2\pi}\ln z

现在上方速度高于下方,压力上方低、下方高,升力出现。库塔–儒可夫斯基定理给出每米展长的升力 L=ρUΓL' = \rho U \Gamma — 1902 年库塔、1906 年儒可夫斯基独立得出。上面可视化里 Γ 滑块所制造的非对称,正是这件事。

叠加 — 所有无粘流动都是加法#

流函数满足拉普拉斯方程 2ψ=0\nabla^2\psi = 0,它是线性的。**两个解之和仍是解。**这一句话支撑了十九世纪流体力学的半壁江山。

四块基本积木便够。Uniform ψ=Uy\psi = UySource/Sink ψ=±(q/2π)θ\psi = \pm(q/2\pi)\thetaVortex ψ=(Γ/2π)lnr\psi = -(\Gamma/2\pi)\ln rDoublet ψ=msinθ/r\psi = -m\sin\theta/r。把它们摆在平面上,依次得到半体、兰金卵形、旋转圆柱。

Each preset is a sum of elementary flows. The same machinery — superposition of ψ — builds half-bodies, ovals, and lifting cylinders.

Cylinder = U + doublet 就是上面那幅图。Rankine half-body 是均匀流加一个源 — 在上游侧出现鼻形驻点。Rankine oval 把源与汇放在同一轴上,组合成一个闭合形体。Lifting cylinder 则在圆柱组合上再加一个涡,制造上下非对称。

达朗贝尔佯谬 — 零阻力教给我们的事#

W=Uz+m/zW = Uz + m/z 在圆柱表面积分压力,得到的恰是 零阻力。1752 年达朗贝尔亲自推出。他自己也清楚这是矛盾。任何人在水中拖一根棍子都能感到阻力。无粘、无旋、不可压的假设,绝造不出这个阻力。

解决花了将近一个半世纪。1904 年,普朗特发现了 边界层 — 一层贴近壁面、粘性虽小却起主导作用的薄区。粘性虽小,却不为零。它在壁附近作用,生出薄层,薄层中的分离形成下游的尾迹和涡,打破上下游压力对称。这种非对称,就是阻力。

达朗贝尔的零阻力并非错答。**它是无粘流体的精确答案。**这个答案与自然不一致这一事实,正是近代流体力学的起点。

60 行 NumPy — 沿 W(z)W(z) 重画#

import numpy as np
import matplotlib.pyplot as plt
 
def cylinder_potential(z, U=1.0, m=1.0, gamma=0.0):
    """返回 W = Uz + m/z - i*gamma/(2π)*ln(z) 的 (phi, psi)。"""
    safe_z = np.where(np.abs(z) < 1e-9, 1e-9 + 0j, z)
    W = U * safe_z + m / safe_z - 1j * gamma / (2 * np.pi) * np.log(safe_z)
    return W.real, W.imag  # (phi, psi)
 
def velocity_from_W(z, U=1.0, m=1.0, gamma=0.0):
    """dW/dz = u - iv。取共轭还原 (u, v)。"""
    safe_z = np.where(np.abs(z) < 1e-9, 1e-9 + 0j, z)
    dW = U - m / safe_z**2 - 1j * gamma / (2 * np.pi * safe_z)
    return dW.real, -dW.imag
 
def cylinder_surface_pressure(theta, U=1.0, R=1.0, gamma=0.0):
    """圆柱表面 (含环量) 的伯努利压力系数 cp。"""
    u_t = -2 * U * np.sin(theta) - gamma / (2 * np.pi * R)
    return 1 - (u_t / U) ** 2  # cp = 1 - (V/U)^2
 
def integrate_drag_lift(U=1.0, R=1.0, gamma=0.0, N=1024):
    """无粘表面压力积分 → (drag, lift) / (rho U^2 R)。"""
    theta = np.linspace(0, 2 * np.pi, N, endpoint=False)
    cp = cylinder_surface_pressure(theta, U, R, gamma)
    drag = -np.trapz(cp * np.cos(theta), theta)
    lift = -np.trapz(cp * np.sin(theta), theta)
    return drag, lift
 
if __name__ == "__main__":
    U, m, gamma = 1.0, 1.0, 0.0
    R = np.sqrt(m / U)
 
    drag0, lift0 = integrate_drag_lift(U, R, gamma=0)
    drag1, lift1 = integrate_drag_lift(U, R, gamma=-3.0)
    print(f"Γ=0    : drag = {drag0:+.4e}, lift = {lift0:+.4e}")  # 两者 ~ 0
    print(f"Γ=-3.0 : drag = {drag1:+.4e}, lift = {lift1:+.4e}")  # lift = -ρUΓ
 
    x = np.linspace(-3, 3, 400)
    y = np.linspace(-2, 2, 240)
    X, Y = np.meshgrid(x, y)
    Z = X + 1j * Y
    Z_out = np.where(np.abs(Z) < R, np.nan, Z)
    _, psi = cylinder_potential(Z_out, U, m, gamma=-3.0)
 
    fig, ax = plt.subplots(figsize=(7, 4))
    ax.contour(X, Y, psi, levels=24, linewidths=0.7)
    ax.add_patch(plt.Circle((0, 0), R, color="white", ec="k"))
    ax.set_aspect("equal"); plt.show()

运行后输出如下两行。

Γ=0    : drag = +1.7e-15, lift = -3.5e-16
Γ=-3.0 : drag = -2.0e-14, lift = +3.000e+00

阻力始终为零。升力精确锁在 ρUΓ-\rho U \Gamma(ρ=1,U=1\rho=1, U=1L=3L' = 3)。达朗贝尔对了,错的是假设。

三件值得记住的事#

  • 两项复势 W=Uz+m/zW = Uz + m/z 是均匀来流圆柱绕流的精确无粘解 — 没人画圆,圆却出现。
  • 柯西–黎曼方程并非只是可微条件,而是二维无旋流动的 ϕ\phiψ\psi 成对结合为一个正则函数的真正原因。
  • 零阻力的达朗贝尔解不是错答,而是无粘流体的诚实写照,它指向了边界层理论的起点。

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