Demo for using hifir4py
with SciPy’s GMRES¶
In this example, we show how to use hifir4py
HIFIR preconditioner
coupling with the built-in GMRES solver in SciPy. The example system is
a saddle-point formulation of 3D Stokes equation with Taylor-Hood
elements.
import numpy as np
from scipy.io import loadmat
from hifir4py import *
# load the MATFILE from scipy.io
f = loadmat("demo_inputs/data.mat")
A = f["A"]
b = f["b"].reshape(-1)
Let’s show some basic information of the system, including shape, nnz, and leading block symmetry
# A is scipy.sparse.csr_matrix
print("The system shape is {}, where the nnz is {}".format(A.shape, A.nnz))
The system shape is (2990, 2990), where the nnz is 44632
Now, let’s build the preconditioenr \(\boldsymbol{M}\) with more
aggressive options, i.e. droptol
for L and U factors is 1e-2,
condest
for L, U, and D is 5, and \(\alpha\) for L and U is 3.
M = HIF()
params = Params()
params['tau_L'] = params['tau_U'] = 0.01
params['kappa'] = params['kappa_d'] = 5.0
params['alpha_L'] = params['alpha_U'] = 3
M.factorize(A, params=params)
With the preconditioenr successfully been built, let’s print out some basic information
print("M levels are {}, with nnz {}".format(M.levels, M.nnz))
M levels are 2, with nnz 114848
Now, we solve with the built-in flexible GMRES solver in SciPy. Notice that the GMRES in SciPy is left-preconditioned, which is not recommended.
from scipy.sparse.linalg import gmres
iters = 0
def counter(res=None):
global iters
iters += 1
print("At iteration {}, residual is {}".format(iters, res))
x, flag = gmres(A, b, M=M.to_scipy(), callback=counter)
At iteration 1, residual is 0.03726697689855636
At iteration 2, residual is 0.004555930822500451
At iteration 3, residual is 0.0005254851747732505
At iteration 4, residual is 4.8775926768822654e-05
At iteration 5, residual is 4.3329265915834745e-06
At iteration 6, residual is 3.830896351600058e-07
print("solver done, flag={}, res={}".format(flag, np.linalg.norm(b-A.dot(x))/np.linalg.norm(b)))
solver done, flag=0, res=3.7186961167705056e-07