FGMRES(Flexible Generalized Minimal Residual)方法是GMRES的变种,主要用于处理变预处理子(即每次迭代的预处理子可能不同)的情况。与标准GMRES相比,FGMRES通过存储预处理后的向量而非预处理子本身,避免了因预处理子变化导致的子空间不一致问题。
FGMRES与GMRES的核心区别
-
预处理子的灵活性
- GMRES:要求预处理子固定(即每次迭代的预处理子 ( M ) 必须相同)。若预处理子变化,Krylov子空间的正交性会被破坏,导致收敛失败。
- FGMRES:允许预处理子 ( M_i ) 在每次迭代中动态变化(例如依赖当前迭代的解或残差),更适合非线性预处理或自适应预处理场景。
-
存储的向量不同
- GMRES存储的是预处理前的向量 ( v_j = M^{-1} A q_j )。
- FGMRES存储的是预处理后的向量 ( z_j = M_j^{-1} v_j ),从而适应预处理子的变化。
-
计算开销
FGMRES需要额外存储预处理后的向量 ( z_j ),但避免了重新构造整个Krylov子空间。
FGMRES的优势场景
当预处理子需要动态调整时,FGMRES是唯一选择。例如:
- 非线性预处理:预处理子依赖当前解(如基于物理的近似)。
- 内迭代法作为预处理子:例如用不完全LU分解(ILU)或少量迭代的GMRES作为预处理子,但内层迭代的精度可能随外层变化。
- 自适应策略:预处理子的参数(如阈值、填充级别)根据残差动态调整。
具体例子
问题:求解线性系统 ( Ax = b ),其中 ( A ) 是病态矩阵,预处理子通过内层GMRES迭代实现(每次内层迭代次数可能不同)。
GMRES的局限
若用内层GMRES(如5次迭代)作为固定预处理子,外层GMRES可能因预处理子不精确而收敛缓慢甚至失败。
FGMRES的解决方案
允许内层GMRES的迭代次数动态调整(例如基于残差阈值)。FGMRES的伪代码如下:
for k = 1, 2, ...:# 动态生成预处理子 M_k(例如内层GMRES迭代次数由残差决定)z_k = M_k^{-1} v_k # 内层迭代求解# 将z_k加入FGMRES的子空间并正交化# 更新解和残差
此时,即使每次 ( M_k^{-1} ) 不同(如内层迭代次数从5次变为10次),FGMRES仍能保证子空间的正交性。
数学形式对比
- GMRES:构建Krylov子空间 ( \mathcal{K}_m(A M^{-1}, r_0) ),要求 ( M ) 固定。
- FGMRES:构建子空间 ( \text{span}{z_1, z_2, \dots, z_m} ),其中 ( z_j = M_j^{-1} v_j ),允许 ( M_j ) 变化。
总结
- 使用FGMRES当:预处理子需要动态调整(如非线性、内层迭代不精确或自适应策略)。
- 使用GMRES当:预处理子固定且易于求逆(如静态ILU、SSOR)。
典型应用:
- 多物理场耦合问题(预处理子依赖其他场的解)。
- 嵌套迭代法(外层FGMRES + 内层GMRES预处理)。
通过灵活处理变预处理子,FGMRES扩展了GMRES的适用性,但代价是更高的存储需求和潜在稳定性风险(需监控残差)。
使用FGMRES方法迭代求解的指南与实例
FGMRES (Flexible Generalized Minimal Residual) 方法是GMRES的一种变体,特别适用于预处理子可能随迭代变化的情况。下面我将详细介绍FGMRES方法及其应用实例。
FGMRES方法概述
FGMRES是GMRES的灵活变体,主要特点:
- 允许预处理子在每次迭代中变化
- 适用于非线性预处理或迭代依赖的预处理
- 保持GMRES的最小残差特性
- 需要存储所有基向量,内存需求与GMRES相同
算法基本步骤:
- 初始化残差和第一个基向量
- 构建Krylov子空间
- 应用灵活预处理
- 正交化过程
- 最小化残差
实际应用实例:计算流体力学中的Navier-Stokes方程求解
问题描述
考虑二维不可压缩Navier-Stokes方程:
∂u/∂t + u·∇u = -∇p + (1/Re)∇²u
∇·u = 0
其中u是速度场,p是压力场,Re是雷诺数。
离散化后的线性系统
经过半离散化和线性化后,我们得到如下块线性系统:
[ A G ][u] = [f]
[ D 0 ][p] [g]
其中A是速度矩阵,G是梯度算子,D是散度算子。
使用FGMRES求解
由于这是一个 saddle-point 问题,我们采用分块预处理策略,预处理子可能随物理参数或迭代变化,因此FGMRES是合适选择。
MATLAB代码示例
% 假设已定义:A, G, D, f, g 和预处理子函数 apply_preconditioner% 构建块系统矩阵
n = size(A,1);
m = size(D,1);
bigA = [A, G; D, sparse(m,m)];% 右侧向量
rhs = [f; g];% FGMRES参数设置
maxit = 100; % 最大迭代次数
tol = 1e-6; % 容差
restart = 30; % 重启次数% 定义预处理函数 (可能随迭代变化)
precond_func = @(x) apply_preconditioner(x, A, G, D);% 调用FGMRES
[x, flag, relres, iter, resvec] = fgmres(@(x)bigA*x, rhs, [], tol, maxit, precond_func);% 提取解
u_sol = x(1:n);
p_sol = x(n+1:end);
预处理子函数示例
function y = apply_preconditioner(x, A, G, D)% 分块预处理示例n = size(A,1);m = size(D,1);% 分解x为速度和压力部分x_u = x(1:n);x_p = x(n+1:n+m);% 近似求解速度块 (可能使用不完全LU分解)[L,U] = ilu(A); % 可能每次迭代不同u_sol = U\(L\x_u);% 压力Schur补近似 (使用质量矩阵或对角线近似)S_approx = diag(diag(D*(diag(diag(A))\G)); % 简单对角近似p_sol = S_approx\x_p;% 组合结果y = [u_sol; p_sol];
end
实际应用中的考虑因素
-
预处理子选择:在CFD中常用:
- 分块三角预处理
- 近似Schur补预处理
- 多重网格作为预处理
-
可变预处理:当非线性较强时,预处理可能需要在迭代间更新
-
重启策略:由于内存限制,需要定期重启FGMRES
-
收敛性:对于对流主导问题,可能需要特殊的预处理技术
其他应用领域
FGMRES还常用于:
- 电磁场计算(Maxwell方程)
- 结构力学中的耦合问题
- 多物理场模拟
- 大规模优化问题
优势与局限
优势:
- 处理变预处理子的灵活性
- 保持最小残差性质
- 适用于复杂物理问题
局限:
- 与GMRES相同的存储需求(随迭代次数线性增长)
- 重启可能影响收敛
- 预处理质量对性能影响大
结论
FGMRES是处理需要灵活预处理的大型稀疏线性系统的强大工具,特别适用于多物理场耦合问题和非线性预处理情况。在实际应用中,预处理子的设计和实现通常是获得良好性能的关键。