Nonlinear preconditioning transforms the residual so that Newton-type methods encounter a 'tamer' function. This is useful for systems with extreme nonlinearities, such as exponential I-V curves in semiconductors.
Use the precondition keyword to provide a function G(fu, u, p) that acts as a left preconditioner. The solver replaces the residual $f(u, p)$ with the root-equivalent composition $u \to G(f(u, p), u, p)$ for all internal operations, including function evaluations, automatic-differentiation Jacobians, line-search merit functions, and termination criteria.
Requirements for G:
- It must be root-preserving: $G(r, u, p) = 0$ if and only if $r = 0$.
- If you provide manual derivatives (
jac, jvp, vjp, etc.) in the NonlinearFunction, they must describe the derivatives of the composed map $G \circ f$, not the raw $f$.
Note for Least Squares: For NonlinearLeastSquaresProblems, precondition re-weights the objective to $||G(f(u))||^2$. For overdetermined systems, this can be used for residual weighting, but it may change the minimizer.
using NonlinearSolve
p = (; Is = 1.0e-14, Vt = 0.025, It = 1.0e-2)
f_diode(v, p) = p.Is * expm1(v / p.Vt) - p.It
prob = NonlinearProblem(f_diode, 2.0, p)
# Apply asinh compression to tame the exponential residual
G(fu, u, p) = asinh(fu)
sol_G = solve(prob, NewtonRaphson(); precondition = G)