版本对应:
shallowWaterFoam不好归类于任何一个求解器模块。因此在所有的OpenFOAM版本中,都通过shallowWaterFoam来调用。
CFD: 浅水方程算法
浅水方程的假设是高度方向的流动尺度要远远小于水平面的尺度。在这种情况下,可以认为高度方向的速度近似为0。不考虑粘性的浅水方程是标准的双曲偏微分方程系统。其有的时候也会被称之为Saint-Venant方程。由于浅水方程构成了一个双曲系统,因此浅水方程与欧拉方程类似,可以用于研究各类对流格式。
控制方程
浅水方程的控制方程为
其中\(h\)表示水深,\(h_0\)表示河底的高度,其为一个用户自定义高度,\(\bfF=(2\boldsymbol{\Omega}\cdot\bfn_g)\bfn_g\)表示科氏力,\(\bfn_g\)表示重力方向的单位矢量。方程(1)表示的是关于水深的连续性方程。方程(2)表示的是关于\(\bfU\)的动量方程。
考虑一维情况,如果忽略科氏力源项,浅水方程可以写为
现在观察\(-|\bfg|h\frac{\p( h+h_0)}{\p x}\),有:
大量的文献将其写为矢量形式:
其中
方程(7)可以进一步的用来分析方程的特征值以及特征向量,其被文献证明为一个双曲系统。
离散
回到OpenFOAM中求解的方程(1)与(2)。在求解中动量方程可以使用守恒变量或者原始变量。OpenFOAM求解的为守恒变量,即将\(h\bfU\)看做一个整体。在这里定义:
因此有:
如果不考虑科氏力,则可以简化为
方程(1)与(11)是shallowWaterFoam求解的浅水方程。(1)可以求解\(h\),(11)可以求解\(\mathcal{U}_h\)。但由于二者直接互相耦合,如果在一个时间步内顺序求解,存在失耦特性,因此迭代算法必不可少。
现将整个迭代思路进行简述。参考CFD:不可压+瞬态算法,若进行动量预测步骤,则需要针对方程(11)对\(\mathcal{U}_h\)做离散,其中时间项以及对流项均为隐性离散,\(h\)的梯度项需要显性离散,求解后有\(\mathcal{U}_h^*\)。若不进行动量预测步骤,则仅仅使用时间项与对流项进行离散并组建矩阵,\(\mathcal{U}_h\)不更新。两种情况下都可组建\(\bfHbyA_\rP^{*}\):
注意:
若进行动量预测,方程右侧为\(\mathcal{U}_h^*\)。若不进行动量预测,方程右侧为\(\mathcal{U}_h^t\)。
其中\(\bfHbyA_\rP^*\)并没有考虑\(-|\bfg|h\nabla(h+h_0)\)的贡献。因此在后续组建\(h\)方程的时候,需要考虑体积力(浮力)的附加效应。将\(\bfHbyA_\rP^*\)可以带入到方程(1)中可求解\(h\),求解\(h\)后,可更新\(\mathcal{U}_h^{**}\)。由于\(h\)与\(\mathcal{U}_h^{**}\)的解耦求解,因此需要迭代2-3次。此即浅水方程求解的思想。
对于连续性方程,将其进行离散且考虑\(h\)的梯度项贡献后有:
求解方程(15)后,有\(h^*\)。其可用于更新\(\mathcal{U}_h\):
有了\(\mathcal{U}_h^{**}\),可以通过方程(12)继续更新下一个迭代步的\(\bfHbyA\),进而继续更新\(\mathcal{U}_h\)。整个迭代过程迭代2-3次即可进行下一个时间步的推进。
关键代码
fvVectorMatrix hUEqn
(
fvm::ddt(hU)
+ fvm::div(phiv, hU)
);
上述代码对应无源项的方程(11)。
fvScalarMatrix hEqn
(
fvm::ddt(h)
+ fvc::div(phiHbyA)
- fvm::laplacian(ghrAUf, h)
);
上述代码对应无源项的方程(15)。
hU = HbyA - rAU*h*magg*fvc::grad(h + h0);
上述代码对应无源项的方程(16)。