如何计算 PETSc 中的 Schur 补码?

计算科学 pde 线性代数 宠物
2021-12-14 09:56:40

如何计算 Schur 补码:

S=KbbKbaKaa1Kab

在哪里

K=(KaaKabKbaKbb)

(按某种顺序)是 PETSc 矩阵(Mat)?

1个回答

计算矩阵的舒尔补非常昂贵,而且在实践中很少需要。PETSc 强烈建议避免使用需要它的算法。矩阵(密集或稀疏)的 Schur 补集本质上总是密集的,所以从以下开始:

  • 形成一个密集的矩阵Kba,
  • 还创建另一个密集矩阵T大小相同。
  • 然后要么考虑矩阵Kaa 直接使用MatLUFactor()or MatCholeskyFactor(),或者如果你想使用外部求解器包,如 SuperLU_Dist,则使用后跟MatGetFactor()调用结果MatLUFactorSymbolic()MatLUFactorNumeric()A
  • 然后调用MatMatSolve(A,Kba,T)
  • 然后调用MatMatMult(Kab,T,MAT_INITIAL_MATRIX,1.0,&S)
  • 现在打电话MatAXPY(S,-1.0,Kbb,MAT_SUBSET_NONZERO)
  • 其次是MatScale(S,-1.0)

对于像这样计算 Schur 补码,使用迭代求解器没有意义,KSP因为使用直接因式分解解决许多中等规模的问题比迭代求解器快得多。如您所见,这需要大量的工作空间和计算,因此最好避免。但是,没有必要组装 Schur 补码S为了用它解决系统。用于MatCreateSchurComplement(Kaa,Kaa_pre,Kab,Kba,Kbb,&S)创建一个矩阵,该矩阵应用S(using Kaa_preto solve with Kaa) 的动作,但不组装。

或者,如果您已经有一个块矩阵

K=(KaaKabKbaKbb)
(以某种顺序),然​​后您可以创建索引集 ( IS) isa 和 isb 来寻址每个块,然后用于MatGetSchurComplement()创建 Schur 补码和/或适合预处理的近似值。自从S通常是密集的,标准预处理方法通常不能直接应用于 Schur 补码。有许多方法可以预处理 Schur 补码,包括使用 SIMPLE 近似KbbKbadiag(Kaa)1Kab创建一个近似于 Schur 补码的稀疏矩阵(默认情况下为 中的可选“预处理”矩阵返回MatGetSchurComplement())。

另一种选择是将矩阵解释为微分运算符并应用近似交换子参数来找到可以有效应用的光谱等效运算(参见 Elman、Silvester 和 Wathen 的“PCD”预条件子)。它的一个变体是最小二乘交换器,它与 Moore-Penrose 伪逆密切相关,并且可用于PCLSC对类型为 的矩阵进行运算MATSCHURCOMPLEMENT