typedef enum {/* converged */ SNES_CONVERGED_FNORM_ABS = 2, /* F < F_minabs */ SNES_CONVERGED_FNORM_RELATIVE = 3, /* F < F_mintol*F_initial */ SNES_CONVERGED_PNORM_RELATIVE = 4, /* step size small */ SNES_CONVERGED_ITS = 5, /* maximum iterations reached */ SNES_CONVERGED_TR_DELTA = 7, /* diverged */ SNES_DIVERGED_FUNCTION_DOMAIN = -1, SNES_DIVERGED_FUNCTION_COUNT = -2, SNES_DIVERGED_LINEAR_SOLVE = -3, SNES_DIVERGED_FNORM_NAN = -4, SNES_DIVERGED_MAX_IT = -5, SNES_DIVERGED_LS_FAILURE = -6, SNES_DIVERGED_LOCAL_MIN = -8, /* || J^T b || is small, implies converged to local minimum of F() */ SNES_CONVERGED_ITERATING = 0} SNESConvergedReason;
Notes: this must match finclude/petscsnes.h
The two most common reasons for divergence are
1) an incorrectly coded or computed Jacobian or
2) failure or lack of convergence in the linear system (in this case we recommend
testing with -pc_type lu to eliminate the linear solver as the cause of the problem).
If F'(x) is NOT invertible AND F'(x)^T F(x) = 0 then Q'(0) = 0 and the Newton direction is NOT a descent direction so the line search will fail. All one can do at this point is change the initial guess and try again.
An alternative explanation: Newton's method can be regarded as replacing the function with its linear approximation and minimizing the 2-norm of that. That is F(x+s) approx F(x) + F'(x)s so we minimize || F(x) + F'(x) s ||^2_2; do this using Least Squares. If F'(x) is invertible then s = - F'(x)^(-1)F(x) otherwise F'(x)^T F'(x) s = -F'(x)^T F(x). If F'(x)^T F(x) is NOT zero then there exists a nontrival (that is F'(x)s != 0) solution to the equation and this direction is s = - [F'(x)^T F'(x)]^(-1) F'(x)^T F(x) so Q'(0) = - F(x)^T F'(x) [F'(x)^T F'(x)]^(-T) F'(x)^T F(x) = - (F'(x)^T F(x)) [F'(x)^T F'(x)]^(-T) (F'(x)^T F(x)). Since we are assuming (F'(x)^T F(x)) != 0 and F'(x)^T F'(x) has no negative eigenvalues Q'(0) < 0 so s is a descent direction and the line search should succeed for small enough alpha.
Note that this RARELY happens in practice. Far more likely the linear system is not being solved (well enough?) or the Jacobian is wrong.
Developer note: The string versions of these are in src/snes/interface/snes.c called convergedreasons. If these enums are changed you much change those.
Level:beginner
Location:src/snes/../../include/petscsnes.h
Index of all SNES routines
Table of Contents for all manual pages
Index of all manual pages