GMRES 迭代次数随着时间的推移而增加,使用牛顿法

计算科学 收敛 牛顿法 格瑞斯
2021-12-25 06:33:48

我在有限元设置中使用牛顿法求解非线性时间相关方程组,即首先我为当前时间创建雅可比矩阵,然后尝试求解系统(使用 GMRES 求解器,使用 AMG 方法进行预处理)以获取解决方案更新。重复此过程,直到残差不再变小,然后将时间增加一个时间步长。对于每个时间步,记录必要的 GMRES 迭代。
现在我注意到,最初 GMRES 迭代在每个时间步保持 50 次迭代不变,但在一段时间后(取决于输入参数)它们突然增加到 75-100 次迭代,并且在下一个时间步求解器无法收敛完全没有(即使在 >10000 次迭代之后)。
这里给出了几个建议:为什么我的迭代线性求解器不收敛?,但实施这些建议需要一些时间,因此,如果已经有一些基于我可以使用的行为的提示给我一个初步的想法,那将减少查找错误所需的时间。
此外,在我目前使用 > 40kk 个元素之后,使用直接求解器是不可能的(这对于可用内存来说太大了)。为了在不引入振荡的情况下正确计算方程,我不能减少元素的数量。

关于评论:

  • 我正在使用 Crank-Nicholson 方法离散化我的时间步,以避免不稳定
  • 我的系统由三个耦合的非线性热方程类方程组成,它们在求解过程中是强耦合的
  • 我正在使用固定的时间步长和固定的网格密度
  • 我的系统有大约 40e6 个自由度。通常(对于较小的系统)我允许求解器使用尽可能多的迭代,因为我有自由度,但在这里我想研究系统的行为,因此我减少了允许的迭代量。此外,约 50 次迭代需要约 50 秒,因此允许 40e6 次迭代将完全停止求解程序。
  • 目前我正在使用 28 个 krylov 向量(求解器的默认设置),但可以更改它。如果有关于我应该使用的尺寸的建议,我可以实现它,虽然
  • 预处理从左边开始
1个回答

在我看来,你能做的最有帮助的事情就是增加你正在使用的 krylov 向量的数量。这与我看到的第一步花费时间最长的典型行为有些不同,但也许物理学已经足够不同了。我认为了解 GMRES 的工作原理很重要,因为您的一些解释揭示了一些误解。Saad 用此处链接的算法写了一本很棒的书:https ://www-users.cs.umn.edu/~saad/IterMethBook_2ndEd.pdf

你从一个线性系统开始:

Ax=b
并且您想找到一个 x 向量,使得
r=bAx=0
你从对 x 的一些猜测开始(通常是 x = 0),你得到一个残差向量r0=b这将是您的搜索方向(v 向量),因此您对其进行归一化并将其乘以 A 矩阵以获得 aw 向量。这个向量被每个先前的搜索方向(v 向量)点缀,然后 w 向量从它中减去沿着每个先前使用的搜索方向的分量。这个 w 向量被归一化并成为新的搜索方向。你走到顶部并重复。需要注意的是,这是对完整 GMRES 求解器的描述,它保证在最多使用系统的未知数作为搜索方向后获得线性系统的解。使用这么多搜索方向显然是站不住脚的,因为对于 nxn 系统,每个搜索方向都有 n 个元素。这意味着对于 n 个搜索方向,我们存储了一个完整的 nxn 系统,这显然很昂贵;所以我们使用重新启动的GMRES。重新启动的 GMRES 使用给定数量的 krylov 向量,通常远少于列数,并且将循环这个部分 GMRES 求解器,现在使用x00并以最后的猜测继续x. 重新启动的 GMRES 在记忆方面的效率要高得多,但它可能会停滞不前,因此人们经常会使用各种预处理器或不同数量的 krylov 向量来帮助解决更棘手的问题。

一些额外的事情要知道,GMRES 将阻止你的迭代求解器发散假设你的预处理器没有发散,但是你希望大部分工作由一个强大的预处理器完成,GMRES 阻止你的代码爆炸。预处理 GMRES 有几种不同的方法;通常最好使用灵活的右预处理,因为它允许您使用以最小成本计算的实际线性残差截断中间迭代。灵活的预处理确实需要 2 倍于典型的左或右预处理 GMRES 的内存,但它更便宜。所以我建议你增加 Krylov 向量的数量并使用灵活的右预处理(通常称为灵活),问题应该会消失。希望这可以帮助!