FGMRES(Flexible Generalized Minimal Residual)方法

FGMRES(Flexible Generalized Minimal Residual)方法是GMRES的变种,主要用于处理变预处理子(即每次迭代的预处理子可能不同)的情况。与标准GMRES相比,FGMRES通过存储预处理后的向量而非预处理子本身,避免了因预处理子变化导致的子空间不一致问题。


FGMRES与GMRES的核心区别

  1. 预处理子的灵活性

    • GMRES:要求预处理子固定(即每次迭代的预处理子 ( M ) 必须相同)。若预处理子变化,Krylov子空间的正交性会被破坏,导致收敛失败。
    • FGMRES:允许预处理子 ( M_i ) 在每次迭代中动态变化(例如依赖当前迭代的解或残差),更适合非线性预处理或自适应预处理场景。
  2. 存储的向量不同

    • GMRES存储的是预处理前的向量 ( v_j = M^{-1} A q_j )。
    • FGMRES存储的是预处理后的向量 ( z_j = M_j^{-1} v_j ),从而适应预处理子的变化。
  3. 计算开销

    FGMRES需要额外存储预处理后的向量 ( z_j ),但避免了重新构造整个Krylov子空间。


FGMRES的优势场景

当预处理子需要动态调整时,FGMRES是唯一选择。例如:

  • 非线性预处理:预处理子依赖当前解(如基于物理的近似)。
  • 内迭代法作为预处理子:例如用不完全LU分解(ILU)或少量迭代的GMRES作为预处理子,但内层迭代的精度可能随外层变化。
  • 自适应策略:预处理子的参数(如阈值、填充级别)根据残差动态调整。

具体例子

问题:求解线性系统 ( Ax = b ),其中 ( A ) 是病态矩阵,预处理子通过内层GMRES迭代实现(每次内层迭代次数可能不同)。

GMRES的局限

若用内层GMRES(如5次迭代)作为固定预处理子,外层GMRES可能因预处理子不精确而收敛缓慢甚至失败。

FGMRES的解决方案

允许内层GMRES的迭代次数动态调整(例如基于残差阈值)。FGMRES的伪代码如下:

python 复制代码
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相同

算法基本步骤:

  1. 初始化残差和第一个基向量
  2. 构建Krylov子空间
  3. 应用灵活预处理
  4. 正交化过程
  5. 最小化残差

实际应用实例:计算流体力学中的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代码示例
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);
预处理子函数示例
matlab 复制代码
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

实际应用中的考虑因素

  1. 预处理子选择:在CFD中常用:

    • 分块三角预处理
    • 近似Schur补预处理
    • 多重网格作为预处理
  2. 可变预处理:当非线性较强时,预处理可能需要在迭代间更新

  3. 重启策略:由于内存限制,需要定期重启FGMRES

  4. 收敛性:对于对流主导问题,可能需要特殊的预处理技术

其他应用领域

FGMRES还常用于:

  1. 电磁场计算(Maxwell方程)
  2. 结构力学中的耦合问题
  3. 多物理场模拟
  4. 大规模优化问题

优势与局限

优势

  • 处理变预处理子的灵活性
  • 保持最小残差性质
  • 适用于复杂物理问题

局限

  • 与GMRES相同的存储需求(随迭代次数线性增长)
  • 重启可能影响收敛
  • 预处理质量对性能影响大

结论

FGMRES是处理需要灵活预处理的大型稀疏线性系统的强大工具,特别适用于多物理场耦合问题和非线性预处理情况。在实际应用中,预处理子的设计和实现通常是获得良好性能的关键。

相关推荐
weixin_428498497 天前
MPI Code for Ghost Data Exchange in 3D Domain Decomposition with Multi-GPUs
hpc·cfd
weixin_428498497 天前
分布式GPU上计算长向量模的方法
hpc
weixin_4284984913 天前
解决 Ubuntu 下 VTune 无法收集 CPU 硬件时间计数数据的问题
hpc
weixin_4284984917 天前
CFD中的动量方程非守恒形式详解
hpc
weixin_4284984917 天前
在OpenFOAM中自定义动态变化的边界条件
c++·hpc
weixin_4284984917 天前
在AMGCL中使用多个GPU和多个计算节点求解大规模稀疏矩阵方程
hpc
weixin_4284984920 天前
在Fortran程序中嵌入Lua解释器
lua·hpc
weixin_4284984921 天前
使用MPI-IO并行读写HDF5文件
hpc
weixin_4284984922 天前
AMGCL库的Backends及使用示例
hpc