SciML / ModelingToolkit.jl

An acausal modeling framework for automatically parallelized scientific machine learning (SciML) in Julia. A computer algebra system for integrated symbolics for physics-informed machine learning and automated transformations of differential equations
https://mtk.sciml.ai/dev/
Other
1.41k stars 203 forks source link

Events for @mtkmodel components #2421

Open cgutsche opened 7 months ago

cgutsche commented 7 months ago

In component based modeling your components might need to do event handeling. These events should be declarable within the component for easy modeling. As far as I can understand the code, there is no nice way to do this at the moment. Therefore I think additional syntax like the following would be nice:

@mtkmodel FOL begin
    @parameters begin
        τ # parameters
    end
    @variables begin
        x(t) # dependent variables
    end
    @equations begin
        D(x) ~ (1 - x) / τ
    end
    @discrete_events begin
        (t > 5) => [x ~ x + 1]
    end
    @continuous_events begin
        [t ~ 1] => [x ~ x + 1]
    end
end

I think this would be the easiest way to do it. Maybe a more Modelica like syntax including the events into the equation block would be possible but I think this is not necessary.

cgutsche commented 7 months ago

Hey, me again.

I implemented the feature by changing model_parsing.jl, you can have a look here: https://github.com/cgutsche/ModelingToolkit.jl/tree/dev-event-support

I tested the implementation with the following code and it worked:

@variables t
D = Differential(t)

@mtkmodel M begin
    @parameters begin 
        b[1:2]
    end
    @variables begin
        f(t)
        x(t)
    end
    @equations begin
        b[1] * f ~ D(f)
        b[2] * x ~ D(x)
    end
    @continuous_events begin
        [x ~ 0.9] => [b[2] ~ 5]
        [t ~ 0.5] => [x ~ 1]
        [t ~ 0.75] => [x ~ 1, f ~ f + 1]
    end
    @discrete_events begin
        (t == 0.8) => [b[2] ~ 2]
        (t == 0.5) => [f ~ f + 1]
    end
end

@mtkmodel N begin
    @components begin
        m = M(; b=[0, 1])
    end
    @parameters begin
        ω
    end
    @variables begin
        y(t)
        v(t)
    end 
    @equations begin
        v ~ D(y)
        ω*y ~ -D(v)
    end
    @continuous_events begin
        [t ~ 1.5] => [y ~ 5]
    end
end

@mtkbuild model = N(; ω=10)

u0 = [model.y => 1.0, model.v => 0, model.m.f => 1.0, model.m.x => 10]
prob = ODEProblem(model, u0, (0, 2.0))
sol = solve(prob, FBDF(), tstops=[0.5, 0.8])

p = plot(sol)
display(p)

However, I needed to add some if statements to create specific ODESystem Expressions for different cases where events are defined or not. (see line 99...) Maybe there is a better way to do that?

cgutsche commented 7 months ago

accidently closed the issue, oops

cgutsche commented 7 months ago

Okay, I think I found the best way to avoid the if statements. See the solution here: https://github.com/cgutsche/ModelingToolkit.jl/tree/dev-add-event-support-mtkmodel

SLiemann commented 6 months ago

Hi,

would the event support for @mtkmodel also include the generalized affect functions like in https://docs.sciml.ai/ModelingToolkit/stable/basics/Events/#func_affects ?

Does #2427 respect this?

Thanks for any comments.

cgutsche commented 6 months ago

Hey,

would the event support for @mtkmodel also include the generalized affect functions like in https://docs.sciml.ai/ModelingToolkit/stable/basics/Events/#func_affects ?

Does #2427 respect this?

Yes, generalized affect functions are supported too.