跳到主要内容
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。模拟与图形均为原创,模型适用边界见上文。