-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Currently a single tolerance (tol
argument) is used, which is impractical, when using an iterative solver as a preconditioner. In that case it is desirable to set a relative tolerance to some not-so-small value (e.g. 1e-2), without caring about the absolute tolerance. The current behaviour prevents that, as something like setting tol=1e-2
often leads to absolute convergence in iteration zero of the preconditioner, hence no preconditioning done at all.
This behaviour breaks the IMHO very good lgmres
solver. For example, the following happens when using lgmres
with cg
(tol=1e-2
) as a preconditioner for symmetric positive definite diagonal blocks:
<snip>
sfepy: cg-s: iteration 1
sfepy: cg-s: iteration 2
sfepy: cg-s: iteration 3
sfepy: cg-s: iteration 4
sfepy: cg-s: iteration 5
sfepy: cg-s: iteration 6
sfepy: cg-s: cg convergence: 0 (successful exit)
rhs norm: 8.751133e-02, solution norm: 4.484927e+00
sfepy: iterative-s: iteration 4: |Ax-b| = 2.323006e-03
sfepy: cg-s: iteration 1
sfepy: cg-s: cg convergence: 0 (successful exit)
rhs norm: 4.101975e-04, solution norm: 0.000000e+00
sfepy: cg-s: iteration 1
sfepy: cg-s: cg convergence: 0 (successful exit)
rhs norm: 2.286502e-03, solution norm: 0.000000e+00
Traceback (most recent call last):
<snip>
File "....local/lib/python2.7/site-packages/scipy/sparse/linalg/isolve/lgmres.py", line 145, in lgmres
"|v| ~ %.1g, |M v| = 0" % rnorm)
RuntimeError: Preconditioner returned a zero vector; |v| ~ 0.002, |M v| = 0
This happened because the rhs norm was 2.286502e-03 < 1e-2 (see the line above the traceback), so no solution was attempted.
So I propose having both rtol
and atol
arguments (or allow tol
to be a tuple), and possibly adding a tol_mode
argument - either 'and' or 'or', defaulting to 'or', that tell whether both tolerances have to be met ('and' mode) or a single one is enough.
I can make a PR implementing this for lgmres
, as it is written in Python. I am not sure if I am brave enough to dive into the legacy fortran of the other solvers.