FVM in CFD 学习笔记_第8章_空间离散之扩散项

学习自F. Moukalled, L. Mangani, M. Darwish所著The Finite Volume Method in Computational Fluid Dynamics - An Advanced Introduction with OpenFOAM and Matlab
Chapter 8 Spatial Discretization: The Diffusion Term

本章将详细讲解由Laplace算子所表示的扩散项的空间离散方法。流体控制方程中,扩散项和对流项反映了两种截然不同的物理现象,所以两者的离散方法也是不同的,需要分开来讲解。本章首先讲解二维矩形计算域在笛卡尔网格上的含源项的扩散方程的离散方法,然后讲解Dirichlet、Von Neumann、mixed和symmetry边界条件的添加方法。接下来,介绍下在非正交的笛卡尔网格上的离散方法,并详细讲讲非正交的结构和非结构网格上的离散方法、非正交交叉扩散,还会提及非各向同性扩散的处理方法、对高度非线性系统的欠松弛处理方法。最后,讲讲uFVM中对扩散项离散过程的代码实现。

1 在矩形域上的二维扩散

在这里插入图片描述
如上图所示,将简单的矩形区域用笛卡尔网格剖分,并在该网格上对下面的稳态扩散方程进行离散
− ∇ ⋅ ( Γ ϕ ∇ ϕ ) = Q ϕ -\nabla\cdot(\Gamma^\phi\nabla\phi)=Q^\phi (Γϕϕ)=Qϕ
其中 ϕ \phi ϕ代表一个标量(比如温度、湍动能等), Q ϕ Q^\phi Qϕ为单位体积 ϕ \phi ϕ的生成项(源项), Γ ϕ \Gamma^\phi Γϕ为扩散系数。该方程可写成更加通用的形式,定义diffusion flux扩散通量 J ϕ , D \bold J^{\phi,D} Jϕ,D
J ϕ , D = − Γ ϕ ∇ ϕ \bold J^{\phi,D}=-\Gamma^\phi\nabla\phi Jϕ,D=Γϕϕ
则原方程变为
∇ ⋅ J ϕ , D = Q ϕ \nabla\cdot\bold J^{\phi,D}=Q^\phi Jϕ,D=Qϕ
根据前面章节提到的离散方式和Gauss梯度定理,可得单元 C C C的离散形式
∑ f ∼ n b ( C ) ( − Γ ϕ ∇ ϕ ) f ⋅ S f = Q C ϕ V C \sum_{f \sim nb(C)}(-\Gamma^\phi\nabla\phi)_f \cdot \bold S_f = Q_C^\phi V_C fnb(C)(Γϕϕ)fSf=QCϕVC
上式的展开形式为
( − Γ ϕ ∇ ϕ ) e ⋅ S e + ( − Γ ϕ ∇ ϕ ) w ⋅ S w + ( − Γ ϕ ∇ ϕ ) n ⋅ S n + ( − Γ ϕ ∇ ϕ ) s ⋅ S s = Q C ϕ V C (-\Gamma^\phi\nabla\phi)_e \cdot \bold S_e + (-\Gamma^\phi\nabla\phi)_w \cdot \bold S_w + (-\Gamma^\phi\nabla\phi)_n \cdot \bold S_n + (-\Gamma^\phi\nabla\phi)_s \cdot \bold S_s = Q_C^\phi V_C (Γϕϕ)eSe+(Γϕϕ)wSw+(Γϕϕ)nSn+(Γϕϕ)sSs=QCϕVC
对于图中的均匀笛卡尔网格,单元的构成面的面积矢量为
S e = + ( Δ y ) e i = ∣ ∣ S e ∣ ∣ i = S e i , S w = − ( Δ y ) w i = − ∣ ∣ S w ∣ ∣ i = − S w i S n = + ( Δ x ) n j = ∣ ∣ S n ∣ ∣ j = S n j , S s = − ( Δ x ) s j = − ∣ ∣ S s ∣ ∣ j = − S s j \begin{aligned} \bold S_e &= +(\Delta y)_e \bold i=||\bold S_e|| \bold i=S_e \bold i, \quad\quad \bold S_w =-(\Delta y)_w \bold i=-||\bold S_w|| \bold i=-S_w \bold i \\ \bold S_n &=+(\Delta x)_n \bold j=||\bold S_n|| \bold j=S_n \bold j, \quad\quad \bold S_s =-(\Delta x)_s \bold j=-||\bold S_s|| \bold j=-S_s \bold j \end{aligned} SeSn=+(Δy)ei=Sei=Sei,Sw=(Δy)wi=Swi=Swi=+(Δx)nj=Snj=Snj,Ss=(Δx)sj=Ssj=Ssj
那么东边面的扩散通量为
J e ϕ , D = − ( Γ ϕ ∇ ϕ ) e ⋅ S e = − Γ e ϕ S e ( ∂ ϕ ∂ x i + ∂ ϕ ∂ y j ) e ⋅ i = − Γ e ϕ ( Δ y ) e ( ∂ ϕ ∂ x ) e \begin{aligned} J^{\phi,D}_e &= -(\Gamma^\phi\nabla\phi)_e \cdot \bold S_e \\ &= -\Gamma^\phi_e S_e \left( \frac{\partial\phi}{\partial x} \bold i+ \frac{\partial\phi}{\partial y} \bold j \right)_e \cdot \bold i \\ & = -\Gamma^\phi_e (\Delta y)_e \left( \frac{\partial\phi}{\partial x} \right)_e \end{aligned} Jeϕ,D=(Γϕϕ)eSe=ΓeϕSe(xϕi+yϕj)ei=Γeϕ(Δy)e(xϕ)e
该扩散通量的离散形式可写成
J e ϕ , D = F l u x T e = F l u x C e ϕ C + F l u x F e ϕ E + F l u x V e J^{\phi,D}_e = FluxT_e=FluxC_e\phi_C+FluxF_e\phi_E+FluxV_e Jeϕ,D=FluxTe=FluxCeϕC+FluxFeϕE+FluxVe
为了确定系数 F l u x C e ,   F l u x F e ,   F l u x V e FluxC_e,~FluxF_e,~FluxV_e FluxCe, FluxFe, FluxVe,需要给出变量\phi在该面两侧单元形心之间的变化规律,以便计算面上的梯度值。假设 ϕ \phi ϕ在两单元形心之间是线性变化的,如图
在这里插入图片描述
那么在面 e e e上沿着 i \bold i i方向的梯度可以写成
( ∂ ϕ ∂ x ) e = ϕ E − ϕ C ( δ x ) e \left( \frac{\partial\phi}{\partial x} \right)_e=\frac{\phi_E-\phi_C}{(\delta x)_e} (xϕ)e=(δx)eϕEϕC
那么面 e e e处扩散通量的最终离散形式为
F l u x T e = − Γ e ϕ ( Δ y ) e ϕ E − ϕ C ( δ x ) e = − Γ e ϕ ( Δ y ) e ( δ x ) e ( ϕ E − ϕ C ) = F l u x C e ϕ C + F l u x F e ϕ E + F l u x V e \begin{aligned} FluxT_e &=-\Gamma^\phi_e (\Delta y)_e\frac{\phi_E-\phi_C}{(\delta x)_e} \\ &=-\Gamma^\phi_e \frac{(\Delta y)_e}{(\delta x)_e} (\phi_E-\phi_C) \\ &=FluxC_e\phi_C+FluxF_e\phi_E+FluxV_e \end{aligned} FluxTe=Γeϕ(Δy)e(δx)eϕEϕC=Γeϕ(δx)e(Δy)e(ϕEϕC)=FluxCeϕC+FluxFeϕE+FluxVe

g D i f f e = ( Δ y ) e ( δ x ) e = ∣ ∣ S e ∣ ∣ ∣ ∣ d C E ∣ ∣ = S e d C E gDiff_e=\frac{(\Delta y)_e}{(\delta x)_e} = \frac{||\bold S_e||}{||\bold d_{CE}||} =\frac{S_e}{d_{CE}} gDiffe=(δx)e(Δy)e=dCESe=dCESe
其中 d C E \bold d_{CE} dCE为单元 C C C E E E形心之间的距离矢量,系数为
F l u x C e = Γ e ϕ g D i f f e F l u x F e = − Γ e ϕ g D i f f e F l u x V e = 0 \begin{aligned} FluxC_e &= \Gamma^\phi_e gDiff_e \\ FluxF_e &= - \Gamma^\phi_e gDiff_e \\ FluxV_e &= 0 \end{aligned} FluxCeFluxFeFluxVe=ΓeϕgDiffe=ΓeϕgDiffe=0
采用同样的方法,也可以推得w界面的扩散通量离散形式
F l u x T w = F l u x C w ϕ C + F l u x F w ϕ W + F l u x V w FluxT_w =FluxC_w\phi_C+FluxF_w\phi_W+FluxV_w FluxTw=FluxCwϕC+FluxFwϕW+FluxVw
其中
F l u x C w = Γ w ϕ g D i f f w F l u x F w = − Γ w ϕ g D i f f w F l u x V w = 0 \begin{aligned} FluxC_w &= \Gamma^\phi_w gDiff_w \\ FluxF_w &= - \Gamma^\phi_w gDiff_w \\ FluxV_w &= 0 \end{aligned} FluxCwFluxFwFluxVw=ΓwϕgDiffw=ΓwϕgDiffw=0

g D i f f w = ( Δ y ) w ( δ x ) w = ∣ ∣ S w ∣ ∣ ∣ ∣ d C W ∣ ∣ = S w d C W gDiff_w=\frac{(\Delta y)_w}{(\delta x)_w} = \frac{||\bold S_w||}{||\bold d_{CW}||} =\frac{S_w}{d_{CW}} gDiffw=(δx)w(Δy)w=dCWSw=dCWSw
同样也可得到 n n n s s s面上的扩散通量离散形式
F l u x T n = F l u x C n ϕ C + F l u x F n ϕ N + F l u x V n F l u x T s = F l u x C s ϕ C + F l u x F s ϕ S + F l u x V s \begin{aligned} FluxT_n &= FluxC_n\phi_C+FluxF_n\phi_N+FluxV_n \\ FluxT_s &= FluxC_s\phi_C+FluxF_s\phi_S+FluxV_s \end{aligned} FluxTnFluxTs=FluxCnϕC+FluxFnϕN+FluxVn=FluxCsϕC+FluxFsϕS+FluxVs
其中
F l u x C n = Γ n ϕ g D i f f n , F l u x F n = − Γ n ϕ g D i f f n , F l u x V n = 0 F l u x C s = Γ s ϕ g D i f f s , F l u x F s = − Γ s ϕ g D i f f s , F l u x V s = 0 \begin{aligned} FluxC_n &= \Gamma^\phi_n gDiff_n, \quad FluxF_n = - \Gamma^\phi_n gDiff_n, \quad & FluxV_n = 0 \\ FluxC_s &= \Gamma^\phi_s gDiff_s, \quad FluxF_s = - \Gamma^\phi_s gDiff_s, \quad & FluxV_s = 0 \end{aligned} FluxCnFluxCs=ΓnϕgDiffn,FluxFn=ΓnϕgDiffn,=ΓsϕgDiffs,FluxFs=ΓsϕgDiffs,FluxVn=0FluxVs=0

g D i f f n = ( Δ x ) n ( δ y ) n = ∣ ∣ S n ∣ ∣ ∣ ∣ d C N ∣ ∣ = S n d C N g D i f f s = ( Δ x ) s ( δ y ) s = ∣ ∣ S s ∣ ∣ ∣ ∣ d C S ∣ ∣ = S s d C S gDiff_n=\frac{(\Delta x)_n}{(\delta y)_n} = \frac{||\bold S_n||}{||\bold d_{CN}||} =\frac{S_n}{d_{CN}} \\ \quad \\ gDiff_s=\frac{(\Delta x)_s}{(\delta y)_s} = \frac{||\bold S_s||}{||\bold d_{CS}||} =\frac{S_s}{d_{CS}} gDiffn=(δy)n(Δx)n=dCNSn=dCNSngDiffs=(δy)s(Δx)s=dCSSs=dCSSs
将各个面的对流通量离散形式汇总代入到原方程的半离散格式,可得
a C ϕ C + a E ϕ E + a W ϕ W + a N ϕ N + a S ϕ S = b C a_C\phi_C + a_E\phi_E + a_W \phi_W + a_N \phi_N + a_S \phi_S = b_C aCϕC+aEϕE+aWϕW+aNϕN+aSϕS=bC
其中
a E = F l u x F e = − Γ e ϕ g D i f f e a W = F l u x F w = − Γ w ϕ g D i f f w a N = F l u x F n = − Γ n ϕ g D i f f n a S = F l u x F s = − Γ s ϕ g D i f f s a C = F l u x C e + F l u x C w + F l u x C n + F l u x C s = − ( a E + a W + a N + a S ) b C = Q C ϕ V C − ( F l u x V e + F l u x V w + F l u x V n + F l u x V s ) \begin{aligned} a_E &=FluxF_e = - \Gamma^\phi_e gDiff_e \\ a_W &=FluxF_w = - \Gamma^\phi_w gDiff_w \\ a_N &=FluxF_n = - \Gamma^\phi_n gDiff_n \\ a_S &=FluxF_s = - \Gamma^\phi_s gDiff_s \\ a_C &=FluxC_e+FluxC_w+FluxC_n+FluxC_s \\ &=-(a_E+a_W+a_N+a_S) \\ b_C &= Q_C^\phi V_C-(FluxV_e+FluxV_w+FluxV_n+FluxV_s) \end{aligned} aEaWaNaSaCbC=FluxFe=ΓeϕgDiffe=FluxFw=ΓwϕgDiffw=FluxFn=ΓnϕgDiffn=FluxFs=ΓsϕgDiffs=FluxCe+FluxCw+FluxCn+FluxCs=(aE+aW+aN+aS)=QCϕVC(FluxVe+FluxVw+FluxVn+FluxVs)
或者,写成紧致格式
a C ϕ C + ∑ F ∼ N B ( C ) a F ϕ F = b C a_C\phi_C+\sum_{F\sim NB(C)} a_F \phi_F=b_C aCϕC+FNB(C)aFϕF=bC
其中
a F = F l u x F f = − Γ f ϕ g D i f f f a C = ∑ f ∼ n b ( C ) F l u x C f b C = Q C ϕ V C − ∑ f ∼ n b ( C ) F l u x V f \begin{aligned} a_F &=FluxF_f = - \Gamma^\phi_f gDiff_f \\ a_C &=\sum_{f\sim nb(C)} FluxC_f \\ b_C &= Q_C^\phi V_C-\sum_{f\sim nb(C)} FluxV_f \end{aligned} aFaCbC=FluxFf=ΓfϕgDifff=fnb(C)FluxCf=QCϕVCfnb(C)FluxVf
其中的 F F F代表单元 C C C的邻近单元 E , W , N , S E,W,N,S E,W,N,S,小写 f f f代表单元 C C C的构成面(邻近面) e , w , n , s e,w,n,s e,w,n,s

2 离散方程的解释

合适的离散方法得到的离散代数方程应该能反映原守恒方程的特性。所以推出的离散方程的系数需要满足如下两个准则。

2.1 零加和准则

即无源项的时候,各系数加和应为0。
a C + ∑ F ∼ N B ( C ) a F = 0 a_C+\sum_{F\sim NB(C)} a_F =0 aC+FNB(C)aF=0

a C = − ∑ F ∼ N B ( C ) a F a_C=-\sum_{F\sim NB(C)} a_F aC=FNB(C)aF

∑ F ∼ N B ( C ) a F a C = − 1 \sum_{F\sim NB(C)} \frac{a_F}{a_C} =-1 FNB(C)aCaF=1

2.2 反号准则

a C a_C aC a F a_F aF是反号的,这样才能保证当 ϕ F \phi_F ϕF增加/减小的时候, ϕ C \phi_C ϕC是增加/减小的,从而保证了有界性boundedness。

3 边界条件

边界条件的添加至关重要,尽管控制方程相同,然而不同的边界条件所得到的解是不同的,对应的物理意义也不一样,添加错误的边界条件会导致无法得到解,或者得到的解与原物理问题毫不相干。

扩散方程,即,拉普拉斯方程的边界条件通常有Dirichlet、Von Neumann、mixed和symmetry,边界条件是施加在边界单元上的,它们有1个或多个面位于边界上,变量 ϕ \phi ϕ既存储在单元形心上,也存储在面形心上。

在这里插入图片描述
如图, C C C代表边界单元的形心,该单元有1个边界面, b b b为该边界面的形心, S b \bold S_b Sb为该边界面的面积矢量。跟前面一样地,也可以推出单元 C C C的离散格式
∑ f ∼ n b ( C ) ( J ϕ , D ⋅ S ) f = Q C ϕ V C \sum_{f \sim nb(C)} (\bold J^{\phi,D} \cdot \bold S)_f = Q_C^\phi V_C fnb(C)(Jϕ,DS)f=QCϕVC
内部面的通量还跟之前一样离散,而边界通量的离散则是要构建跟 ϕ C \phi_C ϕC相关的线性格式
J b ϕ , D ⋅ S b = F l u x T b = − Γ b ϕ ( ∇ ϕ ) b ⋅ S b = F l u x C b ϕ b + F l u x V b \begin{aligned} \bold J^{\phi,D}_b \cdot \bold S_b &=FluxT_b \\ &= -\Gamma_b^\phi (\nabla \phi)_b \cdot \bold S_b \\ &= FluxC_b\phi_b+FluxV_b \end{aligned} Jbϕ,DSb=FluxTb=Γbϕ(ϕ)bSb=FluxCbϕb+FluxVb
边界条件的添加,要么给定边界值 ϕ b \phi_b ϕb,要么是给出边界通量 J b ϕ , D \bold J^{\phi,D}_b Jbϕ,D。不同边界条件的添加方法如下。

3.1 Dirichlet边界条件

Dirichlet边界条件是直接给定边界上的变量值 ϕ \phi ϕ,即
ϕ b = ϕ s p e c i f i e d \phi_b=\phi_{specified} ϕb=ϕspecified
那么
F l u x T b = − Γ b ϕ ( ∇ ϕ ) b ⋅ S b = − Γ b ϕ ∣ ∣ S b ∣ ∣ ∣ ∣ d C b ∣ ∣ ( ϕ b − ϕ C ) = F l u x C b ϕ C + F l u x V b \begin{aligned} FluxT_b &= -\Gamma_b^\phi (\nabla \phi)_b \cdot \bold S_b \\ &= -\Gamma_b^\phi \frac{||\bold S_b||}{||\bold d_{Cb}||} (\phi_b - \phi_C) \\ &= FluxC_b\phi_C+FluxV_b \end{aligned} FluxTb=Γbϕ(ϕ)bSb=ΓbϕdCbSb(ϕbϕC)=FluxCbϕC+FluxVb
推得
F l u x C b = Γ b ϕ g D i f f b = a b F l u x V b = − Γ b ϕ g D i f f b ϕ b = − a b ϕ b \begin{aligned} FluxC_b &= \Gamma_b^\phi gDiff_b=a_b \\ FluxV_b &= -\Gamma_b^\phi gDiff_b \phi_b = -a_b \phi_b \end{aligned} FluxCbFluxVb=ΓbϕgDiffb=ab=ΓbϕgDiffbϕb=abϕb
其中
g D i f f b = S b d C b gDiff_b=\frac{S_b}{d_{Cb}} gDiffb=dCbSb
对于图中所示的 C C C单元, a E a_E aE系数变成0了(这个边界单元也没有 E E E单元,所以系数肯定是0了),其离散方程变为
a C ϕ C + a W ϕ W + a N ϕ N + a S ϕ S = b C a_C\phi_C + a_W \phi_W + a_N \phi_N + a_S \phi_S = b_C aCϕC+aWϕW+aNϕN+aSϕS=bC
其中
a E = 0 a W = F l u x F w = − Γ w ϕ g D i f f w a N = F l u x F n = − Γ n ϕ g D i f f n a S = F l u x F s = − Γ s ϕ g D i f f s a C = F l u x C b + ∑ f ∼ n b ( C ) F l u x C f = F l u x C b + ( F l u x C w + F l u x C n + F l u x C s ) b C = Q C ϕ V C − ( F l u x V b + ∑ f ∼ n b ( C ) F l u x V f ) \begin{aligned} a_E &=0 \\ a_W &=FluxF_w = - \Gamma^\phi_w gDiff_w \\ a_N &=FluxF_n = - \Gamma^\phi_n gDiff_n \\ a_S &=FluxF_s = - \Gamma^\phi_s gDiff_s \\ a_C &=FluxC_b+\sum_{f\sim nb(C)}FluxC_f\\ &=FluxC_b+(FluxC_w+FluxC_n+FluxC_s) \\ b_C &= Q_C^\phi V_C-(FluxV_b+\sum_{f\sim nb(C)}FluxV_f) \end{aligned} aEaWaNaSaCbC=0=FluxFw=ΓwϕgDiffw=FluxFn=ΓnϕgDiffn=FluxFs=ΓsϕgDiffs=FluxCb+fnb(C)FluxCf=FluxCb+(FluxCw+FluxCn+FluxCs)=QCϕVC(FluxVb+fnb(C)FluxVf)
注意:

  1. 系数 a b a_b ab比其它邻居系数都要大,因为 b b b距离 C C C更近,所以其对 ϕ C \phi_C ϕC的影响更大。
  2. 系数 a C a_C aC仍旧是所有邻居系数的加和,包括 a b a_b ab。这也就是说,边界单元的 ∑ f ∼ n b ( C ) ∣ a F ∣ / ∣ a C ∣ < 1 \sum_{f\sim nb(C)}|a_F|/|a_C|<1 fnb(C)aF/aC<1,不能保证离散方程满足零系数加和准则,有 ∣ a C ∣ > ∑ f ∼ n b ( C ) ∣ a F ∣ |a_C|>\sum_{f\sim nb(C)}|a_F| aC>fnb(C)aF(严格对角占优了),从而在使用迭代方法求解线性方程的时候,是能获得收敛解的。
  3. a b ϕ b a_b\phi_b abϕb项产生了 F l u x V b FluxV_b FluxVb,现在位于方程的右端项,是 b C b_C bC的一部分,因为其不含未知量。

3.2 Von Neumann边界条件

在这里插入图片描述
如上图,如果边界上给定的是 ϕ \phi ϕ的通量(或垂直于面的梯度值),那么这种边界条件就是Neumann边界条件。此时,这个给定的通量是
− ( Γ ϕ ∇ ϕ ) b ⋅ i = q b -(\Gamma^\phi\nabla\phi)_b\cdot\bold i=q_b (Γϕϕ)bi=qb
这样的话,通量 J b ϕ , D \bold J_b^{\phi,D} Jbϕ,D可得
J b ϕ , D ⋅ S b = − ( Γ ϕ ∇ ϕ ) b ⋅ ∣ ∣ S b ∣ ∣ i = q b ∣ ∣ S b ∣ ∣ = F l u x C b ϕ C + F l u x V b \bold J_b^{\phi,D}\cdot\bold S_b=-(\Gamma^\phi\nabla\phi)_b \cdot ||\bold S_b|| \bold i=q_b||\bold S_b||=FluxC_b\phi_C+FluxV_b Jbϕ,DSb=(Γϕϕ)bSbi=qbSb=FluxCbϕC+FluxVb
其中
F l u x C b = 0 F l u x V b = q b S b = q b ( Δ y ) C \begin{aligned} FluxC_b &=0 \\ FluxV_b &=q_bS_b=q_b(\Delta y)_C \end{aligned} FluxCbFluxVb=0=qbSb=qb(Δy)C
当与所使用的坐标系统方向相同的时候,通量分量为正值。

这样,单元 C C C的离散方程为:
a C ϕ C + a W ϕ W + a N ϕ N + a S ϕ S = b C a_C\phi_C + a_W \phi_W + a_N \phi_N + a_S \phi_S = b_C aCϕC+aWϕW+aNϕN+aSϕS=bC
其中
a E = 0 a W = F l u x F w = − Γ w ϕ g D i f f w a N = F l u x F n = − Γ n ϕ g D i f f n a S = F l u x F s = − Γ s ϕ g D i f f s a C = ∑ f ∼ n b ( C ) F l u x C f = − ( a W + a N + a S ) b C = Q C ϕ V C − ( F l u x V b + ∑ f ∼ n b ( C ) F l u x V f ) \begin{aligned} a_E &=0 \\ a_W &=FluxF_w = - \Gamma^\phi_w gDiff_w \\ a_N &=FluxF_n = - \Gamma^\phi_n gDiff_n \\ a_S &=FluxF_s = - \Gamma^\phi_s gDiff_s \\ a_C &=\sum_{f\sim nb(C)}FluxC_f=-(a_W+a_N+a_S) \\ b_C &= Q_C^\phi V_C-(FluxV_b+\sum_{f\sim nb(C)}FluxV_f) \end{aligned} aEaWaNaSaCbC=0=FluxFw=ΓwϕgDiffw=FluxFn=ΓnϕgDiffn=FluxFs=ΓsϕgDiffs=fnb(C)FluxCf=(aW+aN+aS)=QCϕVC(FluxVb+fnb(C)FluxVf)
注意:

  1. Von Neumann边界条件生成的系数 a C a_C aC并不是占优的(也就意味着迭代解法是不靠谱的了)。
  2. 如果 q b q_b qb S C ϕ S_C^\phi SCϕ为0,即边界不流入通量,且单元内部没有源项,则 ϕ C \phi_C ϕC的值是完全由其周围邻近单元所限定的。而在其它情况下( q b q_b qb S C ϕ S_C^\phi SCϕ不0,即有边界通量流入,或者是单元内部有源项生成的时候), ϕ C \phi_C ϕC则可以超过(或是低于)周围邻近值 ϕ \phi ϕ,这是合情合理的。举个例子,如果 ϕ \phi ϕ是温度,则 q b q_b qb代表的就是施加在边界上的热流通量,那么如果边界上有热量流入的话,则靠近边界区域的温度是会比内部区域的温度要高的。
  3. 关于边界上 ϕ \phi ϕ值的计算,一旦单元 ϕ C \phi_C ϕC算出来后,边界的 ϕ b \phi_b ϕb可以用下面的式子来计算
    ϕ b = Γ b ϕ g D i f f b ϕ C − q b Γ b ϕ g D i f f b \phi_b=\frac{\Gamma_b^{\phi}gDiff_b\phi_C-q_b}{\Gamma_b^{\phi}gDiff_b} ϕb=ΓbϕgDiffbΓbϕgDiffbϕCqb
  4. Von Neumann边界条件可以认为是FVM的自然边界条件,因为当某个边界面所给定的通量为0时,离散后跟该面相关的啥项也没有了。可是,Dirichlet边界条件中,即便边界面的给定 ϕ \phi ϕ为0,依然在离散方程中出现了相关项。

3.3 混合边界条件

在这里插入图片描述
混合边界条件如上图所示,边界条件是通过对流传热系数( h ∞ h_\infin h)和 ϕ \phi ϕ的周围环境值 ϕ ∞ \phi_\infin ϕ来给出的
J b ϕ , D ⋅ S b = − ( Γ ϕ ∇ ϕ ) b ⋅ ∣ ∣ S b ∣ ∣ i = − h ∞ ( ϕ ∞ − ϕ b ) ( Δ y ) C \bold J_b^{\phi,D}\cdot\bold S_b=-(\Gamma^\phi\nabla\phi)_b \cdot ||\bold S_b|| \bold i = -h_\infin(\phi_\infin-\phi_b)(\Delta y)_C Jbϕ,DSb=(Γϕϕ)bSbi=h(ϕϕb)(Δy)C
重新写成如下形式
− Γ b ϕ S b ( ϕ b − ϕ C δ x b ) = − h ∞ ( ϕ ∞ − ϕ b ) S b -\Gamma_b^\phi S_b \left( \frac{\phi_b - \phi_C}{\delta x_b} \right) = - h_\infin(\phi_\infin-\phi_b)S_b ΓbϕSb(δxbϕbϕC)=h(ϕϕb)Sb
从这个方程可以解出 ϕ b \phi_b ϕb
ϕ b = h ∞ ϕ ∞ + ( Γ b ϕ / δ x b ) ϕ C h ∞ + ( Γ b ϕ / δ x b ) \phi_b=\frac{h_\infin\phi_\infin + (\Gamma_b^\phi/\delta x_b)\phi_C}{h_\infin+(\Gamma_b^\phi/\delta x_b)} ϕb=h+(Γbϕ/δxb)hϕ+(Γbϕ/δxb)ϕC
ϕ b \phi_b ϕb代入到 J b ϕ , D ⋅ S b = − h ∞ ( ϕ ∞ − ϕ b ) ( Δ y ) C \bold J_b^{\phi,D}\cdot\bold S_b = -h_\infin(\phi_\infin-\phi_b)(\Delta y)_C Jbϕ,DSb=h(ϕϕb)(Δy)C中,可得
J b ϕ , D ⋅ S b = − h ∞ ( ϕ ∞ − ϕ b ) ( Δ y ) C = − [ h ∞ ( Γ b ϕ / δ x b ) h ∞ + ( Γ b ϕ / δ x b ) S b ] ⏟ R e q ( ϕ ∞ − ϕ C ) = F l u x C b ϕ C + F l u x V b \begin{aligned} \bold J_b^{\phi,D}\cdot\bold S_b & = -h_\infin(\phi_\infin-\phi_b)(\Delta y)_C \\ & = - \underbrace{\left[ \frac{h_\infin (\Gamma_b^\phi/\delta x_b)}{h_\infin+(\Gamma_b^\phi/\delta x_b)} S_b\right]}_{R_{eq}}(\phi_\infin-\phi_C) \\ & = FluxC_b\phi_C + FluxV_b \end{aligned} Jbϕ,DSb=h(ϕϕb)(Δy)C=Req [h+(Γbϕ/δxb)h(Γbϕ/δxb)Sb](ϕϕC)=FluxCbϕC+FluxVb
其中
F l u x C b = R e q F l u x V b = − R e q ϕ ∞ \begin{aligned} FluxC_b &=R_{eq} \\ FluxV_b &=-R_{eq}\phi_{\infin} \end{aligned} FluxCbFluxVb=Req=Reqϕ
那么,对于单元 C C C的离散方程,其最终形式为
a C ϕ C + a W ϕ W + a N ϕ N + a S ϕ S = b C a_C\phi_C + a_W \phi_W + a_N \phi_N + a_S \phi_S = b_C aCϕC+aWϕW+aNϕN+aSϕS=bC
其中
a E = 0 a W = F l u x F w = − Γ w ϕ g D i f f w a N = F l u x F n = − Γ n ϕ g D i f f n a S = F l u x F s = − Γ s ϕ g D i f f s a C = F l u x C b + ∑ f ∼ n b ( C ) F l u x C f = F l u x C b + ( F l u x C w + F l u x C n + F l u x C s ) b C = Q C ϕ V C − ( F l u x V b + ∑ f ∼ n b ( C ) F l u x V f ) \begin{aligned} a_E &=0 \\ a_W &=FluxF_w = - \Gamma^\phi_w gDiff_w \\ a_N &=FluxF_n = - \Gamma^\phi_n gDiff_n \\ a_S &=FluxF_s = - \Gamma^\phi_s gDiff_s \\ a_C &=FluxC_b+\sum_{f\sim nb(C)}FluxC_f=FluxC_b+(FluxC_w+FluxC_n+FluxC_s) \\ b_C &= Q_C^\phi V_C-(FluxV_b+\sum_{f\sim nb(C)}FluxV_f) \end{aligned} aEaWaNaSaCbC=0=FluxFw=ΓwϕgDiffw=FluxFn=ΓnϕgDiffn=FluxFs=ΓsϕgDiffs=FluxCb+fnb(C)FluxCf=FluxCb+(FluxCw+FluxCn+FluxCs)=QCϕVC(FluxVb+fnb(C)FluxVf)

3.4 对称边界条件

沿着对称边界条件,标量 ϕ \phi ϕ的法向通量为0,因此,对称边界条件等效于Neumann边界条件(将通量值设为0),即, F l u x C b = F l u x V b = 0 FluxC_b=FluxV_b=0 FluxCb=FluxVb=0,那么直接把之前推出来的Neumann边界条件离散格式中的 q b q_b qb设成0就行了,即
a C ϕ C + a W ϕ W + a N ϕ N + a S ϕ S = b C a_C\phi_C + a_W \phi_W + a_N \phi_N + a_S \phi_S = b_C aCϕC+aWϕW+aNϕN+aSϕS=bC
其中
a E = 0 a W = F l u x F w = − Γ w ϕ g D i f f w a N = F l u x F n = − Γ n ϕ g D i f f n a S = F l u x F s = − Γ s ϕ g D i f f s a C = ∑ f ∼ n b ( C ) F l u x C f = − ( a W + a N + a S ) b C = Q C ϕ V C − ∑ f ∼ n b ( C ) F l u x V f \begin{aligned} a_E &=0 \\ a_W &=FluxF_w = - \Gamma^\phi_w gDiff_w \\ a_N &=FluxF_n = - \Gamma^\phi_n gDiff_n \\ a_S &=FluxF_s = - \Gamma^\phi_s gDiff_s \\ a_C &=\sum_{f\sim nb(C)}FluxC_f=-(a_W+a_N+a_S) \\ b_C &= Q_C^\phi V_C-\sum_{f\sim nb(C)}FluxV_f \end{aligned} aEaWaNaSaCbC=0=FluxFw=ΓwϕgDiffw=FluxFn=ΓnϕgDiffn=FluxFs=ΓsϕgDiffs=fnb(C)FluxCf=(aW+aN+aS)=QCϕVCfnb(C)FluxVf

4 界面扩散系数

前面的离散方程中,还需要用到扩散系数 Γ e ϕ ,   Γ w ϕ ,   Γ n ϕ ,   Γ s ϕ \Gamma_e^\phi,~\Gamma_w^\phi,~\Gamma_n^\phi,~\Gamma_s^\phi Γeϕ, Γwϕ, Γnϕ, Γsϕ,它们分别代表着扩散系数 Γ ϕ \Gamma^\phi Γϕ e ,   w ,   n ,   s e,~w,~n,~s e, w, n, s面处的值。当扩散系数 Γ ϕ \Gamma^\phi Γϕ随空间位置变化时(比如在可压缩流动问题中,粘性系数是温度的函数,随温度不同粘性也不相同),扩散系数同样也是存储在单元形心 E ,   W ,   N ,   S . . . E,~W,~N,~S... E, W, N, S...上的,那么就需要去计算界面上的扩散系数值了。实际上,湍流粘性、热传导系数等都是非均匀分部的。当然,如果扩散系数整场是定值的话,就不用这么折腾了。

计算界面扩散系数最简单的方法莫过于直接用两侧单元值做线性插值了,即
Γ e ϕ = ( 1 − g e ) Γ C ϕ + g e Γ E ϕ \Gamma_e^\phi=(1-g_e)\Gamma_C^\phi+g_e\Gamma_E^\phi Γeϕ=(1ge)ΓCϕ+geΓEϕ
其中插值因子 g e g_e ge是距离的比值,即
g e = d C e d C e + d e E g_e=\frac{d_{Ce}}{d_{Ce}+d_{eE}} ge=dCe+deEdCe
如果是笛卡尔网格,且界面刚好位于两侧单元中间的话, g e = 0.5 g_e=0.5 ge=0.5,那么 Γ e ϕ = ( Γ C ϕ + Γ E ϕ ) / 2 \Gamma_e^\phi=(\Gamma_C^\phi+\Gamma_E^\phi)/2 Γeϕ=(ΓCϕ+ΓEϕ)/2。同样也可以定义其它插值系数
g w = d C w d C e + d w W g n = d C n d C n + d n N g s = d C s d C s + d s S g_w=\frac{d_{Cw}}{d_{Ce}+d_{wW}} \\ \quad \\ g_n=\frac{d_{Cn}}{d_{Cn}+d_{nN}} \\ \quad \\ g_s=\frac{d_{Cs}}{d_{Cs}+d_{sS}} gw=dCe+dwWdCwgn=dCn+dnNdCngs=dCs+dsSdCs
然而,在某些情况下,这种处理方法会导致错误,比如当复合材料中的传导突变的情况下。幸运的是,有个更好的且相对简单易于实现的方法。在该方法中,界面的局部传导系数不是重点,它主要关注的是如何获得界面上的扩散通量 J ϕ , D \bold J^{\phi,D} Jϕ,D
在这里插入图片描述
如图所示的1维问题,假设单元 C C C是由导热系数 Γ C ϕ \Gamma_C^\phi ΓCϕ的材料构成,而单元 E E E是由导热系数为 Γ E ϕ \Gamma_E^\phi ΓEϕ的材料构成,则对于C和E之间的非均匀分片,稳态1维分析(不含源项)有(界面e的任何一边的通量假设是相同的)
J e ϕ , D ⋅ S e = ϕ C − ϕ e ( δ x ) C e Γ C ϕ = ϕ e − ϕ E ( δ x ) e E Γ E ϕ = ϕ C − ϕ E ( δ x ) C e Γ C ϕ + ( δ x ) e E Γ E ϕ = ϕ C − ϕ E ( δ x ) C E Γ e ϕ \begin{aligned} \bold J_e^{\phi,D}\cdot \bold S_e &=\frac{\phi_C-\phi_e}{\displaystyle \frac{(\delta x)_{Ce}}{\Gamma_C^\phi}} = \frac{\phi_e-\phi_E}{\displaystyle \frac{(\delta x)_{eE}}{\Gamma_E^\phi}} \\ &=\frac{\phi_C-\phi_E}{\displaystyle \frac{(\delta x)_{Ce}}{\Gamma_C^\phi} + \frac{(\delta x)_{eE}}{\Gamma_E^\phi}} = \frac{\phi_C-\phi_E}{\displaystyle \frac{(\delta x)_{CE}}{\Gamma_e^\phi}} \end{aligned} Jeϕ,DSe=ΓCϕ(δx)CeϕCϕe=ΓEϕ(δx)eEϕeϕE=ΓCϕ(δx)Ce+ΓEϕ(δx)eEϕCϕE=Γeϕ(δx)CEϕCϕE
于是推得了该片的导热系数
( δ x ) C E Γ e ϕ = ( δ x ) C e Γ C ϕ + ( δ x ) e E Γ E ϕ ⇒ 1 Γ e ϕ = 1 − g e Γ C ϕ + g e Γ E ϕ \frac{(\delta x)_{CE}}{\Gamma_e^\phi} = \frac{(\delta x)_{Ce}}{\Gamma_C^\phi} + \frac{(\delta x)_{eE}}{\Gamma_E^\phi} \Rightarrow \frac{1}{\Gamma_e^\phi} = \frac{1-g_e}{\Gamma_C^\phi} + \frac{g_e}{\Gamma_E^\phi} Γeϕ(δx)CE=ΓCϕ(δx)Ce+ΓEϕ(δx)eEΓeϕ1=ΓCϕ1ge+ΓEϕge
当界面刚好位于 C C C E E E的中间时, g e = 0.5 g_e=0.5 ge=0.5,上式变为
Γ e ϕ = 2 Γ C ϕ Γ E ϕ Γ C ϕ + Γ E ϕ \Gamma_e^\phi=\frac{2\Gamma_C^\phi\Gamma_E^\phi}{\Gamma_C^\phi+\Gamma_E^\phi} Γeϕ=ΓCϕ+ΓEϕ2ΓCϕΓEϕ
这是 Γ C ϕ \Gamma_C^\phi ΓCϕ Γ E ϕ \Gamma_E^\phi ΓEϕ的调和平均(harmonic mean),而非算术平均。

需要注意的是,对于不连续扩散系数的调和平均插值方法,仅对1维扩散问题是精确的。然而,其对高维问题的应用也很有优势,比如流体和固体区域可以不加区分,当成一个区域来计算传热系数。


例1
在这里插入图片描述

如图热传导问题,2维矩形区域由两种材料构成,如下偏微分方程为其控制方程
∇ ⋅ ( k ∇ T ) = 0 \nabla \cdot (k \nabla T) = 0 (kT)=0
其中 T T T代表温度,热传导系数 k k k和边界条件如图所示
a.推导出所有单元的代数方程
b. 使用Gauss-Seidel迭代方法求解系统方程获得单元 T T T
c. 计算底部、顶部、右侧的 T T T
d. 计算通过底部、顶部、左侧边界的净热流通量,并检查能量守恒是否满足。


求解过程较为繁琐,不再详述。


5 非笛卡尔正交网格

在这里插入图片描述
如图,网格还是正交的,但是它和 x x x y y y轴不是对齐的,这样的网格相当于是把笛卡尔网格转了个角度。

这种网格上的离散方程和笛卡尔网格上的离散方程式完全一样的,边界条件也是一样的,解法也是一样的。

比如
∇ ⋅ J ϕ , D = Q ϕ \nabla\cdot\bold J^{\phi,D}=Q^\phi Jϕ,D=Qϕ
半离散形式
∑ f ∼ n b ( C ) ( − Γ ϕ ∇ ϕ ) f ⋅ S f = Q C ϕ V C \sum_{f \sim nb(C)}(-\Gamma^\phi\nabla\phi)_f \cdot \bold S_f = Q_C^\phi V_C fnb(C)(Γϕϕ)fSf=QCϕVC
考虑到界面 e e e,有
J e ϕ , D = − Γ e ϕ ( ∇ ϕ ⋅ n ) e S e = − Γ e ϕ ( ∂ ϕ ∂ n ) e S e J^{\phi,D}_e = -\Gamma^\phi_e (\nabla\phi \cdot \bold n)_e S_e = -\Gamma^\phi_e \left( \frac{\partial\phi}{\partial n} \right)_e S_e Jeϕ,D=Γeϕ(ϕn)eSe=Γeϕ(nϕ)eSe
其中
( ∇ ϕ ⋅ n ) e = ( ∂ ϕ ∂ n ) e (\nabla\phi \cdot \bold n)_e = \left( \frac{\partial\phi}{\partial n} \right)_e (ϕn)e=(nϕ)e
为变量 ϕ \phi ϕ在界面 e e e上沿着 n \bold n n方向的梯度,再次对 ϕ \phi ϕ使用线性假设,该梯度可得
( ∂ ϕ ∂ n ) e = ϕ E − ϕ C d C E \left( \frac{\partial\phi}{\partial n} \right)_e=\frac{\phi_E-\phi_C}{d_{CE}} (nϕ)e=dCEϕEϕC
其它项也将得出和笛卡尔网格同样的离散方程。

6 非正交非结构网格

6.1 非正交

在这里插入图片描述

前面所讲的情况下,通量是与面垂直的。然而,在一般情况下,结构化曲线网格和非结构网格是非正交的,即,面矢量 S f \bold S_f Sf和连接面两侧单元形心的矢量 C F \bold {CF} CF是不共线的,如上图。这样,垂直于面的梯度就无法写成 ϕ F \phi_F ϕF ϕ C \phi_C ϕC的函数,而它实际上有了个垂直于 C F \bold {CF} CF的分量。

这样,在正交网格上梯度沿着界面法向为
( ∇ ϕ ⋅ n ) f = ( ∂ ϕ ∂ n ) f = ϕ F − ϕ C ∣ ∣ r F − r C ∣ ∣ = ϕ F − ϕ C d C F (\nabla\phi\cdot\bold n)_f=\left(\frac{\partial\phi}{\partial n}\right)_f=\frac{\phi_F-\phi_C}{||\bold r_F - \bold r_C||}=\frac{\phi_F-\phi_C}{d_{CF}} (ϕn)f=(nϕ)f=rFrCϕFϕC=dCFϕFϕC
因为 C F \bold {CF} CF n \bold n n(面单位法矢量)是共线的。而在非结构网格上,上面这个式子所表示的梯度方向是包含 ϕ F \phi_F ϕF ϕ C \phi_C ϕC且沿着连接点 C C C F F F的连线方向的(跟面法向的梯度是不同的,它仅仅是真正的面法向梯度的一个分量而已)。

如果 e \bold e e代表沿着连接节点 C C C F F F单位矢量,那么
e = r F − r C ∣ ∣ r F − r C ∣ ∣ = d C F d C F \bold e=\frac{\bold r_F - \bold r_C}{||\bold r_F - \bold r_C||}=\frac{\bold d_{CF}}{d_{CF}} e=rFrCrFrC=dCFdCF
这样,在 e \bold e e方向的梯度可以写成
( ∇ ϕ ⋅ e ) f = ( ∂ ϕ ∂ e ) f = ϕ F − ϕ C ∣ ∣ r F − r C ∣ ∣ = ϕ F − ϕ C d C F (\nabla\phi\cdot\bold e)_f = \left(\frac{\partial\phi}{\partial e}\right)_f=\frac{\phi_F-\phi_C}{||\bold r_F - \bold r_C||}=\frac{\phi_F-\phi_C}{d_{CF}} (ϕe)f=(eϕ)f=rFrCϕFϕC=dCFϕFϕC
这样为了获得非正交网格上的线性化通量,面矢量 S f \bold S_f Sf应该写成两个矢量 E f \bold E_f Ef T f \bold T_f Tf的加和形式,即
S f = E f + T f \bold S_f = \bold E_f + \bold T_f Sf=Ef+Tf
其中 E f \bold E_f Ef是沿着 C F \bold {CF} CF方向的,以保证扩散通量中的一部分可以写成节点值 ϕ C \phi_C ϕC ϕ F \phi_F ϕF的函数,即
( ∇ ϕ ) f ⋅ S f = ( ∇ ϕ ) f ⋅ E f ⏟ o r t h o g o n a l − l i k e   c o n t r i b u t a t i o n + ( ∇ ϕ ) f ⋅ T ⏟ n o n − o r t h o g o n a l   l i k e   c o n t r i b u t a t i o n = E f ( ∂ ϕ ∂ e ) f + ( ∇ ϕ ) f ⋅ T f = E f ϕ F − ϕ C d C F + ( ∇ ϕ ) f ⋅ T f \begin{aligned} (\nabla\phi)_f\cdot\bold S_f &= \underbrace{(\nabla\phi)_f\cdot\bold E_f}_{orthogonal-like~contributation} + \underbrace{(\nabla\phi)_f\cdot\bold T}_{non-orthogonal~like~contributation} \\ &=E_f\left(\frac{\partial\phi}{\partial e}\right)_f + (\nabla\phi)_f\cdot\bold T_f \\ &=E_f\frac{\phi_F-\phi_C}{d_{CF}} + (\nabla\phi)_f\cdot\bold T_f \end{aligned} (ϕ)fSf=orthogonallike contributation (ϕ)fEf+nonorthogonal like contributation (ϕ)fT=Ef(eϕ)f+(ϕ)fTf=EfdCFϕFϕC+(ϕ)fTf
上式中右侧第一项与正交网格上的式子一样,其代表了正交贡献量。而第2项则是由于网格的非正交性所产生的交叉扩散非正交扩散。对 S f \bold S_f Sf的分解可以有不同的选择,如下所述。

6.2 最小修正方法Minimum Correction Approach

在这里插入图片描述
如图所示, S f \bold S_f Sf的分解方法是要保证非正交修正尽可能的小,即让 E f \bold E_f Ef T f \bold T_f Tf正交。伴随着非正交修正的增加,从 ϕ F \phi_F ϕF ϕ C \phi_C ϕC的扩散贡献将减小。矢量 E f \bold E_f Ef是这样计算的
E f = ( e ⋅ S f ) e = ( S f cos ⁡ θ ) e \bold E_f=(\bold e \cdot \bold S_f) \bold e=(S_f \cos \theta)\bold e Ef=(eSf)e=(Sfcosθ)e

6.3 正交修正方法Orthogonal Correction Approach

在这里插入图片描述这种方法让包含 ϕ F \phi_F ϕF ϕ C \phi_C ϕC的项和它们在正交网格上的贡献是同样的,即, S f \bold S_f Sf E f \bold E_f Ef的幅值是一样的,那么矢量 E f \bold E_f Ef选择为
E f = S f e \bold E_f=S_f\bold e Ef=Sfe

6.4 过松弛方法 Over-Relaxed Approach

在这里插入图片描述
该方法中,包含 ϕ F \phi_F ϕF ϕ C \phi_C ϕC的项将随着非正交性的增加而增加,如上图所示。通过将 T f \bold T_f Tf选择为垂直于 S f \bold S_f Sf来实现,这样 E f \bold E_f Ef是这样计算的
E f = ( S f cos ⁡ θ ) e = ( S f 2 S f cos ⁡ θ ) e = S f ⋅ S f e ⋅ S f e \bold E_f=\left( \frac{S_f}{\cos \theta} \right)\bold e=\left( \frac{S_f^2}{S_f \cos \theta} \right) \bold e = \frac{\bold S_f \cdot \bold S_f}{\bold e \cdot \bold S_f}\bold e Ef=(cosθSf)e=(SfcosθSf2)e=eSfSfSfe
总结一下,在非正交网格上的单元面的扩散通量不能简单地写成该面两侧单元值的形式,必须添加上一个非正交修正项。该修正项在文献中常称为“交叉扩散”,其算法如下
( ∇ ϕ ) f ⋅ T f = ( ∇ ϕ ) f ⋅ ( S f − E f ) = { ( ∇ ϕ ) f ⋅ ( n − cos ⁡ θ e ) S f m i n i m u m   c o r r e c t i o n ( ∇ ϕ ) f ⋅ ( n − e ) S f n o r m a l   c o r r e c t i o n ( ∇ ϕ ) f ⋅ ( n − 1 cos ⁡ θ e ) S f o v e r − r e l a x e d \begin{aligned} (\nabla\phi)_f \cdot \bold T_f &= (\nabla\phi)_f \cdot (\bold S_f - \bold E_f) \\ & = \begin{cases} (\nabla\phi)_f \cdot (\bold n - \cos \theta \bold e)S_f & minimum~correction \\ (\nabla\phi)_f \cdot (\bold n - \bold e)S_f & normal~correction \\ (\nabla\phi)_f \cdot (\bold n - \displaystyle \frac{1}{\cos \theta} \bold e)S_f & over-relaxed \end{cases} \end{aligned} (ϕ)fTf=(ϕ)f(SfEf)=(ϕ)f(ncosθe)Sf(ϕ)f(ne)Sf(ϕ)f(ncosθ1e)Sfminimum correctionnormal correctionoverrelaxed
对于正交网格而言, n \bold n n e \bold e e是共线的,角度 θ \theta θ是0,因此交叉扩散项是0。当交叉扩散项非0时,因为其不能写成 ϕ F \phi_F ϕF ϕ C \phi_C ϕC的函数,所以它将作为源项添加在单元的代数方程中。
上面的方法都是正确的,它们的差别是在非正交网格上的准确性和稳定性(accuracy和stability)。其中over-relaxed方法已经被发现是最稳定的,即便是网格高度非正交的时候。然而,扩散项离散后的最终通有形式,对于三种方法来说都是一样的。

6.5 交叉扩散项的处理方法

交叉扩散项无法展开成节点值的形式,因为其含有 ( ∇ ϕ ) f (\nabla\phi)_f (ϕ)f,所以,它只好作为延迟修正方式来处理,通过使用当前梯度场来算出交叉扩散项的值,并将其作为源项添加到代数方程的右端项中去。如下所述,梯度是在主网格(单元形心)上计算的,即 ( ∇ ϕ ) C (\nabla\phi)_C (ϕ)C,并且插值到界面上去的,即 ( ∇ ϕ ) f (\nabla\phi)_f (ϕ)f。(注意,这里的交叉扩散项指的是 ( ∇ ϕ ) f ⋅ T f (\nabla\phi)_f\cdot\bold T_f (ϕ)fTf,即该项该如何计算,而在第9章第4节中所讲的是 ( ∇ ϕ ) f (\nabla\phi)_f (ϕ)f在非正交网格上式如何计算的,两者是不一样的!)

6.6 梯度计算

在正交网格上,单元形心的梯度值可以直接由单元两侧单元的形心值给出,面形心的梯度值也可由其两侧单元的形心值给出。然而,在非正交网格和非结构网格上,梯度的计算较为复杂,常用的方法是Green-Gauss或梯度定理来计算,即对于任何封闭体积 V V V,其由面 ∂ V \partial V V所包围而成,则有
∫ V ∇ ϕ  d V = ∮ ∂ V ϕ d S \int_V\nabla\phi~\text dV=\oint_{\partial V}\phi \text d \bold S Vϕ dV=VϕdS
其中 d S \text d\bold S dS为指向外侧的面矢量。为获取上式的离散形式,使用中值定理,得
∫ V ∇ ϕ  d V = ∇ ϕ ‾ V \int_V\nabla\phi~\text dV=\overline{\nabla\phi}V Vϕ dV=ϕV
于是,在单元 C C C上的平均梯度为
∇ ϕ ‾ C = 1 V C ∮ ∂ V C ϕ f S f \overline{\nabla\phi}_C = \frac{1}{V_C}\oint_{\partial V_C}\phi_f \bold S_f ϕC=VC1VCϕfSf
接下来,对于单元面的积分可近似为面形心值与面面积的乘积,这样 ∇ ϕ ‾ C \overline{\nabla\phi}_C ϕC,或简写成 ∇ ϕ C \nabla\phi_C ϕC,可由下式计算
∇ ϕ C = 1 V C ∑ f ∼ n b ( C ) ϕ f S f {\nabla\phi}_C = \frac{1}{V_C}\sum_{f\sim nb(C)}\phi_f \bold S_f ϕC=VC1fnb(C)ϕfSf
算得单元形心的梯度后,面形心的梯度可由面两侧单元形心梯度的加权平均来获取,即
∇ ϕ f = g C ∇ ϕ C + g F ∇ ϕ E \nabla\phi_f=g_C\nabla\phi_C+g_F\nabla\phi_E ϕf=gCϕC+gFϕE
其中的 g C g_C gC g F g_F gF为几何插值系数,其与单元 C C C和单元 F F F以及面 f f f的位置相关。

6.7 非正交网格的代数方程

将面矢量 S f \bold S_f Sf分解为 E f \bold E_f Ef T f \bold T_f Tf矢量,并将其等效表达式代入到半离散扩散通量方程中去,可得
∑ f ∼ n b ( C ) ( J f ϕ , D ⋅ S f ) = ∑ f ∼ n b ( C ) ( − ( Γ ϕ ∇ ϕ ) f ⋅ ( E f + T f ) ) = ∑ f ∼ n b ( C ) ( − ( Γ ϕ ∇ ϕ ) f ⋅ E f ) ⏟ O r t h o g o n a l   L i n e a r i z e a b l e   P a r t + ∑ f ∼ n b ( C ) ( − ( Γ ϕ ∇ ϕ ) f ⋅ T f ) ⏟ N o n − o r t h o g o n a l   N o n − L i n e a r i z e a b l e   P a r t = ∑ f ∼ n b ( C ) ( − Γ f ϕ E f ϕ F − ϕ C d C F ) + ∑ f ∼ n b ( C ) ( − ( Γ ϕ ∇ ϕ ) f ⋅ T f ) = ∑ f ∼ n b ( C ) Γ f ϕ g D i f f f ( ϕ C − ϕ F ) + ∑ f ∼ n b ( C ) ( − ( Γ ϕ ∇ ϕ ) f ⋅ T f ) = ( ∑ f ∼ n b ( C ) F l u x C f ) ϕ C + ∑ f ∼ n b ( C ) ( F l u x F f ϕ F ) + ∑ f ∼ n b ( C ) F l u x V f \begin{aligned} \sum_{f\sim nb(C)}\left( \bold J_f^{\phi,D} \cdot \bold S_f\right) &= \sum_{f\sim nb(C)} \left( -(\Gamma^\phi\nabla\phi)_f \cdot (\bold E_f+\bold T_f) \right) \\ &= \underbrace{\sum_{f\sim nb(C)} \left( -(\Gamma^\phi\nabla\phi)_f \cdot \bold E_f \right)}_{Orthogonal~Linearizeable~Part} + \underbrace{\sum_{f\sim nb(C)} \left( -(\Gamma^\phi\nabla\phi)_f \cdot \bold T_f \right)}_{Non-orthogonal~Non-Linearizeable~Part} \\ &= \sum_{f\sim nb(C)} \left( -\Gamma^\phi_f E_f \frac{\phi_F-\phi_C}{d_{CF}} \right) + \sum_{f\sim nb(C)} \left( -(\Gamma^\phi\nabla\phi)_f \cdot \bold T_f \right) \\ &= \sum_{f\sim nb(C)} \Gamma^\phi_f gDiff_f (\phi_C-\phi_F) + \sum_{f\sim nb(C)} \left( -(\Gamma^\phi\nabla\phi)_f \cdot \bold T_f \right) \\ &=\left( \sum_{f\sim nb(C)} FluxC_f \right)\phi_C+ \sum_{f\sim nb(C)} (FluxF_f\phi_F) + \sum_{f\sim nb(C)} FluxV_f \end{aligned} fnb(C)(Jfϕ,DSf)=fnb(C)((Γϕϕ)f(Ef+Tf))=Orthogonal Linearizeable Part fnb(C)((Γϕϕ)fEf)+Nonorthogonal NonLinearizeable Part fnb(C)((Γϕϕ)fTf)=fnb(C)(ΓfϕEfdCFϕFϕC)+fnb(C)((Γϕϕ)fTf)=fnb(C)ΓfϕgDifff(ϕCϕF)+fnb(C)((Γϕϕ)fTf)=fnb(C)FluxCfϕC+fnb(C)(FluxFfϕF)+fnb(C)FluxVf
其中 g D i f f f gDiff_f gDifff为几何扩散系数,即
g D i f f f = E f d C F gDiff_f=\frac{E_f}{d_{CF}} gDifff=dCFEf
使用上述的扩散通量形式,在非结构/结构的非正交网格上的扩散方程的最终离散形式为
a C ϕ C + ∑ f ∼ n b ( C ) a F ϕ F = b C a_C\phi_C+\sum_{f\sim nb(C)}a_F\phi_F=b_C aCϕC+fnb(C)aFϕF=bC
其中
a F = F l u x F f = − Γ f ϕ g D i f f f a C = ∑ f ∼ n b ( C ) F l u x C f = − ∑ f ∼ n b ( C ) F l u x F f = ∑ f ∼ n b ( C ) Γ f ϕ g D i f f f b C = Q C ϕ V C − ∑ f ∼ n b ( C ) F l u x V f = Q C ϕ V C + ∑ f ∼ n b ( C ) ( ( Γ ϕ ∇ ϕ ) f ⋅ T f ) \begin{aligned} & a_F=FluxFf=-\Gamma_f^\phi gDiff_f \\ & a_C=\sum_{f\sim nb(C)}FluxC_f=-\sum_{f\sim nb(C)}FluxF_f=\sum_{f\sim nb(C)}\Gamma_f^\phi gDiff_f \\ & b_C=Q_C^\phi V_C - \sum_{f\sim nb(C)}FluxV_f=Q_C^\phi V_C+ \sum_{f\sim nb(C)}\left( (\Gamma^\phi\nabla\phi)_f \cdot \bold T_f \right) \end{aligned} aF=FluxFf=ΓfϕgDifffaC=fnb(C)FluxCf=fnb(C)FluxFf=fnb(C)ΓfϕgDifffbC=QCϕVCfnb(C)FluxVf=QCϕVC+fnb(C)((Γϕϕ)fTf)
注意非正交项的符号有所变化,因为其作为源项整到了方程的右端项中去。


例2
对于如图所示的多边形单元 C C C和其邻居单元 F F F,在任何点处的解满足 ϕ = x 2 + y 2 + x 2 y 2 \phi=x^2+y^2+x^2y^2 ϕ=x2+y2+x2y2,如果单元 C C C的体积是 V C = 8.625 V_C=8.625 VC=8.625,那么计算:

  1. 单元 C C C的梯度值,即 ∇ ϕ C \nabla\phi_C ϕC,使用数值方法求解,并和解析解对比;
  2. 解析解 ∇ ϕ F \nabla\phi_F ϕF
  3. 用数值解 ∇ ϕ C \nabla\phi_C ϕC和解析解 ∇ ϕ F \nabla\phi_F ϕF插值计算 ∇ ϕ f 1 \nabla\phi_{f_1} ϕf1的近似解,并与解析解 ∇ ϕ f 1 \nabla\phi_{f_1} ϕf1对比;
  4. ∇ ϕ f 1 ⋅ S f 1 \nabla\phi_{f_1}\cdot\bold S_{f_1} ϕf1Sf1展开为 ϕ C \phi_C ϕC ϕ F \phi_F ϕF的形式,使用
    a. 最小修正方法Minimum Correction Approach
    b. 正交修正方法Orthogonal Correction Approach
    c. 过松弛方法 Over-Relaxed Approach

在这里插入图片描述


较为繁琐,省去不表,感兴趣的话可自行计算。


6.8 非正交网格的边界条件

非正交网格的边界条件处理与正交网格是非常类似的,只是在非正交扩散的处理上略有不同。

6.8.1 Dirchlet 边界条件

在这里插入图片描述
在Direchlet边界条件上,变量值 ϕ \phi ϕ是已知的,与在结构网格上的离散过程类似,只是需要考虑交叉扩散,只不过这时是把边界面当成内部面来处理就好了。当面矢量与 连接边界面紧邻边界单元的形心与该边界面的形心的矢量 不共线的时候,需要考虑交叉扩散。扩撒通量沿着边界面可被离散为
J b ϕ , D ⋅ S b = − ( Γ ϕ ∇ ϕ ) b ⋅ S b = − ( Γ ϕ ∇ ϕ ) b ⋅ ( E b + T b ) = − Γ b ϕ ( ϕ b − ϕ C d C b ) E b − Γ b ϕ ( ∇ ϕ ) b ⋅ T b = F l u x C b ϕ C + F l u x V b \begin{aligned} \bold J_b^{\phi,D} \cdot \bold S_b &= -(\Gamma^\phi\nabla\phi)_b \cdot \bold S_b = -(\Gamma^\phi\nabla\phi)_b \cdot (\bold E_b+\bold T_b) \\ &= -\Gamma^\phi_b \left(\frac{\phi_b-\phi_C}{d_{Cb}}\right) E_b - \Gamma^\phi_b(\nabla\phi)_b \cdot \bold T_b \\ & = FluxC_b\phi_C + FluxV_b \end{aligned} Jbϕ,DSb=(Γϕϕ)bSb=(Γϕϕ)b(Eb+Tb)=Γbϕ(dCbϕbϕC)EbΓbϕ(ϕ)bTb=FluxCbϕC+FluxVb
其中
F l u x C b = Γ b ϕ g D i f f b F l u x V b = − Γ b ϕ g D i f f b ϕ b − Γ b ϕ ( ∇ ϕ ) b ⋅ T b g D i f f b = E b d C b \begin{aligned} FluxC_b &= \Gamma_b^\phi gDiff_b \\ FluxV_b &= -\Gamma_b^\phi gDiff_b \phi_b - \Gamma^\phi_b(\nabla\phi)_b \cdot \bold T_b \\ gDiff_b &= \frac{E_b}{d_{Cb}} \end{aligned} FluxCbFluxVbgDiffb=ΓbϕgDiffb=ΓbϕgDiffbϕbΓbϕ(ϕ)bTb=dCbEb
把上面式子代入到单元的离散方程中去,可得各项修正的系数为
a F = F l u x F f a C = ∑ f ∼ n b ( C ) F l u x C f + F l u x C b b C = Q C ϕ V C − F l u x V b − ∑ f ∼ n b ( C ) F l u x V f \begin{aligned} a_F&=FluxF_f \quad\quad a_C=\sum_{f\sim nb(C)}FluxC_f+FluxC_b \\ b_C&=Q_C^\phi V_C - FluxV_b - \sum_{f\sim nb(C)}FluxV_f \end{aligned} aFbC=FluxFfaC=fnb(C)FluxCf+FluxCb=QCϕVCFluxVbfnb(C)FluxVf

6.8.2 Neumann 边界条件

Neumann边界条件对于非结构网格的处理与结构网格是一样的,边界上给定的通量将作为源项添加。边界的代数方程是一样的,修正系数也是一样的,并没有任何差别和改变。

6.8.3 Mixed边界条件

对于混合边界条件,其由对流导热系数 h ∞ h_\infin h和周围变量值 ϕ ∞ \phi_\infin ϕ来定义,扩散通量可写成
J b ϕ , D ⋅ S b = − Γ b ϕ ( ϕ b − ϕ C d C b ) E b − Γ b ϕ ( ∇ ϕ ) b ⋅ T b = − h ∞ ( ϕ ∞ − ϕ b ) S b \begin{aligned} \bold J_b^{\phi,D}\cdot\bold S_b &=-\Gamma^\phi_b\left( \frac{\phi_b - \phi_C}{d_{Cb}} \right) E_b - \Gamma_b^\phi (\nabla \phi)_b \cdot \bold T_b\\ &= -h_\infin(\phi_\infin-\phi_b)S_b \end{aligned} Jbϕ,DSb=Γbϕ(dCbϕbϕC)EbΓbϕ(ϕ)bTb=h(ϕϕb)Sb
可得到 ϕ b \phi_b ϕb的表达式如下
ϕ b = h ∞ S b ϕ ∞ + Γ b ϕ E b d C b ϕ C − Γ b ϕ ( ∇ ϕ ) b ⋅ T b h ∞ S b + Γ b ϕ E b d C b \phi_b=\frac {h_\infin S_b \phi_\infin + \displaystyle\frac{\Gamma_b^\phi E_b}{d_{Cb}}\phi_C - \Gamma_b^\phi (\nabla \phi)_b \cdot \bold T_b} {h_\infin S_b + \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}} ϕb=hSb+dCbΓbϕEbhSbϕ+dCbΓbϕEbϕCΓbϕ(ϕ)bTb
将上式待会到上上式中,可得
J b ϕ , D ⋅ S b = − [ h ∞ S b Γ b ϕ E b d C b h ∞ S b + Γ b ϕ E b d C b ] ⏟ a b ( ϕ ∞ − ϕ C ) − h ∞ S b Γ b ϕ ( ∇ ϕ ) b ⋅ T b h ∞ S b + Γ b ϕ E b d C b ⏟ S b ϕ , C D = F l u x C b ϕ C + F l u x V b \begin{aligned} \bold J_b^{\phi,D}\cdot\bold S_b &= \underbrace{-\left[ \frac{h_\infin S_b \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}}{h_\infin S_b + \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}} \right] }_{a_b} (\phi_\infin - \phi_C) - \underbrace{\frac{h_\infin S_b \Gamma_b^\phi(\nabla\phi)_b\cdot\bold T_b}{h_\infin S_b + \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}}}_{S_b^{\phi,CD}} \\ &= FluxC_b \phi_C + FluxV_b \end{aligned} Jbϕ,DSb=ab hSb+dCbΓbϕEbhSbdCbΓbϕEb(ϕϕC)Sbϕ,CD hSb+dCbΓbϕEbhSbΓbϕ(ϕ)bTb=FluxCbϕC+FluxVb
其中
F l u x C b = h ∞ S b Γ b ϕ E b d C b h ∞ S b + Γ b ϕ E b d C b F l u x V b = − F l u x C b ϕ ∞ − h ∞ S b Γ b ϕ ( ∇ ϕ ) b ⋅ T b h ∞ S b + Γ b ϕ E b d C b \begin{aligned} FluxC_b &= \frac{h_\infin S_b \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}}{h_\infin S_b + \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}} \\ FluxV_b &= -FluxC_b\phi_\infin - \frac{h_\infin S_b \Gamma_b^\phi(\nabla\phi)_b\cdot\bold T_b}{h_\infin S_b + \displaystyle \frac{\Gamma_b^\phi E_b}{d_{Cb}}} \end{aligned} FluxCbFluxVb=hSb+dCbΓbϕEbhSbdCbΓbϕEb=FluxCbϕhSb+dCbΓbϕEbhSbΓbϕ(ϕ)bTb
对于边界单元的离散方程的修正系数为
a F = F l u x F f a C = ∑ f ∼ n b ( C ) F l u x C f + F l u x C b b C = Q C ϕ V C − F l u x V b − ∑ f ∼ n b ( C ) F l u x V f \begin{aligned} a_F&=FluxF_f \quad\quad a_C=\sum_{f\sim nb(C)}FluxC_f+FluxC_b \\ b_C&=Q_C^\phi V_C - FluxV_b - \sum_{f\sim nb(C)}FluxV_f \end{aligned} aFbC=FluxFfaC=fnb(C)FluxCf+FluxCb=QCϕVCFluxVbfnb(C)FluxVf

7 Skewness(偏斜)

构成通用离散方程的很多项在计算的时候都需要,单元面上的 ϕ \phi ϕ值。可以用面上的平均值来代替面上的值,那么如果面上各处的 ϕ \phi ϕ值不同的话,变量 ϕ \phi ϕ在面上的平均值就是位于面形心处的 ϕ \phi ϕ值了。

然而一般是用面两侧单元形心的值来做线性插值获取面上的值,但是这样子获得的是面两侧单元形心连线与面交点处的值,如下图所示,这个交点是 f ′ f' f,这个点跟面形心 f f f点往往是不重合的(除非是在正交网格上面两点才重合),也就是说获取的面上点的值,并非是面形心处的值!!

在这里插入图片描述
为了保证离散方法的2阶精度,所有面积分的积分点应在面形心 f f f处,这就需要采取修正措施将 f ′ f' f处的值修正到 f f f处,一般用Taylor展开来实现,即
ϕ f = ϕ f ′ + ( ∇ ϕ ) f ′ ⋅ d f ′ f \phi_f=\phi_{f'}+(\nabla\phi)_{f'}\cdot\bold d_{f'f} ϕf=ϕf+(ϕ)fdff
其中 d f ′ f \bold d_{f'f} dff为交点 f ′ f' f到面形心点 f f f的距离矢量。

这里只是简要提及一下而已,关于该部分修正的详细内容可参考第9章。

8 各向异性(非各向同性)扩散

目前的扩散方程中都是假设材料对于 ϕ \phi ϕ的传导是没有方向性的,即对于所有的方向扩散系数都是一样的,即,材料是各向同性的。但是,对于某些材料而言,扩散系数是跟方向相关的,扩散是各向异性的!某些固体是各向异性的,其半离散扩散方程为
∑ f ∼ n b ( C ) ( − κ ϕ ⋅ ∇ ϕ ) f ⋅ S f = Q C ϕ V C \sum_{f\sim nb(C)}(-\boldsymbol \kappa^\phi \cdot \nabla \phi )_f\cdot\bold S_f = Q_C^\phi V_C fnb(C)(κϕϕ)fSf=QCϕVC
其中 κ ϕ \boldsymbol \kappa^\phi κϕ为2阶对称张量,对于最通常的三维情况,左端项经过一些数学处理,可写成
( − κ ϕ ⋅ ∇ ϕ ) f ⋅ S f = − [ κ 11 ϕ κ 12 ϕ κ 13 ϕ   κ 21 ϕ κ 22 ϕ κ 23 ϕ   κ 31 ϕ κ 32 ϕ κ 33 ϕ ] f [ ∂ ϕ ∂ x   ∂ ϕ ∂ y   ∂ ϕ ∂ z ] f ⋅ S f (-\boldsymbol \kappa^\phi \cdot \nabla \phi )_f\cdot\bold S_f = -\begin{bmatrix} \boldsymbol \kappa^\phi_{11} & \boldsymbol \kappa^\phi_{12} & \boldsymbol \kappa^\phi_{13} \\ ~\\ \boldsymbol \kappa^\phi_{21} & \boldsymbol \kappa^\phi_{22} & \boldsymbol \kappa^\phi_{23} \\ ~\\ \boldsymbol \kappa^\phi_{31} & \boldsymbol \kappa^\phi_{32} & \boldsymbol \kappa^\phi_{33} \end{bmatrix}_f \begin{bmatrix} \displaystyle \frac{\partial\phi}{\partial x} \\ ~\\ \displaystyle \frac{\partial\phi}{\partial y} \\ ~\\ \displaystyle \frac{\partial\phi}{\partial z} \end{bmatrix}_f \cdot \bold S_f (κϕϕ)fSf=κ11ϕ κ21ϕ κ31ϕκ12ϕκ22ϕκ32ϕκ13ϕκ23ϕκ33ϕfxϕ yϕ zϕfSf
经过矩阵相乘,上式变为
( − κ ϕ ⋅ ∇ ϕ ) f ⋅ S f = − [ κ 11 ϕ ∂ ϕ ∂ x + κ 12 ϕ ∂ ϕ ∂ y + κ 13 ϕ ∂ ϕ ∂ z   κ 21 ϕ ∂ ϕ ∂ x + κ 22 ϕ ∂ ϕ ∂ y + κ 23 ϕ ∂ ϕ ∂ z   κ 31 ϕ ∂ ϕ ∂ x + κ 32 ϕ ∂ ϕ ∂ y + κ 33 ϕ ∂ ϕ ∂ z ] f ⋅ [ S x   S y   S z ] f (-\boldsymbol \kappa^\phi \cdot \nabla \phi )_f\cdot\bold S_f = -\begin{bmatrix} \boldsymbol \kappa^\phi_{11}\displaystyle \frac{\partial\phi}{\partial x} + \boldsymbol \kappa^\phi_{12} \displaystyle \frac{\partial\phi}{\partial y} + \boldsymbol \kappa^\phi_{13} \displaystyle \frac{\partial\phi}{\partial z} \\ ~\\ \boldsymbol \kappa^\phi_{21} \displaystyle \frac{\partial\phi}{\partial x} + \boldsymbol \kappa^\phi_{22}\displaystyle \frac{\partial\phi}{\partial y} + \boldsymbol \kappa^\phi_{23} \displaystyle \frac{\partial\phi}{\partial z}\\ ~\\ \boldsymbol \kappa^\phi_{31} \displaystyle \frac{\partial\phi}{\partial x} + \boldsymbol \kappa^\phi_{32}\displaystyle \frac{\partial\phi}{\partial y} + \boldsymbol \kappa^\phi_{33}\displaystyle \frac{\partial\phi}{\partial z} \end{bmatrix}_f \cdot \begin{bmatrix} S^x \\ ~\\ S^y \\ ~\\ S^z \end{bmatrix}_f (κϕϕ)fSf=κ11ϕxϕ+κ12ϕyϕ+κ13ϕzϕ κ21ϕxϕ+κ22ϕyϕ+κ23ϕzϕ κ31ϕxϕ+κ32ϕyϕ+κ33ϕzϕfSx Sy Szf
进一步处理得到
( − κ ϕ ⋅ ∇ ϕ ) f ⋅ S f = − [ ∂ ϕ ∂ x ∂ ϕ ∂ y ∂ ϕ ∂ z ] f [ κ 11 ϕ κ 21 ϕ κ 31 ϕ   κ 12 ϕ κ 22 ϕ κ 32 ϕ   κ 13 ϕ κ 23 ϕ κ 33 ϕ ] f ⋅ [ S x   S y   S z ] f = − ( ∇ ϕ ) f ⋅ [ ( κ ϕ ) T ⋅ S ] f = − ( ∇ ϕ ) f ⋅ S f ′ \begin{aligned} (-\boldsymbol \kappa^\phi \cdot \nabla \phi )_f\cdot\bold S_f &= -\begin{bmatrix} \displaystyle \frac{\partial\phi}{\partial x} & \displaystyle \frac{\partial\phi}{\partial y} & \displaystyle \frac{\partial\phi}{\partial z} \end{bmatrix}_f \begin{bmatrix} \boldsymbol \kappa^\phi_{11} & \boldsymbol \kappa^\phi_{21} & \boldsymbol \kappa^\phi_{31} \\ ~\\ \boldsymbol \kappa^\phi_{12} & \boldsymbol \kappa^\phi_{22} & \boldsymbol \kappa^\phi_{32} \\ ~\\ \boldsymbol \kappa^\phi_{13} & \boldsymbol \kappa^\phi_{23} & \boldsymbol \kappa^\phi_{33} \end{bmatrix}_f \cdot \begin{bmatrix} S^x \\ ~\\ S^y \\ ~\\ S^z \end{bmatrix}_f \\ &= -(\nabla\phi)_f\cdot[(\boldsymbol\kappa^\phi)^T\cdot S]_f=-(\nabla\phi)_f\cdot\bold S'_f \end{aligned} (κϕϕ)fSf=[xϕyϕzϕ]fκ11ϕ κ12ϕ κ13ϕκ21ϕκ22ϕκ23ϕκ31ϕκ32ϕκ33ϕfSx Sy Szf=(ϕ)f[(κϕ)TS]f=(ϕ)fSf
于是,扩散方程的离散格式变成
∑ f ∼ n b ( C ) − ( ∇ ϕ ) f ⋅ S f ′ = Q C ϕ V C \sum_{f\sim nb(C)}-(\nabla\phi)_f\cdot\bold S'_f = Q_C^\phi V_C fnb(C)(ϕ)fSf=QCϕVC
通过以上分析发现,只需要在离散过程中把原本的扩散系数 Γ \Gamma Γ替换为 1 1 1,把面矢量 S f \bold S_f Sf替换为 S f ′ \bold S'_f Sf,而其余的部分是完全相同的,就可以求解各向同性和各向异性扩散问题了。

9 迭代求解问题的欠松弛处理

对于更加通常的扩散问题, Γ ϕ \Gamma^\phi Γϕ可能是未知量 ϕ \phi ϕ的函数,网格可能高度的非正交,有很大的交叉扩散项,这时就需要做延迟修正处理了。因为 ϕ \phi ϕ在迭代中的较大变化会导致较大的源项和较大的系数变化,这些会导致迭代迭代求解过程的发散。该发散是由于系数和交叉扩散项的非线性效应引起的,即,源项被当前流场影响较大而无法收敛。为了获得收敛解,需要减慢 ϕ \phi ϕ在迭代过程中的变化,这种技术就是欠松弛。有许多方法来引入欠松弛,这里介绍一种,其余的可参考第14章内容。在通有离散方程上进行处理
a C ϕ C + ∑ F ∼ N B ( C ) a F ϕ F = b C a_C\phi_C+\sum_{F\sim NB(C)}a_F\phi_F=b_C aCϕC+FNB(C)aFϕF=bC
上述方程可以写成
ϕ C = − ∑ F ∼ N B ( C ) a F ϕ F + b C a C \phi_C=\frac{-\displaystyle\sum_{F\sim NB(C)}a_F\phi_F+b_C}{a_C} ϕC=aCFNB(C)aFϕF+bC
ϕ C ∗ \phi_C^* ϕC代表上次迭代的 ϕ C \phi_C ϕC值,将其从右端项中减去并加上,即
ϕ C = ϕ C ∗ + ( − ∑ F ∼ N B ( C ) a F ϕ F + b C a C − ϕ C ∗ ) \phi_C=\phi_C^* + \left( \frac{-\displaystyle\sum_{F\sim NB(C)}a_F\phi_F+b_C}{a_C} - \phi_C^* \right) ϕC=ϕC+aCFNB(C)aFϕF+bCϕC
上式中括号里的项代表了当前迭代步对 ϕ C \phi_C ϕC的改变,该变化可以通过引入松弛因子 λ ϕ \lambda^\phi λϕ来修正,即
ϕ C = ϕ C ∗ + λ ϕ ( − ∑ F ∼ N B ( C ) a F ϕ F + b C a C − ϕ C ∗ ) \phi_C=\phi_C^* + \lambda^\phi \left( \frac{-\displaystyle\sum_{F\sim NB(C)}a_F\phi_F+b_C}{a_C} - \phi_C^* \right) ϕC=ϕC+λϕaCFNB(C)aFϕF+bCϕC

a C λ ϕ ϕ C + ∑ F ∼ N B ( C ) a F ϕ F = b C + ( 1 − λ ϕ ) a C λ ϕ ϕ C ∗ \frac{a_C}{\lambda^\phi}\phi_C+\sum_{F\sim NB(C)}a_F\phi_F=b_C+\frac{(1-\lambda^\phi)a_C}{\lambda^\phi}\phi_C^* λϕaCϕC+FNB(C)aFϕF=bC+λϕ(1λϕ)aCϕC
即,收敛的时候, ϕ C \phi_C ϕC ϕ C ∗ \phi_C^* ϕC是一样的。

根据 λ ϕ \lambda^\phi λϕ的不同,方程可以是欠松弛( 0 < λ ϕ < 1 0<\lambda^\phi<1 0<λϕ<1)的,也可以是超松弛( λ ϕ > 1 \lambda^\phi>1 λϕ>1)的。在CFD中,一般常用的都是欠松弛的处理方式。 λ ϕ \lambda^\phi λϕ接近1意味着轻微的欠松弛,而其接近0则意味着较为强烈的欠松弛,即 ϕ C \phi_C ϕC每次迭代的变化非常小。

最适宜的欠松弛因子是因问题而定的,并没有通用的规则可寻。影响松弛因子的因素包括求解问题的类型、系统方程的规模(计算域中网格点数目)、网格尺度、网格增长率、采用的迭代方法等。通常来说, λ ϕ \lambda^\phi λϕ是凭借之前计算中所积攒的经验来选取的。而且,没必要再整个计算域中采用同样的松弛因子,也没必要在每次迭代时采用同样的松弛因子。(这话说的,跟没说也差不多了,总之就是不收敛了你就调小点,收敛慢了你就调大点,大概就是这么个意思了)

加了松弛因子的离散方程也能归并成统一的格式,即,让 a C a_C aC b C b_C bC项做替换就可以了
a C ← a C λ ϕ a_C \leftarrow \frac{a_C}{\lambda^\phi} aCλϕaC
b C ← b C + ( 1 − λ ϕ ) a C λ ϕ ϕ C ∗ b_C \leftarrow b_C+\frac{(1-\lambda^\phi)a_C}{\lambda^\phi}\phi_C^* bCbC+λϕ(1λϕ)aCϕC
实际上,松弛处理的方法是求解非线性问题中常用的一种稳定求解的方法。

10 代码讲解

10.1 uFVM

在uFVM中,对于内部面的扩散项离散的实现是由函数cfdAssembleDiffusionTermInterior来完成的,代码和个人理解展示如下

% 将gamma从单元形心值插值到面形心值
gamma_f = cfdInterpolateFromElementsToFaces('Average',gamma);
gamma_f = [gamma_f(iFaces)];

% 提取面几何扩散系数 gDiff_f = Ef / CF
geoDiff_f = [theMesh.faces(iFaces).geoDiff]';
% 提取面面积矢量Sf
Sf = [theMesh.faces(iFaces).Sf]';
% 提取面的非正交修正矢量Tf = Sf - CF
Tf = [theMesh.faces(iFaces).T]';

% 面左单元标识
iOwners = [theMesh.faces(iFaces).iOwner]';
% 面右单元标识
iNeighbours = [theMesh.faces(iFaces).iNeighbour]';

%8.6.7(第8章第6.7节)中的离散代数方程形式相对应
% 面扩散通量FluxCf,加和后为phiC的系数,正值,也是该面的own单元系数
theFluxes.FLUXC1f(iFaces,1) = gamma_f .* gDiff_f;
% 面扩散通量FluxFf,phiF的系数,负值,也是该面的neighbour单元系数
theFluxes.FLUXC2f(iFaces,1) = -gamma_f .* gDiff_f;

% 非正交扩散项FluxVf,加和后为源项bC的第2项
theFluxes.FLUXVf(iFaces,1) = gamma_f .* dot(grad_f(:,:)',Tf(:,:)')';
% 经过这个面的所有通量加和,即,经过这个面的净通量
theFluxes.FLUXTf(iFaces,1) = theFluxes.FLUXC1f(iFaces) .* ...
    phi(iOwners) + theFluxes.FLUXC2f(iFaces) .* phi(iNeighbours) + ...
    theFluxes.FLUXVf(iFaces);

注意,上述代码并没有做面循环(by the way,matlab里面做循环的话效率会低到让人想撞墙),这里是整场来做运算的,把全部向量一起计算了。此外,面几何扩散系数 g D i f f f = E f / C F gDiff_f = Ef / CF gDifff=Ef/CF的计算是在函数cfdProcessOpenFoamMesh.m函数中进行的,相关代码如下

% 面右单元形心F到左单元形心C的矢量CF
theMesh.faces(iFace).dCF = element2.centroid - element1.centroid;

% CF矢量单位化,的eCF矢量
eCF = dCF/cfdMagnitude(dCF);

% 在矢量eCF上整一个跟面面积一样的长度矢量E
E = theFace.area*eCF;

% 面的几何扩散系数gDiff=Ef/dCF
theMesh.faces(iFace).gDiff = cfdMagnitude(E)/cfdMagnitude(dCF);

% 非正交扩散矢量T = 面积矢量Sf - 正交矢量E(Sf在CF方向的分量)
theMesh.faces(iFace).T = theFace.Sf - E;

% 注意,这里的非正交修正用的是Orthogonal Correction Approach
% 即,让Ef和Sf的幅值相同,即正交项和正交网格上的值相同。

边界条件对方程的影响在边界单元上应充分考虑,下面给出Dirichlet边界条件的情况下扩散项在边界面的处理代码

% 取出网格、单元总数、内部面总数
theMesh = cfdGetMesh;
numberOfElements = theMesh.numberOfElements;
numberOfInteriorFaces = theMesh.numberOfInteriorFaces;

% 取出第iPatch个边界Patch,及其所含边界面数目
theBoundary = theMesh.boundaries(iPatch);
numberOfBFaces = theBoundary.numberOfBFaces;

% 该片边界patch的起始、结束、范围面标识信息
iFaceStart = theBoundary.startFace;
iFaceEnd = iFaceStart+numberOfBFaces-1;
iBFaces = iFaceStart:iFaceEnd;

% 该片边界对应的起始单元、结束单元、单元范围标识信息
iElementStart = numberOfElements+iFaceStart-numberOfInteriorFaces;
iElementEnd = iElementStart+numberOfBFaces-1;
iBElements = iElementStart:iElementEnd;

% 取出面的几何扩散系数、非正交修正矢量、面的所属单元标识(边界面对应一个边界单元哈)
geodiff = [theMesh.faces(iBFaces).geoDiff]';
Tf = [theMesh.faces(iBFaces).T]';
iOwners = [theMesh.faces(iBFaces).iOwner]';

% 计算扩散方程离散形式的相关系数
% 计算边界条件在 aC系数中的添加项 FluxCb = gamma * gDiff
theFluxes.FLUXC1f(iBFaces) = gamma(iBElements).*geodiff;
% 计算边界条件在 bC系数中的添加项 FluxVb1 = - FluxCb = - gamma * gDiff
theFluxes.FLUXC2f(iBFaces) = - gamma(iBElements).*geodiff;
% 计算边界条件在 bCx系数中的添加项 FluxVb2 = - gamma * (grad(phi)) dot T
theFluxes.FLUXVf(iBFaces) = - ...
    gamma(iBElements).*dot(grad(iBElements,:)',Tf(:,:)')';

其它边界条件的添加方式可参考cfAssembleDiffusionTerm.m函数。

当这些线性系数对于内部面和边界面都算好之后,就可以把它们组装成整体(稀疏)矩阵了。这部分操作是在cfdAssembleIntoGlobalMatrixFaceFluxes函数中进行的,内部面系数组装成左端项LHS矩阵和右端项RHS矢量的代码展示如下:

%
% Assemble fluxes of interior faces
%
for iFace = 1:numberOfInteriorFaces
    theFace = theMesh.faces(iFace);
    iOwner = theFace.iOwner;
    iOwnerNeighbourCoef = theFace.iOwnerNeighbourCoef;
    iNeighbour = theFace.iNeighbour;
    iNeighbourOwnerCoef = theFace.iNeighbourOwnerCoef;
    %
    % assemble fluxes for owner cell
    ac(iOwner) = ac(iOwner) ...
        + vf_f(iFace)*theFluxes.FLUXC1f(iFace);
    anb{iOwner}(iOwnerNeighbourCoef) = anb{iOwner}(iOwnerNeighbourCoef) ...
        + vf_f(iFace)*theFluxes.FLUXC2f(iFace);
    bc(iOwner) = bc(iOwner) ...
        - vf_f(iFace)*theFluxes.FLUXTf(iFace);
    %
    % assemble fluxes for neighbour cell
    ac(iNeighbour) = ac(iNeighbour) ...
        - vf_f(iFace)*theFluxes.FLUXC2f(iFace);
    anb{iNeighbour}(iNeighbourOwnerCoef) = anb{iNeighbour}(iNeighbourOwnerCoef) ...
        - vf_f(iFace)*theFluxes.FLUXC1f(iFace);
    bc(iNeighbour) = bc(iNeighbour) ...
        + vf_f(iFace)*theFluxes.FLUXTf(iFace);
end

对于每个内部面来说,其系数同时组装到owner和neighbour两个单元的方程中去。Owner的系数是ac(iOwner)、anb(iOwner)(iOwnerNeighbourCoef)和bc(iOwner),而Neighbour的系数则是ac(iNeighbour)、anb(iNeighbour)(iNeighbourOwnerCoef)和bc(iNeighbour)。组装俩方程时候不同的正负号是因为面矢量是指向neighbour单元,而指出owner单元的。

10.2 OpenFOAM

to be continued…

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值