Skip to content

SemilinearODEProblem errors when quadratic terms are present #4257

Description

@sablonl

Describe the bug 🐞

In the test of SemilinearODEProblem, the function has a linear part, a non-linear part but no quadratic term. Hence, the test pass. However, on the classic lorenz system, it fails.

Expected behavior

Correct initialization.

Minimal Reproducible Example 👇

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D

@variables x(t) = 0.1 y(t) = 0.1 z(t) = 0.1
@parameters σ = 10.0 ρ = 28.0 β = 8 / 3

eqs_1 = [
    D(x) ~ σ * (y - x),
    D(y) ~ x * (ρ - z) - y,
    D(z) ~ x * y - β * z,
]

eqs_2 = [
    D(x) ~ σ * (y - x),
    D(y) ~ x * (ρ - 0) - y,
    D(z) ~ 0*x * y - β * z,
] # No quadratic term here

@mtkcompile sys_1 = System(eqs_1, t)
@mtkcompile sys_2 = System(eqs_2, t)

prob_1 = SemilinearODEProblem(sys_1, nothing, (0.0, 10.0)) # Errors 
prob_2 = SemilinearODEProblem(sys_2, nothing, (0.0, 10.0)) # Works

Error & Stacktrace ⚠️

julia> show(err)
1-element ExceptionStack:
LoadError: ArgumentError: System sys_1: variable quadratic_Bₘₜₖ_3 does not exist
Stacktrace:
  [1] getvar(sys::System, name::Symbol; namespace::Bool)
    @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/7DETx/src/systems/abstractsystem.jl:1124
  [2] getproperty(sys::System, name::Symbol; namespace::Bool)
    @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/7DETx/src/systems/abstractsystem.jl:1065
  [3] getproperty(sys::System, name::Symbol; namespace::Bool) (repeats 2 times)
    @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/7DETx/src/systems/abstractsystem.jl:1063
  [4] getproperty(sys::System, name::Symbol)
    @ ModelingToolkitBase ~/.julia/packages/ModelingToolkitBase/7DETx/src/systems/abstractsystem.jl:1059
  [5] (::ModelingToolkit.var"#82#83")(i::Int64)
    @ ModelingToolkit ./none:-1
  [6] iterate
    @ ./generator.jl:48 [inlined]
  [7] collect_to!(dest::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}, itr::Base.Generator{UnitRange{Int64}, ModelingToolkit.var"#82#83"}, offs::Int64, st::Int64)
    @ Base ./array.jl:848
  [8] collect_to_with_first!(dest::Vector{SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}}, v1::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, itr::Base.Generator{UnitRange{Int64}, ModelingToolkit.var"#82#83"}, st::Int64)
    @ Base ./array.jl:826
  [9] collect(itr::Base.Generator{UnitRange{Int64}, ModelingToolkit.var"#82#83"})
    @ Base ./array.jl:800
 [10] SemilinearODEProblem{true, SciMLBase.FullSpecialize}(sys::System, op::Nothing, tspan::Tuple{Float64, Float64}; check_compatibility::Bool, u0_eltype::Nothing, expression::Type, callback::Nothing, sparse::Bool, stiff_linear::Bool, stiff_quadratic::Bool, stiff_nonlinear::Bool, jac::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit ~/.julia/packages/ModelingToolkit/dBZDD/src/problems/semilinearodeproblem.jl:98
 [11] SemilinearODEProblem
    @ ~/.julia/packages/ModelingToolkit/dBZDD/src/problems/semilinearodeproblem.jl:69 [inlined]
 [12] SemilinearODEProblem
    @ ./none:-1 [inlined]
 [13] SemilinearODEProblem(sys::System, op::Nothing, tspan::Tuple{Float64, Float64})
    @ ModelingToolkit ./none:-1

Environment (please complete the following information):

  • Output of using Pkg; Pkg.status()
(jl_AEuYml) pkg> st
Status `/tmp/jl_AEuYml/Project.toml`
  [961ee093] ModelingToolkit v11.9.0
  • Output of versioninfo()
julia> versioninfo()
Julia Version 1.12.4
Commit 01a2eadb047 (2026-01-06 16:56 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 64 × AMD Ryzen Threadripper 3970X 32-Core Processor
  WORD_SIZE: 64
  LLVM: libLLVM-18.1.7 (ORCJIT, znver2)
  GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 64 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_VSCODE_REPL = 1
  JULIA_PKG_USE_CLI_GIT = true

Activity

  1. DhairyaLGandhi commented on Feb 9, 2026

    @DhairyaLGandhi
    Member

    We are actively looking at this in https://github.com/JuliaComputing/SymbolicCompilerPasses.jl which should scale to larger systems. The nonlinear terms should get implictly filled in (as a structural zero in the jacobian) see JuliaComputing/SymbolicCompilerPasses.jl#22 as an example.

  2. sablonl commented on Feb 10, 2026

    @sablonl
    Author

    Great ! Does that mean that the SemilinearODEProblem will be replaced by the optimize = ... kwargs in ODEProblem ? Unfortunately, in the current state, passing SCP_BASIC leads to a ~250x increase in time to construct the ODEProblem (from ~20s to +5000s).

    I see you mention the jacobian, would it require to pass jac = true to ODEProblem (once again, I cannot do this since the size and complexity of my equations lead to OOM)?

  3. DhairyaLGandhi commented on Feb 10, 2026

    @DhairyaLGandhi
    Member

    That compile time is definitely not supposed to blow up like that, I'll look into it.

  4. lsablon commented on Jul 17, 2026

    @lsablon

    Any updates on this side ? It looks like SymbolicCompilerPasses.jl is not updated anymore.

  5. DhairyaLGandhi commented on Jul 17, 2026

    @DhairyaLGandhi
    Member

    The active development for SymbolicCompilerPasses.jl has moved to DyadCompilerPasses.jl as part of the Dyad distribution.

  6. lsablon commented on Jul 23, 2026

    @lsablon

    Which I suppose cannot be used without the whole Dyad machinery ?

  7. dwan-ith commented on Oct 9, 2026

    @dwan-ith

    I have seen this be open for a while now. If no one is working on this issue, I would like to be assigned to work on this

  8. ChrisRackauckas-Claude commented on Oct 9, 2026

    @ChrisRackauckas-Claude
    Member

    @dwan-ith thanks, you're welcome to take this. Nobody else is working on it.

    It still reproduces in public ModelingToolkit today. With ModelingToolkit v11.45.3 on Julia 1.12, running the MRE from the top of this issue:

    sys_1 (lorenz):        ArgumentError: System sys_1: variable quadratic_Bₘₜₖ_3 does not exist
    sys_2 (no quadratic):  ArgumentError: New length must be >= 0
    

    So the case with no quadratic term, which worked when this was filed, now fails as well. It is probably a related bug in the same path.

    Everything needed is in this repository; it does not depend on the separate compiler-passes work mentioned above. Places to start:

    • src/problems/semilinearodeproblem.jl: SemilinearODEProblem/SemilinearODEFunction, which call calculate_semiquadratic_form and then add_semiquadratic_parameters.
    • src/systems/codegen.jl: calculate_semiquadratic_form, and get_quadratic_form_name/get_quadratic_form_param, which generate the quadratic_Bₘₜₖ_i parameters. The lorenz error suggests a B_i matrix is referenced (state 3) without a matching parameter having been added. My guess is that rows whose quadratic part is all zero are skipped in one place but not the other. The sys_2 error points at the empty-quadratic case.

    A good PR would add both systems from this issue as tests (test/semilinearodeproblem.jl, if that is where the existing SemilinearODEProblem test lives) and check the solution against the plain ODEProblem solution.

    🤖 Posted by an AI agent (Claude Code, model claude-opus-5-5[1m]) on behalf of Chris Rackauckas: https://claude.ai/code/session_01H4fXBChQshAwfpLMCpEvAX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions