Skip to content

Commit 9c415dc

Browse files
Merge pull request #3456 from vyudu/better-warning
fix: Throw better warning when a guess is missing
2 parents 0ad773d + d680da2 commit 9c415dc

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

src/systems/diffeqs/abstractodesystem.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1504,5 +1504,5 @@ function InitializationProblem{iip, specialize}(sys::AbstractSystem,
15041504
else
15051505
NonlinearLeastSquaresProblem
15061506
end
1507-
TProb(isys, u0map, parammap; kwargs..., build_initializeprob = false)
1507+
TProb(isys, u0map, parammap; kwargs..., build_initializeprob = false, is_initializeprob = true)
15081508
end

src/systems/problem_utils.jl

+32-5
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,24 @@ function Base.showerror(io::IO, err::UnexpectedSymbolicValueInVarmap)
325325
""")
326326
end
327327

328+
struct MissingGuessError <: Exception
329+
syms::Vector{Any}
330+
vals::Vector{Any}
331+
end
332+
333+
function Base.showerror(io::IO, err::MissingGuessError)
334+
println(io,
335+
"""
336+
Cyclic guesses detected in the system. Symbolic values were found for the following variables/parameters in the map: \
337+
""")
338+
for (sym, val) in zip(err.syms, err.vals)
339+
println(io, "$sym => $val")
340+
end
341+
println(io,
342+
"""
343+
In order to resolve this, please provide additional numeric guesses so that the chain can be resolved to assign numeric values to each variable. """)
344+
end
345+
328346
"""
329347
$(TYPEDSIGNATURES)
330348
@@ -342,10 +360,11 @@ Keyword arguments:
342360
[`missingvars`](@ref) to perform the check.
343361
- `allow_symbolic` allows the returned array to contain symbolic values. If this is `true`,
344362
`promotetoconcrete` is set to `false`.
363+
- `is_initializeprob, guesses`: Used to determine whether the system is missing guesses.
345364
"""
346365
function better_varmap_to_vars(varmap::AbstractDict, vars::Vector;
347366
tofloat = true, use_union = true, container_type = Array,
348-
toterm = default_toterm, promotetoconcrete = nothing, check = true, allow_symbolic = false)
367+
toterm = default_toterm, promotetoconcrete = nothing, check = true, allow_symbolic = false, is_initializeprob = false)
349368
isempty(vars) && return nothing
350369

351370
if check
@@ -354,9 +373,17 @@ function better_varmap_to_vars(varmap::AbstractDict, vars::Vector;
354373
end
355374
vals = map(x -> varmap[x], vars)
356375
if !allow_symbolic
376+
missingsyms = Any[]
377+
missingvals = Any[]
357378
for (sym, val) in zip(vars, vals)
358379
symbolic_type(val) == NotSymbolic() && continue
359-
throw(UnexpectedSymbolicValueInVarmap(sym, val))
380+
push!(missingsyms, sym)
381+
push!(missingvals, val)
382+
end
383+
384+
if !isempty(missingsyms)
385+
is_initializeprob ? throw(MissingGuessError(missingsyms, missingvals)) :
386+
throw(UnexpectedSymbolicValueInVarmap(missingsyms[1], missingvals[1]))
360387
end
361388
end
362389

@@ -704,7 +731,7 @@ Keyword arguments:
704731
- `fully_determined`: Override whether the initialization system is fully determined.
705732
- `check_initialization_units`: Enable or disable unit checks when constructing the
706733
initialization problem.
707-
- `tofloat`, `use_union`: Passed to [`better_varmap_to_vars`](@ref) for building `u0` (and
734+
- `tofloat`, `use_union`, `is_initializeprob`: Passed to [`better_varmap_to_vars`](@ref) for building `u0` (and
708735
possibly `p`).
709736
- `u0_constructor`: A function to apply to the `u0` value returned from `better_varmap_to_vars`
710737
to construct the final `u0` value.
@@ -742,7 +769,7 @@ function process_SciMLProblem(
742769
circular_dependency_max_cycles = 10,
743770
substitution_limit = 100, use_scc = true,
744771
force_initialization_time_independent = false, algebraic_only = false,
745-
allow_incomplete = false, kwargs...)
772+
allow_incomplete = false, is_initializeprob = false, kwargs...)
746773
dvs = unknowns(sys)
747774
ps = parameters(sys; initial_parameters = true)
748775
iv = has_iv(sys) ? get_iv(sys) : nothing
@@ -815,7 +842,7 @@ function process_SciMLProblem(
815842

816843
u0 = better_varmap_to_vars(
817844
op, dvs; tofloat = true, use_union = false,
818-
container_type = u0Type, allow_symbolic = symbolic_u0)
845+
container_type = u0Type, allow_symbolic = symbolic_u0, is_initializeprob)
819846

820847
if u0 !== nothing
821848
u0 = u0_constructor(u0)

src/variables.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ end
219219

220220
function Base.showerror(io::IO, e::MissingVariablesError)
221221
println(io, MISSING_VARIABLES_MESSAGE)
222-
println(io, e.vars)
222+
println(io, join(e.vars, ", "))
223223
end
224224

225225
function _varmap_to_vars(varmap::Dict, varlist; defaults = Dict(), check = false,

test/initial_values.jl

+19-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ end
172172
[p => 2q, q => 3p]; warn_cyclic_dependency = true)
173173
catch
174174
end
175-
@test_throws ModelingToolkit.UnexpectedSymbolicValueInVarmap ODEProblem(
175+
@test_throws ModelingToolkit.MissingGuessError ODEProblem(
176176
sys, [x => 1, y => 2], (0.0, 1.0), [p => 2q, q => 3p])
177177
end
178178

@@ -199,3 +199,21 @@ end
199199
@test SciMLBase.successful_retcode(sol)
200200
@test sol.u[1] [1.0, 1.0, 0.5, 0.5]
201201
end
202+
203+
@testset "Missing/cyclic guesses throws error" begin
204+
@parameters g
205+
@variables x(t) y(t) [state_priority = 10] λ(t)
206+
eqs = [D(D(x)) ~ λ * x
207+
D(D(y)) ~ λ * y - g
208+
x^2 + y^2 ~ 1]
209+
@mtkbuild pend = ODESystem(eqs, t)
210+
211+
@test_throws ModelingToolkit.MissingGuessError ODEProblem(pend, [x => 1], (0, 1), [g => 1], guesses = [y => λ, λ => y + 1])
212+
ODEProblem(pend, [x => 1], (0, 1), [g => 1], guesses = [y => λ, λ => 0.5])
213+
214+
# Throw multiple if multiple are missing
215+
@variables a(t) b(t) c(t) d(t) e(t)
216+
eqs = [D(a) ~ b, D(b) ~ c, D(c) ~ d, D(d) ~ e, D(e) ~ 1]
217+
@mtkbuild sys = ODESystem(eqs, t)
218+
@test_throws ["a(t)", "c(t)"] ODEProblem(sys, [e => 2, a => b, b => a + 1, c => d, d => c + 1], (0, 1))
219+
end

0 commit comments

Comments
 (0)