跳到主要内容
Sandbox Physics

流体力学 · 能亲手推动的数值流场

Interactive Jet

在流体模拟里,平流、扩散和压力投影各起什么作用? 平流把染料和旋涡顺着流动带走,扩散把它们抹平。压力投影减去一个压力场的梯度,消掉散度,流体就不会在哪里堆积或变稀。这个压力场要迭代求解,迭代次数有限,就会剩下一点能测出来的散度。

透明流动室里,一个二维不可压缩速度场被拉出浅浅的纵深,画成发光粒子。调节黏度、染料扩散、压力迭代和涡量增强,看喷流绕过圆柱后怎样卷吸周围流体、留下尾迹。开启流体刷,在测试区拖动,就能同时注入染料和动量。

交互模型Interactive Jet
最近求解步耗时0 ms0\,\mathrm{ms}
模拟时间0.0000 s0.0000\,\mathrm{s}
当前流场 DliveD_{\mathrm{live}}0.0000 s−10.0000\,\mathrm{s^{-1}}
上次投影前 DbeforeD_{\mathrm{before}}n/a\text{n/a}
上次投影后 DafterD_{\mathrm{after}}n/a\text{n/a}
散度压缩倍数n/a\text{n/a}
上次实际迭代次数n/a\text{n/a}
投影快照状态还没有投影
平均动能 K/ρK/\rho0.00 J kg−10.00\,\mathrm{J\,kg^{-1}}
峰值涡量 ∣ω∣max⁡\lvert\omega\rvert_{\max}0.00 s−10.00\,\mathrm{s^{-1}}

物理教程

可操纵喷流:平流、扩散与投影分别做什么

背景速度和染料都存放在一张固定网格上。每个时间步交替做速度扩散、平流和压力投影,然后搬运染料。横向和纵向各用自己的实际网格间距;慢放只改变播放速度,读数的时间单位不变。

为什么值得理解把求解步骤一步步拆开,旋涡就不只是好看的特效。你能测出压力投影前后的散度,也能看到稳定性和数值耗散之间的取舍。

先抓重点

核心问题
速度场被随手推乱以后,为什么一次压力投影就能让它重新接近不可压缩?
一句话直觉
压力投影从中间速度里减去一个速度势的梯度。暂停后刷入动量、只做投影,就能比较同一个场的前后变化。迭代次数有限,网格又是同位网格,总会剩下测得出的残余,所以不能说已经做到 ∇h⋅u=0\nabla_h\cdot\boldsymbol{u}=0。

核心数学模型

不可压缩速度演化

∂u∂t+(u⋅∇)u=−∇p+ν∇2u+f,∇⋅u=0\frac{\partial\boldsymbol{u}}{\partial t}+\left(\boldsymbol{u}\cdot\nabla\right)\boldsymbol{u}=-\nabla p+\nu\nabla^2\boldsymbol{u}+\boldsymbol{f},\qquad \nabla\cdot\boldsymbol{u}=0

平流搬运动量,黏性把速度差扩散开,喷口和流体刷提供外力,压力让流场保持不可压缩。

半 Lagrangian 回溯

ϕn+1(x)≈ϕn ⁣(x−Δt un(x))\phi^{n+1}(\boldsymbol{x})\approx\phi^n\!\left(\boldsymbol{x}-\Delta t\,\boldsymbol{u}^n(\boldsymbol{x})\right)

从每个网格点逆着速度往回追,在落点插值取旧场的值。这一步很稳健,但反复插值会抹平细节。

压力投影

∇h2φ=∇h⋅u∗,u′=u∗−∇hφ\nabla_h^2\varphi=\nabla_h\cdot\boldsymbol{u}^{*},\qquad \boldsymbol{u}'=\boldsymbol{u}^{*}-\nabla_h\varphi

程序存的是速度势,时间步和密度因子已经并在里面,所以它不是以帕斯卡计的压力。网格格子是矩形,Poisson 松弛在横向和纵向用不同的权重。迭代次数有限,投影后散度不一定严格为零。

当前场的散度均方根

Dlive=1Nf∑i∈fluid(∇h⋅u)i2,R=DbeforeDafterD_{\mathrm{live}}=\sqrt{\frac{1}{N_f}\sum_{i\in\mathrm{fluid}}\left(\nabla_h\cdot\boldsymbol{u}\right)_i^2},\qquad R=\frac{D_{\mathrm{before}}}{D_{\mathrm{after}}}

当前值每次都从此刻的速度重新算。上次投影的前后两个值是一对历史快照,刷入动量或改动参数后会标为过期。速度场为零时,压缩比没有定义。

常见难点

稳定不等于精确

容易误解算法没爆掉,说明所有小旋涡都算对了。

正确理解半 Lagrangian 平流在较大时间步下也能保持稳定,但插值会带来数值耗散。涡量增强只是把视觉细节补回来,丢掉的真实尺度找不回来。

粒子有纵深,不等于求解是三维的

容易误解粒子分布有纵深,所以求解器已经解析了三维湍流。

正确理解所有粒子读的都是同一个二维速度截面。纵深只是让结构更容易看清,不会产生三维的涡拉伸。

动手实验

  1. 01

    建立圆柱尾迹

    选择“圆柱尾迹”,等染料绕过障碍。

    你会看到: 喷流在圆柱前减速并分成两股;圆柱后方是一片低速尾迹,里面的涡旋转方向左右交替。
  2. 02

    检查压力投影

    暂停求解,开启流体刷,拖出一个扰动。打开“散度诊断”,点击“只做压力投影”。改变迭代次数后再投影一次。

    你会看到: “上次投影前”的读数等于点击前的当前散度,“上次投影后”的读数等于新的当前散度。时间和染料都不前进。迭代次数加多,残余通常更小,但这仍不能证明流场严格不可压缩。
  3. 03

    亲手加入动量

    开启流体刷,在尾迹里横向拖动;想旋转装置时再关掉刷子。

    你会看到: 拖过的地方,染料和速度一起变化。新扰动随后被平流带走、扩散开,并再次经过压力投影。

概念灵感:FluidMotion。模拟和图形都是原创,模型的适用范围见上文。

反馈这个页面有错误、看不明白,或者缺了什么?告诉我们
反馈类型

提交时会附带本页地址、Lab ID、网站语言和设备类型。请不要填写个人信息。反馈最多保存 12 个月。隐私政策