From 44dce665292ce31d1cbc1d5fd9f77e4395fb5985 Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Thu, 7 Nov 2024 17:16:01 +0100 Subject: [PATCH 1/7] Move informative error message up the call stack so it is hit --- lib/OrdinaryDiffEqCore/src/initialize_dae.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index e88deeef1a..0d237e1f02 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -47,6 +47,10 @@ variable, then the system is not Index 1! function DiffEqBase.initialize_dae!(integrator::ODEIntegrator, initializealg = integrator.initializealg) + if !hasmethod(_initialize_dae!, (Any, typeof(integrator.sol.prob), + BrownFullBasicInit, Val)) + error("This ODE requires a DAE initialization and thus a nonlinear solve but no nonlinear solve has been loaded. To solve this problem, do `using OrdinaryDiffEqNonlinearSolve` or pass a custom `nlsolve` choice into the `initializealg`.") + end _initialize_dae!(integrator, integrator.sol.prob, initializealg, Val(DiffEqBase.isinplace(integrator.sol.prob))) From 6a8547e77c74fc5b69c5e3e08528a747edeb0a75 Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Fri, 8 Nov 2024 14:19:11 +0100 Subject: [PATCH 2/7] Make hasmethod check if BrownFullBasicInit is defined --- lib/OrdinaryDiffEqCore/src/initialize_dae.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index 0d237e1f02..46dfa94729 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -47,9 +47,10 @@ variable, then the system is not Index 1! function DiffEqBase.initialize_dae!(integrator::ODEIntegrator, initializealg = integrator.initializealg) - if !hasmethod(_initialize_dae!, (Any, typeof(integrator.sol.prob), - BrownFullBasicInit, Val)) - error("This ODE requires a DAE initialization and thus a nonlinear solve but no nonlinear solve has been loaded. To solve this problem, do `using OrdinaryDiffEqNonlinearSolve` or pass a custom `nlsolve` choice into the `initializealg`.") + if !hasmethod(_initialize_dae!, (typeof(integrator), + typeof(integrator.sol.prob), BrownFullBasicInit, + Val{DiffEqBase.isinplace(integrator.sol.prob)})) + error("This ODE requires a DAE initialization and thus a nonlinear solve but no nonlinear solve has been loaded. To solve this problem, do `using OrdinaryDiffEqNonlinearSolve` or pass a custom `nlsolve` choice into the `initializealg`.") end _initialize_dae!(integrator, integrator.sol.prob, initializealg, From 1a070a9e55c0a2935c809c8b039060d631a67a3f Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Wed, 13 Nov 2024 15:20:47 +0100 Subject: [PATCH 3/7] Add CheckInit error message --- lib/OrdinaryDiffEqCore/src/initialize_dae.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index 46dfa94729..9c905923b4 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -203,7 +203,17 @@ end function Base.showerror(io::IO, e::CheckInitFailureError) print(io, - "CheckInit specified but initialization not satisifed. normresid = $(e.normresid) > abstol = $(e.abstol)") + "DAE initialization failed: your u0 did not satisfy the initialization requirements, + normresid = $(e.normresid) > abstol = $(e.abstol). If you wish for the system to + automatically change the algebraic variables to satisfy the algebraic constraints, + please pass `initializealg = BrownBasicInit()` to solve (this option will require + `using OrdinaryDiffEqNonlinearSolve`). If you wish to perform an initialization on the + complete u0, please pass initializealg = ShampineCollocationInit() to solve. Note that + initialization can be a very difficult process for DAEs and in many cases can be + numerically intractable without symbolic manipulation of the system. For an automated + system that will generate numerically stable initializations, see ModelingToolkit.jl + structural simplification for more details." + ) end function _initialize_dae!(integrator, prob::ODEProblem, alg::CheckInit, From 17b35afd5fb479feb6ca5d3f791efd97ddef6965 Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Wed, 13 Nov 2024 15:21:57 +0100 Subject: [PATCH 4/7] Swap BrownFullBasicInit for CheckInit --- lib/OrdinaryDiffEqCore/src/initialize_dae.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index 9c905923b4..ccb2db0a7f 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -66,7 +66,7 @@ function _initialize_dae!(integrator, prob::ODEProblem, OverrideInit(integrator.opts.abstol), x) else _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) + CheckInit(), x) end end @@ -77,7 +77,7 @@ function _initialize_dae!(integrator, prob::ODEProblem, OverrideInit(integrator.opts.abstol), x) else _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) + CheckInit(), x) end end @@ -91,7 +91,7 @@ function _initialize_dae!(integrator, prob::DAEProblem, ShampineCollocationInit(), x) else _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) + CheckInit(), x) end end @@ -105,7 +105,7 @@ function _initialize_dae!(integrator, prob::DAEProblem, ShampineCollocationInit(), x) else _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) + CheckInit(), x) end end From e9eedf826ae0ac0bc35c733f1f28202fa2b4d9e6 Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Tue, 3 Dec 2024 14:23:02 +0100 Subject: [PATCH 5/7] Unify methods so that CheckInit is default for all cases --- lib/OrdinaryDiffEqCore/src/initialize_dae.jl | 50 ++------------------ 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index 4e156175c0..d949377159 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -37,11 +37,6 @@ variable, then the system is not Index 1! function DiffEqBase.initialize_dae!(integrator::ODEIntegrator, initializealg = integrator.initializealg) - if !hasmethod(_initialize_dae!, (typeof(integrator), - typeof(integrator.sol.prob), BrownFullBasicInit, - Val{DiffEqBase.isinplace(integrator.sol.prob)})) - error("This ODE requires a DAE initialization and thus a nonlinear solve but no nonlinear solve has been loaded. To solve this problem, do `using OrdinaryDiffEqNonlinearSolve` or pass a custom `nlsolve` choice into the `initializealg`.") - end _initialize_dae!(integrator, integrator.sol.prob, initializealg, Val(DiffEqBase.isinplace(integrator.sol.prob))) @@ -49,50 +44,13 @@ end ## Default algorithms -function _initialize_dae!(integrator, prob::ODEProblem, - alg::DefaultInit, x::Val{true}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - else - _initialize_dae!(integrator, prob, - CheckInit(), x) - end -end - -function _initialize_dae!(integrator, prob::ODEProblem, - alg::DefaultInit, x::Val{false}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - else - _initialize_dae!(integrator, prob, - CheckInit(), x) - end -end - -function _initialize_dae!(integrator, prob::DAEProblem, - alg::DefaultInit, x::Val{false}) +function _initialize_dae!(integrator, + prob::Union{ODEProblem, DAEProblem}, + alg::DefaultInit, + x::Union{Val{true}, Val{false}}) if SciMLBase.has_initializeprob(prob.f) _initialize_dae!(integrator, prob, OverrideInit(integrator.opts.abstol), x) - elseif prob.differential_vars === nothing - _initialize_dae!(integrator, prob, - ShampineCollocationInit(), x) - else - _initialize_dae!(integrator, prob, - CheckInit(), x) - end -end - -function _initialize_dae!(integrator, prob::DAEProblem, - alg::DefaultInit, x::Val{true}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - elseif prob.differential_vars === nothing - _initialize_dae!(integrator, prob, - ShampineCollocationInit(), x) else _initialize_dae!(integrator, prob, CheckInit(), x) From 555369b308de78a58256f4fcba1409cc92224f5c Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Tue, 3 Dec 2024 14:23:21 +0100 Subject: [PATCH 6/7] Export BrownFullBasicInit and ShampineCollocationInit --- .../src/OrdinaryDiffEqNonlinearSolve.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl index 593f27ee77..659278af97 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl @@ -64,4 +64,6 @@ include("functional.jl") include("newton.jl") include("initialize_dae.jl") +export BrownFullBasicInit, ShampineCollocationInit + end From 226b1ca19104c116133bfe39f5f04f4cf513f648 Mon Sep 17 00:00:00 2001 From: Isaac Wheeler Date: Mon, 9 Dec 2024 10:21:48 +0100 Subject: [PATCH 7/7] Remove export so it can live in non-breaking pull request --- .../src/OrdinaryDiffEqNonlinearSolve.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl index 659278af97..593f27ee77 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl @@ -64,6 +64,4 @@ include("functional.jl") include("newton.jl") include("initialize_dae.jl") -export BrownFullBasicInit, ShampineCollocationInit - end