二维泊松方程求解-SIP-最速下降法-共轭梯度

1. 直接解法:LU分解

在前面的内容中曾经提到,使用有限差分或有限体积法通过隐式离散得到A\phi=Q的求解形式,其中A为系数矩阵。在一定条件下,A能够通过因式分解为A=LU,其中L为下三角矩阵,U为上三角矩阵。

这样的分解方式在高斯消元中十分有用,对A\phi=Q的求解可分为以下两步
U\phi=Y \\ LY=Q

2. 迭代法:incomplete LU decomposition

如果存在一个与A近似的矩阵M,对M做LU分解,我们把这样的步骤称为A的不完全LU分解,ILU,即
M=LU=A+N
其中N为小量。

2.1. SIP

Stone提出了基于ILU且具有良好普适性的strongly implicit procedure (SIP),接下来我们简要介绍一下该算法。

在ILU中,如果矩阵A中的(i,j)元素非零,那么LU矩阵在该元素对应位置上的对角线非零。以下图所示的A为五对角矩阵为例说明,图中非零元素占据五条对角线,那么对应的LU各自包含三条对角线。

five_diagonals.png

U主对角线上元素为1。可见,LU的乘积不可能为五对角矩阵,而是七对角矩阵,因此不可能还原为A,而是LU=M,如下图所示

matrix_product.png

令两次相邻迭代的差值为\delta,则原代数方程组可写成
A\phi^{n+1}-A\phi^n=Q-A\phi^n

A\delta^{n}=R^n
矩阵R为残差矩阵,为已知值。设想如果A能够完全LU分解,那么便可以通过直接解法解出\delta^n,然后加到\phi^n求出\phi^{n+1},整个过程只需一次迭代。可是根据前文的分析,五对角矩阵A无法完全LU分解,因此Stone的目标变成了尽可能的让LU的乘积M接近A。计算M\delta的乘积可得
M\delta=LU\delta=M_P\delta_P+M_S\delta_S+M_N\delta_N+M_E\delta_E+M_W\delta_W+\\ M_{NW}\delta_{NW}+M_{SE}\delta_{SE}
A\delta的乘积只有五项,对比来看多出了最后两项。因此Stone认为应尽量地消去最后两项。对\delta_{NW}做Taylor展开
\delta_{NW}\approx\delta_P-\frac{\partial \delta}{\partial x}\bigg|_P\Delta x+\frac{\partial \delta}{\partial y}\bigg|_P\Delta y
\frac{\partial \delta}{\partial x}\bigg|_P\approx \frac{\delta_P-\delta_W}{\Delta x}
\frac{\partial \delta}{\partial y}\bigg|_P\approx \frac{\delta_N-\delta_P}{\Delta y}
代入前文的Taylor展开可得
\delta_{NW}\approx -\delta_P+\delta_N+\delta_W
\delta_{SE}\approx -\delta_P+\delta_E+\delta_S

node_index.png

Stone另外提出了校正系数\alpha,其作用是\delta_{NW}=\alpha(-\delta_P+\delta_N+\delta_W)\delta_{SE}同理。
将这层关系替换到M\delta=R中可得:
(M_P-\alpha M_{NW}-\alpha M_{SE})\delta_P+(M_E+\alpha M_{SE})\delta_E+\\ (M_S+\alpha M_{SE})\delta_S+(M_N+\alpha M_{NW})\delta_N+(M_W+\alpha M_{NW})\delta_W = R_P

A\delta=R对比可得矩阵MA的关系。而M是由LU相乘而得,因此LU也能够顺利求出。以上就是SIP算法的大致介绍,该算法中的“强隐式”体现在LU的求解。

上文中图片来自《Computational Methods for Fluid Dynamics》, Ferziger

2.2. 代码实现

上一篇文章介绍了点迭代法,其特点是不涉及系数矩阵,内部结点P仅和上下左右四点相关,换句话说我们只要判断(i,j)处的P点的上下左右四个结点在模拟区域中的位置即可。

本文介绍的SIP方法显然是对系数矩阵进行操作,这更符合工程应用中求解CFD的习惯,因为实际问题往往是网格量大、编号无规则、代数矩阵稀疏。

同样求解上一篇文章中的二维泊松方程,模拟区域xy方向均存在N个结点,故结点数或变量数为N\times N=N^2,因此系数矩阵A的大小为N^2\times N^2,变量数和矩阵大小切勿弄混。

程序中我们采用一维数组对结点编号,即\phi_{1...N^2},对于边界上的结点,例如\phi_{1,2...N},其值已知,因为Dirichlet边界条件。下面是计算步骤:

  1. 构建系数矩阵A和源项Q,注意,第一个结点在程序中的编号从0开始,故右边界的结点编号为N-1。边界结点kA中的值为1,即A[k,k]=1Q[k]直接为边界上的值。内部结点iA[i,i]=4,其上下左右四个结点的系数为-1,推导过程见上一篇文章。
  2. 利用A构建LU矩阵,这部分计算流程见Sandip Mazumder所著《Numerical Methods for Partial Differential Equations》,需要注意的是书中几个变量的定义(书中公式3.38和3.57),例如向量B的第k个值表示编号为k的结点的正下方邻居结点的系数。
  3. 给定\phi初值,我在程序中直接将Q的值作为\phi的初值。然后计算R=Q-A\phi并计算向量R的二范数,若二范数小于0.01则认为收敛。接着计算LY=RL为下三角,Y_0可以直接求出,因此可以快速的求出Y;接着计算U\delta =YU为上三角,\delta[-1]可以直接求出,\delta可以求出。接着\phi^{n+1}=\phi+\delta,完成更新。

2.3. 计算结果

N=51,二范数收敛标准0.01,Stone系数\alpha=0.9,需要说明的是,这里的迭代次数与点迭代的计算方式完全不同,但复杂度均与结点数目成正比。

Method Iteration number
SIP 182

SIP


sip_0.9.png

analytical


analytical.png

3. 最速下降法

Method of Steepest Descent (MSD),该算法思想是将代数方程组的求解转化为求二次型相关的极值问题。例如,对于ax=b,我们可以将其看作二次函数y=0.5ax^2-bx+c求极值问题,也就是对二次函数求导并求导数为0对应的值,这样就解出了x

将这样的思路转换到代数方程组求解问题,对于A\phi=Q,如果A正定矩阵或负定,则我们可以构造“二次函数”
f(\phi)=\frac{1}{2}\phi^TA\phi-\phi^TQ-c
上述函数的极值就是原代数方程组的解。其中\phi=[\phi_1,\phi_2,...,\phi_m]

对上述函数求导
\nabla f(\phi)= \left[ \begin{matrix} \frac{\partial f}{\partial \phi_1} \\ \frac{\partial f}{\partial \phi_2} \\ \cdots \\ \frac{\partial f}{\partial \phi_m} \end{matrix} \right] =\frac{1}{2}A^T\phi+\frac{1}{2}A\phi-Q=0

如果矩阵A对称,则A^T=A

MSD适用范围为:矩阵A对称且正定或负定,当满足这个条件时,求上述二次函数的极值便等价于求A\phi=Q

3.1. MSD求解

  1. 给定初值\phi^n,代入矩阵求解残差R^n
    (\nabla f)^n=-R^n=Q-A\phi^n
  2. 沿着梯度下降的方向进行更新,其中\alpha为沿梯度方向走的步长
    \phi^{n+1}=\phi^n-\alpha^n(\nabla f)^n=\phi^n+\alpha^n R^n
  3. 计算步长\alpha
    MSD的思想是沿着初始计算的梯度方向一直走,在刚开始走的过程中,函数值一定是单调递增或递减,当走到某一个点,在这个点往后的函数值与之前的变化规律不同,这时MSD认为应该重新计算梯度。举个例子,下山过程,从山顶开始沿着最大梯度下降的方向行进,到走到某个地方发现眼前不再是下坡,这时就需要重新看一看此处哪个方向的梯度最大,然后改变方向继续走。
    用数学的语言来说,f\alpha的变化达到拐点时就需要重新计算梯度,因此也变成了寻找极值的问题
    \frac{\partial f}{\partial \alpha}\bigg|^{n+1}=0
    由链式求导法则
    \left[ \frac{\partial f}{\partial\phi_1}\frac{\partial\phi_1}{\partial\alpha} + \frac{\partial f}{\partial\phi_2}\frac{\partial\phi_2}{\partial\alpha} +...+ \frac{\partial f}{\partial\phi_N}\frac{\partial\phi_N}{\partial\alpha} \right]^{n+1}=0
    \phi\alpha的关系由上一步的迭代通式给出,代入上式可得
    \left[ \frac{\partial f}{\partial\phi_1}\bigg|^{n+1}R_1^n + \frac{\partial f}{\partial\phi_2}\bigg|^{n+1}R_2^n +...+ \frac{\partial f}{\partial\phi_N}\bigg|^{n+1}R_N^n \right]^{n+1}=0
    \nabla fR的关系已在第一步给出,因此上式可以整理为
    -(R^{n+1})^T R^n=-(Q-A\phi^{n+1})^TR^n=0
    \phi^{n+1}\phi^n的关系代入上式并整理可得\alpha的计算通式
    \alpha^n=\frac{(R^n)^T R^n}{(R^n)^T A R^n}

3.2. 结果讨论

N=51,二范数收敛标准0.01,迭代及其缓慢,迭代600次二范数为0.13,还远远达不到收敛标准。

3.3. 举例

A\phi= \left[ \begin{matrix} 3 & 2 \\ 2 & 6 \\ \end{matrix} \right] \left[ \begin{matrix} \phi_1 \\ \phi_2 \\ \end{matrix} \right] =Q= \left[ \begin{matrix} 2 \\ -8 \\ \end{matrix} \right]

解析解为[2,-2]

3.3.1. 构造二次函数

f(\phi_1,\phi_2)=\frac{3}{2}\phi_1^2+2\phi_1\phi_2+3\phi_2^2-2\phi_1+8\phi_2+c

3.3.2. 求偏导

\nabla f= \left[ \begin{matrix} 3\phi_1+2\phi_2-2 \\ 2\phi_1+6\phi_2+8 \\ \end{matrix} \right]

3.3.3. 更新梯度

令初值为\phi^n=[-2,-2],则
\nabla f^n= \left[ \begin{matrix} -12 \\ -8 \\ \end{matrix} \right]

4. 共轭梯度法

最速下降法中,后一次梯度方向垂直于前一次梯度方向,这种“台阶式”的迭代模式会使迭代效率大大下降,前文迭代600次,残差也仍未达到指定要求。

共轭梯度法(Conjugate gradient, CG)与MSD的区别是,后一次梯度方向并不垂直于前一次,而是前一次与当前计算结果的线性叠加,因此能够提高迭代效率。

4.1. 计算流程

  1. 给定初始值\phi^0
  2. 计算残差向量R^0
  3. 初始化方向向量D^0,令D^0=R^0
  4. 用方向向量计算步长\alpha^{n+1}
    \alpha^{n+1}=\frac{(R^n)^T R^n}{(D^n)^T A D^n}
  5. 更新\phi^{n+1}=\phi^n+\alpha^{n+1}D^n
  6. 计算新的残差向量R^{n+1}=Q-A\phi^{n+1}以及向量二范数
  7. 计算残差向量与方向向量叠加的权重\beta
    \beta^{n+1}=\frac{(R^{n+1})^TR^{n+1}}{(R^n)^TR^n}
  8. 计算新的方向向量
    D^{n+1}=R^{n+1}+\beta^{n+1}D^n
  9. 判断第6步计算的二范数是否达到收敛要求,若不,则回到第4步

4.2. 结果讨论

N=51,二范数收敛标准0.01

Method Iteration number
CG 81
cg.png

4.3. 代码

使用python实现上述三种方法(SIP,MSD,CG)代码,代码链接

4.4. 总结和比较

从以上介绍中可以看出,SIP、MSD、CG均要求系数矩阵A是对称矩阵,但在实际问题中往往达不到这种要求,比如遇到非均匀网格排列、非结构化网格、曲线网格、传递系数非定值等情况时,A不会对称。

为了解决CG方法只能应用于对称矩阵的情况,研究者提出了有代表性的CGS和BiCG方法,前者是Conjugate gradient squared,后者是Bi-Conjugate gradient

前文说过,只有系数矩阵对称时,“二次函数”的极值问题才能等价于求解AX=Q,如果不对称,则需要多计算A^T,BiCG方法就是多计算了A^T。该方法是OpenFOAM中常见的非对称矩阵求解器之一。

CGS并不打算求A^T,而是在CG的基础上又加入了一个共轭方向向量D^{*},这里不再多做讨论

5. 预处理Preconditioning

影响迭代收敛的因素有很多,目前达成共识的是降低系数矩阵A条件数会有利于迭代收敛。因此预处理的目的就是将原始矩阵A做某些处理从而降低其条件数。

处理方法就是在A\phi=Q两边同乘矩阵M^{-1}
M^{-1}A\phi=M^{-1}Q
上式中的M^{-1}被称为preconditioner即预处理矩阵。处理效果就是新矩阵M^{-1}A的条件数小于A。最优的M^{-1}自然是A^{-1},然而这个矩阵很难求出,解出该矩阵意味着直接获得了方程的解。因此M^{-1}越接近A^{-1}越好。

常用的preconditioner可分为以下几类:

  1. 基于经典迭代算法的
    a. Jacobi: A的对角线组成的矩阵,即M=D=diag(A)
    b. GS
  2. 基于不完全分解的ILU
    a. ILU(0)
    b. ILU(n)
    c. ILUT
  3. 基于不完全Cholesky分解
  4. 多项式

6. 多重网格法Multigrid Method

多重网格法可以理解为其目的是降低系数矩阵的特征值。网格越大即结点间距越大,系数矩阵特征值越小,意味着粗网格下的收敛速度快,本文和上一篇文章都验证了这个现象,结点越少收敛越快,但精度越低。

根据使用场景,多重网格法可以分为两种:

  1. GMG: Geometric MultiGrid
  2. AMG: Algebraic MultiGrid

6.1. GMG

该方法采用一系列大小不同的网格(不同间距的结点)来离散模拟区域。

  1. 方程离散。在每一套网格上都做一遍方程离散
  2. 光滑操作
    a. smoother:选择一款简单的代数方程组求解器作为smoother,比如本文和上文介绍过的六种求解器,GS求解器是一款常用的smoother
    b. smoothing:采用上述求解器求解最细网格的离散方程
    c. partial convergence:不必完全收敛,达到一定精度即可。通常使得残差向量的二范数下降两个数量级即可。
  3. restriction:将细网格的残差向量赋值给粗网格。在粗网格上继续迭代计算,此时要达到收敛标准即full convergence
  4. prolongation:将粗网格结果加上原来细网格的计算结果作为细网格新的值。
  5. 检查是否收敛

通常网格层数越多,所需的迭代会越少。

6.2. AMG

借用GMG的概念。GMG必须要对模拟区域进行多重网格划分,但是AMG并没有进行多重划分,而只是在一套网格上构建离散方程,然后通过融合和映射得到其他层网格的离散方程。该方法的关键步骤是融合。

6.2.1. 融合agglomeration

由于上述方程是在细网格结点上离散的,那么粗网格结点就需要将周围几个细网格结点融合起来。如下图所示


agglomeration_process.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容