Terminate Nonlinearsolve when residual does not decrease

Hi!

I am trying to terminate the solution of a nonlinear equation system when the residual does not decrease with successive iterations. I have tried two approaches:

  1. Trying to access the residuals during each iteration using a callback and then manually doing it.
function print_residual_callback(state)
    println("Iteration $(state.iteration): Residual norm = $(state.f_norm)")
    return true  # Continue the iterations.
end

# Create a Newton-Raphson solver (using KrylovJL_GMRES for the linear solve).
solver = NewtonRaphson(linsolve = KrylovJL_GMRES())

# Solve the problem while using the callback to print the residual each iteration.
sol = solve(problem, solver, callback = print_residual_callback)

But this does not print the residual for each iteration indicating i dont have access to it

  1. Using the AbsNormSafeTerminationMode termination condition. I would be grateful for any assistance in setting this up. I get this error:
UndefVarError: AbsNormSafeTerminationMode not defined

Thanks for your time!

Hi Pavan,

can you share the output of Pkg.status()?

In a fresh environment with NonlinearSolve v4.3.0 I have access to AbsNormSafeTerminationMode in a test environment without any other packages. The documentation is scarce but these at least doesn’t error out with a toy example:

sol = solve(prob, NewtonRaphson(), termination_condition = AbsNormSafeTerminationMode(NonlinearSolve.L2_NORM) )

Hi!

The output is:

julia> Pkg.status()
Status `~/.julia/environments/v1.10/Project.toml`
  [093aae92] BSplineKit v0.18.1
  [336ed68f] CSV v0.10.15
  [a93c6f00] DataFrames v1.7.0
  [39dd38d3] Dierckx v0.5.4
  [0c46a032] DifferentialEquations v7.15.0
  [cf66c380] FastChebInterp v1.2.0
  [f6369f11] ForwardDiff v0.10.38
  [38e38edf] GLM v1.9.0
  [e9467ef8] GLMakie v0.11.2
  [de52edbc] Integrals v4.5.0
  [a98d9a8b] Interpolations v0.15.1
  [42fd0dbc] IterativeSolvers v0.9.4
  [ba0b0d4f] Krylov v0.9.9
  [b964fa9f] LaTeXStrings v1.4.0
  [77ba4419] NaNMath v1.1.2
  [8913a72c] NonlinearSolve v4.3.0
  [be0214bd] NonlinearSolveBase v1.4.0
  [afe20452] PCHIPInterpolation v0.2.1
  [91a5bcdd] Plots v1.40.9
  [f27b6e38] Polynomials v4.0.15
  [c3572dad] Sundials v4.26.1
  [592b5752] Trapz v2.0.3

Interestingly, I get the error message UndefVarError: L2_NORM not defined and when i remove it, i get the same termination mode not defined error. This is a mwe ive been testing with:

using NonlinearSolve
using Krylov


function example_residual!(F, u, p)
    @. F = u*u - 1
end

c_guess = rand(10)         
p = (dummy = 1.0,)        
problem = NonlinearProblem(example_residual!, c_guess, p)

solver = NewtonRaphson(linsolve = KrylovJL_GMRES())


sol = solve(problem, solver,termination_condition = AbsNormSafeTerminationMode(NonlinearSolve.L2_NORM))

println("Final solution: ", sol.u)
println("Return code: ", sol.retcode)

Are you not on latest versions? Show ]st.

Hi @ChrisRackauckas, thanks for the follow up. I updated the various packages listed in my comment above (mainly Nonlinearsolve from 4.3.0 to 4.4.0) and that seems to have solved the problem.