diff --git a/Manifest.toml b/Manifest.toml index 4fb69b6ae..e62925a59 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -164,7 +164,7 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DiffEqBase]] deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "0ab52aef95c5cc71e9a8c9d26919ce1f7fb472fa" +git-tree-sha1 = "94384b09e50ea01819b6db01ac08403ebe09bf65" repo-rev = "ap/tstable_termination" repo-url = "https://github.com/SciML/DiffEqBase.jl" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" diff --git a/docs/pages.jl b/docs/pages.jl index f1b239bc9..a68b0f8e2 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -6,7 +6,6 @@ pages = ["index.md", "Handling Large Ill-Conditioned and Sparse Systems" => "tutorials/large_systems.md", "Symbolic System Definition and Acceleration via ModelingToolkit" => "tutorials/modelingtoolkit.md", "tutorials/small_compile.md", - "tutorials/termination_conditions.md", "tutorials/iterator_interface.md"], "Basics" => Any["basics/NonlinearProblem.md", "basics/NonlinearFunctions.md", diff --git a/docs/src/basics/TerminationCondition.md b/docs/src/basics/TerminationCondition.md index 97bec6d32..a4ff5272b 100644 --- a/docs/src/basics/TerminationCondition.md +++ b/docs/src/basics/TerminationCondition.md @@ -1,10 +1,75 @@ # [Termination Conditions](@id termination_condition) Provides a API to specify termination conditions for [`NonlinearProblem`](@ref) and -[`SteadyStateProblem`](@ref). For details on the various termination modes, i.e., -NLSolveTerminationMode, see the documentation for [`NLSolveTerminationCondition`](@ref). +[`SteadyStateProblem`](@ref). For details on the various termination modes: -## Termination Condition API +## Termination Conditions + +The termination condition is constructed as: + +```julia +cache = init(du, u, AbsNormTerminationMode(); 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 +terminated = cache(du, u, uprev) +``` + +!!! note + + The default for NonlinearSolve.jl is `AbsSafeBestTerminationMode`! + +### Absolute Tolerance + +```@docs +AbsTerminationMode +AbsNormTerminationMode +AbsSafeTerminationMode +AbsSafeBestTerminationMode +``` + +### Relative Tolerance + +```@docs +RelTerminationMode +RelNormTerminationMode +RelSafeTerminationMode +RelSafeBestTerminationMode +``` + +### Both Absolute and Relative Tolerance + +```@docs +NormTerminationMode +SteadyStateDiffEqTerminationMode +SimpleNonlinearSolveTerminationMode +``` + +### Return Codes + +```@docs +DiffEqBase.NonlinearSafeTerminationReturnCode +DiffEqBase.NonlinearSafeTerminationReturnCode.Success +DiffEqBase.NonlinearSafeTerminationReturnCode.Default +DiffEqBase.NonlinearSafeTerminationReturnCode.Failure +DiffEqBase.NonlinearSafeTerminationReturnCode.PatienceTermination +DiffEqBase.NonlinearSafeTerminationReturnCode.ProtectiveTermination +``` + +## [Deprecated] Termination Condition API + +!!! warning + + This is deprecated. Currently only parts of `SimpleNonlinearSolve` uses this API. That + will also be phased out soon! ```@docs NLSolveTerminationCondition diff --git a/docs/src/tutorials/termination_conditions.md b/docs/src/tutorials/termination_conditions.md deleted file mode 100644 index 6a7e8a3cd..000000000 --- a/docs/src/tutorials/termination_conditions.md +++ /dev/null @@ -1,3 +0,0 @@ -# [More Detailed Termination Conditions](@id termination_conditions_tutorial) - -This is a stub article to be completed soon. diff --git a/test/23_test_problems.jl b/test/23_test_problems.jl index 7a67d1a9f..5ec5e611f 100644 --- a/test/23_test_problems.jl +++ b/test/23_test_problems.jl @@ -11,7 +11,8 @@ function test_on_library(problems, dicts, alg_ops, broken_tests, ϵ = 1e-4) @testset "$idx: $(dict["title"])" begin for alg in alg_ops try - sol = solve(nlprob, alg; termination_condition = AbsNormTerminationMode()) + sol = solve(nlprob, alg; + termination_condition = AbsNormTerminationMode()) problem(res, sol.u, nothing) broken = idx in broken_tests[alg] ? true : false diff --git a/test/basictests.jl b/test/basictests.jl index fafcb1453..d9fc47a1e 100644 --- a/test/basictests.jl +++ b/test/basictests.jl @@ -22,7 +22,7 @@ const TERMINATION_CONDITIONS = [ SteadyStateDiffEqTerminationMode(), SimpleNonlinearSolveTerminationMode(), NormTerminationMode(), RelTerminationMode(), RelNormTerminationMode(), AbsTerminationMode(), AbsNormTerminationMode(), RelSafeTerminationMode(), - AbsSafeTerminationMode(), RelSafeBestTerminationMode(), AbsSafeBestTerminationMode() + AbsSafeTerminationMode(), RelSafeBestTerminationMode(), AbsSafeBestTerminationMode(), ] # --- NewtonRaphson tests --- @@ -133,6 +133,7 @@ const TERMINATION_CONDITIONS = [ @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, NewtonRaphson(); termination_condition).u .≈ sqrt(2.0)) end @@ -297,6 +298,7 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, TrustRegion(); termination_condition).u .≈ sqrt(2.0)) end @@ -413,6 +415,7 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, LevenbergMarquardt(); termination_condition).u .≈ sqrt(2.0)) end @@ -547,6 +550,7 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, DFSane(); termination_condition).u .≈ sqrt(2.0)) end @@ -667,6 +671,7 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, PseudoTransient(; alpha_initial = 10.0); termination_condition).u .≈ sqrt(2.0)) @@ -764,6 +769,7 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, GeneralBroyden(); termination_condition).u .≈ sqrt(2.0)) end @@ -860,8 +866,9 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) - @test all(solve(probN,GeneralKlement(); termination_condition).u .≈ sqrt(2.0)) + @test all(solve(probN, GeneralKlement(); termination_condition).u .≈ sqrt(2.0)) end end @@ -876,7 +883,7 @@ end end function benchmark_nlsolve_iip(f, u0, p = 2.0; linesearch = LineSearch(), - termination_condition = AbsNormTerminationMode()) + termination_condition = AbsNormTerminationMode()) prob = NonlinearProblem{true}(f, u0, p) return solve(prob, LimitedMemoryBroyden(; linesearch); abstol = 1e-9, termination_condition) @@ -960,8 +967,9 @@ end @testset "Termination condition: $(termination_condition) u0: $(_nameof(u0))" for termination_condition in TERMINATION_CONDITIONS, u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) - @test all(solve(probN, LimitedMemoryBroyden(); + @test all(solve(probN, LimitedMemoryBroyden(); termination_condition).u .≈ sqrt(2.0)) end end diff --git a/test/polyalgs.jl b/test/polyalgs.jl index 01fd011b6..4b5377159 100644 --- a/test/polyalgs.jl +++ b/test/polyalgs.jl @@ -34,7 +34,7 @@ function f(du, u, p) end prob = NonlinearProblem(f, [2.0, 2.0, 2.0], [1.0, 2.0, 2.5]) -sol = solve(prob; abstol=1e-9) +sol = solve(prob; abstol = 1e-9) @test SciMLBase.successful_retcode(sol) # https://github.com/SciML/NonlinearSolve.jl/issues/187 @@ -43,11 +43,11 @@ ff(u, p) = 0.5 / 1.5 * NaNMath.log.(u ./ (1.0 .- u)) .- 2.0 * u .+ 1.0 uspan = (0.02, 0.1) prob = IntervalNonlinearProblem(ff, uspan) -sol = solve(prob; abstol=1e-9) +sol = solve(prob; abstol = 1e-9) @test SciMLBase.successful_retcode(sol) u0 = 0.06 p = 2.0 prob = NonlinearProblem(ff, u0, p) -sol = solve(prob; abstol=1e-9) +sol = solve(prob; abstol = 1e-9) @test SciMLBase.successful_retcode(sol)