-
-
Notifications
You must be signed in to change notification settings - Fork 234
Description
Describe the bug 🐞
When adding an assertion to a flow-like system boundary, and running the system in isolation, a BoundsError is thrown when constructing the problem.
Expected behavior
Unsure? At least a more helpful error message.
Minimal Reproducible Example 👇
using ModelingToolkit, OrdinaryDiffEq
using ModelingToolkit: t_nounits as t, D_nounits as D
@variables y(t) u(t)
@named flow = System([y ~ 2*u], t; assertions = [(u > 0.0) => "Oops!"])
combined = compose(System([flow.u ~ -t], t; name = :combined), flow)
combined = mtkcompile(combined)
prob = ODEProblem(combined, [], (0.0, 10.0))
sol = OrdinaryDiffEq.solve(prob, ROS3P())Error & Stacktrace
julia> include("bounds_err.jl")
WARNING: import of ModelingToolkit.t_nounits into Main conflicts with an existing identifier; ignored.
ERROR: LoadError: BoundsError: attempt to access 0-element Vector{Any} at index [0]
Stacktrace:
[1] throw_boundserror(A::Vector{Any}, I::Tuple{Int64})
@ Base ./essentials.jl:14
[2] getindex(A::Vector{Any}, i::Int64)
@ Base ./essentials.jl:916
[3] generate_rhs(sys::System; implicit_dae::Bool, scalar::Bool, expression::Type, wrap_gfw::Type, eval_expression::Bool, eval_module::Module, override_discrete::Bool, kwargs::@Kwargs{…})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/kD28h/src/systems/codegen.jl:76
[4] (ODEFunction{…})(sys::System; u0::Nothing, p::MTKParameters{…}, tgrad::Bool, jac::Bool, t::Nothing, eval_expression::Bool, eval_module::Module, sparse::Bool, steady_state::Bool, checkbounds::Bool, sparsity::Bool, analytic::Nothing, simplify::Bool, cse::Bool, initialization_data::SciMLBase.OverrideInitData{…}, expression::Type, check_compatibility::Bool, nlstep::Bool, nlstep_compile::Bool, nlstep_scc::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/kD28h/src/problems/odeproblem.jl:11
[5] process_SciMLProblem(constructor::Type, sys::System, op::Vector{…}; build_initializeprob::Bool, implicit_dae::Bool, t::Float64, guesses::Dict{…}, warn_initialize_determined::Bool, initialization_eqs::Vector{…}, eval_expression::Bool, eval_module::Module, fully_determined::Nothing, check_initialization_units::Bool, u0_eltype::Nothing, tofloat::Bool, u0_constructor::typeof(identity), p_constructor::typeof(identity), check_length::Bool, symbolic_u0::Bool, warn_cyclic_dependency::Bool, circular_dependency_max_cycle_length::Int64, circular_dependency_max_cycles::Int64, substitution_limit::Int64, use_scc::Bool, time_dependent_init::Bool, algebraic_only::Bool, allow_incomplete::Bool, is_initializeprob::Bool, kwargs::@Kwargs{…})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/kD28h/src/systems/problem_utils.jl:1476
[6] (ODEProblem{…})(sys::System, op::Vector{…}, tspan::Tuple{…}; callback::Nothing, check_length::Bool, eval_expression::Bool, expression::Type, eval_module::Module, check_compatibility::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/kD28h/src/problems/odeproblem.jl:81
[7] ODEProblem
@ ~/.julia/packages/ModelingToolkit/kD28h/src/problems/odeproblem.jl:73 [inlined]
[8] ODEProblem
@ ./none:0 [inlined]
[9] ODEProblem(sys::System, op::Vector{Any}, tspan::Tuple{Float64, Float64})
@ ModelingToolkit ./none:0
[10] top-level scope
@ ~/projects/julia/ControlsWebsite.jl/bounds_err.jl:9
in expression starting at /home/tictac/projects/julia/cwx.jl/bounds_err.jl:9
Some type information was truncated. Use `show(err)` to see complete types.Environment (please complete the following information):
- Output of
using Pkg; Pkg.status()
Status `~/projects/julia/cwx.jl/Project.toml`
[e084ae63] CoolProp v0.2.2
[82cc6244] DataInterpolations v8.6.1
[a98d9a8b] Interpolations v0.16.2
[961ee093] ModelingToolkit v10.24.0
[429524aa] Optim v1.13.2
[1dea7af3] OrdinaryDiffEq v6.102.1
[a03496cd] PlotlyBase v0.8.21
[f2990250] PlotlyKaleido v2.3.0
[592b5752] Trapz v2.0.3- Output of
versioninfo()
Julia Version 1.11.7
Commit f2b3dbda30a (2025-09-08 12:10 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 16 × AMD Ryzen 7 7800X3D 8-Core Processor
WORD_SIZE: 64
LLVM: libLLVM-16.0.6 (ORCJIT, znver4)
Threads: 1 default, 0 interactive, 1 GC (on 16 virtual cores)
Environment:
JULIA_EDITOR = code
JULIA_VSCODE_REPL = 1Additional context
I ran into this problem when trying to hunt down a bug in a system. I was trying to add assertions to the boundary of a commonly used system which acts as a flow, but kept getting this error when trying to unit test the connector in isolation. This error doesn't get thrown when using the connector in a larger context.
Curiously, if you change the MWE to
using ModelingToolkit, OrdinaryDiffEq
using ModelingToolkit: t_nounits as t, D_nounits as D
@variables y(t) u(t)
@named flow = System([D(y) ~ 2*u], t; assertions = [(u > 0.0) => "Oops!"]) # < ---------- Now has a derivative.
combined = compose(System([flow.u ~ -t], t; name = :combined), flow)
combined = mtkcompile(combined)
prob = ODEProblem(combined, [flow.y => 1.0], (0.0, 10.0)) # < ----------- Initial Condition
sol = OrdinaryDiffEq.solve(prob, ROS3P())the model doesn't throw the BoundsError, and the problem properly halts at 0.