欢迎光临
我们一直在努力

SWE 的原理解析

二、SWE 的运动机制

SWE 的运动机制可以理解成:水面坡度改变流速,流动的汇聚和发散改变水深。

假设你在平静水面中央制造一个隆起:

  • 中央与周围出现水面高度差。
  • 高度差产生水平压力梯度,使水向周围加速。
  • 中央流出的水多,水面下降;周围得到水,水面上升。
  • 当水面暂时变平时,水仍然具有速度。
  • 水继续运动,产生新的凹陷和隆起,扰动由此向外传播。
  • 所以,SWE 需要同时保存“水有多少”和“水如何运动”。

    这也解释了为什么:仅根据当前高度图,通常不能唯一决定下一时刻的水面。 两片形状完全相同的水面,可能一个正在向外流动,另一个正在向内汇聚,它们下一刻的变化会不同。

    1、质量守恒

    对于密度恒定的水,质量守恒等价于体积守恒。

    不可压缩流体的三维连续性方程(散度形式):

    ∂u∂x+∂w∂y+∂v∂z=0
    \\frac{\\partial u}{\\partial x} + \\frac{\\partial w}{\\partial y} + \\frac{\\partial v}{\\partial z} = 0
    ∂x∂u​+∂y∂w​+∂z∂v​=0

    考虑水平面积为 A 的一个网格单元,内部水的体积为:

    V=Ah
    V = Ah
    V=Ah

    若流入、流出的体积流量分别为 Qin、Qout,那么:

    dVdt=Qin−Qout
    \\frac{dV}{dt} = Q_{in} – Q_{out}
    dtdV​=Qin​−Qout​

    因此:

    dhdt=Qin−QoutA
    \\frac{dh}{dt} = \\frac{Q_{in} – Q_{out}}{A}
    dtdh​=AQin​−Qout​​

    例如,面积为1m^2的单元,每秒流入 0.03m^3、流出 0.01m^3,水深就每秒增加 0.02m。

    把这个关系写成连续空间中的方程:

    ∂h∂t+∂(hu)∂x+∂(hv)∂z=0
    \\frac{\\partial h}{\\partial t} + \\frac{\\partial(hu)}{\\partial x} + \\frac{\\partial(hv)}{\\partial z} = 0
    ∂t∂h​+∂x∂(hu)​+∂z∂(hv)​=0

    其中:

    • hu:沿 x 方向的单位宽度体积流量;
    • hv:沿 z 方向的单位宽度体积流量;
    • 后两项之和:一个位置附近净流出的程度。

    净流出为正,水深下降;净流入为正,水深上升。这就是没有外部水源时的连续性方程。

    展开可以得到:

    ∂h∂t+u∂h∂x+v∂h∂z=−h(∂u∂x+∂v∂z)
    \\frac{\\partial h}{\\partial t} + u\\frac{\\partial h}{\\partial x} + v\\frac{\\partial h}{\\partial z} = -h\\left( \\frac{\\partial u}{\\partial x} + \\frac{\\partial v}{\\partial z} \\right)
    ∂t∂h​+u∂x∂h​+v∂z∂h​=−h(∂x∂u​+∂z∂v​)

    右侧括号内是水平速度的散度:

    ∇⋅u=∂u∂x+∂v∂z
    \\nabla\\cdot\\boldsymbol{u} = \\frac{\\partial u}{\\partial x} + \\frac{\\partial v}{\\partial z}
    ∇⋅u=∂x∂u​+∂z∂v​

    跟随水流观察时:

    • 速度场向外发散,水柱被摊开,水深减小;
    • 速度场向内汇聚,水被堆积,水深增大。

    水本身没有被压缩,改变的是水柱的形状。

    2、水平动量方程

    另外两条核心方程是水平动量方程,它们决定流速怎样变化。

    先考虑固定底床,并忽略摩擦、风力和地球自转:

    ∂u∂t+u∂u∂x+v∂u∂z=−g∂η∂x
    \\frac{\\partial u}{\\partial t} + u\\frac{\\partial u}{\\partial x} + v\\frac{\\partial u}{\\partial z} = -g\\frac{\\partial\\eta}{\\partial x}
    ∂t∂u​+u∂x∂u​+v∂z∂u​=−g∂x∂η​

    ∂v∂t+u∂v∂x+v∂v∂z=−g∂η∂x
    \\frac{\\partial v}{\\partial t} + u\\frac{\\partial v}{\\partial x} + v\\frac{\\partial v}{\\partial z} = -g\\frac{\\partial\\eta}{\\partial x}
    ∂t∂v​+u∂x∂v​+v∂z∂v​=−g∂x∂η​

    这两条式子结构相同,只是分别描述两个水平方向。

    ∂u∂t⏟固定位置的流速变化+u∂u∂x+v∂u∂z⏟流动带来的对流加速度=−g∂η∂x⏟水面坡度引起的加速度
    \\underbrace{\\frac{\\partial u}{\\partial t}}_{\\text{固定位置的流速变化}} + \\underbrace{ u\\frac{\\partial u}{\\partial x} + v\\frac{\\partial u}{\\partial z} }_{\\text{流动带来的对流加速度}} = \\underbrace{ -g\\frac{\\partial\\eta}{\\partial x} }_{\\text{水面坡度引起的加速度}}
    固定位置的流速变化∂t∂u​​​+流动带来的对流加速度u∂x∂u​+v∂z∂u​​​=水面坡度引起的加速度−g∂x∂η​​​

    “对流加速度”可以这样理解:水流到了另一个速度不同的位置,跟随这团水观察,它的速度就会发生变化。

    右边的负号表示,重力所产生的压力作用会使水沿水面降低的方向加速。水面坡度决定的是加速度,而不是直接决定速度。 因此,水面刚变平时,水仍然可能继续流动。

    压力项的来源也很直观。静水压力近似为:

    p=ρg(η−Y)
    p=\\rho g(\\eta-Y)
    p=ρg(η−Y)

    这里使用相对于大气压的压力。在相同竖直高度 Y 上,水面越高,上方压着的水越多,压力越大:

    −1ρ∂p∂x=−g∂η∂x
    -\\frac{1}{\\rho}\\frac{\\partial p}{\\partial x} = -g\\frac{\\partial\\eta}{\\partial x}
    −ρ1​∂x∂p​=−g∂x∂η​

    这就得到了动量方程中的驱动力。

    2.1 动量

    动量(Momentum):是流体带有的“运动的力量”。

    p=mv
    p = mv
    p=mv

    2.2 动量通量

    通量(Flux):​单位时间内,垂直穿过单位面积的某种物理量​。

    动量通量(Momentum Flux)就是指:单位时间内,通过单位面积的动量。

    动量通量=ρu⊗u
    动量通量 = \\rho u ⊗ u
    动量通量=ρu⊗u

    其中 ρ 是密度,u 是速度矢量,⊗ 是张量积。

    如果把它展开,在二维(x, z 平面)的浅水方程中,动量通量张量大概长这样:

    [ρu2ρuwρwuρw2]
    \\begin{bmatrix}
    \\rho u^2 & \\rho uw \\\\
    \\rho wu & \\rho w^2
    \\end{bmatrix}
    [ρu2ρwu​ρuwρw2​]

    • 对角线上的 ρu² 和 ρw² 叫做​正应力​(相当于水流动带来的动压)。
    • 非对角线上的 ρuw 叫做​剪应力​(不同方向水流交错摩擦、拉扯带来的力)。
    2.3 三维 N-S 方程

    对于不可压缩、无粘性的流体,三维 N-S 方程在 xx 方向的动量方程为:

    ∂u∂t+u∂u∂x+v∂u∂y+w∂u∂z=−1ρ∂p∂x+fx
    \\frac{\\partial u}{\\partial t} + u\\frac{\\partial u}{\\partial x} + v\\frac{\\partial u}{\\partial y} + w\\frac{\\partial u}{\\partial z} = -\\frac{1}{\\rho}\\frac{\\partial p}{\\partial x} + f\\mathrm{x}
    ∂t∂u​+u∂x∂u​+v∂y∂u​+w∂z∂u​=−ρ1​∂x∂p​+fx

    其中 u, v, w 分别是 x, y, z 方向的速度, y 是竖直方向,p 是压强, fx 是外力。

    ​2.4 x ​方向动量守恒方程。
    2.4.1 从三维N-S方程出发(x方向)

    利用连续性方程(质量守恒的散度形式),我们可以将左边的对流项(非线性项)改写为​守恒形式​(Flux form,把所有东西都塞进偏导数里面的形式):

    ∂u∂x+∂v∂y+∂w∂z=0
    \\frac{\\partial u}{\\partial x} + \\frac{\\partial v}{\\partial y} + \\frac{\\partial w}{\\partial z} = 0
    ∂x∂u​+∂y∂v​+∂z∂w​=0

    代入 N-S 方程:

    ∂u∂t+u∂u∂x+v∂u∂y+w∂u∂z+u(∂u∂x+∂v∂y+∂w∂z)=−1ρ∂p∂x+fx
    \\frac{\\partial u}{\\partial t} + u\\frac{\\partial u}{\\partial x} + v\\frac{\\partial u}{\\partial y} + w\\frac{\\partial u}{\\partial z} + u(\\frac{\\partial u}{\\partial x} + \\frac{\\partial v}{\\partial y} + \\frac{\\partial w}{\\partial z}) = -\\frac{1}{\\rho}\\frac{\\partial p}{\\partial x} + f\\mathrm{x}
    ∂t∂u​+u∂x∂u​+v∂y∂u​+w∂z∂u​+u(∂x∂u​+∂y∂v​+∂z∂w​)=−ρ1​∂x∂p​+fx

    ∂u∂t+2u∂u∂x+(v∂u∂y+u∂v∂y)+(w∂u∂z+u∂w∂z)=−1ρ∂p∂x+fx
    \\frac{\\partial u}{\\partial t} + 2u\\frac{\\partial u}{\\partial x} + (v\\frac{\\partial u}{\\partial y} + u\\frac{\\partial v}{\\partial y}) + (w\\frac{\\partial u}{\\partial z} + u\\frac{\\partial w}{\\partial z}) = -\\frac{1}{\\rho}\\frac{\\partial p}{\\partial x} + f\\mathrm{x}
    ∂t∂u​+2u∂x∂u​+(v∂y∂u​+u∂y∂v​)+(w∂z∂u​+u∂z∂w​)=−ρ1​∂x∂p​+fx

    整理得:

    ∂u∂t+∂u2∂x+∂uv∂y+∂uw∂z=−1ρ∂p∂x+fx
    \\frac{\\partial u}{\\partial t} + \\frac{\\partial u^2}{\\partial x} + \\frac{\\partial uv}{\\partial y} + \\frac{\\partial uw}{\\partial z} = -\\frac{1}{\\rho}\\frac{\\partial p}{\\partial x} + f\\mathrm{x}
    ∂t∂u​+∂x∂u2​+∂y∂uv​+∂z∂uw​=−ρ1​∂x∂p​+fx

    2.4.2 沿水深 y 方向积分

    由于浅水方程得核心假设是:水平尺度远大于垂直尺度,那么我们假设垂直方向的加速度可以忽略不记,那么有:

    v∂u∂y≈u∂v∂y≈0
    v\\frac{\\partial u}{\\partial y} \\approx u\\frac{\\partial v}{\\partial y} \\approx0
    v∂y∂u​≈u∂y∂v​≈0

    将上述方程从水底 b(x, z)积分到水面 η(x,z,t):

    ∫bη∂u∂tdy=∂∂t∫bηudy=∂hu∂t
    \\int_{b}^{\\eta} \\frac{\\partial u}{\\partial t} dy = \\frac{\\partial}{\\partial t} \\int_{b}^{\\eta} udy = \\frac{\\partial hu}{\\partial t}
    ∫bη​∂t∂u​dy=∂t∂​∫bη​udy=∂t∂hu​

    ∫bη∂(u2)∂xdy=∂∂x∫bηu2dy=∂(hu2)∂x
    \\int_{b}^{\\eta} \\frac{\\partial (u^2)}{\\partial x} dy = \\frac{\\partial}{\\partial x}\\int_{b}^{\\eta} u^2dy = \\frac{\\partial (hu^2)}{\\partial x}
    ∫bη​∂x∂(u2)​dy=∂x∂​∫bη​u2dy=∂x∂(hu2)​

    ∫bη∂(uw)∂zdy=∂∂z∫bηuwdy=∂(huw)∂z
    \\int_{b}^{\\eta} \\frac{\\partial (uw)}{\\partial z} dy = \\frac{\\partial}{\\partial z}\\int_{b}^{\\eta} uwdy = \\frac{\\partial (huw)}{\\partial z}
    ∫bη​∂z∂(uw)​dy=∂z∂​∫bη​uwdy=∂z∂(huw)​

    将 w 改为 v,表示 z 方向上的水流速度。

    2.4.3 处理压强梯度项

    根据​静水压强假设​,任意深度 yy 处的压强由上方水柱的重量产生:

    p(y)=ρg(η−y)
    p(y) = ρg(η−y)
    p(y)=ρg(η−y)

    (其中 ​η ​是水面高度,ρ ​是密度,g ​是重力加速度)

    将其代入积分(利用莱布尼茨积分法则,并考虑到水面 ηη 和水底 bb 随 xx 的变化):

    −1ρ∫bη∂p∂xdy=−g∫bη∂(η−y)∂xdy=−gh∂η∂x
    -\\frac{1}{\\rho}\\int_{b}^{\\eta} \\frac{\\partial p}{\\partial x}dy = – g\\int_{b}^{\\eta} \\frac{\\partial (\\eta – y)}{\\partial x}dy = – gh\\frac{\\partial \\eta}{\\partial x}
    −ρ1​∫bη​∂x∂p​dy=−g∫bη​∂x∂(η−y)​dy=−gh∂x∂η​

    2.4.4 处理底坡/外力项

    方程右边还有一个重力在底坡上的分量 fx,重力沿坡面的分力为:

    fx=−g∂b∂x
    f\\mathrm{x} = -g\\frac{\\partial b}{\\partial x}
    fx=−g∂x∂b​

    积分后(考虑到 hh 的厚度):

    ∫bηfxdy=−gh∂b∂x
    \\int_{b}^{\\eta} f\\mathrm{x} dy = -gh\\frac{\\partial b}{\\partial x}
    ∫bη​fxdy=−gh∂x∂b​

    2.4.5 合并与化简

    最终得到:

    ∂(hu)∂t+∂∂x(hu2+12gh2)+∂(huv)∂z=−gh∂b∂x
    \\frac{\\partial (hu)}{\\partial t} + \\frac{\\partial}{\\partial x}(hu^2 + \\frac{1}{2}gh^2) + \\frac{\\partial (huv)}{\\partial z} = -gh\\frac{\\partial b}{\\partial x}
    ∂t∂(hu)​+∂x∂​(hu2+21​gh2)+∂z∂(huv)​=−gh∂x∂b​

    如上我们就得到了包含固定底床起伏的二维非线性 SWE 方程组:

    ①∂h∂t+∂(hu)∂x+∂(hv)∂z=0
    ①\\frac{\\partial h}{\\partial t} + \\frac{\\partial(hu)}{\\partial x} + \\frac{\\partial(hv)}{\\partial z} = 0
    ①∂t∂h​+∂x∂(hu)​+∂z∂(hv)​=0

    ②∂(hu)∂t+∂∂x(hu2+12gh2)+∂(huv)∂z=−gh∂b∂x
    ②\\frac{\\partial (hu)}{\\partial t} + \\frac{\\partial}{\\partial x}(hu^2 + \\frac{1}{2}gh^2) + \\frac{\\partial (huv)}{\\partial z} = -gh\\frac{\\partial b}{\\partial x}
    ②∂t∂(hu)​+∂x∂​(hu2+21​gh2)+∂z∂(huv)​=−gh∂x∂b​

    ③∂(hv)∂t+∂(huv)∂x+∂∂z(hu2+12gh2)=−gh∂b∂z
    ③\\frac{\\partial (hv)}{\\partial t} + \\frac{\\partial (huv)}{\\partial x} + \\frac{\\partial}{\\partial z}(hu^2 + \\frac{1}{2}gh^2) = -gh\\frac{\\partial b}{\\partial z}
    ③∂t∂(hv)​+∂x∂(huv)​+∂z∂​(hu2+21​gh2)=−gh∂z∂b​

    3、初始化项

    有地形时,一个关键性质是:水深不同,也可以完全静止。
    静水平衡满足:

    u=v=0,η=常数
    u = v = 0, \\eta = 常数
    u=v=0,η=常数

    由于:

    h=η−b
    h = \\eta – b
    h=η−b

    底床起伏会使水深变化,但水平水面不会因此产生水平加速度。

    在守恒方程中,这种静止依靠两部分相互抵消:

    ∂∂x(12gh2)=−gh∂b∂x
    \\frac{\\partial}{\\partial x} \\left(\\frac12gh^2\\right) = -gh\\frac{\\partial b}{\\partial x}
    ∂x∂​(21​gh2)=−gh∂x∂b​

    如果程序分别近似压力通量和底床源项,却没有让它们正确平衡,就可能出现“没有施加扰动,水也自己流动”的假象。

    能够在离散计算中保持这类平衡的数值方法称为 ​well-balanced,良平衡方法​。静水重构是实现这一性质的一类经典方法。

    因此,做 Unity 地形水体时,静水初始化通常应当是:

    h(x,z,0)=max⁡(η_0−b(x,z),0)
    h(x,z,0)=\\max\\big(\\eta\\_0-b(x,z),0\\big)
    h(x,z,0)=max(η_0−b(x,z),0)

    4、SWE 波速

    4.1 连续性方程

    考虑平底、静止背景水体,平均水深为常数 H。令:

    h=H+ζ
    h = H + \\zeta
    h=H+ζ

    为了推导方便,我们现在只看一维(x 方向),忽略 z 方向的流动(或者假设流动在 z 方向均匀),方程变成:

    ∂h∂t+∂(hu)∂x=0
    \\frac{\\partial h}{\\partial t} + \\frac{\\partial (hu)}{\\partial x} = 0
    ∂t∂h​+∂x∂(hu)​=0

    利用乘积求导法则展开第二项:

    ∂h∂t+h∂u∂x+u∂h∂x=0
    \\frac{\\partial h}{\\partial t} + h\\frac{\\partial u}{\\partial x} + u \\frac{\\partial h}{\\partial x}= 0
    ∂t∂h​+h∂x∂u​+u∂x∂h​=0

    引入“微小扰动(小振幅波)”假设,假设水面本来平静(静止水深为 H),你往水里丢了一颗小石子。水面产生了一个非常微小的波澜(高度为 ζ)。

    此时:总水深 h(x,t)=H+ζ(x,t),并且水流速度 u(x,t) 也非常小。

    把 h=H+ζ 代入刚才的一维方程:

    ∂(H+ζ)∂t+(H+ζ)∂u∂x+u∂(H+ζ)∂x=0
    \\frac{\\partial (H+\\zeta)}{\\partial t} + (H + \\zeta)\\frac{\\partial u}{\\partial x} + u\\frac{\\partial (H+\\zeta)}{\\partial x} = 0
    ∂t∂(H+ζ)​+(H+ζ)∂x∂u​+u∂x∂(H+ζ)​=0

    由于H 是不随时间变化的常数,则有:

    ∂H∂t=∂H∂x=0
    \\frac{\\partial H}{\\partial t} = \\frac{\\partial H}{\\partial x} = 0
    ∂t∂H​=∂x∂H​=0

    又因为 ζ 和 u 都是微小量,可以忽略,也有:

    ζ≈0,u≈0
    \\zeta \\approx 0, u \\approx 0
    ζ≈0,u≈0

    所以原式等于:

    ∂ζ∂t+H∂u∂x=0
    \\frac{\\partial \\zeta}{\\partial t} + H\\frac{\\partial u}{\\partial x} = 0
    ∂t∂ζ​+H∂x∂u​=0

    4.2 动量方程

    在只考虑一维(x方向)且忽略底部摩擦的情况下,浅水方程的标准动量方程是:

    ∂u∂t+u∂u∂x=−g∂η∂x
    \\frac{\\partial u}{\\partial t} + u\\frac{\\partial u}{\\partial x} = -g\\frac{\\partial \\eta}{\\partial x}
    ∂t∂u​+u∂x∂u​=−g∂x∂η​

    • ​左边​:速度随时间的变化率 + ​对流加速度​(你之前问过的,流体跑到了流速不同的地方产生的加速度)。
    • ​右边​:由水面高度差(压力梯度)产生的加速度(水往低处流)。

    现在,假设水面非常平静,轻轻吹了一口气,产生了一个极小的涟漪。

    • 水流速度 u 非常非常小(趋近于 0)。
    • 水面高度的变化量 ζ 也非常非常小。

    则有:

    u∂u∂x≈0
    u\\frac{\\partial u}{\\partial x} \\approx 0
    u∂x∂u​≈0

    那么原式就变为:

    ∂u∂t+g∂η∂x=0
    \\frac{\\partial u}{\\partial t} + g\\frac{\\partial \\eta}{\\partial x} = 0
    ∂t∂u​+g∂x∂η​=0

    4.3 计算波速

    对连续性方程两边求 t 的偏导:

    ∂2ζ∂t2+H∂2u∂x∂t=0
    \\frac{\\partial^2 \\zeta}{\\partial t^2} + H\\frac{\\partial^2 u}{\\partial x \\partial t} = 0
    ∂t2∂2ζ​+H∂x∂t∂2u​=0

    对动量方程两边求 x 的偏导:

    ∂2u∂x∂t+g∂η∂2x=0
    \\frac{\\partial^2 u}{\\partial x \\partial t} + g\\frac{\\partial \\eta}{\\partial^2 x} = 0
    ∂x∂t∂2u​+g∂2x∂η​=0

    联立得到:

    ∂2ζ∂t2=Hg∂2η∂x2
    \\frac{\\partial^2 \\zeta}{\\partial t^2} = Hg\\frac{\\partial^2 \\eta}{\\partial x^2}
    ∂t2∂2ζ​=Hg∂x2∂2η​

    又因为:

    η=ζ+H
    \\eta = \\zeta + H
    η=ζ+H

    则有:

    ∂2η∂t2=Hg∂2η∂x2
    \\frac{\\partial^2 \\eta}{\\partial t^2} = Hg\\frac{\\partial^2 \\eta}{\\partial x^2}
    ∂t2∂2η​=Hg∂x2∂2η​

    波动方程标准形式为:

    ∂2η∂t2=c2∂2η∂x2
    \\frac{\\partial^2 \\eta}{\\partial t^2} = c^2\\frac{\\partial^2 \\eta}{\\partial x^2}
    ∂t2∂2η​=c2∂x2∂2η​

    所以得到物理波速公式:

    c=gH
    c = \\sqrt{gH}
    c=gH​

    • g 是重力加速度(约 9.81 m/s29.81m/s2)
    • HH 是​静水深​(或者当地实际水深 hh)

    ​这个公式非常直观​:

    • 水越深,波传得越快(太平洋里的海啸速度接近飞机)。
    • 水越浅,波传得越慢(冲上海滩的波浪会减速)。

    三、数值离散方法

    从方程到程序,需要选择数值离散方法。SWE 本身并不是某一种固定算法。

    常见的层次关系是:

    层次解决的问题示例
    物理模型 水遵循什么规律 非线性 SWE、线性 SWE
    空间离散 怎样表示空间变化 有限差分、有限体积、有限元
    界面通量 相邻单元之间交换多少量 Rusanov、HLL、Roe
    时间推进 怎样从当前状态推进到下一时刻 显式 Euler、Runge–Kutta

    3.1 物理模型

    3.1.1 选择物理模型的目的

    真实水体包含大量现象:

    • 水平流动、竖直运动;
    • 压力变化;
    • 黏性、摩擦和湍流;
    • 波浪传播、破碎、飞溅;
    • 不同波长的波以不同速度传播。

    如果完整保留这些现象,求解成本会非常高。因此,需要选择一个适合研究目标的简化模型。

    SWE 的主要简化是:沿水深方向进行平均,用水深和深度平均水平速度描述水体,并采用静水压力近似。它适用于水深相对水平运动尺度较小的情况。

    选择物理模型,本质上是在决定:哪些现象需要计算,哪些现象可以近似或忽略。

    3.1.2 一维非线性 SWE

    对于平底、没有摩擦和外力的一维水流,非线性 SWE 为:

    ∂h∂t+∂(hu)∂x=0
    \\frac{\\partial h}{\\partial t} + \\frac{\\partial (hu)}{\\partial x} = 0
    ∂t∂h​+∂x∂(hu)​=0

    ∂(hu)∂x+∂∂x(hu2+12gh2)=0
    \\frac{\\partial (hu)}{\\partial x} + \\frac{\\partial }{\\partial x}(hu^2 + \\frac{1}{2}gh^2) = 0
    ∂x∂(hu)​+∂x∂​(hu2+21​gh2)=0

    第一条描述质量守恒,第二条描述水平动量守恒。

    定义状态向量:

    U=[hm],m=hu
    U = \\begin{bmatrix} h \\\\ m \\end{bmatrix}, m = hu
    U=[hm​],m=hu

    其中,m 是省略常数密度因子的动量变量。

    再定义物理通量:

    F(U)=[mm2h+12gh2]
    F(U) = \\begin{bmatrix} m \\\\ \\frac{m^2}{h} + \\frac{1}{2}gh^2 \\end{bmatrix}
    F(U)=[mhm2​+21​gh2​]

    于是,两条方程可以统一写成:

    ∂U∂t+∂F(U)∂x=0
    \\frac{\\partial U}{\\partial t} + \\frac{\\partial F(U)}{\\partial x} = 0
    ∂t∂U​+∂x∂F(U)​=0

    这里的“非线性”,意味着状态量之间存在乘积、平方等关系。例如:

    hu,hu2,h2
    hu,hu^2,h^2
    hu,hu2,h2

    水深和速度会相互影响,波的传播速度也依赖当前状态:

    u−gh,u+gh
    u – \\sqrt{gh},u+\\sqrt{gh}
    u−gh​,u+gh​

    因此,波浪的不同部分可能具有不同传播速度,逐渐形成陡峭波面,甚至出现水跃等间断结构。

    3.1.3 一维线性 SWEH

    假设水体最初静止,平均水深为常数 H,扰动为 ζ:

    h=H+ζ
    h = H + \\zeta
    h=H+ζ

    线性化时忽略扰动量之间的高阶乘积,化简连续性方程得到:

    ∂ζ∂t+H∂u∂x=0
    \\frac{\\partial \\zeta}{\\partial t} + H\\frac{\\partial u}{\\partial x} = 0
    ∂t∂ζ​+H∂x∂u​=0

    动量方程相应简化为:

    ∂u∂t+g∂ζ∂x=0
    \\frac{\\partial u}{\\partial t} + g\\frac{\\partial \\zeta}{\\partial x} = 0
    ∂t∂u​+g∂x∂ζ​=0

    它们描述围绕静止背景的小扰动传播,波速为:

    c=gH
    c = \\sqrt{gH}
    c=gH​

    3.1.4 两种物理模型的区别
    比较内容线性 SWE非线性 SWE
    主要描述对象 背景状态附近的小扰动 较一般的浅水流动
    状态之间的相互作用 经过线性化简化 保留非线性耦合
    静止、常水深背景的波速 固定为\\(\\sqrt{gH}\\) 随局部水深、流速变化
    水跃、明显的波面陡化 不能完整描述 可以描述,需合适的数值格式
    典型用途 小波动分析、简化波纹模拟 浅水流动、溃坝、交互水体等

    把网格加密,不能补回物理模型已经忽略的现象。

    例如,线性 SWE 即使用很细的网格,也不会自动变成非线性 SWE;基础 SWE 即使求解得非常精确,也不会自动产生真实水滴和翻卷浪头。

    此外,物理问题还需要配套的初始条件、边界条件和外部作用。例如:最初的水深、墙壁位置、入口流量,以及物体怎样向水体施加扰动。

    3.2 空间离散

    3.2.1 空间离散的含义

    连续模型中的:

    h(x,t),u(x,t)
    h(x, t),u(x, t)
    h(x,t),u(x,t)

    在任意位置都具有值。计算机无法保存无限多个位置,因此需要用有限个数据近似整个空间。

    例如,将一条水槽划分为 N 个区域:

    Δx=LN
    \\Delta x = \\frac{L}{N}
    Δx=NL​

    但“划分网格”只是开始,还需要明确:

    • 每个位置保存什么;
    • 一个区域内部的状态怎样表示;
    • 空间导数或区域积分怎样近似。

    有限差分、有限体积和有限元,在这些问题上采用不同思路。下面通过一维网格来介绍这些方法。

    3.2.2 有限差分法

    有限差分法通常保存若干位置上的函数值:

    hi(t)≈h(xi,t)
    h_i(t)\\approx h(x_i,t)
    hi​(t)≈h(xi​,t)

    例如,用中心差分近似水面坡度:

    ∂η∂x∣xi≈ηi+1−ηi−12Δx
    \\left. \\frac{\\partial \\eta}{\\partial x} \\right |_{x_i} \\approx \\frac{\\eta_{i+1}-\\eta_{i-1}}{2\\Delta x}
    ∂x∂η​​xi​​≈2Δxηi+1​−ηi−1​​

    如果采用线性 SWE:

    ∂u∂t=−g∂ζ∂x
    \\frac{\\partial u}{\\partial t} = -g\\frac{\\partial \\zeta}{\\partial x}
    ∂t∂u​=−g∂x∂ζ​

    空间离散后就得到:

    duidt≈−gζi+1−ζi−12Δx
    \\frac{du_i}{dt} \\approx -g\\frac{\\zeta_{i+1}-\\zeta_{i-1}}{2\\Delta x}
    dtdui​​≈−g2Δxζi+1​−ζi−1​​

    原本连续的空间导数,变成了相邻数据之间的运算。注意,此时只完成了空间离散,还没有决定如何推进时间。

    有限差分法的直观特点是:

    • 对规则网格很容易实现;
    • 相邻采样和纹理操作比较自然;
    • 可以构造高阶导数近似;
    • 稳定性和守恒性取决于具体格式。

    空间离散(算空间导数)和时间离散(算时间推进)必须满足稳定性条件(CFL 条件),且不同组合的稳定性完全不同。 不要以为随便用什么方法(比如中心差分 + 显示时间推进)都能算出正确结果。

    3.2.3 有限体积法

    有限体积法把每个网格视为一个有大小的控制体。

    1、有限体积法区域内存量变化计算

    一维情况下,单元 i 的左右边界为:

    xi−12,xi+12
    x_{i – \\frac{1}{2}},x_{i + \\frac{1}{2}}
    xi−21​​,xi+21​​

    这里:

    • 整数下标 i:单元;
    • 半整数下标 i+1/2:两个单元之间的界面。

    保存的状态是单元平均值:

    Ui‾=1Δx∫xi−12xi+12U(x,t) dx
    \\overline{U_i} = \\frac{1}{\\Delta x}\\int_{x_{i-\\frac{1}{2}}}^{x_{i+\\frac{1}{2}}} U(x, t)\\,dx
    Ui​​=Δx1​∫xi−21​​xi+21​​​U(x,t)dx

    公式两边同时对时间 t 求导数:

    Ui‾=ddt(1Δx∫xi−12xi+12U(x,t) dx)
    \\overline{U_i} = \\frac{d}{dt} \\left ( \\frac{1}{\\Delta x}\\int_{x_{i-\\frac{1}{2}}}^{x_{i+\\frac{1}{2}}} U(x, t)\\,dx \\right )
    Ui​​=dtd​​Δx1​∫xi−21​​xi+21​​​U(x,t)dx​

    积分区间固定,可以由莱布尼茨积分法则把时间导数直接移到积分括号里面:

    Ui‾=1Δx∫xi−12xi+12∂U(x,t)∂t dx
    \\overline{U_i} = \\frac{1}{\\Delta x}\\int_{x_{i-\\frac{1}{2}}}^{x_{i+\\frac{1}{2}}} \\frac{\\partial U(x, t)}{\\partial t}\\,dx
    Ui​​=Δx1​∫xi−21​​xi+21​​​∂t∂U(x,t)​dx

    由一维浅水方程核心部分:

    ∂U∂t+∂F∂x=0
    \\frac{\\partial U}{\\partial t} + \\frac{\\partial F}{\\partial x} = 0
    ∂t∂U​+∂x∂F​=0

    其中 U=[h,hu]T,F=[hu,hu2+12gh2]T
    其中\\,U=[h, hu]^T,F = [hu, hu^2+\\frac{1}{2}gh^2]^T
    其中U=[h,hu]T,F=[hu,hu2+21​gh2]T

    将其带入刚才的积分中:

    dUi‾dt=1Δx∫xi−12xi+12(−∂F(x,t)∂x)dx
    \\frac{d\\overline{U_i}}{dt} = \\frac{1}{\\Delta x}\\int_{x_{i-\\frac{1}{2}}}^{x_{i+\\frac{1}{2}}} \\left ( -\\frac{\\partial F(x, t)}{\\partial x}\\right )dx
    dtdUi​​​=Δx1​∫xi−21​​xi+21​​​(−∂x∂F(x,t)​)dx

    最终得到:

    dUi‾dt=−F(xi+12)−F(xi−12)Δx
    \\frac{d\\overline{U_i}}{dt} = -\\frac{F(x_{i+\\frac{1}{2}}) – F(x_{i-\\frac{1}{2}})}{\\Delta x}
    dtdUi​​​=−ΔxF(xi+21​​)−F(xi−21​​)​

    实际计算时,再用数值通量近似界面通量:

    dUi‾dt=−F^(xi+12)−F^(xi−12)Δx
    \\frac{d\\overline{U_i}}{dt} = -\\frac{\\widehat{F}(x_{i+\\frac{1}{2}})- \\widehat{F}(x_{i-\\frac{1}{2}})}{\\Delta x}
    dtdUi​​​=−ΔxF(xi+21​​)−F(xi−21​​)​

    上式表达的是:单元内部存量的变化。由左右两侧的净流入决定。

    2、有限体积元的内部守恒变量的处理

    ① 常数

    有限体积法并不意味着每个单元内部永远只能是一个常数。最简单的做法是分片常数,即整个单元都使用同一个状态。这通常对应基础的一阶空间近似。即:

    U(x)≈U‾i
    U(x) \\approx \\overline{U}_i
    U(x)≈Ui​

    ② 线性重构

    使用分片线性重构:

    Ui(x)≈U‾i+σi(x−xi)
    U_i(x) \\approx \\overline{U}_i + \\sigma_i(x – x_i)
    Ui​(x)≈Ui​+σi​(x−xi​)

    其中 σi 是单元内的斜率。

    这样可以更好地表示平滑波形。但在陡峭波面附近,直接使用较大的斜率可能产生过冲,例如计算出不合理的负水深。因此,通常需要限制器;对于 SWE,还可能需要额外的正水深约束与静水平衡处理。

    3.2.4 有限元法

    有限元法的基本形式是:

    Uh(x,t)=∑jaj(t)ϕj(x)
    U_h(x, t) = \\sum_{j}a_j(t) \\phi_j(x)
    Uh​(x,t)=j∑​aj​(t)ϕj​(x)

    其中:

    • ϕj(x)ϕj​(x):预先选定的基函数;
    • aj(t)aj​(t):需要求解的系数;
    • UhUh​:对真实状态的近似。

    例如,最简单的线性单元,可以通过端点值在单元内部进行线性插值。

    随后,将微分方程乘以测试函数并进行积分,使方程在这种积分意义下成立。这称为​弱形式​。

    有限元也有不同类型。连续 Galerkin 有限元通常要求相邻单元的解满足相应连续性;间断 Galerkin(DG)允许单元之间出现状态跳跃,因此同样需要数值界面通量来连接相邻单元。

    3.2.5 三种离散方法的区别
    方法常见未知量表示对当前项目的主要考虑
    有限差分 网格点上的状态值 规则网格实现直接,适合先理解导数和波动
    有限体积 单元平均状态 便于明确跟踪水量、动量以及区域之间的交换
    有限元 基函数系数 适合复杂几何、高阶近似等需求,入门实现更复杂

    3.3 界面通量

    3.3.1 物理通量和数值通量的关系

    物理模型给出了:

    F(U)=[huhu2+12gh2]
    F(U) = \\begin{bmatrix} hu \\\\ hu^2 + \\frac{1}{2}gh^2 \\end{bmatrix}
    F(U)=[huhu2+21​gh2​]

    但在离散网格中,同一个界面有两个来源不同的状态:

    UL,UR
    U_L,U_R
    UL​,UR​

    它们分别来自:

    • 左单元的右边界;
    • 右单元的左边界。

    两侧水深、速度可能不同,因此:

    F(UL)≠F(UR)
    F(U_L) \\neq F(U_R)
    F(UL​)=F(UR​)

    而一个共享界面需要有统一的交换量,因此要根据左右两侧状态计算:

    F‾=F(UL,UR)
    \\overline{F} = \\mathcal F(U_L, U_R)
    F=F(UL​,UR​)

    这里:

    • F:由物理模型规定的物理通量;
    • \\mathcal F:选择的数值通量算法;
    • \\overline F:实际用于网格更新的界面通量。
    3.3.2 局部 Riemann 问题

    可以把两个单元之间的界面暂时看成一道隔板:

    • 左侧具有状态 UL;
    • 右侧具有状态 UR;
    • 在某一时刻移除隔板。

    随后会产生波,并在界面附近形成新的流动状态。

    这种左右初始状态各自为常数的问题,称为 ​Riemann 问题​。

    精确求解它可以得到界面处的状态和通量。但在大量网格、每个时间步都要计算的情况下,通常会采用近似求解器。

    3.3.3 Rusanov:平均物理通量,加上数值耗散

    Rusanov 通量也称局部 Lax-Friderichs 通量:

    F^Rus=FL+FR2−a2(UR−UL)
    \\widehat F _{Rus} = \\frac{F_L + F_R}{2}-\\frac{a}{2}(U_R-U_L)
    FRus​=2FL​+FR​​−2a​(UR​−UL​)

    其中:

    FL=F(UL),FR=F(UR)
    F_L = F(U_L),F_R = F(U_R)
    FL​=F(UL​),FR​=F(UR​)

    对全湿 SWE,一种常见的局部速度估计为:

    a=max(∣uL∣+ghL,∣uR∣+ghR)
    a = max \\left ( |u_L| + \\sqrt{gh_L},|u_R| + \\sqrt{gh_R} \\right )
    a=max(∣uL​∣+ghL​​,∣uR​∣+ghR​​)

    公式分为两部分:

    FL+FR2
    \\frac{F_L + F_R}{2}
    2FL​+FR​​

    取两侧物理通量的平均值;

    −a2(UR−UL)
    -\\frac{a}{2}(U_R-U_L)
    −2a​(UR​−UL​)

    根据状态差异加入数值耗散。

    这种耗散有助于抑制振荡,但也可能把陡峭变化和细小波纹抹平。因此,Rusanov 实现简单,但计算出的波浪细节也与网格大小、重构阶数有关。

    例如,设:

    hL=2,hR=1uL=uR=0,g=9.81
    h_L = 2,h_R = 1 \\\\
    u_L = u_R = 0,g = 9.81
    hL​=2,hR​=1uL​=uR​=0,g=9.81

    则:

    UL=[20],UR=[10]
    U_L = \\begin{bmatrix} 2 \\\\ 0 \\end{bmatrix},U_R = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}
    UL​=[20​],UR​=[10​]

    物理通量为:

    FL=[019.62],FR=[04.905]
    F_L = \\begin{bmatrix} 0 \\\\ 19.62 \\end{bmatrix},F_R = \\begin{bmatrix} 0 \\\\ 4.905 \\end{bmatrix}
    FL​=[019.62​],FR​=[04.905​]

    最大速度估计:

    a=9.81×2≈4.429
    a = \\sqrt{9.81 \\times 2} \\approx 4.429
    a=9.81×2​≈4.429

    最终:

    F^Rus≈[2.21512.263]
    \\widehat F_{Rus} \\approx \\begin{bmatrix} 2.215 \\\\ 12.263 \\end{bmatrix}
    FRus​≈[2.21512.263​]

    第一项是单位宽度体积流量,正号表示向右输水。

    尽管两侧初始速度都是零,水深差引起的压力不平衡仍会产生流动。 数值通量是在近似界面问题随即发生的演化。

    3.3.4 HLL:分别估计向左和向右的波速

    HLL 使用两个波速:

    SL,SR
    S_L,S_R
    SL​,SR​

    分别表示最左侧和最右侧传播信号的速度估计。

    对全湿 SWE,一种基础估计是:

    SL=min(uL−ghL,uR−ghR)SL=max(uL+ghL,uR+ghR)
    S_L = min\\left ( u_L – \\sqrt{gh_L},u_R – \\sqrt{gh_R} \\right ) \\\\
    S_L = max\\left ( u_L + \\sqrt{gh_L},u_R + \\sqrt{gh_R} \\right )
    SL​=min(uL​−ghL​​,uR​−ghR​​)SL​=max(uL​+ghL​​,uR​+ghR​​)

    具体求解器也可能采用更稳健的速度估计,干床情况尤其需要专门处理。

    HLL 通量为:

    F^HLL={FL,SL≥0SRFL−SLFR+SLSR(UR−UL)SR−SL,SL<0<SRFR,SR≤0
    \\widehat F_{HLL} =
    \\begin{cases}
    F_L, & S_L \\ge0 \\\\
    \\frac{S_R F_L – S_L F_R + S_L S_R(U_R – U_L)}{S_R-S_L}, & S_L < 0 < S_R \\\\
    F_R, & S_R \\le0
    \\end{cases}
    FHLL​=⎩⎨⎧​FL​,SR​−SL​SR​FL​−SL​FR​+SL​SR​(UR​−UL​)​,FR​,​SL​≥0SL​<0<SR​SR​≤0​

    它体现了传播方向:

    • 如果所有信号都向右传播,界面由左侧状态决定;
    • 如果所有信号都向左传播,界面由右侧状态决定;
    • 如果信号向两侧传播,就使用中间表达式。

    HLL 将两个外侧波之间的复杂结构近似为一个平均状态。

    Rusanov 与 HLL 还有一个直接关系。令:

    SL=−a,SR=a
    S_L = -a,S_R = a
    SL​=−a,SR​=a

    HLL 就会化简成 Rusanov 通量。

    所以,​HLL 并不保证在每一种状态下都比 Rusanov 更精细​;采用对称速度估计时,两者可以完全相同。

    3.3.5 Roe:分解不同的波,再分别处理传播

    Roe 的思路是:在界面附近构造一个具有特定守恒性质的局部线性系统,用它近似原来的非线性问题。

    对一维 SWE,常用 Roe 平均为:

    u~=uLhL+uRhRhL+hRh~=hL+hR2,c~=gh~
    \\widetilde u = \\frac{u_L \\sqrt{h_L} + u_R{\\sqrt{h_R}}}{\\sqrt{h_L} + \\sqrt{h_R}} \\\\
    \\widetilde h = \\frac{h_L + h_R}{2},\\widetilde c = \\sqrt{g\\widetilde h}
    u=hL​​+hR​​uL​hL​​+uR​hR​​​h=2hL​+hR​​,c=gh​

    两个特征速度为:

    λ~1=u~−c~,λ~2=u~+c~
    \\widetilde \\lambda_1 = \\widetilde u – \\widetilde c,\\widetilde \\lambda_2 = \\widetilde u + \\widetilde c
    λ1​=u−c,λ2​=u+c

    把状态差分解成两个波:

    UR−UL=α1r1+α2r2
    U_R – U_L = \\alpha_1 \\boldsymbol r_1 + \\alpha_2\\boldsymbol r_2
    UR​−UL​=α1​r1​+α2​r2​

    再计算:

    F^Roe=FL+FR2−12∑p=12∣λ~p∣αprp
    \\widehat F_{Roe} = \\frac{F_L + F_R}{2} – \\frac{1}{2}\\sum_{p=1}^{2}|\\widetilde \\lambda_p| \\alpha_p \\boldsymbol r_p
    FRoe​=2FL​+FR​​−21​p=1∑2​∣λp​∣αp​rp​

    可以把它理解为:每一种波按照自己的传播速度提供相应的数值耗散。

    Roe 能较细致地处理波结构,但标准 Roe 方法还存在需要处理的问题,例如跨声速稀疏波的熵修正,以及某些状态下出现非物理负水深。

    3.3.6 三种通量应怎样比较
    通量核心做法主要考虑
    Rusanov鲁萨诺夫 一个最大传播速度控制耗散 简单,适合作为基础实现;耗散可能较大
    HLL 使用左右两个传播速度 体现传播方向,稳健性依赖速度估计等配套处理
    Roe 对不同特征波分别处理 波结构分辨较细,需要熵修正、正水深等处理

    ​一个单元界面的平均水面是平的,也不意味着动量通量为零​。静水中仍有压力通量;静止状态依靠两侧压力作用相互抵消来保持。

    3.4 时间推进

    3.4.1 空间离散后,得到的是变化率

    完成空间离散和通量计算后,可以写出:

    dU‾idt=Li(U‾)
    \\frac{d\\overline{\\boldsymbol U}_i}{dt} = \\mathcal L_i(\\overline{\\boldsymbol U})
    dtdUi​​=Li​(U)

    其中:

    Li(U‾)=−F^i+12−F^i−12Δx+S‾i
    \\mathcal L_i(\\overline{\\boldsymbol U}) = -\\frac{ \\widehat{\\boldsymbol F}_{i+\\frac12} – \\widehat{\\boldsymbol F}_{i-\\frac12} }{\\Delta x} + \\overline{\\boldsymbol S}_i
    Li​(U)=−ΔxFi+21​​−Fi−21​​​+Si​

    \\mathcal L 是离散空间算子,它负责根据当前状态计算:

    • 各界面的流动;
    • 单元内水深的变化率;
    • 单元内动量的变化率;
    • 必要的源项作用。

    此时,整个问题成为一组关于时间的常微分方程。

    时间推进方法决定:如何利用这些变化率,把当前状态推进到下一时刻。

    这种先离散空间、再求解时间变化的方法通常称为线方法。

    3.4.2 显式 Euler:使用当前变化率前进一步

    显示 Euler 为:

    U(n+1)=Un+ΔtL(Un)
    U^(n+1) = U^n + \\Delta t \\mathcal L(U^n)
    U(n+1)=Un+ΔtL(Un)

    含义是:假设在这一个短时间段内,状态按照当前变化率变化。它只计算一次空间算子,形式最简单,时间精度为一阶。

    使用 3.3.3 中的例子,设两个单元宽度均为:

    Δx=1m
    \\Delta x = 1 m
    Δx=1m

    它们之间的体积通量约为:

    F^h=2.215m2/s
    \\widehat F_h = 2.215 m^2/s
    Fh​=2.215m2/s

    若外侧边界没有水流通过,取:

    Δt=0.05s
    \\Delta t = 0.05s
    Δt=0.05s

    则左单元水深减少:

    ΔhL=−ΔtΔxF^h≈−0.1107m
    \\Delta h_L = – \\frac{\\Delta t}{\\Delta x}\\widehat F_h \\approx -0.1107m
    ΔhL​=−ΔxΔt​Fh​≈−0.1107m

    右单元增加相同水深:

    ΔhR≈+0.1107m
    \\Delta h_R \\approx +0.1107m
    ΔhR​≈+0.1107m

    于是:

    hLn+1≈1.8893hRn+1≈1.1107
    h_L^{n+1} \\approx 1.8893 \\\\
    h_R^{n+1} \\approx 1.1107
    hLn+1​≈1.8893hRn+1​≈1.1107

    这里展示了质量分量;实际求解器还必须同步更新动量分量。

    4.2.3 Runge-Kutta:在一个时间步内多次评估变化率

    Runge–Kutta 是一类方法的统称。它通过构造中间状态,多次评估变化率,再组合得到下一时刻的结果。

    常见的二阶 SSP Runge–Kutta 为:

    U(1)=Un+ΔtL(Un)U(n+1)=12Un+12[U(1)+ΔtL(U(1))]
    U^{(1)}=U^n+\\Delta t\\mathcal L(U^n) \\\\
    U^{(n+1)}=\\frac{1}{2}U^n+\\frac{1}{2}\\left [ U^{(1)}+\\Delta t \\mathcal L(U^{(1)}) \\right ]
    U(1)=Un+ΔtL(Un)U(n+1)=21​Un+21​[U(1)+ΔtL(U(1))]

    第一阶段得到预测状态;第二阶段重新计算预测状态下的变化率,再进行组合。第二阶段必须重新计算通量。

    4.2.4 SSPRK3 与“强稳定保持”

    三阶 SSP Runge-Kutta 的常见形式为:

    U(1)=Un+ΔtL(Un)U(2)=34Un+14[U(1)+ΔtL(U(1))]U(n+1)=13Un+23[U(2)+ΔtL(U(2))]
    U^{(1)}=U^n+\\Delta t\\mathcal L(U^n) \\\\
    U^{(2)}=\\frac{3}{4}U^n+\\frac{1}{4}\\left [ U^{(1)}+\\Delta t \\mathcal L(U^{(1)}) \\right ] \\\\
    U^{(n+1)}=\\frac{1}{3}U^n+\\frac{2}{3}\\left [ U^{(2)}+\\Delta t \\mathcal L(U^{(2)}) \\right ]
    U(1)=Un+ΔtL(Un)U(2)=43​Un+41​[U(1)+ΔtL(U(1))]U(n+1)=31​Un+32​[U(2)+ΔtL(U(2))]

    它需要三次空间算子评估。

    SSP 的含义是:如果空间离散与前向 Euler 在一定步长限制下具有某种合适的稳定性质,SSP 时间方法可以在相应限制下保留该性质。它不能自动修复本来就不稳定或会产生负水深的空间离散。

    3.2.5 三种离散方式的区别
    方法时间阶数每步空间算子评估次数
    显式 Euler 1 1
    SSPRK2 2 2
    SSPRK3 3 3
    经典 RK4 4 4

    时间阶数更高,并不自动意味着更适合你的实现。还需要考虑稳定性、空间误差、显存访问和总计算成本。

    3.2.6 时间精度与空间精度的耦合

    假设空间离散只有一阶,而时间推进使用四阶 RK,整体误差仍可能主要来自空间离散:

    误差∼CxΔx+CtΔt4
    误差 \\sim C_x \\Delta x + C_t \\Delta t^4
    误差∼Cx​Δx+Ct​Δt4

    这是平滑解条件下的示意关系。

    因此:

    • 一阶空间方法加高阶时间方法,不能自动恢复被空间耗散抹掉的波纹;
    • 高阶空间方法加过于粗糙的时间推进,也可能损失精度;
    • 存在间断时,局部精度还会受到限制器等因素影响。

    一个常见的升级方向是:先建立一阶有限体积与显式 Euler 基线,再增加受限线性重构和 SSPRK2。

    3.2.7 时间步长的稳定性要求

    对常见一维显式格式,CFL 条件具有如下形式:

    Δt≤CCFLΔxmaxi(∣ui∣+ghi)
    \\Delta t \\leq C_{CFL}\\frac{\\Delta x}{max_i(|u_i|+\\sqrt{gh_i})}
    Δt≤CCFL​maxi​(∣ui​∣+ghi​​)Δx​

    这里的 Ccfl 上限依赖具体格式。对于显式 Euler 时间推进,一维情况下 ​Cmax=1;但在多维或高阶格式下,通常取 0.5∼0.9 ​以确保安全。

    二维非分裂格式常见的保守步长形式为:

    Δt≤CCFLaxΔx+azΔz
    \\Delta t \\leq \\frac{C_{CFL}}{\\frac{a_x}{\\Delta x}+\\frac{a_z}{\\Delta z}}
    Δt≤Δxax​​+Δzaz​​CCFL​​

    其中 ax, az 是两个方向的最大传播速度估计。

    CFL 约束将前面各层联系起来:物理模型决定传播速度,空间网格决定信息需要跨越的距离,时间方法影响允许的稳定步长。显式 SWE 求解器通常据此选择时间步。

    对于二维规则网格,如果其他条件不变,将两个方向的网格间距都减半:

    • 单元总数约增加到 4 倍;
    • 显式时间步通常也需要减半;
    • 模拟同样物理时长的基础计算量可能接近 8 倍。
    赞(0)
    未经允许不得转载:171主机测评 » SWE 的原理解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址