Skip to content

How can one implement multimode systems that also include continuous events effectively? #3928

@zalanzsiboras

Description

@zalanzsiboras

How can one implement multimode systems that also include continuous events effectively❓

I would like to create a multimode system, where the derivative of some unknowns depend on the (discrete) mode, and where the mode is changed by continuous events.

  1. Firstly, should mode be a time-dependent parameter, or a variable/unknown❓

On the one hand, if mode is a time-dependent parameter, then according to the Event Handling and Callback Functions tutorial it needs to be marked as a discrete parameter within the continuous event. However, using the @continuous_events macro does not seem to set mode as a discrete parameter, and it also does not seem to accept SymbolicContinuousCallback().

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

@mtkmodel MultiModeSystem begin
    @parameters begin
        mode(t)::Bool = false
    end
    @variables begin
        # Depends on "mode"
        x(t) = 0.0
        # Event triggerer var. - "mode" depends on it
        v(t) = 0.0
        d_v(t) = 10.0
    end
    @equations begin
        # Depends on "mode"
        D(x) ~ mode * 1.0
        # Event triggerer var. - "mode" depends on it
        D(v) ~ d_v
        D(d_v) ~ 0.0
    end
    @continuous_events begin
        [v ~ 10.0] => [v ~ 0.0, d_v ~ -10.0, mode ~ true]
        [v ~ -10.0] => [v ~ 0.0, d_v ~ 10.0, mode ~ false]
    end
end

@mtkcompile sys = MultiModeSystem()
prob = ODEProblem(sys, [], (0, 3.0))

using OrdinaryDiffEq: solve
sol = solve(prob)
# Incorrect solution because "x" does not change!

Using SymbolicContinuousCallback() within @continuous_events results in the following error during system definition:

ERROR: LoadError: Malformed continuous event ModelingToolkit.SymbolicContinuousCallback([v ~ 10.0] => [v ~ 0.0, d_v ~ -10.0, mode ~ true], discrete_parameters = [mode]).
Stacktrace:
 [1] error(s::String)
   @ Base .\error.jl:35
 [2] parse_continuous_events!(c_evts::Vector{Any}, dict::Dict{Symbol, Any}, body::Expr)
   @ ModelingToolkit ..\.julia\packages\ModelingToolkit\hlGut\src\systems\model_parsing.jl:1164
 [3] parse_model!(exprs::Vector{…}, comps::Vector{…}, ext::Vector{…}, eqs::Vector{…}, icon::Base.RefValue{…}, vs::Vector{…}, ps::Vector{…}, sps::Vector{…}, c_evts::Vector{…}, d_evts::Vector{…}, cons::Vector{…}, costs::Vector{…}, dict::Dict{…}, mod::Module, arg::Expr, kwargs::OrderedCollections.OrderedSet{…}, where_types::Vector{…})
   @ ModelingToolkit ..\.julia\packages\ModelingToolkit\hlGut\src\systems\model_parsing.jl:667
 [4] _model_macro(mod::Module, fullname::Symbol, expr::Expr, isconnector::Bool)
   @ ModelingToolkit ..\.julia\packages\ModelingToolkit\hlGut\src\systems\model_parsing.jl:82
 [5] var"@mtkmodel"(__source__::LineNumberNode, __module__::Module, fullname::Union{Expr, Symbol}, body::Any)
   @ ModelingToolkit ..\.julia\packages\ModelingToolkit\hlGut\src\systems\model_parsing.jl:33
in expression starting at ..\Coding\ModularEnergySystemSim.jl\dev\features\dev_degmin_calc_with_events.jl:7

On the other hand, if mode is a variable/unknown an additional equation needs to be added. This could be D(mode) ~ 0, however D() unsurprisingly only supports continuous variable/unknown.

  1. During the previous question, I assumed that mode is discrete (is of type bool or int). Would it help if it was treated as a continuous parameter or variable/unknown❓

  2. If so, how could one implement the "mode conditions" within equations robustly❓
    For example, if mode is a variabe/unknown a tiny numerical error ifelse(mode == 1.0, cond_true_eq, cond_false_eq) could still "trigger" the use of "cond_false_eq" equations even if D(mode) ~ 0 and mode is set to 1.0 by a continuous event. (In production code I also would like to avoid the use of isapprox().) Whereas, if mode is a continuous parameter, then the continuous events cannot be defined with the @continuous_events macro.

I also think that a tutorial on multimode systems (using events) could be a great addition to the documentation and I would be happy to help with that if we can find an effective solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions