|
1 | 1 | abstract type AbstractCallback end |
2 | 2 |
|
3 | | -struct FunctionalAffect |
4 | | - f::Any |
5 | | - sts::Vector |
6 | | - sts_syms::Vector{Symbol} |
7 | | - pars::Vector |
8 | | - pars_syms::Vector{Symbol} |
9 | | - discretes::Vector |
10 | | - ctx::Any |
11 | | -end |
12 | | - |
13 | | -function FunctionalAffect(f, sts, pars, discretes, ctx = nothing) |
14 | | - # sts & pars contain either pairs: resistor.R => R, or Syms: R |
15 | | - vs = [x isa Pair ? x.first : x for x in sts] |
16 | | - vs_syms = Symbol[x isa Pair ? Symbol(x.second) : getname(x) for x in sts] |
17 | | - length(vs_syms) == length(unique(vs_syms)) || error("Variables are not unique") |
18 | | - |
19 | | - ps = [x isa Pair ? x.first : x for x in pars] |
20 | | - ps_syms = Symbol[x isa Pair ? Symbol(x.second) : getname(x) for x in pars] |
21 | | - length(ps_syms) == length(unique(ps_syms)) || error("Parameters are not unique") |
22 | | - |
23 | | - FunctionalAffect(f, vs, vs_syms, ps, ps_syms, discretes, ctx) |
24 | | -end |
25 | | - |
26 | | -function FunctionalAffect(; f, sts, pars, discretes, ctx = nothing) |
27 | | - FunctionalAffect(f, sts, pars, discretes, ctx) |
28 | | -end |
29 | | - |
30 | | -func(a::FunctionalAffect) = a.f |
31 | | -context(a::FunctionalAffect) = a.ctx |
32 | | -parameters(a::FunctionalAffect) = a.pars |
33 | | -parameters_syms(a::FunctionalAffect) = a.pars_syms |
34 | | -unknowns(a::FunctionalAffect) = a.sts |
35 | | -unknowns_syms(a::FunctionalAffect) = a.sts_syms |
36 | | -discretes(a::FunctionalAffect) = a.discretes |
37 | | - |
38 | | -function Base.:(==)(a1::FunctionalAffect, a2::FunctionalAffect) |
39 | | - isequal(a1.f, a2.f) && isequal(a1.sts, a2.sts) && isequal(a1.pars, a2.pars) && |
40 | | - isequal(a1.sts_syms, a2.sts_syms) && isequal(a1.pars_syms, a2.pars_syms) && |
41 | | - isequal(a1.ctx, a2.ctx) |
42 | | -end |
43 | | - |
44 | | -function Base.hash(a::FunctionalAffect, s::UInt) |
45 | | - s = hash(a.f, s) |
46 | | - s = hash(a.sts, s) |
47 | | - s = hash(a.sts_syms, s) |
48 | | - s = hash(a.pars, s) |
49 | | - s = hash(a.pars_syms, s) |
50 | | - s = hash(a.discretes, s) |
51 | | - hash(a.ctx, s) |
52 | | -end |
53 | | - |
54 | 3 | function has_functional_affect(cb) |
55 | | - (affects(cb) isa FunctionalAffect || affects(cb) isa ImperativeAffect) |
| 4 | + affects(cb) isa ImperativeAffect |
56 | 5 | end |
57 | 6 |
|
58 | 7 | struct AffectSystem |
@@ -97,7 +46,7 @@ function Base.hash(a::AffectSystem, s::UInt) |
97 | 46 | hash(aff_to_sys(a), s) |
98 | 47 | end |
99 | 48 |
|
100 | | -function vars!(vars, aff::Union{FunctionalAffect, AffectSystem}; op = Differential) |
| 49 | +function vars!(vars, aff::AffectSystem; op = Differential) |
101 | 50 | for var in Iterators.flatten((unknowns(aff), parameters(aff), discretes(aff))) |
102 | 51 | vars!(vars, var) |
103 | 52 | end |
|
161 | 110 | ############################### |
162 | 111 | ###### Continuous events ###### |
163 | 112 | ############################### |
164 | | -const Affect = Union{AffectSystem, FunctionalAffect, ImperativeAffect} |
| 113 | +const Affect = Union{AffectSystem, ImperativeAffect} |
165 | 114 |
|
166 | 115 | """ |
167 | 116 | SymbolicContinuousCallback(eqs::Vector{Equation}, affect = nothing, iv = nothing; |
@@ -233,7 +182,7 @@ struct SymbolicContinuousCallback <: AbstractCallback |
233 | 182 | conditions = (conditions isa AbstractVector) ? conditions : [conditions] |
234 | 183 |
|
235 | 184 | if isnothing(reinitializealg) |
236 | | - if any(a -> (a isa FunctionalAffect || a isa ImperativeAffect), |
| 185 | + if any(a -> a isa ImperativeAffect, |
237 | 186 | [affect, affect_neg, initialize, finalize]) |
238 | 187 | reinitializealg = SciMLBase.CheckInit() |
239 | 188 | else |
@@ -263,8 +212,8 @@ function SymbolicContinuousCallback(cb::Tuple, args...; kwargs...) |
263 | 212 | end |
264 | 213 |
|
265 | 214 | make_affect(affect::Nothing; kwargs...) = nothing |
266 | | -make_affect(affect::Tuple; kwargs...) = FunctionalAffect(affect...) |
267 | | -make_affect(affect::NamedTuple; kwargs...) = FunctionalAffect(; affect...) |
| 215 | +make_affect(affect::Tuple; kwargs...) = ImperativeAffect(affect...) |
| 216 | +make_affect(affect::NamedTuple; kwargs...) = ImperativeAffect(; affect...) |
268 | 217 | make_affect(affect::Affect; kwargs...) = affect |
269 | 218 |
|
270 | 219 | function make_affect(affect::Vector{Equation}; discrete_parameters = Any[], |
@@ -446,7 +395,7 @@ struct SymbolicDiscreteCallback <: AbstractCallback |
446 | 395 | c = is_timed_condition(condition) ? condition : value(scalarize(condition)) |
447 | 396 |
|
448 | 397 | if isnothing(reinitializealg) |
449 | | - if any(a -> (a isa FunctionalAffect || a isa ImperativeAffect), |
| 398 | + if any(a -> a isa ImperativeAffect, |
450 | 399 | [affect, initialize, finalize]) |
451 | 400 | reinitializealg = SciMLBase.CheckInit() |
452 | 401 | else |
|
498 | 447 | ############################################ |
499 | 448 | ########## Namespacing Utilities ########### |
500 | 449 | ############################################ |
501 | | -function namespace_affects(affect::FunctionalAffect, s) |
502 | | - FunctionalAffect(func(affect), |
503 | | - renamespace.((s,), unknowns(affect)), |
504 | | - unknowns_syms(affect), |
505 | | - renamespace.((s,), parameters(affect)), |
506 | | - parameters_syms(affect), |
507 | | - renamespace.((s,), discretes(affect)), |
508 | | - context(affect)) |
509 | | -end |
510 | | - |
511 | 450 | function namespace_affects(affect::AffectSystem, s) |
512 | 451 | AffectSystem(renamespace(s, system(affect)), |
513 | 452 | renamespace.((s,), unknowns(affect)), |
@@ -652,36 +591,6 @@ function compile_condition( |
652 | 591 | return CompiledCondition{is_discrete(cbs)}(fs) |
653 | 592 | end |
654 | 593 |
|
655 | | -""" |
656 | | -Compile user-defined functional affect. |
657 | | -""" |
658 | | -function compile_functional_affect(affect::FunctionalAffect, sys; kwargs...) |
659 | | - dvs = unknowns(sys) |
660 | | - ps = parameters(sys) |
661 | | - dvs_ind = Dict(reverse(en) for en in enumerate(dvs)) |
662 | | - v_inds = map(sym -> dvs_ind[sym], unknowns(affect)) |
663 | | - |
664 | | - if has_index_cache(sys) && (ic = get_index_cache(sys)) !== nothing |
665 | | - p_inds = [(pind = parameter_index(sys, sym)) === nothing ? sym : pind |
666 | | - for sym in parameters(affect)] |
667 | | - else |
668 | | - ps_ind = Dict(reverse(en) for en in enumerate(ps)) |
669 | | - p_inds = map(sym -> get(ps_ind, sym, sym), parameters(affect)) |
670 | | - end |
671 | | - # HACK: filter out eliminated symbols. Not clear this is the right thing to do |
672 | | - # (MTK should keep these symbols) |
673 | | - u = filter(x -> !isnothing(x[2]), collect(zip(unknowns_syms(affect), v_inds))) |> |
674 | | - NamedTuple |
675 | | - p = filter(x -> !isnothing(x[2]), collect(zip(parameters_syms(affect), p_inds))) |> |
676 | | - NamedTuple |
677 | | - |
678 | | - let u = u, p = p, user_affect = func(affect), ctx = context(affect) |
679 | | - (integ) -> begin |
680 | | - user_affect(integ, u, p, ctx) |
681 | | - end |
682 | | - end |
683 | | -end |
684 | | - |
685 | 594 | is_discrete(cb::AbstractCallback) = cb isa SymbolicDiscreteCallback |
686 | 595 | is_discrete(cb::Vector{<:AbstractCallback}) = eltype(cb) isa SymbolicDiscreteCallback |
687 | 596 |
|
@@ -837,7 +746,7 @@ function compile_affect( |
837 | 746 | elseif aff isa AffectSystem |
838 | 747 | f = compile_equational_affect(aff, sys; kwargs...) |
839 | 748 | wrap_save_discretes(f, save_idxs) |
840 | | - elseif aff isa FunctionalAffect || aff isa ImperativeAffect |
| 749 | + elseif aff isa ImperativeAffect |
841 | 750 | f = compile_functional_affect(aff, sys; kwargs...) |
842 | 751 | wrap_save_discretes(f, save_idxs) |
843 | 752 | end |
|
0 commit comments