@@ -3,7 +3,9 @@ get_continuous_events(sys::AbstractSystem) = Equation[]
3
3
get_continuous_events (sys:: AbstractODESystem ) = getfield (sys, :continuous_events )
4
4
has_continuous_events (sys:: AbstractSystem ) = isdefined (sys, :continuous_events )
5
5
6
- has_discrete_events (sys:: AbstractSystem ) = isdefined (sys, :discrete_events ) && length (sys. discrete_events) > 0
6
+ function has_discrete_events (sys:: AbstractSystem )
7
+ isdefined (sys, :discrete_events ) && length (sys. discrete_events) > 0
8
+ end
7
9
function get_discrete_events (sys:: AbstractSystem )
8
10
has_discrete_events (sys) || return SymbolicDiscreteCallback[]
9
11
getfield (sys, :discrete_events )
@@ -15,8 +17,10 @@ struct FunctionalAffect
15
17
sts_syms:: Vector{Symbol}
16
18
pars:: Vector
17
19
pars_syms:: Vector{Symbol}
18
- ctx
19
- FunctionalAffect (f, sts, sts_syms, pars, pars_syms, ctx = nothing ) = new (f,sts, sts_syms, pars, pars_syms, ctx)
20
+ ctx:: Any
21
+ function FunctionalAffect (f, sts, sts_syms, pars, pars_syms, ctx = nothing )
22
+ new (f, sts, sts_syms, pars, pars_syms, ctx)
23
+ end
20
24
end
21
25
22
26
function FunctionalAffect (f, sts, pars, ctx = nothing )
@@ -32,7 +36,7 @@ function FunctionalAffect(f, sts, pars, ctx = nothing)
32
36
FunctionalAffect (f, vs, vs_syms, ps, ps_syms, ctx)
33
37
end
34
38
35
- FunctionalAffect (;f, sts, pars, ctx = nothing ) = FunctionalAffect (f, sts, pars, ctx)
39
+ FunctionalAffect (; f, sts, pars, ctx = nothing ) = FunctionalAffect (f, sts, pars, ctx)
36
40
37
41
func (f:: FunctionalAffect ) = f. f
38
42
context (a:: FunctionalAffect ) = a. ctx
@@ -42,9 +46,9 @@ states(a::FunctionalAffect) = a.sts
42
46
states_syms (a:: FunctionalAffect ) = a. sts_syms
43
47
44
48
function Base.:(== )(a1:: FunctionalAffect , a2:: FunctionalAffect )
45
- isequal (a1. f, a2. f) && isequal (a1. sts, a2. sts) && isequal (a1. pars, a2. pars) &&
46
- isequal (a1. sts_syms, a2. sts_syms) && isequal (a1. pars_syms, a2. pars_syms) &&
47
- isequal (a1. ctx, a2. ctx)
49
+ isequal (a1. f, a2. f) && isequal (a1. sts, a2. sts) && isequal (a1. pars, a2. pars) &&
50
+ isequal (a1. sts_syms, a2. sts_syms) && isequal (a1. pars_syms, a2. pars_syms) &&
51
+ isequal (a1. ctx, a2. ctx)
48
52
end
49
53
50
54
function Base. hash (a:: FunctionalAffect , s:: UInt )
@@ -60,12 +64,12 @@ has_functional_affect(cb) = affects(cb) isa FunctionalAffect
60
64
61
65
namespace_affect (affect, s) = namespace_equation (affect, s)
62
66
function namespace_affect (affect:: FunctionalAffect , s)
63
- FunctionalAffect (func (affect),
64
- renamespace .((s,), states (affect)),
65
- states_syms (affect),
66
- renamespace .((s,), parameters (affect)),
67
- parameters_syms (affect),
68
- context (affect))
67
+ FunctionalAffect (func (affect),
68
+ renamespace .((s,), states (affect)),
69
+ states_syms (affect),
70
+ renamespace .((s,), parameters (affect)),
71
+ parameters_syms (affect),
72
+ context (affect))
69
73
end
70
74
71
75
# ################################### continuous events #####################################
@@ -80,7 +84,7 @@ struct SymbolicContinuousCallback
80
84
end
81
85
make_affect (affect) = affect
82
86
make_affect (affect:: Tuple ) = FunctionalAffect (affect... )
83
- make_affect (affect:: NamedTuple ) = FunctionalAffect (;affect... )
87
+ make_affect (affect:: NamedTuple ) = FunctionalAffect (; affect... )
84
88
85
89
function Base.:(== )(e1:: SymbolicContinuousCallback , e2:: SymbolicContinuousCallback )
86
90
isequal (e1. eqs, e2. eqs) && isequal (e1. affect, e2. affect)
@@ -154,28 +158,32 @@ struct SymbolicDiscreteCallback
154
158
# Δts::Vector{Real} - events trigger in this times (Preset)
155
159
# condition::Vector{Equation} - event triggered when condition is true
156
160
# TODO : Iterative
157
- condition
158
- affects
161
+ condition:: Any
162
+ affects:: Any
159
163
160
164
function SymbolicDiscreteCallback (condition, affects = NULL_AFFECT)
161
165
c = scalarize_condition (condition)
162
166
a = scalarize_affects (affects)
163
- new (c,a)
167
+ new (c, a)
164
168
end # Default affect to nothing
165
169
end
166
170
167
171
is_timed_condition (cb) = false
168
- is_timed_condition (:: R ) where {R<: Real } = true
169
- is_timed_condition (:: V ) where {V<: AbstractVector } = eltype (V) <: Real
172
+ is_timed_condition (:: R ) where {R <: Real } = true
173
+ is_timed_condition (:: V ) where {V <: AbstractVector } = eltype (V) <: Real
170
174
is_timed_condition (:: Num ) = false
171
175
is_timed_condition (cb:: SymbolicDiscreteCallback ) = is_timed_condition (condition (cb))
172
176
173
- scalarize_condition (condition) = is_timed_condition (condition) ? condition : value (scalarize (condition))
174
- namespace_condition (condition, s) = is_timed_condition (condition) ? condition : namespace_expr (condition, s)
177
+ function scalarize_condition (condition)
178
+ is_timed_condition (condition) ? condition : value (scalarize (condition))
179
+ end
180
+ function namespace_condition (condition, s)
181
+ is_timed_condition (condition) ? condition : namespace_expr (condition, s)
182
+ end
175
183
176
184
scalarize_affects (affects) = scalarize (affects)
177
185
scalarize_affects (affects:: Tuple ) = FunctionalAffect (affects... )
178
- scalarize_affects (affects:: NamedTuple ) = FunctionalAffect (;affects... )
186
+ scalarize_affects (affects:: NamedTuple ) = FunctionalAffect (; affects... )
179
187
scalarize_affects (affects:: FunctionalAffect ) = affects
180
188
181
189
SymbolicDiscreteCallback (p:: Pair ) = SymbolicDiscreteCallback (p[1 ], p[2 ])
238
246
# ################################ compilation functions ####################################
239
247
240
248
# handles ensuring that affect! functions work with integrator arguments
241
- function add_integrator_header (out= :u )
249
+ function add_integrator_header (out = :u )
242
250
integrator = gensym (:MTKIntegrator )
243
251
244
252
expr -> Func ([DestructuredArgs (expr. args, integrator, inds = [:u , :p , :t ])], [],
250
258
function condition_header ()
251
259
integrator = gensym (:MTKIntegrator )
252
260
expr -> Func ([expr. args[1 ], expr. args[2 ],
253
- DestructuredArgs (expr. args[3 : end ], integrator, inds = [:p ])], [], expr. body)
261
+ DestructuredArgs (expr. args[3 : end ], integrator, inds = [:p ])], [], expr. body)
254
262
end
255
263
256
264
"""
@@ -265,7 +273,6 @@ Notes
265
273
"""
266
274
function compile_condition (cb:: SymbolicDiscreteCallback , sys, dvs, ps;
267
275
expression = Val{true }, kwargs... )
268
-
269
276
u = map (x -> time_varying_as_func (value (x), sys), dvs)
270
277
p = map (x -> time_varying_as_func (value (x), sys), ps)
271
278
t = get_iv (sys)
@@ -416,10 +423,12 @@ function compile_user_affect(affect::FunctionalAffect, sys, dvs, ps; kwargs...)
416
423
417
424
# HACK: filter out eliminated symbols. Not clear this is the right thing to do
418
425
# (MTK should keep these symbols)
419
- u = filter (x -> ! isnothing (x[2 ]), collect (zip (states_syms (affect), v_inds))) |> NamedTuple
420
- p = filter (x -> ! isnothing (x[2 ]), collect (zip (parameters_syms (affect), p_inds))) |> NamedTuple
426
+ u = filter (x -> ! isnothing (x[2 ]), collect (zip (states_syms (affect), v_inds))) |>
427
+ NamedTuple
428
+ p = filter (x -> ! isnothing (x[2 ]), collect (zip (parameters_syms (affect), p_inds))) |>
429
+ NamedTuple
421
430
422
- let u= u, p= p, user_affect= func (affect), ctx= context (affect)
431
+ let u = u, p = p, user_affect = func (affect), ctx = context (affect)
423
432
function (integ)
424
433
user_affect (integ, u, p, ctx)
425
434
end
433
442
function generate_timed_callback (cb, sys, dvs, ps; kwargs... )
434
443
cond = condition (cb)
435
444
as = compile_affect (affects (cb), sys, dvs, ps; expression = Val{false },
436
- kwargs... )
445
+ kwargs... )
437
446
if cond isa AbstractVector
438
447
# Preset Time
439
448
return PresetTimeCallback (cond, as)
@@ -447,15 +456,15 @@ function generate_discrete_callback(cb, sys, dvs, ps; kwargs...)
447
456
if is_timed_condition (cb)
448
457
return generate_timed_callback (cb, sys, dvs, ps, kwargs... )
449
458
else
450
- c = compile_condition (cb, sys, dvs, ps; expression= Val{false }, kwargs... )
459
+ c = compile_condition (cb, sys, dvs, ps; expression = Val{false }, kwargs... )
451
460
as = compile_affect (affects (cb), sys, dvs, ps; expression = Val{false },
452
- kwargs... )
461
+ kwargs... )
453
462
return DiscreteCallback (c, as)
454
463
end
455
464
end
456
465
457
466
function generate_discrete_callbacks (sys:: AbstractSystem , dvs = states (sys),
458
- ps = parameters (sys); kwargs... )
467
+ ps = parameters (sys); kwargs... )
459
468
has_discrete_events (sys) || return nothing
460
469
symcbs = discrete_events (sys)
461
470
isempty (symcbs) && return nothing
0 commit comments