【CFD小工坊】浅水方程的离散及求解方法

【CFD小工坊】浅水方程的离散及求解方法

前言

我们模型的控制方程,即浅水方程组的表达式如下:
∂ U ∂ t + ∂ E ( U ) ∂ x + ∂ G ( U ) ∂ y = S ( U ) U = ( h h u h v ) , E ( U ) = ( h u h u 2 + g h 2 2 h u v ) , G ( U ) = ( h v h u v h v 2 + g h 2 2 ) , S ( U ) = ( 0 g h ( S 0 x − S f x ) g h ( S 0 y − S f y ) ) S 0 x = − ∂ z b ∂ x , S 0 y = − ∂ z b ∂ y S f x = n 2 u u 2 + v 2 h − 4 / 3 , S f y = n 2 v u 2 + v 2 h − 4 / 3 \dfrac{\partial \bold{U}}{\partial t} + \dfrac{\partial \bold{E(U)}}{\partial x} + \dfrac{\partial \bold{G(U)}}{\partial y} = \bold{S(U)} \\[6pt] \bold{U} = \left( \begin{matrix} h \\ hu \\ hv \end{matrix} \right), \bold{E(U)} = \left( \begin{matrix} hu \\ hu^2+\dfrac{gh^2}{2} \\ huv \end{matrix} \right), \bold{G(U)} = \left( \begin{matrix} hv \\ huv \\ hv^2+\dfrac{gh^2}{2} \end{matrix} \right), \\[6pt] \bold{S(U)} = \left( \begin{matrix} 0 \\ gh(S_{0x} - S_{fx}) \\ gh(S_{0y} - S_{fy}) \end{matrix} \right) \\[6pt] S_{0x} = -\dfrac{\partial z_b}{\partial x}, S_{0y} = -\dfrac{\partial z_b}{\partial y} \\[6pt] S_{fx} = n^2 u \sqrt{u^2+v^2} h^{-4/3}, S_{fy} = n^2 v \sqrt{u^2+v^2} h^{-4/3} ∂t∂U+∂x∂E(U)+∂y∂G(U)=S(U)U= hhuhv ,E(U)= huhu2+2gh2huv ,G(U)= hvhuvhv2+2gh2 ,S(U)= 0gh(S0x−Sfx)gh(S0y−Sfy) S0x=−∂x∂zb,S0y=−∂y∂zbSfx=n2uu2+v2 h−4/3,Sfy=n2vu2+v2 h−4/3

对此,我们首先将式中物理量离散于三角形网格 中,后采用有限体积法将浅水方程改写成其离散形式 。在离散的浅水方程中,水位、流速等物理量的计算可转化为对网格界面的通量项和网格内源项的计算。对于离散方程中的通量项,本模型将会采用基于Riemann近似解的Roe格式数值求解界面通量。

基于有限体积法的方程离散

对于我们的浅水模型,水深、流速等物理量被定义在网格中心,如下图所示。对于网格i与j,它们间的质量、动量传输是通过其网格边界E~i,j~发生的(下图中加粗的网格边)。网格i和j之间边界的外法相量定义为n=(n~x~, n~y~)。

之后,对于控制体网格i,我们采用高斯散度定理将浅水方程沿着边界E~i,j~线积分,得到:
∬ Ω ∂ U ∂ t d Ω = − ∫ S [ E ( U ) n x + G ( U ) n y ] d s + ∬ Ω S ( U ) d Ω \iint_{\Omega} \dfrac{\partial \bold{U}}{\partial t} d\Omega = -\int_{S} [\bold{E(U)}n_x + \bold{G(U)}n_y] ds + \iint_{\Omega} \bold{S(U)} d\Omega ∬Ω∂t∂UdΩ=−∫S[E(U)nx+G(U)ny]ds+∬ΩS(U)dΩ

式中,Ω表示网格i所对应的控制体,S表示边界E~i,j~;dΩ和ds分别表示面积分和线积分的微元。

在我们的模型中,各个水力要素在网格体内被假定是均匀分布的。在对上式的时间导数项采用前差格式离散,得到数值解为:
U i n + 1 = U i n − Δ t Ω i ∑ j = 1 3 F n j L j + Δ t S ˉ F n = E ( U ) n x + G ( U ) n y \bold{U}{i}^{n+1} = \bold{U}{i}^{n} - \dfrac{\Delta t}{\Omega_i} \sum_{j=1}^{3} \bold{F}_{nj}L_j + \Delta t \bar{S} \\[6pt] \bold{F_n} = \bold{E(U)}n_x + \bold{G(U)}n_y Uin+1=Uin−ΩiΔtj=1∑3FnjLj+ΔtSˉFn=E(U)nx+G(U)ny

其中,Δt为时间步长,Ω~i~表示网格单元i的面积,F~nj~表示网格i中第j条边的外通量,L~j~表示网格i中第j条边的长度;S表示源项, S ˉ \bar{S} Sˉ表示源项S在网格i的体积分值。

注意,上式就是模型求解过程中最核心的表达式。它完成了从该时间步水力变量到下一步水力变量的更新计算。

界面通量与源项计算

接下来要解决的问题是通量项 F n \bold{F_n} Fn的计算。首先,我们将网格边通量计算转化为一个Riemann近似解问题。采用Roe格式来求解这个近似黎曼解:
F n = 1 2 ( E ( U ~ L ) + G ( U ~ R ) ) − ∑ k = 1 3 α ~ k ∣ λ k ∣ γ k ) \bold{F_n} = \dfrac{1}{2} (\bold{E(\tilde{U}_L)} + \bold{G(\tilde{U}R))} - \sum{k=1}^{3} \tilde{\alpha}^k |\lambda^k| \gamma^k) Fn=21(E(U~L)+G(U~R))−k=1∑3α~k∣λk∣γk)

式中, λ k \lambda^k λk为基于 Roe 平均的雅克比矩阵 J J J的特征值, γ k \gamma^k γk为特征值对应的特征向量; α k \alpha^k αk表示特征强度。各项表达如下:
{ λ 1 = u ~ − c ~ λ 2 = u ~ λ 3 = u ~ + c ~ , { γ 1 = ( 1 , u − c ~ , v ~ ) T γ 2 = ( 0 , 0 , 1 ) T γ 3 = ( 1 , u + c ~ , v ~ ) T , { α ~ 1 = 1 2 [ h R − h L − h ~ c ~ ( u R − u L ) ] α ~ 2 = h ~ ( v R − v L ) α ~ 3 = 1 2 [ h R − h L + h ~ c ~ ( u R − u L ) ] \left\{ \begin{aligned} \lambda^1 & = \tilde u-\tilde{c} \\ \lambda^2 & = \tilde u \\ \lambda^3 & = \tilde u+\tilde{c} \end{aligned} \right. , \left\{ \begin{aligned} \gamma^1 & = (1, u-\tilde{c}, \tilde{v})^T \\ \gamma^2 & = (0,0,1)^T \\ \gamma^3 & = (1, u+\tilde{c}, \tilde{v})^T \end{aligned} \right. , \left\{ \begin{aligned} \tilde \alpha^1 & = \dfrac{1}{2}[h_R - h_L - \dfrac{\tilde h}{\tilde{c}}(u_R- u_L)] \\ \tilde \alpha^2 & = \tilde h (v_R - v_L) \\ \tilde \alpha^3 & = \dfrac{1}{2}[h_R - h_L + \dfrac{\tilde h}{\tilde{c}}(u_R- u_L)] \end{aligned} \right. ⎩ ⎨ ⎧λ1λ2λ3=u~−c~=u~=u~+c~,⎩ ⎨ ⎧γ1γ2γ3=(1,u−c~,v~)T=(0,0,1)T=(1,u+c~,v~)T,⎩ ⎨ ⎧α~1α~2α~3=21[hR−hL−c~h~(uR−uL)]=h~(vR−vL)=21[hR−hL+c~h~(uR−uL)]

上述变量中下标L和R分别表示该变量是边界内、外侧网格上的值(如上图所示); u ~ \tilde u u~、 v ~ \tilde v v~、 c ~ \tilde{c} c~和 h ~ \tilde h h~都是Roe平均变量,定义如下:
u ~ = u L h L + u R h R h L + h R , v ~ = v L h L + v R h R h L + h R , c ~ = g ( h L + h R ) 2 , h ~ = h L h R \tilde{u} = \dfrac{u_L \sqrt{h_L} + u_R \sqrt{h_R}}{\sqrt{h_L} + \sqrt{h_R}}, \tilde{v} = \dfrac{v_L \sqrt{h_L} + v_R \sqrt{h_R}}{\sqrt{h_L} + \sqrt{h_R}}, \\[6pt] \tilde c = \sqrt{\dfrac{g(h_L + h_R)}{2}}, \tilde h=\sqrt{h_L h_R} u~=hL +hR uLhL +uRhR ,v~=hL +hR vLhL +vRhR ,c~=2g(hL+hR) ,h~=hLhR

注意,此处下标含L和R的速度 u ~ \tilde u u~均是垂直于网格边(与外法向n同向)的速度分量,且波速c的方向也与外法向n同向。同理,下标含L和R的 v ~ \tilde v v~则是与法相量n相垂直。

此外,对源项S中的底坡和摩阻项的处理将直接关系到模型的计算精度和稳定性。为了获得和谐、守恒的结果,对底坡源项进行特征分解和迎风处理以适应Riemann求解格式。首先,对底坡源项在控制体Ω内积分得到 S ˉ 0 \bar{S}0 Sˉ0:
S ˉ 0 = ∑ j = 0 3 ∑ k = 0 3 [ 1 2 ( 1 − s i g n ( λ k ˉ ) ) ( β k r k ˉ ) L j ] j ( β 1 , β 2 , β 3 ) = ( − 1 2 c ~ Δ z b , 0 , 1 2 c ~ Δ z b ) , Δ z b = ( z b ) L − ( z b ) R r 1 ˉ = ( 1 u ~ + c ~ v ~ ) , r 2 ˉ = ( 0 0 c ~ ) , r 3 ˉ = ( 1 u ~ − c ~ v ~ ) , \bar{S}0 = \sum{j=0}^{3} \sum
{k=0}^{3} [\dfrac{1}{2} (1-sign(\bar{\lambda^k})) ({\beta^k} \bar{r^k}) L_{j}]^j \\[6pt] (\beta^1,\beta^2,\beta^3)= (-\dfrac{1}{2}\tilde{c}\Delta{z_b}, 0 , \dfrac{1}{2}\tilde{c}\Delta{z_b}), \Delta{z_b} = (z_b)_L - (z_b)_R \\[6pt] \bar{r^1}= \left( \begin{matrix} 1 \\ \tilde{u} + \tilde{c} \\ \tilde{v} \end{matrix} \right), \bar{r^2}= \left( \begin{matrix} 0 \\ 0 \\ \tilde{c} \end{matrix} \right), \bar{r^3}= \left( \begin{matrix} 1 \\ \tilde{u} - \tilde{c} \\ \tilde{v} \end{matrix} \right), Sˉ0=j=0∑3k=0∑3[21(1−sign(λkˉ))(βkrkˉ)Lj]j(β1,β2,β3)=(−21c~Δzb,0,21c~Δzb),Δzb=(zb)L−(zb)Rr1ˉ= 1u~+c~v~ ,r2ˉ= 00c~ ,r3ˉ= 1u~−c~v~ ,

式中,sign( )为符号函数。

为增加格式的稳定性,对摩阻源项进行半隐式离散,其表达式为:
S f = ( 1 − θ ) S f n + θ S f n + 1 = S f n + θ ∂ S f ∂ U ∂ U ∂ t Δ t \bold{S}_f = (1-\theta) \bold{S}_f^{n} + \theta \bold{S}_f^{n+1} = \bold{S}_f^{n} + \theta \dfrac{\partial \bold{S}_f}{\partial \bold{U}} \dfrac{\partial \bold{U}}{\partial t} \Delta t Sf=(1−θ)Sfn+θSfn+1=Sfn+θ∂U∂Sf∂t∂UΔt

θ=0时意味着完全显式,θ=1时意味着完全隐式;令 Q f = ∂ S f ∂ U \bold{Q}f = \dfrac{\partial \bold{S}f}{\partial \bold{U}} Qf=∂U∂Sf,离散后的动量方程通量表达式为:
Δ U = U n + 1 − U n = [ I − Δ t θ Q f n ] − 1 [ Δ t Ω i ∑ j = 1 3 ( F n j + ∑ k = 0 3 [ 1 2 ( 1 − s i g n ( λ k ˉ ) ) ( β k r k ˉ ) ) L j + Δ t S f ] \Delta \bold{U} = \bold{U}^{n+1} - \bold{U}^{n} = [\bold{I}- \Delta t \theta \bold{Q}f ^{n}]^{-1} [\dfrac{\Delta t}{\Omega_i} \sum{j=1}^{3} (\bold{F}
{nj} +\sum
{k=0}^{3} [\dfrac{1}{2} (1-sign(\bar{\lambda^k})) ({\beta^k} \bar{r^k}) )L_j + \Delta t \bold{S}_f] ΔU=Un+1−Un=[I−ΔtθQfn]−1[ΩiΔtj=1∑3(Fnj+k=0∑3[21(1−sign(λkˉ))(βkrkˉ))Lj+ΔtSf]

干-湿网格的处理

对于复杂的地形,计算区域内的实际模拟范围和计算边界变化频繁。网格上可能出现淹没-干底-再淹没的过程,这对模型的计算提出较高的稳定性要求。为避免水深较小时网格=出现流速过大的非物理现象,本模型采用限制水深法来准确、稳定地模拟网格淹没、干底这一过程。

首先,设置两个临界水深 h d r y h_{dry} hdry和 h w e t h_{wet} hwet(且 h d r y < h w e t h_{dry}<h_{wet} hdry<hwet),再将网格分为三类:

  1. 当水深大于 h w e t h_{wet} hwet,该网格为"湿网格",参与正常的模拟计算,同时求解质量和动量通量;
  2. 当水深小于 h d r y h_{dry} hdry,该网格为"干网格",不参与当前时间步的计算;
  3. 当水深在 h d r y h_{dry} hdry和 h w e t h_{wet} hwet之间,该网格为"半干网格",仅计算该时间步的质量通量,而没有计算动量通量。

数值离散的稳定性条件

本模型基于Riemann显式方法,即当前时刻的网格变量可直接由上一时刻的计算结果得到,无需经过迭代计算。但显式求解法受到CFL条件的限制,实际计算过程中的最大时间步长通常不为定值。

本模型将采用动态时间步长方法得到模拟的时间步长;同时需要用户输入一个可允许的最大步长 Δ t m a x \Delta t_{max} Δtmax,以及一个允许的最大Courant数 C m a x C_{max} Cmax( 0 < C < 1.0 0< C <1.0 0<C<1.0)。模型的时间步长按下式确定:
Δ t = m i n ( Δ t m a x , C m a x m i n ( R i u i 2 + v i 2 + g h i ) ) , i = 1 , 2 , 3 , . . . , N c \Delta t = min(\Delta t_{max}, C_{max} min(\dfrac{R_i}{\sqrt{u^2_i + v^2_i} + \sqrt{gh_i}})), i=1,2,3,...,N_c Δt=min(Δtmax,Cmaxmin(ui2+vi2 +ghi Ri)),i=1,2,3,...,Nc

参考文献

  1. 刘臻,史宏达,黄燕.一种基于Roe格式的有限体积法在二维溃坝问题中的应用[J].中国海洋大学学报:自然科学版, 2007, 37(2):5.
  2. [王志力,耿艳芬,金生.具有复杂计算域和地形的二维浅水流动数值模拟[J].水利学报, 2005, 36(4):6.
相关推荐
kitesxian9 分钟前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode
VertexGeek1 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz1 小时前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
jiao_mrswang2 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca2 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱2 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子2 小时前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
是阿建吖!2 小时前
【优选算法】二分查找
c++·算法
王燕龙(大卫)2 小时前
leetcode 数组中第k个最大元素
算法·leetcode
不去幼儿园3 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习