参考:
我们有流体力学基本方程的通用形式如下
∂t∂(ρϕ)+∇⋅(ρUϕ)−∇⋅(Γ∇ϕ)=Sϕ
注意!这里的 ϕ 仅表示某种物理量,不要和以后会经常出现的质量通量混淆!
从左至右依次为时间项、对流项、扩散项、源项。其中 Γ 是扩散系数。
本阶段推荐优先理解四大项的离散,把握有限体积法的主要思想,以后再分别理解网格、边界条件、高级离散格式等 内容。
有限体积法的重点
下面详细介绍。
半离散方程
在某一个时间步上,把基本方程对空间离散的单元(网格单元)上做体积积分,有
∫VP(∂t∂(ρϕ)+∇⋅(ρUϕ)−∇⋅(Γ∇ϕ))dV=∫VPSϕdV
整理为
∫VP(∂t∂(ρϕ))dV+∫VP(∇⋅(ρUϕ))dV−∫VP(∇⋅(Γ∇ϕ))dV=∫VPSϕdV
说明
正式开始之前,有必要进行一些说明
符号约定
计算流体力学的几乎每本书的符号系统都不太一样,有时候会让人很困惑。
约定后文中
- 上标指示时间
- 上标 t 表示当前时间步(已知量)。
- 上标 t+1 表示新时间步(待求量)。
- 更高时间步依次类推,使用上标 t+n。
- 下标指示空间
- 下标 P 表示当前单元体心值(取Owner的 O 实在很容易混淆)。
- 下标 N 表示相邻单元体心值(Neighbour)。
- 下标 f 表示当前单元和相邻单元之间的界面的面心值(face)。
- 网格单元属性
- VP 表示单元的体积。做了体积分后,也就是被积系统的体积。
- ∂VP 表示单元的总面积。做了面积分后,也就是被积系统的面积。
平均值
对于有限体积法,我们约定单元信息存储在单元的体中心上,近似等于单元的体平均值
ϕP=ϕˉ=VP1∫VPϕ(x)dV
两个单元的界面上面心值,近似等于面平均值
ϕf=ϕˉf=Sf1∫fϕ(x)dS
高斯定理
高斯定理(散度定理,物理量散度在系统的体积积分等于物理量在系统的面积分)
矢量的高斯定理,结果是标量
∫V∇⋅adV=∫∂Va⋅dS
标量的高斯定理,结果是矢量
∫V∇ϕdV=∫∂Vϕ⋅dS
时间项
时间项如下,
∫VP(∂t∂(ρϕ))dVdt
对时间的偏导和体积没有任何关系,所以上式
∫VP(∂t∂(ρϕ))dVdt=∂t∂(ρϕ)∫VPdV=VP∂t∂(ρϕ)
最终有
时间项半离散表达式
∫VP(∂t∂(ρϕ))dV=VP∂t∂(ρϕ)
注意,时间的偏导需要进一步离散处理。
对流项
对流项如下
∫VP(∇⋅(ρUϕ))dV
由散度定理
∫VP(∇⋅(ρUϕ))dV=∫∂VP(ρUϕ)⋅dS
单元上的面积分等于各个离散面积分的总和
∫∂VP(ρUϕ)⋅dS=f∑∫∂VP(ρUϕ)f⋅dS
每个离散面上的积分近似(产生误差)等于其面心值乘以面矢量
f∑∫∂VP(ρUϕ)⋅dS≈f∑(ρUϕ)f⋅Sf=f∑Ffϕf
最终有
对流项半离散表达式
∫VP(∇⋅(ρUϕ))dV=f∑Ffϕf
其中 Ff 被称为质量通量
Ff=ρfUf⋅Sf
定义对流通量有
FluxC=Ffϕf
理解为因为对流现象,物理量在面上的输运。
注意,因为物理量存储在单元体心上,所以面上的值(下标f) 需要根据体心值进一步离散处理。
扩散项
扩散项如下
∫VP(∇⋅(Γ∇ϕ))dV
由散度定理
∫VP(∇⋅(Γ∇ϕ))dV=∫∂VP(Γ∇ϕ)⋅dS
单元表面是一个完整的闭合面,由若干离散面组成。例如六面体网格由六个离散面组成,单元上的面积分等于这六个个离散面的积分的总和。这里没有引入近似。
∫∂VP(Γ∇ϕ)⋅dS=f∑∫f(Γ∇ϕ)⋅dS
每个离散面上的积分近似(产生误差)等于其面心值乘以面矢量(因为面心值有方向)
f∑∫f(Γ∇ϕ)⋅dS≈f∑(Γ∇ϕ)f⋅Sf
最终有
扩散项半离散表达式
∫VP(∇⋅(Γ∇ϕ))dV=f∑(Γ∇ϕ)f⋅Sf
定义扩散通量
FluxD=(Γ∇ϕ)f⋅Sf
理解为因为扩散现象,物理量在面上的输运。
注意,除了面心值,面心值的梯度也需要进一步离散处理。
源项
源项如下
∫VPSϕdV
当源项是线性的时候 Sϕ=Su+Spϕ
最终有
源项离散表达式
∫VPSϕdV=SuVP+SpVPϕP
半离散方程
VP∂t∂(ρϕ)+f∑Ffϕf−f∑(Γ∇ϕ)f⋅Sf=SuVP+SpVPϕP
- Ffϕf 称为对流通量 convective flux
- (Γ∇ϕ)f⋅Sf 称为扩散通量 diffusive flux
数值处理
半离散方程中还有很多项需要进一步处理。
面插值
线性面插值
对于面心值 Uf ,可以基于本单元和邻单元的体心值,根据一定的插值格式得到
比如
Uf=fxUP+(1−fx)UN
fx=PNfN=∣d∣Xf−XN
物性面插值
对于面心值 Γf ,如果扩散系数也是连续的,可以按照一般面心值离散处理。
如果材料是复合材料,扩散系数在材料变化处理应有一个突变。
插值公式为
Γf=ΓP+ΓN2ΓPΓN
参见 The Finite Volume Method in Computational Fluid Dynamics: An Advanced Introduction with OpenFOAM® and Matlab | SpringerLink 第225页。
输运面插值
对流是有明显流向特征的物理现象。对于一个物理量的对流输运来说,下游的物理量总是小于等于上游。
参考 The Finite Volume Method in Computational Fluid Dynamics: An Advanced Introduction with OpenFOAM® and Matlab | SpringerLink 第11章。
对于待求的面心上的输运量 ϕf 来说,我们需要建立它和体心之间的关系
-
如果我们采用线性面插值格式,求解可能会产生振荡(越界)。
-
如果我们采用迎风格式ϕf=ϕupwind,求解稳定有界,但是精度低且有扩散性。
-
如果我们采用二阶迎风格式,对于强对流,求解会出现大梯度以及振荡(越界)。
-
如果我们使用 TVD 格式(以后讨论),求解具有二阶精度且有界。
所以,我们需要知道离散格式对求解有着很大的影响,不用担心,后续会详细讨论这些数值细节。
不管使用哪种格式,最终面心值和体心值建立了某种插值关系。
梯度
回忆 CFD 基本方程中的动量方程,其中可能会出现的压力梯度
∇p
要怎么离散呢?
- 通过格林高斯法求梯度
对单元面求体积分,应用高斯定理
∫V∇pdV=∫∂VPpdS
面积分等于离散面积分之和,离散面的积分继而等于面心值乘以面矢量
∫∂VPpdS=f∑pfSf
此外,压力梯度本身和体积没有关系,所以另外有
∫V∇pdV=VP∇pP
所以可以建立等式关系,最后有
∇pP=VP1f∑pfSf
- 通过最小二乘法求梯度
参考 The Finite Volume Method in Computational Fluid Dynamics: An Advanced Introduction with OpenFOAM® and Matlab | SpringerLink 第11章。
无论通过哪种方式求梯度,最后得到的是体心梯度值,最后还需要应用面插值格式到面心梯度值。
比如,可以使用简单的线性面插值格式
∇pf=fx∇pP+(1−fx)∇pN
fx=fN/PN
正交修正
扩散项的计算中为什么会有正交修正这个问题呢?
扩散通量的计算为
FluxD=(Γ∇ϕ)f⋅Sf
如果网格是正交的
(Γ∇ϕ)f⋅Sf=Γ∣PN∣ϕN−ϕP∣Sf∣
当网格非正交的时候,如下图所示
对于上图面矢量 Sf 依然垂直于单元面,但是物理量梯度 ∇ϕf 并不垂直于单元面。
将面矢量 Sf 分解成沿 PN 方向 Ef 和其他方向分量 Tf,Tf 的具体方向由正交近似 方法决定。
Sf=Ef+Tf
此时扩散通量计算为
(Γ∇ϕ)f⋅Sf=(Γ∇ϕ)f⋅Ef+(Γ∇ϕ)f⋅Tf=(Γ∂n∂ϕ)fEf+(Γ∇ϕ)f⋅Tf=Γ∣PN∣ϕN−ϕPEf+(∇ϕ)f⋅Tf
右边第一项称为正交影响,第二项称为非正交影响。
正交修正本质上是把扩散量调整到合适的数值,近似分解到了单元面法向上。
- 关于非正交贡献
可以通过插值得到界面上的温度梯度
(∇ϕ)f=gN(∇ϕ)P+gP(∇ϕ)N
其中,由高斯通量求得体心温度的梯度有
(∇T)P=VP1f∑(Tf⋅Sf)
最终还是归结在面通量的计算。
- 关于正交贡献
常见有以下几种近似处理
如果我们采用正交修正近似,即定义
Ef=Sfe
参考 The Finite Volume Method in Computational Fluid Dynamics: An Advanced Introduction with OpenFOAM® and Matlab | SpringerLink 第241页。
以后会详细讨论。
请考虑一个问题,四大项都需要正交修正吗?(不需要回答,带着问题即可)
其他
其他像是网格扭曲修正、松弛等等数值方法均放在后续详细讨论。本阶段,只需要把握最基本的离散思路即可。
离散方程
半离散方程已经讨论了四大项的离散思路,下面将结合“数值处理”和“时间积分”,得到最后的离散方程。
以动量方程为例
∂t∂U+∇⋅(UU)−∇⋅(ν∇U)=−∇p
时间项
时间上使用欧拉插值格式
∫t∫V∂t∂UdVdt=∫tVP∂t∂(ρϕ)dt=VPΔtΔtUPt+1−UPt=(UPt+1−UPt)VP
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4
| ddtSchemes { default Euler; }
|
梯度项
采用高斯定理,时间上采用全显式,空间上采用线性插值格式
∫t∫V∇pdVdt=∫tVPVP1f∑pfSfdt=Δtf∑2pNt+pPtSf
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4 5
| gradSchemes { default Gauss linear; grad(p) Gauss linear; }
|
对流项
使用高斯定理(散度定理),时间上采用全隐式,空间上采用线性插值格式(公式给出中心差分作为演示)
∫f∫V∇⋅(UU)dVdt=∫tf∑Ffϕfdt=Δtf∑Fft2UN∗+UP∗
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4 5
| divSchemes { default none; div(phi,U) Gauss linear; }
|
扩散项
采用高斯定理(散度定理),时间上采用隐式,空间上采用线性插值格式、无正交修正(默认使用正交网格)
∫t∫V∇⋅(ν∇U)dVdt=Δtf∑(ν∇U∗)f⋅Sf
其中
(∇U∗)f⋅Sf=∣PN∣UN∗−UP∗⋅∣Sf∣
梯度项计算已经在上一小节被指定。
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4
| laplacianSchemes { default Gauss linear; }
|
面插值
对于面心值到体心值的插值
比如
Fft=(Uft⋅Sf)
采用线性面插值
Uft=fxUPt+(1−fx)UNt
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4
| interpolationSchemes { default linear; }
|
正交修正
如果网格是非正交的,梯度计算(如压力梯度)需要采用正交修正的方法。
比如 OpenFOAM 的 fvSchemes
中指定
1 2 3 4
| snGradSchemes { default orthogonal; }
|
离散方程
最终离散方程为
Δt(UP∗−UPt)VP+f∑Fft2UN∗+UP∗−f∑ν∣d∣UN∗−UP∗⋅∣Sf∣=−f∑2pNt+pPtSf
整理为
(Δt1+VP1f∑2Fft+VP1f∑ν∣d∣∣Sf∣)UP∗+VP1f∑(2Fft−ν∣d∣∣Sf∣)UN∗=Δt1UPt−VP1f∑2pNt+pPtSf
简写成
APUP∗+f∑ANUN∗=SPt−VP1f∑2pNt+pPtSf
左侧是已知系数矩阵和未知待求量,右侧是已知量。
即是线性代数系统
Ax=b
可以使用不同的数值方法进行求解。
当然这里又涉及到压力项耦合解法,这里不多赘述,暂时只需要把握主要思路就可以。
小结
到此为止,有限体积法求解偏微分方程的基本思路就梳理清楚了。
也就是,我们通过有限体积法离散控制方程,构建线性代数系统,再通过一些数值方法求解,得到物理场。
不用担心,后续会展开讨论其中的数值细节。