diff --git a/Project.toml b/Project.toml index 572dbb6fe..8841eca18 100644 --- a/Project.toml +++ b/Project.toml @@ -64,7 +64,7 @@ BandedMatrices = "1.5" BenchmarkTools = "1.4" CUDA = "5.5" ConcreteStructs = "0.2.3" -DiffEqBase = "6.155.3" +DiffEqBase = "6.158.3" DifferentiationInterface = "0.6.1" Enzyme = "0.13.2" ExplicitImports = "1.5" diff --git a/docs/src/basics/solve.md b/docs/src/basics/solve.md index 8ceeaa5de..f7c238966 100644 --- a/docs/src/basics/solve.md +++ b/docs/src/basics/solve.md @@ -21,7 +21,7 @@ solve(prob::SciMLBase.NonlinearProblem, args...; kwargs...) `real(oneunit(T)) * (eps(real(one(T))))^(4 // 5)`. - `reltol::Number`: The relative tolerance. Defaults to `real(oneunit(T)) * (eps(real(one(T))))^(4 // 5)`. - - `termination_condition`: Termination Condition from DiffEqBase. Defaults to + - `termination_condition`: Termination Condition from NonlinearSolveBase. Defaults to `AbsSafeBestTerminationMode()` for `NonlinearSolve.jl` and `AbsTerminateMode()` for `SimpleNonlinearSolve.jl`. diff --git a/docs/src/basics/termination_condition.md b/docs/src/basics/termination_condition.md index fd01a06ad..9a7c718ec 100644 --- a/docs/src/basics/termination_condition.md +++ b/docs/src/basics/termination_condition.md @@ -14,9 +14,6 @@ cache = init(du, u, AbsSafeBestTerminationMode(); abstol = 1e-9, reltol = 1e-9) If `abstol` and `reltol` are not supplied, then we choose a default based on the element types of `du` and `u`. -We can query the `cache` using `DiffEqBase.get_termination_mode`, `DiffEqBase.get_abstol` -and `DiffEqBase.get_reltol`. - To test for termination simply call the `cache`: ```julia @@ -28,8 +25,8 @@ terminated = cache(du, u, uprev) ```@docs AbsTerminationMode AbsNormTerminationMode -AbsSafeTerminationMode -AbsSafeBestTerminationMode +AbsNormSafeTerminationMode +AbsNormSafeBestTerminationMode ``` ### Relative Tolerance @@ -37,20 +34,6 @@ AbsSafeBestTerminationMode ```@docs RelTerminationMode RelNormTerminationMode -RelSafeTerminationMode -RelSafeBestTerminationMode -``` - -### Both Absolute and Relative Tolerance - -```@docs -NormTerminationMode -SteadyStateDiffEqTerminationMode -``` - -The following was named to match an older version of SimpleNonlinearSolve. It is currently -not used as a default anywhere. - -```@docs -SimpleNonlinearSolveTerminationMode +RelNormSafeTerminationMode +RelNormSafeBestTerminationMode ``` diff --git a/ext/NonlinearSolveFastLevenbergMarquardtExt.jl b/ext/NonlinearSolveFastLevenbergMarquardtExt.jl index 262f811a7..e772043b3 100644 --- a/ext/NonlinearSolveFastLevenbergMarquardtExt.jl +++ b/ext/NonlinearSolveFastLevenbergMarquardtExt.jl @@ -3,6 +3,7 @@ module NonlinearSolveFastLevenbergMarquardtExt using ArrayInterface: ArrayInterface using FastClosures: @closure using FastLevenbergMarquardt: FastLevenbergMarquardt +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, FastLevenbergMarquardtJL using SciMLBase: SciMLBase, NonlinearLeastSquaresProblem, NonlinearProblem, ReturnCode using StaticArraysCore: SArray @@ -33,8 +34,8 @@ function SciMLBase.__solve(prob::Union{NonlinearLeastSquaresProblem, NonlinearPr else @closure (du, u, p) -> fn(du, u) end - abstol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u)) - reltol = NonlinearSolve.DEFAULT_TOLERANCE(reltol, eltype(u)) + abstol = get_tolerance(abstol, eltype(u)) + reltol = get_tolerance(reltol, eltype(u)) _jac_fn = NonlinearSolve.__construct_extension_jac( prob, alg, u, resid; alg.autodiff, can_handle_oop = Val(prob.u0 isa SArray)) diff --git a/ext/NonlinearSolveFixedPointAccelerationExt.jl b/ext/NonlinearSolveFixedPointAccelerationExt.jl index 6e26e5351..2d36d7f56 100644 --- a/ext/NonlinearSolveFixedPointAccelerationExt.jl +++ b/ext/NonlinearSolveFixedPointAccelerationExt.jl @@ -1,5 +1,6 @@ module NonlinearSolveFixedPointAccelerationExt +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, FixedPointAccelerationJL using SciMLBase: SciMLBase, NonlinearProblem, ReturnCode using FixedPointAcceleration: FixedPointAcceleration, fixed_point @@ -13,7 +14,7 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::FixedPointAccelerationJL f, u0, resid = NonlinearSolve.__construct_extension_f( prob; alias_u0, make_fixed_point = Val(true), force_oop = Val(true)) - tol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u0)) + tol = get_tolerance(abstol, eltype(u0)) sol = fixed_point(f, u0; Algorithm = alg.algorithm, MaxIter = maxiters, MaxM = alg.m, ConvergenceMetricThreshold = tol, ExtrapolationPeriod = alg.extrapolation_period, diff --git a/ext/NonlinearSolveLeastSquaresOptimExt.jl b/ext/NonlinearSolveLeastSquaresOptimExt.jl index 6abe13a9c..20dac092d 100644 --- a/ext/NonlinearSolveLeastSquaresOptimExt.jl +++ b/ext/NonlinearSolveLeastSquaresOptimExt.jl @@ -2,6 +2,7 @@ module NonlinearSolveLeastSquaresOptimExt using ConcreteStructs: @concrete using LeastSquaresOptim: LeastSquaresOptim +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, LeastSquaresOptimJL, TraceMinimal using SciMLBase: SciMLBase, NonlinearLeastSquaresProblem, NonlinearProblem, ReturnCode @@ -42,8 +43,8 @@ function SciMLBase.__init(prob::Union{NonlinearLeastSquaresProblem, NonlinearPro NonlinearSolve.__test_termination_condition(termination_condition, :LeastSquaresOptim) f!, u, resid = NonlinearSolve.__construct_extension_f(prob; alias_u0) - abstol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u)) - reltol = NonlinearSolve.DEFAULT_TOLERANCE(reltol, eltype(u)) + abstol = get_tolerance(abstol, eltype(u)) + reltol = get_tolerance(reltol, eltype(u)) if prob.f.jac === nothing && alg.autodiff isa Symbol lsoprob = LSO.LeastSquaresProblem(; x = u, f!, y = resid, alg.autodiff, diff --git a/ext/NonlinearSolveMINPACKExt.jl b/ext/NonlinearSolveMINPACKExt.jl index 8299b0b45..3761a817f 100644 --- a/ext/NonlinearSolveMINPACKExt.jl +++ b/ext/NonlinearSolveMINPACKExt.jl @@ -1,6 +1,7 @@ module NonlinearSolveMINPACKExt using MINPACK: MINPACK +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, CMINPACK using SciMLBase: SciMLBase, NonlinearLeastSquaresProblem, NonlinearProblem, ReturnCode using FastClosures: @closure @@ -21,7 +22,7 @@ function SciMLBase.__solve( show_trace = ShT tracing = StT - tol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u0)) + tol = get_tolerance(abstol, eltype(u0)) if alg.autodiff === missing && prob.f.jac === nothing original = MINPACK.fsolve( diff --git a/ext/NonlinearSolveNLSolversExt.jl b/ext/NonlinearSolveNLSolversExt.jl index e78dab947..a9f41c87c 100644 --- a/ext/NonlinearSolveNLSolversExt.jl +++ b/ext/NonlinearSolveNLSolversExt.jl @@ -6,6 +6,7 @@ using FiniteDiff: FiniteDiff using ForwardDiff: ForwardDiff using LinearAlgebra: norm using NLSolvers: NLSolvers, NEqOptions, NEqProblem +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, NLSolversJL using SciMLBase: SciMLBase, NonlinearProblem, ReturnCode @@ -14,8 +15,8 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::NLSolversJL, args...; alias_u0::Bool = false, termination_condition = nothing, kwargs...) NonlinearSolve.__test_termination_condition(termination_condition, :NLSolversJL) - abstol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(prob.u0)) - reltol = NonlinearSolve.DEFAULT_TOLERANCE(reltol, eltype(prob.u0)) + abstol = get_tolerance(abstol, eltype(prob.u0)) + reltol = get_tolerance(reltol, eltype(prob.u0)) options = NEqOptions(; maxiter = maxiters, f_abstol = abstol, f_reltol = reltol) diff --git a/ext/NonlinearSolveNLsolveExt.jl b/ext/NonlinearSolveNLsolveExt.jl index 9872c7953..301ed7137 100644 --- a/ext/NonlinearSolveNLsolveExt.jl +++ b/ext/NonlinearSolveNLsolveExt.jl @@ -1,6 +1,7 @@ module NonlinearSolveNLsolveExt using LineSearches: Static +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, NLsolveJL, TraceMinimal using NLsolve: NLsolve, OnceDifferentiable, nlsolve using SciMLBase: SciMLBase, NonlinearProblem, ReturnCode @@ -27,7 +28,7 @@ function SciMLBase.__solve( df = OnceDifferentiable(f!, jac!, vec(u0), vec(resid), J) end - abstol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u0)) + abstol = get_tolerance(abstol, eltype(u0)) show_trace = ShT store_trace = StT extended_trace = !(trace_level isa TraceMinimal) diff --git a/ext/NonlinearSolveSIAMFANLEquationsExt.jl b/ext/NonlinearSolveSIAMFANLEquationsExt.jl index 6ec3e8393..65154b63a 100644 --- a/ext/NonlinearSolveSIAMFANLEquationsExt.jl +++ b/ext/NonlinearSolveSIAMFANLEquationsExt.jl @@ -1,6 +1,7 @@ module NonlinearSolveSIAMFANLEquationsExt using FastClosures: @closure +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, SIAMFANLEquationsJL using SciMLBase: SciMLBase, NonlinearProblem, ReturnCode using SIAMFANLEquations: SIAMFANLEquations, aasol, nsol, nsoli, nsolsc, ptcsol, ptcsoli, @@ -40,8 +41,8 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SIAMFANLEquationsJL, arg (; method, delta, linsolve, m, beta) = alg T = eltype(prob.u0) - atol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, T) - rtol = NonlinearSolve.DEFAULT_TOLERANCE(reltol, T) + atol = get_tolerance(abstol, T) + rtol = get_tolerance(reltol, T) if prob.u0 isa Number f = @closure u -> prob.f(u, prob.p) diff --git a/ext/NonlinearSolveSpeedMappingExt.jl b/ext/NonlinearSolveSpeedMappingExt.jl index b39394a3b..ff9b4683b 100644 --- a/ext/NonlinearSolveSpeedMappingExt.jl +++ b/ext/NonlinearSolveSpeedMappingExt.jl @@ -1,5 +1,6 @@ module NonlinearSolveSpeedMappingExt +using NonlinearSolveBase: NonlinearSolveBase, get_tolerance using NonlinearSolve: NonlinearSolve, SpeedMappingJL using SciMLBase: SciMLBase, NonlinearProblem, ReturnCode using SpeedMapping: speedmapping @@ -12,7 +13,7 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::SpeedMappingJL, args...; m!, u, resid = NonlinearSolve.__construct_extension_f( prob; alias_u0, make_fixed_point = Val(true)) - tol = NonlinearSolve.DEFAULT_TOLERANCE(abstol, eltype(u)) + tol = get_tolerance(abstol, eltype(u)) time_limit = ifelse(maxtime === nothing, 1000, maxtime) diff --git a/lib/NonlinearSolveBase/src/utils.jl b/lib/NonlinearSolveBase/src/utils.jl index cb54a6f4c..825f63767 100644 --- a/lib/NonlinearSolveBase/src/utils.jl +++ b/lib/NonlinearSolveBase/src/utils.jl @@ -54,7 +54,7 @@ standardize_norm(f::F) where {F} = f norm_op(norm::N, op::OP, x, y) where {N, OP} = norm(op.(x, y)) function norm_op(::typeof(L2_NORM), op::OP, x, y) where {OP} if fast_scalar_indexing(x, y) - return sqrt(sum(@closure((xᵢ, yᵢ)->begin + return sqrt(sum(@closure((xᵢyᵢ)->begin xᵢ, yᵢ = xᵢyᵢ return op(xᵢ, yᵢ)^2 end), zip(x, y))) diff --git a/src/NonlinearSolve.jl b/src/NonlinearSolve.jl index 853cbdf19..fd2c0bc3d 100644 --- a/src/NonlinearSolve.jl +++ b/src/NonlinearSolve.jl @@ -6,12 +6,7 @@ using PrecompileTools: @compile_workload, @setup_workload using ArrayInterface: ArrayInterface, can_setindex, restructure, fast_scalar_indexing, ismutable using ConcreteStructs: @concrete -using DiffEqBase: DiffEqBase, AbstractNonlinearTerminationMode, - AbstractSafeBestNonlinearTerminationMode, AbsNormTerminationMode, - AbsSafeBestTerminationMode, AbsSafeTerminationMode, AbsTerminationMode, - NormTerminationMode, RelNormTerminationMode, RelSafeBestTerminationMode, - RelSafeTerminationMode, RelTerminationMode, - SimpleNonlinearSolveTerminationMode, SteadyStateDiffEqTerminationMode +using DiffEqBase: DiffEqBase # Needed for `init` / `solve` dispatches using FastClosures: @closure using LazyArrays: LazyArrays, ApplyArray, cache using LinearAlgebra: LinearAlgebra, ColumnNorm, Diagonal, I, LowerTriangular, Symmetric, @@ -24,7 +19,9 @@ using LinearSolve: LinearSolve, QRFactorization, needs_concrete_A, AbstractFacto using MaybeInplace: @bb using NonlinearSolveBase: NonlinearSolveBase, nonlinearsolve_forwarddiff_solve, nonlinearsolve_dual_solution, nonlinearsolve_∂f_∂p, - nonlinearsolve_∂f_∂u + nonlinearsolve_∂f_∂u, L2_NORM, AbstractNonlinearTerminationMode, + AbstractSafeNonlinearTerminationMode, + AbstractSafeBestNonlinearTerminationMode using Printf: @printf using Preferences: Preferences, @load_preference, @set_preferences! using RecursiveArrayTools: recursivecopy! @@ -51,7 +48,7 @@ using SparseArrays: AbstractSparseMatrix, SparseMatrixCSC using SparseMatrixColorings: ConstantColoringAlgorithm, GreedyColoringAlgorithm, LargestFirst -@reexport using SciMLBase, SimpleNonlinearSolve +@reexport using SciMLBase, SimpleNonlinearSolve, NonlinearSolveBase const DI = DifferentiationInterface @@ -182,12 +179,6 @@ export LineSearch, BackTracking, NoLineSearch, RobustNonMonotoneLineSearch, ## Trust Region Algorithms export RadiusUpdateSchemes -# Export the termination conditions from NonlinearSolveBase -export SteadyStateDiffEqTerminationMode, SimpleNonlinearSolveTerminationMode, - NormTerminationMode, RelTerminationMode, RelNormTerminationMode, AbsTerminationMode, - AbsNormTerminationMode, RelSafeTerminationMode, AbsSafeTerminationMode, - RelSafeBestTerminationMode, AbsSafeBestTerminationMode - # Tracing Functionality export TraceAll, TraceMinimal, TraceWithJacobianConditionNumber diff --git a/src/abstract_types.jl b/src/abstract_types.jl index 0bb2e13d2..415dc5797 100644 --- a/src/abstract_types.jl +++ b/src/abstract_types.jl @@ -263,8 +263,7 @@ Abstract Type for Damping Functions in DampedNewton. ```julia __internal_init( prob::AbstractNonlinearProblem, f::AbstractDampingFunction, initial_damping, - J, fu, u, args...; internal_norm = DEFAULT_NORM, kwargs...) --> -AbstractDampingFunctionCache + J, fu, u, args...; internal_norm = L2_NORM, kwargs...) --> AbstractDampingFunctionCache ``` Returns a [`AbstractDampingFunctionCache`](@ref). @@ -348,7 +347,7 @@ Abstract Type for all Jacobian Initialization Algorithms used in NonlinearSolve. ```julia __internal_init( prob::AbstractNonlinearProblem, alg::AbstractJacobianInitialization, solver, - f::F, fu, u, p; linsolve = missing, internalnorm::IN = DEFAULT_NORM, kwargs...) + f::F, fu, u, p; linsolve = missing, internalnorm::IN = L2_NORM, kwargs...) ``` Returns a [`NonlinearSolve.InitializedApproximateJacobianCache`](@ref). @@ -382,9 +381,8 @@ Abstract Type for all Approximate Jacobian Update Rules used in NonlinearSolve.j ```julia __internal_init( - prob::AbstractNonlinearProblem, alg::AbstractApproximateJacobianUpdateRule, J, - fu, u, du, args...; internalnorm::F = DEFAULT_NORM, kwargs...) where {F} --> -AbstractApproximateJacobianUpdateRuleCache{INV} + prob::AbstractNonlinearProblem, alg::AbstractApproximateJacobianUpdateRule, J, fu, u, + du, args...; internalnorm::F = L2_NORM, kwargs...) where {F} --> AbstractApproximateJacobianUpdateRuleCache{INV} ``` """ abstract type AbstractApproximateJacobianUpdateRule{INV} end @@ -440,9 +438,8 @@ Abstract Type for all Trust Region Methods used in NonlinearSolve.jl. ```julia __internal_init( - prob::AbstractNonlinearProblem, alg::AbstractTrustRegionMethod, f::F, fu, u, - p, args...; internalnorm::IF = DEFAULT_NORM, kwargs...) where {F, IF} --> -AbstractTrustRegionMethodCache + prob::AbstractNonlinearProblem, alg::AbstractTrustRegionMethod, f::F, fu, u, p, args...; + internalnorm::IF = L2_NORM, kwargs...) where {F, IF} --> AbstractTrustRegionMethodCache ``` """ abstract type AbstractTrustRegionMethod end diff --git a/src/algorithms/broyden.jl b/src/algorithms/broyden.jl index 77d2a06c4..4b4b3df9d 100644 --- a/src/algorithms/broyden.jl +++ b/src/algorithms/broyden.jl @@ -171,7 +171,7 @@ end function __internal_init(prob::AbstractNonlinearProblem, alg::Union{GoodBroydenUpdateRule, BadBroydenUpdateRule}, J, fu, u, - du, args...; internalnorm::F = DEFAULT_NORM, kwargs...) where {F} + du, args...; internalnorm::F = L2_NORM, kwargs...) where {F} @bb J⁻¹dfu = similar(u) @bb dfu = copy(fu) if alg isa GoodBroydenUpdateRule || J isa Diagonal diff --git a/src/algorithms/lbroyden.jl b/src/algorithms/lbroyden.jl index bead1a057..8fb0db748 100644 --- a/src/algorithms/lbroyden.jl +++ b/src/algorithms/lbroyden.jl @@ -44,7 +44,7 @@ jacobian_initialized_preinverted(::BroydenLowRankInitialization) = true function __internal_init( prob::AbstractNonlinearProblem, alg::BroydenLowRankInitialization{T}, solver, f::F, fu, u, p; maxiters = 1000, - internalnorm::IN = DEFAULT_NORM, kwargs...) where {T, F, IN} + internalnorm::IN = L2_NORM, kwargs...) where {T, F, IN} if u isa Number # Use the standard broyden return __internal_init(prob, IdentityInitialization(true, FullStructure()), solver, f, fu, u, p; maxiters, kwargs...) diff --git a/src/algorithms/levenberg_marquardt.jl b/src/algorithms/levenberg_marquardt.jl index 501a5dd29..2b7c08f95 100644 --- a/src/algorithms/levenberg_marquardt.jl +++ b/src/algorithms/levenberg_marquardt.jl @@ -98,7 +98,7 @@ end function __internal_init( prob::AbstractNonlinearProblem, f::LevenbergMarquardtDampingFunction, initial_damping, J, fu, u, ::Val{NF}; - internalnorm::F = DEFAULT_NORM, kwargs...) where {F, NF} + internalnorm::F = L2_NORM, kwargs...) where {F, NF} T = promote_type(eltype(u), eltype(fu)) DᵀD = __init_diagonal(u, T(f.min_damping)) if NF diff --git a/src/algorithms/pseudo_transient.jl b/src/algorithms/pseudo_transient.jl index 0da85dd94..1266d0702 100644 --- a/src/algorithms/pseudo_transient.jl +++ b/src/algorithms/pseudo_transient.jl @@ -53,7 +53,7 @@ end function __internal_init( prob::AbstractNonlinearProblem, f::SwitchedEvolutionRelaxation, initial_damping, - J, fu, u, args...; internalnorm::F = DEFAULT_NORM, kwargs...) where {F} + J, fu, u, args...; internalnorm::F = L2_NORM, kwargs...) where {F} T = promote_type(eltype(u), eltype(fu)) return SwitchedEvolutionRelaxationCache( internalnorm(fu), T(1 / initial_damping), internalnorm) diff --git a/src/core/approximate_jacobian.jl b/src/core/approximate_jacobian.jl index 2e0c64a82..3522a39f4 100644 --- a/src/core/approximate_jacobian.jl +++ b/src/core/approximate_jacobian.jl @@ -148,7 +148,7 @@ function SciMLBase.__init( args...; stats = empty_nlstats(), alias_u0 = false, maxtime = nothing, maxiters = 1000, abstol = nothing, reltol = nothing, linsolve_kwargs = (;), termination_condition = nothing, - internalnorm::F = DEFAULT_NORM, kwargs...) where {uType, iip, F} + internalnorm::F = L2_NORM, kwargs...) where {uType, iip, F} timer = get_timer_output() @static_timeit timer "cache construction" begin (; f, u0, p) = prob @@ -162,8 +162,8 @@ function SciMLBase.__init( initialization_cache = __internal_init(prob, alg.initialization, alg, f, fu, u, p; stats, linsolve, maxiters, internalnorm) - abstol, reltol, termination_cache = init_termination_cache( - prob, abstol, reltol, fu, u, termination_condition) + abstol, reltol, termination_cache = NonlinearSolveBase.init_termination_cache( + prob, abstol, reltol, fu, u, termination_condition, Val(:regular)) linsolve_kwargs = merge((; abstol, reltol), linsolve_kwargs) J = initialization_cache(nothing) diff --git a/src/core/generalized_first_order.jl b/src/core/generalized_first_order.jl index ebdaf1fc8..13980c154 100644 --- a/src/core/generalized_first_order.jl +++ b/src/core/generalized_first_order.jl @@ -150,7 +150,7 @@ function SciMLBase.__init( prob::AbstractNonlinearProblem{uType, iip}, alg::GeneralizedFirstOrderAlgorithm, args...; stats = empty_nlstats(), alias_u0 = false, maxiters = 1000, abstol = nothing, reltol = nothing, maxtime = nothing, - termination_condition = nothing, internalnorm = DEFAULT_NORM, + termination_condition = nothing, internalnorm = L2_NORM, linsolve_kwargs = (;), kwargs...) where {uType, iip} timer = get_timer_output() @static_timeit timer "cache construction" begin @@ -161,8 +161,8 @@ function SciMLBase.__init( linsolve = get_linear_solver(alg.descent) - abstol, reltol, termination_cache = init_termination_cache( - prob, abstol, reltol, fu, u, termination_condition) + abstol, reltol, termination_cache = NonlinearSolveBase.init_termination_cache( + prob, abstol, reltol, fu, u, termination_condition, Val(:regular)) linsolve_kwargs = merge((; abstol, reltol), linsolve_kwargs) jac_cache = JacobianCache( diff --git a/src/core/spectral_methods.jl b/src/core/spectral_methods.jl index d141a627b..31e988b70 100644 --- a/src/core/spectral_methods.jl +++ b/src/core/spectral_methods.jl @@ -131,8 +131,8 @@ function SciMLBase.__init(prob::AbstractNonlinearProblem, alg::GeneralizedDFSane linesearch_cache = init(prob, alg.linesearch, fu, u; stats, kwargs...) - abstol, reltol, tc_cache = init_termination_cache( - prob, abstol, reltol, fu, u_cache, termination_condition) + abstol, reltol, tc_cache = NonlinearSolveBase.init_termination_cache( + prob, abstol, reltol, fu, u_cache, termination_condition, Val(:regular)) trace = init_nonlinearsolve_trace(prob, alg, u, fu, nothing, du; kwargs...) if alg.σ_1 === nothing diff --git a/src/default.jl b/src/default.jl index 967b2e0e8..a7cc550d8 100644 --- a/src/default.jl +++ b/src/default.jl @@ -101,7 +101,7 @@ for (probType, pType) in ((:NonlinearProblem, :NLS), (:NonlinearLeastSquaresProb @eval begin function SciMLBase.__init( prob::$probType, alg::$algType{N}, args...; stats = empty_nlstats(), - maxtime = nothing, maxiters = 1000, internalnorm = DEFAULT_NORM, + maxtime = nothing, maxiters = 1000, internalnorm = L2_NORM, alias_u0 = false, verbose = true, kwargs...) where {N} if (alias_u0 && !ismutable(prob.u0)) verbose && @warn "`alias_u0` has been set to `true`, but `u0` is \ @@ -309,7 +309,7 @@ for (probType, pType) in ((:NonlinearProblem, :NLS), (:NonlinearLeastSquaresProb push!(calls, quote resids = tuple($(Tuple(resids)...)) - minfu, idx = __findmin(DEFAULT_NORM, resids) + minfu, idx = __findmin(L2_NORM, resids) end) for i in 1:N diff --git a/src/descent/dogleg.jl b/src/descent/dogleg.jl index 5d0bb1c7c..4c96c98f6 100644 --- a/src/descent/dogleg.jl +++ b/src/descent/dogleg.jl @@ -49,7 +49,7 @@ end function __internal_init(prob::AbstractNonlinearProblem, alg::Dogleg, J, fu, u; pre_inverted::Val{INV} = False, linsolve_kwargs = (;), - abstol = nothing, reltol = nothing, internalnorm::F = DEFAULT_NORM, + abstol = nothing, reltol = nothing, internalnorm::F = L2_NORM, shared::Val{N} = Val(1), kwargs...) where {F, INV, N} newton_cache = __internal_init(prob, alg.newton_descent, J, fu, u; pre_inverted, linsolve_kwargs, abstol, reltol, shared, kwargs...) diff --git a/src/descent/geodesic_acceleration.jl b/src/descent/geodesic_acceleration.jl index 136795057..8e8a305f0 100644 --- a/src/descent/geodesic_acceleration.jl +++ b/src/descent/geodesic_acceleration.jl @@ -87,7 +87,7 @@ end function __internal_init(prob::AbstractNonlinearProblem, alg::GeodesicAcceleration, J, fu, u; shared::Val{N} = Val(1), pre_inverted::Val{INV} = False, linsolve_kwargs = (;), abstol = nothing, reltol = nothing, - internalnorm::F = DEFAULT_NORM, kwargs...) where {INV, N, F} + internalnorm::F = L2_NORM, kwargs...) where {INV, N, F} T = promote_type(eltype(u), eltype(fu)) @bb δu = similar(u) δus = N ≤ 1 ? nothing : map(2:N) do i diff --git a/src/globalization/trust_region.jl b/src/globalization/trust_region.jl index e6e2cba17..8ff6de905 100644 --- a/src/globalization/trust_region.jl +++ b/src/globalization/trust_region.jl @@ -57,7 +57,7 @@ end function __internal_init( prob::AbstractNonlinearProblem, alg::LevenbergMarquardtTrustRegion, f::F, fu, - u, p, args...; stats, internalnorm::IF = DEFAULT_NORM, kwargs...) where {F, IF} + u, p, args...; stats, internalnorm::IF = L2_NORM, kwargs...) where {F, IF} T = promote_type(eltype(u), eltype(fu)) @bb v = copy(u) @bb u_cache = similar(u) @@ -367,7 +367,7 @@ end function __internal_init( prob::AbstractNonlinearProblem, alg::GenericTrustRegionScheme, f::F, fu, u, - p, args...; stats, internalnorm::IF = DEFAULT_NORM, kwargs...) where {F, IF} + p, args...; stats, internalnorm::IF = L2_NORM, kwargs...) where {F, IF} T = promote_type(eltype(u), eltype(fu)) u0_norm = internalnorm(u) fu_norm = internalnorm(fu) diff --git a/src/internal/approximate_initialization.jl b/src/internal/approximate_initialization.jl index 985234ac4..72e46a97e 100644 --- a/src/internal/approximate_initialization.jl +++ b/src/internal/approximate_initialization.jl @@ -65,14 +65,14 @@ end function __internal_init( prob::AbstractNonlinearProblem, alg::IdentityInitialization, solver, f::F, - fu, u::Number, p; internalnorm::IN = DEFAULT_NORM, kwargs...) where {F, IN} + fu, u::Number, p; internalnorm::IN = L2_NORM, kwargs...) where {F, IN} α = __initial_alpha(alg.alpha, u, fu, internalnorm) return InitializedApproximateJacobianCache( α, alg.structure, alg, nothing, true, internalnorm) end function __internal_init(prob::AbstractNonlinearProblem, alg::IdentityInitialization, solver, f::F, fu::StaticArray, u::StaticArray, p; - internalnorm::IN = DEFAULT_NORM, kwargs...) where {IN, F} + internalnorm::IN = L2_NORM, kwargs...) where {IN, F} α = __initial_alpha(alg.alpha, u, fu, internalnorm) if alg.structure isa DiagonalStructure @assert length(u)==length(fu) "Diagonal Jacobian Structure must be square!" @@ -91,7 +91,7 @@ function __internal_init(prob::AbstractNonlinearProblem, alg::IdentityInitializa end function __internal_init( prob::AbstractNonlinearProblem, alg::IdentityInitialization, solver, - f::F, fu, u, p; internalnorm::IN = DEFAULT_NORM, kwargs...) where {F, IN} + f::F, fu, u, p; internalnorm::IN = L2_NORM, kwargs...) where {F, IN} α = __initial_alpha(alg.alpha, u, fu, internalnorm) if alg.structure isa DiagonalStructure @assert length(u)==length(fu) "Diagonal Jacobian Structure must be square!" @@ -147,7 +147,7 @@ end function __internal_init(prob::AbstractNonlinearProblem, alg::TrueJacobianInitialization, solver, f::F, fu, u, p; stats, linsolve = missing, - internalnorm::IN = DEFAULT_NORM, kwargs...) where {F, IN} + internalnorm::IN = L2_NORM, kwargs...) where {F, IN} autodiff = get_concrete_forward_ad( alg.autodiff, prob; check_forward_mode = false, kwargs...) jac_cache = JacobianCache(prob, solver, prob.f, fu, u, p; stats, autodiff, linsolve) diff --git a/src/internal/termination.jl b/src/internal/termination.jl index ef3f7c4c0..7728aea69 100644 --- a/src/internal/termination.jl +++ b/src/internal/termination.jl @@ -1,34 +1,9 @@ -function init_termination_cache(prob::NonlinearProblem, abstol, reltol, du, u, ::Nothing) - return init_termination_cache(prob, abstol, reltol, du, u, - AbsSafeBestTerminationMode(Base.Fix1(maximum, abs); max_stalled_steps = 32)) -end -function init_termination_cache( - prob::NonlinearLeastSquaresProblem, abstol, reltol, du, u, ::Nothing) - return init_termination_cache(prob, abstol, reltol, du, u, - AbsSafeBestTerminationMode(Base.Fix2(norm, 2); max_stalled_steps = 32)) -end - -function init_termination_cache( - prob::Union{NonlinearProblem, NonlinearLeastSquaresProblem}, - abstol, reltol, du, u, tc::AbstractNonlinearTerminationMode) - tc_ = if hasfield(typeof(tc), :internalnorm) && tc.internalnorm === nothing - internalnorm = ifelse( - prob isa NonlinearProblem, Base.Fix1(maximum, abs), Base.Fix2(norm, 2)) - DiffEqBase.set_termination_mode_internalnorm(tc, internalnorm) - else - tc - end - tc_cache = init(du, u, tc_; abstol, reltol, use_deprecated_retcodes = Val(false)) - return DiffEqBase.get_abstol(tc_cache), DiffEqBase.get_reltol(tc_cache), tc_cache -end - function check_and_update!(cache, fu, u, uprev) return check_and_update!(cache.termination_cache, cache, fu, u, uprev) end function check_and_update!(tc_cache, cache, fu, u, uprev) - return check_and_update!( - tc_cache, cache, fu, u, uprev, DiffEqBase.get_termination_mode(tc_cache)) + return check_and_update!(tc_cache, cache, fu, u, uprev, tc_cache.mode) end function check_and_update!(tc_cache, cache, fu, u, uprev, mode) @@ -40,8 +15,7 @@ function check_and_update!(tc_cache, cache, fu, u, uprev, mode) end function update_from_termination_cache!(tc_cache, cache, u = get_u(cache)) - return update_from_termination_cache!( - tc_cache, cache, DiffEqBase.get_termination_mode(tc_cache), u) + return update_from_termination_cache!(tc_cache, cache, tc_cache.mode, u) end function update_from_termination_cache!( diff --git a/src/utils.jl b/src/utils.jl index 6ceb4c9d8..069fde86e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,16 +1,8 @@ # Defaults -@inline DEFAULT_NORM(args...) = DiffEqBase.NONLINEARSOLVE_DEFAULT_NORM(args...) @inline DEFAULT_PRECS(W, du, u, p, t, newW, Plprev, Prprev, cachedata) = nothing, nothing -@inline DEFAULT_TOLERANCE(args...) = DiffEqBase._get_tolerance(args...) # Helper Functions -@static if VERSION ≤ v"1.10-" - @inline @generated function __hasfield(::T, ::Val{field}) where {T, field} - return :($(field ∉ fieldnames(T))) - end -else - @inline __hasfield(::T, ::Val{field}) where {T, field} = hasfield(T, field) -end +@inline __hasfield(::T, ::Val{field}) where {T, field} = hasfield(T, field) @generated function __getproperty(s::S, ::Val{X}) where {S, X} hasfield(S, X) && return :(s.$X) @@ -86,12 +78,10 @@ LazyArrays.applied_axes(::typeof(__zero), x) = axes(x) @inline __is_complex(::Type{T}) where {T} = false @inline __findmin_caches(f::F, caches) where {F} = __findmin(f ∘ get_fu, caches) -# FIXME: DEFAULT_NORM makes an Array of NaNs not a NaN (atleast according to `isnan`) +# FIXME: L2_NORM makes an Array of NaNs not a NaN (atleast according to `isnan`) @generated function __findmin(f::F, x) where {F} # JET shows dynamic dispatch if this is not written as a generated function - if F === typeof(DEFAULT_NORM) - return :(return __findmin_impl(Base.Fix1(maximum, abs), x)) - end + F === typeof(L2_NORM) && return :(return __findmin_impl(Base.Fix1(maximum, abs), x)) return :(return __findmin_impl(f, x)) end @inline @views function __findmin_impl(f::F, x) where {F}