Skip to content

Commit 2eb9674

Browse files
committed
finish SymbolicDiscreteEvent
1 parent 47a257e commit 2eb9674

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/systems/callbacks.jl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,62 @@ function continuous_events(sys::AbstractSystem)
7979
filter(!isempty, cbs)
8080
end
8181

82+
#################################### continuous events #####################################
83+
84+
struct SymbolicDiscreteCallback
85+
condition
86+
affects::Vector{Equation}
87+
function SymbolicDiscreteCallback(condition, affects = NULL_AFFECT)
88+
c = value(scalarize(condition))
89+
a = scalarize(affects)
90+
new(c, a)
91+
end # Default affect to nothing
92+
end
93+
94+
SymbolicDiscreteCallback(p::Pair) = SymbolicDiscreteCallback(p[1], p[2])
95+
SymbolicDiscreteCallback(cb::SymbolicDiscreteCallback) = cb # passthrough
96+
97+
function Base.show(io::IO, db::SymbolicDiscreteCallback)
98+
println(io, "condition: ", db.condition)
99+
println(io, "affects:")
100+
for affect in db.affects
101+
println(io, " ", affect)
102+
end
103+
end
104+
105+
function Base.:(==)(e1::SymbolicDiscreteCallback, e2::SymbolicDiscreteCallback)
106+
isequal(e1.condition, e2.condition) && isequal(e1.affects, e2.affects)
107+
end
108+
function Base.hash(cb::SymbolicDiscreteCallback, s::UInt)
109+
s = foldr(hash, cb.condition, init = s)
110+
foldr(hash, cb.affects, init = s)
111+
end
112+
113+
condition(cb::SymbolicDiscreteCallback) = cb.condition
114+
function conditions(cbs::Vector{<:SymbolicDiscreteCallback})
115+
reduce(vcat, condition(cb) for cb in cbs)
116+
end
117+
118+
affect_equations(cb::SymbolicDiscreteCallback) = cb.affects
119+
function affect_equations(cbs::Vector{SymbolicDiscreteCallback})
120+
reduce(vcat, affect_equations(cb) for cb in cbs)
121+
end
122+
function namespace_equation(cb::SymbolicDiscreteCallback, s)::SymbolicDiscreteCallback
123+
SymbolicDiscreteCallback(namespace_expr(condition(cb), s),
124+
namespace_equation.(affect_equations(cb), Ref(s)))
125+
end
126+
127+
function discrete_events(sys::AbstractSystem)
128+
obs = get_discrete_events(sys)
129+
systems = get_systems(sys)
130+
cbs = [obs;
131+
reduce(vcat,
132+
(map(o -> namespace_equation(o, s), discrete_events(s)) for s in systems),
133+
init = SymbolicDiscreteCallback[])]
134+
filter(!isempty, cbs)
135+
end
136+
137+
82138
################################# compilation functions ####################################
83139

84140
# handles ensuring that affect! functions work with integrator arguments
@@ -91,6 +147,26 @@ function add_integrator_header()
91147
expr.body)
92148
end
93149

150+
"""
151+
compile_condition(cb::SymbolicDiscreteCallback, sys, dvs, ps; expression, kwargs...)
152+
153+
Returns a function `condition(u,p,t)` returning the `condition(cb)`.
154+
155+
Notes
156+
- `expression = Val{true}`, causes the generated function to be returned as an expression.
157+
If set to `Val{false}` a `RuntimeGeneratedFunction` will be returned.
158+
- `kwargs` are passed through to `Symbolics.build_function`.
159+
"""
160+
function compile_condition(cb::SymbolicDiscreteCallback, sys, dvs, ps;
161+
expression = Val{true}, kwargs...)
162+
163+
u = map(x -> time_varying_as_func(value(x), sys), dvs)
164+
p = map(x -> time_varying_as_func(value(x), sys), ps)
165+
t = get_iv(sys)
166+
condit = condition(cb)
167+
build_function(condit, u, p, t; expression, kwargs...)
168+
end
169+
94170
function compile_affect(cb::SymbolicContinuousCallback, args...; kwargs...)
95171
compile_affect(affect_equations(cb), args...; kwargs...)
96172
end

0 commit comments

Comments
 (0)