From 910f7de99b78c3e7425f330affba22bf7b0c8905 Mon Sep 17 00:00:00 2001 From: Herman Sletmoen Date: Fri, 19 Jul 2024 16:44:33 +0200 Subject: [PATCH 1/4] Test a system that should have a guess --- test/initializationsystem.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/initializationsystem.jl b/test/initializationsystem.jl index f4097ecd97..3cd30dd7e6 100644 --- a/test/initializationsystem.jl +++ b/test/initializationsystem.jl @@ -456,3 +456,11 @@ sys = structural_simplify(unsimp; fully_determined = false) sys = extend(sysx, sysy) @test length(equations(generate_initializesystem(sys))) == 2 @test length(ModelingToolkit.guesses(sys)) == 1 + +# https://github.com/SciML/ModelingToolkit.jl/issues/2873 +@testset "Error on missing defaults" begin + @variables x(t) y(t) + @named sys = ODESystem([x^2 + y^2 ~ 25, D(x) ~ 1], t) + ssys = structural_simplify(sys) + @test_throws ArgumentError ODEProblem(ssys, [x => 3], (0, 1), []) # y should have a guess +end From 93d13fbeb3f02b69506ab5329c43528f162909a5 Mon Sep 17 00:00:00 2001 From: Herman Sletmoen Date: Fri, 19 Jul 2024 17:08:44 +0200 Subject: [PATCH 2/4] Disable early return optimization in promote_to_concrete() --- src/utils.jl | 63 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 9aa893e321..2cc75c7da9 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -663,42 +663,43 @@ function promote_to_concrete(vs; tofloat = true, use_union = true) vs = Any[vs...] end T = eltype(vs) - if Base.isconcretetype(T) && (!tofloat || T === float(T)) # nothing to do - return vs - else - sym_vs = filter(x -> SymbolicUtils.issym(x) || SymbolicUtils.iscall(x), vs) - isempty(sym_vs) || throw_missingvars_in_sys(sym_vs) - - C = nothing - for v in vs - E = typeof(v) - if E <: Number - if tofloat - E = float(E) - end - end - if C === nothing - C = E - end - if use_union - C = Union{C, E} - else - @assert C==E "`promote_to_concrete` can't make type $E uniform with $C" - C = E - end - end - y = similar(vs, C) - for i in eachindex(vs) - if (vs[i] isa Number) & tofloat - y[i] = float(vs[i]) #needed because copyto! can't convert Int to Float automatically - else - y[i] = vs[i] + # return early if there is nothing to do + # TODO: reenable after it was disabled to fix missing errors in https://github.com/SciML/ModelingToolkit.jl/issues/2873 + #Base.isconcretetype(T) && (!tofloat || T === float(T)) && return vs + + sym_vs = filter(x -> SymbolicUtils.issym(x) || SymbolicUtils.iscall(x), vs) + isempty(sym_vs) || throw_missingvars_in_sys(sym_vs) + + C = nothing + for v in vs + E = typeof(v) + if E <: Number + if tofloat + E = float(E) end end + if C === nothing + C = E + end + if use_union + C = Union{C, E} + else + @assert C==E "`promote_to_concrete` can't make type $E uniform with $C" + C = E + end + end - return y + y = similar(vs, C) + for i in eachindex(vs) + if (vs[i] isa Number) & tofloat + y[i] = float(vs[i]) #needed because copyto! can't convert Int to Float automatically + else + y[i] = vs[i] + end end + + return y end struct BitDict <: AbstractDict{Int, Int} From 19e8a899759b5fae1b3f410f7e90d657d1300900 Mon Sep 17 00:00:00 2001 From: Herman Sletmoen Date: Sat, 20 Jul 2024 11:49:58 +0200 Subject: [PATCH 3/4] Disable just the faulty branch of the early return optimization, since DDEs rely on the other branch --- src/utils.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 2cc75c7da9..9e6abafc4d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -665,8 +665,7 @@ function promote_to_concrete(vs; tofloat = true, use_union = true) T = eltype(vs) # return early if there is nothing to do - # TODO: reenable after it was disabled to fix missing errors in https://github.com/SciML/ModelingToolkit.jl/issues/2873 - #Base.isconcretetype(T) && (!tofloat || T === float(T)) && return vs + Base.isconcretetype(T) && (!tofloat#= || T === float(T)=#) && return vs # TODO: disabled float(T) to restore missing errors in https://github.com/SciML/ModelingToolkit.jl/issues/2873 sym_vs = filter(x -> SymbolicUtils.issym(x) || SymbolicUtils.iscall(x), vs) isempty(sym_vs) || throw_missingvars_in_sys(sym_vs) From 1b22927d853ed87283f76f1cc8a49147ae2c4d24 Mon Sep 17 00:00:00 2001 From: Herman Sletmoen Date: Sat, 20 Jul 2024 12:33:29 +0200 Subject: [PATCH 4/4] Format --- docs/src/tutorials/initialization.md | 4 ++-- src/utils.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/src/tutorials/initialization.md b/docs/src/tutorials/initialization.md index 8852fc7ac0..f40c28991f 100644 --- a/docs/src/tutorials/initialization.md +++ b/docs/src/tutorials/initialization.md @@ -195,7 +195,7 @@ long enough you will see that `λ = 0` is required for this equation, but since `λ = 1` we end up with a set of equations that are impossible to satisfy. !!! note - + If you would prefer to have an error instead of a warning in the context of non-fully determined systems, pass the keyword argument `fully_determined = true` into the problem constructor. Additionally, any warning about not being fully determined can @@ -278,7 +278,7 @@ sol = solve(iprob) ``` !!! note - + For more information on solving NonlinearProblems and NonlinearLeastSquaresProblems, check out the [NonlinearSolve.jl tutorials!](https://docs.sciml.ai/NonlinearSolve/stable/tutorials/getting_started/). diff --git a/src/utils.jl b/src/utils.jl index 9e6abafc4d..86a28dcae6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -665,7 +665,8 @@ function promote_to_concrete(vs; tofloat = true, use_union = true) T = eltype(vs) # return early if there is nothing to do - Base.isconcretetype(T) && (!tofloat#= || T === float(T)=#) && return vs # TODO: disabled float(T) to restore missing errors in https://github.com/SciML/ModelingToolkit.jl/issues/2873 + #Base.isconcretetype(T) && (!tofloat || T === float(T)) && return vs # TODO: disabled float(T) to restore missing errors in https://github.com/SciML/ModelingToolkit.jl/issues/2873 + Base.isconcretetype(T) && !tofloat && return vs sym_vs = filter(x -> SymbolicUtils.issym(x) || SymbolicUtils.iscall(x), vs) isempty(sym_vs) || throw_missingvars_in_sys(sym_vs)