1. 直接解法:LU分解
在前面的内容中曾经提到,使用有限差分或有限体积法通过隐式离散得到的求解形式,其中为系数矩阵。在一定条件下,能够通过因式分解为,其中为下三角矩阵,为上三角矩阵。
这样的分解方式在高斯消元中十分有用,对的求解可分为以下两步
2. 迭代法:incomplete LU decomposition
如果存在一个与近似的矩阵,对做LU分解,我们把这样的步骤称为的不完全LU分解,ILU,即
其中为小量。
2.1. SIP
Stone提出了基于ILU且具有良好普适性的strongly implicit procedure (SIP),接下来我们简要介绍一下该算法。
在ILU中,如果矩阵中的元素非零,那么或矩阵在该元素对应位置上的对角线非零。以下图所示的为五对角矩阵为例说明,图中非零元素占据五条对角线,那么对应的和各自包含三条对角线。
令主对角线上元素为1。可见,与的乘积不可能为五对角矩阵,而是七对角矩阵,因此不可能还原为,而是,如下图所示
令两次相邻迭代的差值为,则原代数方程组可写成
矩阵为残差矩阵,为已知值。设想如果能够完全LU分解,那么便可以通过直接解法解出,然后加到求出,整个过程只需一次迭代。可是根据前文的分析,五对角矩阵无法完全LU分解,因此Stone的目标变成了尽可能的让的乘积接近。计算的乘积可得
而的乘积只有五项,对比来看多出了最后两项。因此Stone认为应尽量地消去最后两项。对做Taylor展开
代入前文的Taylor展开可得
Stone另外提出了校正系数,其作用是,同理。
将这层关系替换到中可得:
与对比可得矩阵和的关系。而是由和相乘而得,因此和也能够顺利求出。以上就是SIP算法的大致介绍,该算法中的“强隐式”体现在和的求解。
上文中图片来自《Computational Methods for Fluid Dynamics》, Ferziger
2.2. 代码实现
上一篇文章介绍了点迭代法,其特点是不涉及系数矩阵,内部结点仅和上下左右四点相关,换句话说我们只要判断处的点的上下左右四个结点在模拟区域中的位置即可。
本文介绍的SIP方法显然是对系数矩阵进行操作,这更符合工程应用中求解CFD的习惯,因为实际问题往往是网格量大、编号无规则、代数矩阵稀疏。
同样求解上一篇文章中的二维泊松方程,模拟区域方向均存在个结点,故结点数或变量数为,因此系数矩阵的大小为,变量数和矩阵大小切勿弄混。
程序中我们采用一维数组对结点编号,即,对于边界上的结点,例如,其值已知,因为Dirichlet边界条件。下面是计算步骤:
- 构建系数矩阵和源项,注意,第一个结点在程序中的编号从0开始,故右边界的结点编号为。边界结点在中的值为1,即,直接为边界上的值。内部结点的,其上下左右四个结点的系数为-1,推导过程见上一篇文章。
- 利用构建和矩阵,这部分计算流程见Sandip Mazumder所著《Numerical Methods for Partial Differential Equations》,需要注意的是书中几个变量的定义(书中公式3.38和3.57),例如向量的第个值表示编号为的结点的正下方邻居结点的系数。
- 给定初值,我在程序中直接将的值作为的初值。然后计算并计算向量的二范数,若二范数小于0.01则认为收敛。接着计算,为下三角,可以直接求出,因此可以快速的求出;接着计算,为上三角,可以直接求出,可以求出。接着,完成更新。
2.3. 计算结果
N=51,二范数收敛标准0.01,Stone系数,需要说明的是,这里的迭代次数与点迭代的计算方式完全不同,但复杂度均与结点数目成正比。
Method | Iteration number |
---|---|
SIP | 182 |
SIP
analytical
3. 最速下降法
Method of Steepest Descent (MSD),该算法思想是将代数方程组的求解转化为求二次型相关的极值问题。例如,对于,我们可以将其看作二次函数求极值问题,也就是对二次函数求导并求导数为0对应的值,这样就解出了
将这样的思路转换到代数方程组求解问题,对于,如果是正定矩阵或负定,则我们可以构造“二次函数”
上述函数的极值就是原代数方程组的解。其中
对上述函数求导
如果矩阵对称,则
MSD适用范围为:矩阵对称且正定或负定,当满足这个条件时,求上述二次函数的极值便等价于求
3.1. MSD求解
- 给定初值,代入矩阵求解残差
- 沿着梯度下降的方向进行更新,其中为沿梯度方向走的步长
- 计算步长
MSD的思想是沿着初始计算的梯度方向一直走,在刚开始走的过程中,函数值一定是单调递增或递减,当走到某一个点,在这个点往后的函数值与之前的变化规律不同,这时MSD认为应该重新计算梯度。举个例子,下山过程,从山顶开始沿着最大梯度下降的方向行进,到走到某个地方发现眼前不再是下坡,这时就需要重新看一看此处哪个方向的梯度最大,然后改变方向继续走。
用数学的语言来说,随的变化达到拐点时就需要重新计算梯度,因此也变成了寻找极值的问题
由链式求导法则
和的关系由上一步的迭代通式给出,代入上式可得
而与的关系已在第一步给出,因此上式可以整理为
把和的关系代入上式并整理可得的计算通式
3.2. 结果讨论
N=51,二范数收敛标准0.01,迭代及其缓慢,迭代600次二范数为0.13,还远远达不到收敛标准。
3.3. 举例
解析解为
3.3.1. 构造二次函数
3.3.2. 求偏导
3.3.3. 更新梯度
令初值为,则
4. 共轭梯度法
最速下降法中,后一次梯度方向垂直于前一次梯度方向,这种“台阶式”的迭代模式会使迭代效率大大下降,前文迭代600次,残差也仍未达到指定要求。
共轭梯度法(Conjugate gradient, CG)与MSD的区别是,后一次梯度方向并不垂直于前一次,而是前一次与当前计算结果的线性叠加,因此能够提高迭代效率。
4.1. 计算流程
- 给定初始值
- 计算残差向量
- 初始化方向向量,令
- 用方向向量计算步长
- 更新
- 计算新的残差向量以及向量二范数
- 计算残差向量与方向向量叠加的权重
- 计算新的方向向量
- 判断第6步计算的二范数是否达到收敛要求,若不,则回到第4步
4.2. 结果讨论
N=51,二范数收敛标准0.01
Method | Iteration number |
---|---|
CG | 81 |
4.3. 代码
使用python实现上述三种方法(SIP,MSD,CG)代码,代码链接
4.4. 总结和比较
从以上介绍中可以看出,SIP、MSD、CG均要求系数矩阵是对称矩阵,但在实际问题中往往达不到这种要求,比如遇到非均匀网格排列、非结构化网格、曲线网格、传递系数非定值等情况时,不会对称。
为了解决CG方法只能应用于对称矩阵的情况,研究者提出了有代表性的CGS和BiCG方法,前者是Conjugate gradient squared,后者是Bi-Conjugate gradient
前文说过,只有系数矩阵对称时,“二次函数”的极值问题才能等价于求解,如果不对称,则需要多计算,BiCG方法就是多计算了。该方法是OpenFOAM中常见的非对称矩阵求解器之一。
CGS并不打算求,而是在CG的基础上又加入了一个共轭方向向量,这里不再多做讨论
5. 预处理Preconditioning
影响迭代收敛的因素有很多,目前达成共识的是降低系数矩阵的条件数会有利于迭代收敛。因此预处理的目的就是将原始矩阵做某些处理从而降低其条件数。
处理方法就是在两边同乘矩阵
上式中的被称为preconditioner
即预处理矩阵。处理效果就是新矩阵的条件数小于。最优的自然是,然而这个矩阵很难求出,解出该矩阵意味着直接获得了方程的解。因此越接近越好。
常用的preconditioner
可分为以下几类:
- 基于经典迭代算法的
a. Jacobi: 的对角线组成的矩阵,即
b. GS - 基于不完全分解的ILU
a. ILU(0)
b. ILU(n)
c. ILUT - 基于不完全Cholesky分解
- 多项式
6. 多重网格法Multigrid Method
多重网格法可以理解为其目的是降低系数矩阵的特征值。网格越大即结点间距越大,系数矩阵特征值越小,意味着粗网格下的收敛速度快,本文和上一篇文章都验证了这个现象,结点越少收敛越快,但精度越低。
根据使用场景,多重网格法可以分为两种:
- GMG: Geometric MultiGrid
- AMG: Algebraic MultiGrid
6.1. GMG
该方法采用一系列大小不同的网格(不同间距的结点)来离散模拟区域。
- 方程离散。在每一套网格上都做一遍方程离散
- 光滑操作
a.smoother
:选择一款简单的代数方程组求解器作为smoother,比如本文和上文介绍过的六种求解器,GS求解器是一款常用的smoother
b.smoothing
:采用上述求解器求解最细网格的离散方程
c.partial convergence
:不必完全收敛,达到一定精度即可。通常使得残差向量的二范数下降两个数量级即可。 -
restriction
:将细网格的残差向量赋值给粗网格。在粗网格上继续迭代计算,此时要达到收敛标准即full convergence
-
prolongation
:将粗网格结果加上原来细网格的计算结果作为细网格新的值。 - 检查是否收敛
通常网格层数越多,所需的迭代会越少。
6.2. AMG
借用GMG的概念。GMG必须要对模拟区域进行多重网格划分,但是AMG并没有进行多重划分,而只是在一套网格上构建离散方程,然后通过融合和映射得到其他层网格的离散方程。该方法的关键步骤是融合。
6.2.1. 融合agglomeration
由于上述方程是在细网格结点上离散的,那么粗网格结点就需要将周围几个细网格结点融合起来。如下图所示