为什么我的迭代线性求解器不收敛?


26

使用KSPPETSc)的预先设定的Krylov方法时会出什么问题的线性求解器程序包)中的求解稀疏线性系统(例如通过离散化和线性化偏微分方程获得的线性系统)时,会出现什么问题?

我可以采取什么步骤来确定问题出了什么问题?

为了成功有效地求解线性系统,我可以进行哪些更改?


您是要这个问题是专门针对PETSc中的迭代线性求解器的一个问题(这是我将从问题正文中收集的内容),还是一个有关在大多数软件中迭代线性求解器的潜在算法失败的问题-不可知论的上下文(这是我仅从标题来看的内容)?
Geoff Oxberry

4
它具有petsc标签。该方法是通用的,但是我认为,如果每个“尝试此操作”都没有包含“如何”,答案将不太有用。另外,“如何”将需要长时间(和更容易出错的观众),如果它需要一个软件无关的方式来解释。如果有人想说明如何使用其他程序包来做所有这些事情,那么我将很高兴使问题与软件无关,并更改我的回答以声明它描述了在PETSc中的操作。注意:我添加了此内容,它是FAQ的增强版本,因此,我希望人们访问此站点。
杰德·布朗

Answers:


26

初步建议

  • 始终与 -ksp_converged_reason -ksp_monitor_true_residual尝试了解为什么某个方法无法收敛时,请。
  • 使问题的大小和过程数尽可能小,以证明故障。您通常可以通过确定哪些小问题表现出导致您的方法崩溃的行为并减少周转时间来获得洞察力。此外,还有一些调查技术只能用于小型系统。
  • 如果问题仅在经过大量时间步骤,连续步骤或非线性求解步骤之后出现,请考虑在发生故障时写出模型状态,以便您可以快速进行实验。
  • 或者,特别是如果您的软件不具备检查点功能,请使用-ksp_view_binaryMatView()保存线性系统,然后使用以下代码$PETSC_DIR/src/ksp/ksp/examples/tutorials/ex10.c读取矩阵并求解(可能使用不同数量的进程)。这需要一个组装好的矩阵,因此其用途可能会受到限制。
  • 有许多可能的求解器选择(例如,由于任意数量的合成级别,PETSc中的命令行都可以使用无限个数),有关选择线性求解器的一般建议,请参见此问题

KSP无法收敛的常见原因

  • 这些方程偶然地是奇异的(例如,忘记施加边界条件)。使用检查此问题-pc_type svd -pc_svd_monitor。也可以尝试使用直接求解器-pc_type lu(通过并行第三方软件包,例如-pc_type lu -pc_factor_mat_solver_package superlu_dist)。
  • 这些方程有意地是奇异的(例如,恒定的零空间),但Krylov方法未获知,请参见KSPSetNullSpace()
  • 这些方程是有意的单数并KSPSetNullSpace()已使用,但右手侧不一致。MatNullSpaceRemove()在致电之前,您可能必须先致电右侧KSPSolve()
  • 这些方程式是不确定的,因此标准预处理器不起作用。通常您会从物理学上知道这一点,但是可以使用-ksp_compute_eigenvalues进行检查-ksp_gmres_restart 1000 -pc_type none。对于简单的鞍点问题,请尝试-pc_type fieldsplit -pc_fieldsplit_type schur -pc_fieldsplit_detect_saddle_point。有关更多详细信息,请参见用户手册PCFIELDSPLIT手册页。对于更困难的问题,请阅读文献以找到可靠的方法,并在此处(或petsc-users@mcs.anl.govpetsc-maint@mcs.anl.gov)询问是否需要有关如何实现它们的建议。例如,有关高频亥姆霍兹的信息,请参见此问题。对于中等大小的问题,请查看是否可以仅使用直接求解器。
  • 如果该方法收敛于预处理残差而不是真实残差,则预处理器可能是奇异的或接近奇异的。这对于鞍点问题(例如不可压缩的流动)或强非对称算子(例如具有大时间步长的低马赫双曲问题)很常见。
  • 预处理器太弱或不稳定。查看是否-pc_type asm -sub_pc_type lu提高收敛速度。如果GMRES在重新启动中失去太多进展,请查看是否有更长的重新启动帮助-ksp_gmres_restart 300。如果有转置可用,请尝试使用-ksp_type bcgs或重新启动不需要其他方法。(请注意,使用这些方法的收敛通常是不稳定的。)
  • 预处理矩阵可能不接近(可能是未汇编的)运算符。尝试使用直接求解器进行求解,可以-pc_type lu使用第三方程序包(例如-pc_type lu -pc_factor_mat_solver_package superlu_distmumps)与之并行或并行进行。如果矩阵相同,则该方法应在一次迭代中收敛,否则应在“少量”迭代中收敛。-snes_type test如果解决非线性问题,请尝试检查矩阵。
  • 前置条件是非线性的(例如嵌套的迭代求解),请尝试-ksp_type fgmres or -ksp_type gcr
  • 您正在使用几何多重网格,但是某些方程式(通常是边界条件)在各个级别之间不兼容缩放。尝试-pc_mg_galerkin代数构造一个正确缩放的粗略算子,或者如果要使用重新离散化的粗略水平,请确保所有方程式都以相同的方式缩放。
  • 基质病态严重。使用此处介绍方法检查条件编号。通过选择组件/边界条件的相对比例来尝试改进它。尝试-ksp_diagonal_scale -ksp_diagonal_scale_fix。也许改变问题的表述以产生更友好的代数方程。如果无法校正缩放比例,则可能需要使用直接求解器。
  • 矩阵是非线性的(例如,使用非线性函数的有限差分进行评估)。尝试不同的差异参数(例如-mat_mffd_type ds)。尝试使用更高的精度以使差分更准确./configure --with-precision=__float128 --download-f2cblaslapack。检查它是否收敛于“更轻松”的参数范围。
  • 对称方法用于非对称问题。
  • 古典Gram-Schmidt变得不稳定,请尝试-ksp_gmres_modifiedgramschmidt或使用不同正交化的方法,例如-ksp_type gcr

16

我对学生的建议是在这种情况下尝试直接求解器。原因是求解器可能不收敛的原因有两类:(i)矩阵错误,或者(ii)求解器/预处理器存在问题。直接求解器几乎总是可以产生与您期望的解决方案比较的结果,因此,如果直接求解器的答案看起来正确,那么您就知道问题出在迭代求解器/前提条件上。另一方面,如果答案看起来不正确,则问题在于组装矩阵和右侧。

我通常只使用UMFPACK作为直接求解器。我敢肯定,尝试与PETSC类似的事情很简单。


5
-pc_type lu -pc_factor_mat_solver_type umfpack-pc_type cholesky -pc_factor_mat_solver_package cholmod通过PETSc 使用UMFPACK(或用于SPD问题),但请注意UMFPACK和CHOLMOD是串行的。对于并行,使用-pc_factor_mat_solver_package superlu_distmumpspastixspooles
杰德·布朗

2
只是要清楚,使用完整的选项集(例如)superlu_dist-ksp_type preonly -pc_type lu -pc_factor_mat_solver_package superlu_dist。那正确吗?
里昂·艾利

我不知道。如果执行此操作会怎样?
Wolfgang Bangerth '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.