Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no method matching hasmetadata in tearing #3370

Open
cstjean opened this issue Feb 5, 2025 · 3 comments
Open

no method matching hasmetadata in tearing #3370

cstjean opened this issue Feb 5, 2025 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@cstjean
Copy link
Contributor

cstjean commented Feb 5, 2025

Describe the bug 🐞

I get an obscure error from a seemingly well-constructed system. Perhaps it's just that I would need to specify the derivative of f?

Expected behavior

Better error message?

Minimal Reproducible Example 👇

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

f(c, T) = (1 - 3 * c ^ 2)
@register_symbolic f(c, T)

@mtkmodel Tank begin
    @variables begin
        M1(t)
        M2(t)
        c(t)
        b(t)
    end
    @equations begin
        D(M1) ~ b + c
        D(M2) ~ (1 - b) + (1 - c)
        c ~ M1 / (M1 + M2)
        (M1 + M2) * f(c, 80) ~ 10
    end
end

@mtkbuild tank = Tank();

u0 = [tank.c => 0.6]

prob = ODEProblem(tank, u0, (0, 10.0), [],
                  guesses=[tank.M1 => 5,
                           tank.M2 => 5])

This is heavily reduced of course.

Error & Stacktrace ⚠️

ERROR: LoadError: MethodError: no method matching hasmetadata(::Nothing, ::Type{ModelingToolkit.VariableUnit})

Closest candidates are:
  hasmetadata(::Num, ::Any)
   @ Symbolics C:\Users\\.julia\packages\Symbolics\Xv70J\src\Symbolics.jl:194
  hasmetadata(::Complex{Num}, ::Any)
   @ Symbolics C:\Users\\.julia\packages\Symbolics\Xv70J\src\Symbolics.jl:194
  hasmetadata(::SymbolicUtils.Symbolic, ::Any)
   @ SymbolicUtils C:\Users\\.julia\packages\SymbolicUtils\6fncq\src\types.jl:859

Stacktrace:
  [1] _with_unit(::Function, ::SymbolicUtils.BasicSymbolic{Real}, ::Nothing, ::Nothing, ::Vararg{Any})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\utils.jl:1014
  [2] lower_varname_with_unit
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\utils.jl:1023 [inlined]
  [3] lower_varname_withshift(var::SymbolicUtils.BasicSymbolic{Real}, iv::Nothing, order::Int64)
    @ ModelingToolkit.StructuralTransformations C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\structural_transformation\utils.jl:458
  [4] tearing_reassemble(state::TearingState{…}, var_eq_matching::ModelingToolkit.BipartiteGraphs.Matching{…}, full_var_eq_matching::ModelingToolkit.BipartiteGraphs.Matching{…}; simplify::Bool, mm::ModelingToolkit.SparseMatrixCLIL{…}, cse_hack::Bool, array_hack::Bool)
    @ ModelingToolkit.StructuralTransformations C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\structural_transformation\symbolics_tearing.jl:413
  [5] tearing_reassemble
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\structural_transformation\symbolics_tearing.jl:240 [inlined]
  [6] tearing(sys::NonlinearSystem, state::TearingState{…}; mm::ModelingToolkit.SparseMatrixCLIL{…}, simplify::Bool, cse_hack::Bool, array_hack::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit.StructuralTransformations C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\structural_transformation\symbolics_tearing.jl:802
  [7] _structural_simplify!(state::TearingState{…}, io::Nothing; simplify::Bool, check_consistency::Bool, fully_determined::Nothing, warn_initialize_determined::Bool, dummy_derivative::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systemstructure.jl:711
  [8] _structural_simplify!
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systemstructure.jl:676 [inlined]
  [9] #structural_simplify!#1509
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systemstructure.jl:669 [inlined]
 [10] __structural_simplify(sys::NonlinearSystem, io::Nothing; simplify::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systems.jl:102
 [11] __structural_simplify
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systems.jl:83 [inlined]
 [12] structural_simplify(sys::NonlinearSystem, io::Nothing; additional_passes::Vector{…}, simplify::Bool, split::Bool, allow_symbolic::Bool, allow_parameter::Bool, conservative::Bool, fully_determined::Nothing, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systems.jl:33
 [13] structural_simplify (repeats 2 times)
    @ C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\systems.jl:28 [inlined]
 [14] ModelingToolkit.InitializationProblem{…}(sys::ODESystem, t::Int64, u0map::Dict{…}, parammap::Dict{…}; guesses::Dict{…}, check_length::Bool, warn_initialize_determined::Bool, initialization_eqs::Vector{…}, fully_determined::Nothing, check_units::Bool, use_scc::Bool, allow_incomplete::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:1310
 [15] (ModelingToolkit.InitializationProblem{})(::ODESystem, ::Int64, ::Vararg{…}; kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:1265
 [16] ModelingToolkit.InitializationProblem(::ODESystem, ::Int64, ::Vararg{…}; kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:1253
 [17] maybe_build_initialization_problem(sys::ODESystem, op::Dict{…}, u0map::Dict{…}, pmap::Dict{…}, t::Int64, defs::Dict{…}, guesses::Vector{…}, missing_unknowns::Set{…}; implicit_dae::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\problem_utils.jl:559
 [18] process_SciMLProblem(constructor::Type, sys::ODESystem, u0map::Vector{…}, pmap::Vector{…}; build_initializeprob::Bool, implicit_dae::Bool, t::Int64, guesses::Vector{…}, warn_initialize_determined::Bool, initialization_eqs::Vector{…}, eval_expression::Bool, eval_module::Module, fully_determined::Nothing, check_initialization_units::Bool, tofloat::Bool, use_union::Bool, u0_constructor::typeof(identity), du0map::Nothing, 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, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\problem_utils.jl:705
 [19] (ODEProblem{})(sys::ODESystem, u0map::Vector{…}, tspan::Tuple{…}, parammap::Vector{…}; callback::Nothing, check_length::Bool, warn_initialize_determined::Bool, eval_expression::Bool, eval_module::Module, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:832
 [20] (ODEProblem{true})(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any}; kwargs::@Kwargs{guesses::Vector{Pair{…}}})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:813
 [21] ODEProblem(::ODESystem, ::Vector{Pair{Num, Float64}}, ::Vararg{Any}; kwargs::@Kwargs{guesses::Vector{Pair{Num, Int64}}})
    @ ModelingToolkit C:\Users\\.julia\packages\ModelingToolkit\K8zNC\src\systems\diffeqs\abstractodesystem.jl:802

Environment (please complete the following information):

  • Output of using Pkg; Pkg.status()

Julia 1.10.5

MTK v9.62.0

@AayushSabharwal
Copy link
Member

The problem here seems to be that the initialization system thinks f(c, 80) is a variable because (somehow) there's a Differential(t)(f(c, 80)) in the system.

@AayushSabharwal
Copy link
Member

Okay, so the problem is that dummy derivatives tries to differentiate the last equation (the one involving f(c, 80)), resulting in the Differential(t)(f(c, 80)).

@AayushSabharwal
Copy link
Member

This can be solved by providing symbolic derivatives for the registered function as in this section of Symbolics docs. We should surface this in MTK somewhere.

julia> df1(c, T) = -6c
julia> @register_symbolic df1(c, T)
julia> Symbolics.derivative(::typeof(f), args::NTuple{2, Any}, ::Val{1}) = df1(args...)
julia> Symbolics.derivative(::typeof(f), args::NTuple{2, Any}, ::Val{2}) = 0.0
julia> @mtkbuild tank = Tank();
julia> prob = ODEProblem(tank, u0, (0, 10.0), [],
                         guesses=[tank.M1 => 5,
                                  tank.M2 => 5, tank.c => 1.0, tank.b => 1.0])
julia> solve(prob, Rodas5P())
retcode: Success
# ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants