typedef enum {/* converged */ SNES_CONVERGED_FNORM_ABS = 2, /* ||F|| < atol */ SNES_CONVERGED_FNORM_RELATIVE = 3, /* ||F|| < rtol*||F_initial|| */ SNES_CONVERGED_SNORM_RELATIVE = 4, /* Newton computed step size small; || delta x || < stol || x ||*/ SNES_CONVERGED_ITS = 5, /* maximum iterations reached */ SNES_CONVERGED_TR_DELTA = 7, /* diverged */ SNES_DIVERGED_FUNCTION_DOMAIN = -1, /* the new x location passed the function is not in the domain of F */ SNES_DIVERGED_FUNCTION_COUNT = -2, SNES_DIVERGED_LINEAR_SOLVE = -3, /* the linear solve failed */ SNES_DIVERGED_FNORM_NAN = -4, SNES_DIVERGED_MAX_IT = -5, SNES_DIVERGED_LINE_SEARCH = -6, /* the line search failed */ SNES_DIVERGED_INNER = -7, /* inner solve failed */ SNES_DIVERGED_LOCAL_MIN = -8, /* || J^T b || is small, implies converged to local minimum of F() */ SNES_DIVERGED_DTOL = -9, /* || F || > divtol*||F_initial|| */ SNES_DIVERGED_JACOBIAN_DOMAIN = -10, /* Jacobian calculation does not make sense */ SNES_CONVERGED_ITERATING = 0} SNESConvergedReason;
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.
SNES_DIVERGED_MAX_IT means that the solver reached the maximum number of iterations without satisfying any convergence criteria. SNES_CONVERGED_ITS means that SNESConvergedSkip() was chosen as the convergence test; thus the usual convergence criteria have not been checked and may or may not be satisfied.
The string versions of these are in SNESConvergedReasons, if you change any value here you must also adjust that array.
Each reason has its own manual page.