有限元:使用不完全 Cholesky 分解的预条件共轭梯度

计算科学 线性代数 线性求解器 迭代法
2021-12-04 23:59:45

我必须用 C 编写一些有限元代码。

我被要求实施共轭梯度法,我已经这样做了。现在,我希望通过使用不完全 Cholesky 分解来进一步提高程序的效率。

据我了解,而不是解决Ax=B系统,我必须解决M1Ax=M1B系统矩阵M是矩阵的不完全 Cholesky 分解A.

但是,当我尝试实现这一点时,我发现计算M然后在时间上反转它比简单地使用 CG 方法更昂贵。我想我一定是做错了什么,但我真的不明白 PCG with Cholesky 是如何实现的。

1个回答

虽然具有不完全 Cholesky (ICC) 的预处理 CG 在数学上相当简单,但编写一个有效的实现并非易事。

以下是有助于高效实施的一些因素:

  • ICC 实现利用了矩阵的稀疏性A(你会想要存储AM以一些稀疏矩阵格式)
  • M在计算上“容易”反转(您不会计算实际的反转M1, 只是它对向量的作用)
  • 您为 ICC 算法设置适当的超参数(例如,块大小、填充级别、零阈值)和(预)分配内存空间M因此
  • 杂项优化(例如,Eisenstat 技巧,参见 Chan 的论文)
  • 针对您的特定硬件平台的代码优化(我不会在这里详细介绍)。

归根结底,您所追求的是一个预处理迭代,它比未预处理的迭代收敛得更快(在某种客观的衡量标准上)。

帮助您入门的参考资料:

Yousef Saad,稀疏线性系统的迭代方法——特别是第 9.2、9.2.1 和 9.2.2 章处理预处理 CG 迭代(有一些伪代码可以作为初始实现的基础)。

Chan 和 van der Vorst,近似和不完全分解 (他们讨论了不完全 LU 及其变体,但那里的想法也适用于 ICC)。

Chih-Jen Lin 和 Jorge J. Moré,有限内存的不完全 Cholesky 分解,SIAM SISC 21(1),1999

一些高质量的 C/C++ ICC 实现(这些库的学习曲线相当陡峭,但可以查看源代码):

PETSc 的ICC 例程

IFPACK(Trilinos 套件的一部分)。用户手册可以在这里找到。

用于 CG的 Eigen 的C++ ICC 预处理器