Preconditioner not working or bug?

The results are “correct” since fenics / petsc uses the preconditioned residual in order to check the convergence criterion. Also, the petsc faq says that this discrepancy can happen, e.g., for saddle point problems: https://www.mcs.anl.gov/petsc/documentation/faq.html#kspdiverged

You could circumvent this by applying the preconditioner from the right hand side, since you will then always have an unpreconditioned norm in your convergence check. A MWE could look like this:

from fenics import *
from petsc4py import PETSc

opts = PETScOptions
# clean the options, in case something was set before
opts.clear()

opts.set('ksp_type', 'gmres')
opts.set('pc_type', 'hypre')
opts.set('pc_hypre_type', 'boomeramg')
opts.set('ksp_pc_side', 'right')

# Here, you define your variational problem, assemble the system, bcs, etc.

# set up the solver:
ksp = PETSc.KSP().create()
ksp.setFromOptions()
A = as_backend_type(A).mat()
b = as_backend_type(b).vec()
# W is the FunctionSpace
x = PETSc.Vec().createSeq(W.dim())
# The precodnitioner matrix P is optional
ksp.setOperators(A, P)
ksp.setUp()
ksp.solve(b, x)
# do a convergence test
if ksp.getConvergedReason() < 0:
    raise SystemExit('Krylov solver did not converge. Reason: ' + str(ksp.getConvergedReason()))

U.vector()[:] = x[:]

Im not 100 % sure how fenics handles things in the background, but it should be similar to this, and I didn’t experience much overhead, so this should be fine.
You can find more info for the PETScOptions here: https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/singleindex.html
(these are command line options for petsc)

3 Likes