大矩阵上的Matlab预处理共轭梯度

计算科学 矩阵 matlab
2021-11-26 22:31:42

我有一个稀疏的矩阵个非零元素。该矩阵来自对线性弹性问题使用有限元方法,并且是半正定矩阵。我正在尝试使用预处理共轭梯度法来解决它,特别是 MATLAB 中的 pcg() 函数。56562365656236A166526888

我可以期望这完全收敛吗?我试过了

L = ichol(A);
[u,flag,res,iter,resvec] = pcg(A,F,1e-6,max_ter,L,L');

但它似乎根本没有收敛。残差开始大量增加,经过 2000 次迭代(需要几个小时),相对残差上升到104

所以我想我的问题是,你将如何攻击这种规模的系统?我确信有很多方法可以诱使该方法更快地收敛。欢迎任何提示和提示!

2个回答

默认情况下, MATLAB 函数ichol计算不完全 Cholesky 分解的零填充变量。您可以尝试通过使用下降容差来允许更多填充(并因此尝试改进预处理器),例如:

L = ichol(A,struct('type','ict','droptol',1e-03,'michol','on'));

还要注意,单级预处理器,如 ILU(或 ICHOL)、稀疏逆、简单拆分等,不能很好地适应大型问题。因此,如果上述方法不起作用,您可以尝试使用代数多重网格(AMG)。有 AMG 软件包非常适合解决线性弹性问题,例如Hypre的BoomerAMG或 Trilinos 的 ML (据我所知,ML 也有一个 Matlab 接口)。如果您不喜欢 C/C++,您可以考虑尝试Python 中的PyAMG(基于 NumPy 和 SciPy)。

如果您的残差增加,那么您的矩阵可能不是对称的,或者至少不是正定的。在这些情况下,无论有没有预处理器,CG 都不起作用。

有两种方法可以查到:

  • 尝试使用相同程序但使用更粗糙的网格的更小的系统,看看 CG 是否会收敛。
  • 检查你的代码,看看它是否真的做了组装矩阵时应该做的事情。