第I部分 基础流体方程流体无所不在,从我们呼吸的空气到占据整个地球三分之二的海洋,就是它,形成了我们这个星球上那些最美丽最震撼景象:从溅起的水花,到冲天的火焰,到缭绕的烟雾,流体仿真已经成为了计算机图形学的重要课题。本书将讲述制作这类仿真动画的基础,所以,让我们从描述它们运动的微分方程开始吧。在动画中,流体运动服从于著名的“不可压缩的纳维-斯托克斯方程”,这是一组偏微分方程,它们通常写成下面的形式:第一眼瞧上去,它们相当复杂!我们很快就会把它们拆解成容易理解的部分(附录B提供了严格的学术描述),不过,我们首先还是讲讲方程里面出现的符号的含义。
符号字母在流体力学的传统中用于表示流体的速度。为啥不用?这很难说,一种说法是,我们通常约定用来指代三维空间的速度矢量( u, v, w ),而u排在前面,就如同我们通常使用来指代三维空间的位置矢量( x, y, z ),而x排在前面。希腊字母ρ用来表示流体的密度。水的密度是1000公斤/立方米,空气大约是1.3公斤/立方米,两者的比率大概是700 : 1。字母p表示压强,流体施加在任何其他物体上的单位面积上的力。字母是我们熟悉的重力加速度,通常取( 0, -9.81, 0 ) m/s2。顺便提一下,在本书坐标系中,我们取y轴正方向为向上,x轴和z轴是水平轴。在动画中,额外的加速度,例如用来让流体整体流向某个设定的方向所添加的加速度,都会添加到重力项上。我们会把它们打包到一起,用字母来表示。更一般的,人们通常把这一项叫做“体力”( body force ),因为它作用在整个流体上,而不是某个面上。希腊字母ν从技术上讲,叫做运动粘度。它用于度量流体的粘度。像蜂蜜这样的流体具有较高的粘度,而像水银这样的流体则具有较低的粘度。它表示的是流体在流动的时候抵抗变形的能力(或者更直观的说,把它们搅动起来有多难)。
动量方程第一个微分方程(方程1.1),它实际上是三个方程打包到一起的一个矢量方程,它叫做动量方程。它实际上是由古老的牛顿方程变形过来的。它告诉我们当外力作用到流体上的时候所产生的加速度。第二个微分方程(方程1.2)被称为不可??缩条件。我们先来拆解第一个方程。首先让我们想象一下,我们正在使用粒子来仿真一个流体(本书后面会真的使用粒子法,不过现在我们只是用粒子来做一个思想实验)。每一个粒子都是组成流体的一个小液滴。描述它的参数有:质量m,体积V,速度。为了弄清楚在下一个时刻,整个系统的状况,我们需要算出每个粒子的受力情况,通过我们可以算出粒子的加速度,然后获取其运动。我们把加速度写成下面这个有点怪的形式(稍后我们会变形为前面的动量方程的形式):
大写字母D所表示的微分符号被称为“物质导数”( material derivation )。牛顿定律现在就可以写成:
那么,粒子究竟受到了哪些力的作用呢?最简单的当然是重力了: 不过,当我们考虑流体受到剩下的其它力的时候,事情就有意思了:粒子与其它相邻的粒子是如何相互作用的呢?第一个流体力是压力。高压区域向低压区域的推力。注意,我们真正关心的是作用在粒子上的净力:例如,如果压力在各个方向上都相等,那么净力为零,压力就不会产生加速度了。只有当流体的粒子处于不平衡状态时,流体才会流动,例如,粒子一侧的压力高于另一侧的压力,结果就会在粒子上产生一个从高压区域指向低压区域的力。在附录中我们会严格推导这个过程,不过在这里,我就直接告诉你,粒子在某个位置由于压力差导致其受力的大小等于此处压力场的负梯度:(回忆一下微积分,梯度的方向就是标量场变化速度最快的方向,所以,负梯度总是从高压区指向低压区)我们需要整合小液滴(粒子)整个体积上所受到的作用来得到小液滴受到的压力。作为简单的近似,我们直接乘以体积V。你可能会问,压力究竟是什么?我们暂且先跳过不说,等到讲不可压缩性的时候再讨论,现在你只需要知道,它会让流体永远保持一定的体积。另一个流体力是粘性产生的。带粘性的流体会抵抗变形。后面我们会对此进行深入的推导,而现在,我们可以直观的理解为一种力,它试图使我们的粒子以周围粒子的平均速度来运动,例如,他会试图让我们与临近粒子运动速度的差异最小。你也许还记得,从图像处理,数字几何处理、到扩散物理或热耗散等等其它领域,都会使用一个微分算子,用来度量某个量与周围的平均值相差多远,这个算子就是拉普拉斯算子:(现在是时候复习一下矢量微积分了,附录里有,包括像拉普拉斯算子这样的微分算子)。我们整合整个小液滴体积上受到的这种作用力,就形成了所谓的黏滞力。我们将使用动力粘度系数(dynamic viscosity coefficient)来描述这种属性,以希腊字母 η 表示(动力这个词意味着我们从这个参数计算得出的结果是力,而先前我们使用的运动粘度计算得出的是加速度