Skip to content

Commit 33b1d61

Browse files
author
dd
committed
added functional affect component-level testing and fixed issues with cont. events
1 parent 01bf879 commit 33b1d61

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/systems/callbacks.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,20 @@ struct SymbolicContinuousCallback
7575
eqs::Vector{Equation}
7676
affect::Union{Vector{Equation}, FunctionalAffect}
7777
function SymbolicContinuousCallback(eqs::Vector{Equation}, affect = NULL_AFFECT)
78-
new(eqs, affect)
78+
new(eqs, make_affect(affect))
7979
end # Default affect to nothing
8080
end
81+
make_affect(affect) = affect
82+
make_affect(affect::Tuple) = FunctionalAffect(affect...)
83+
make_affect(affect::NamedTuple) = FunctionalAffect(;affect...)
8184

8285
function Base.:(==)(e1::SymbolicContinuousCallback, e2::SymbolicContinuousCallback)
8386
isequal(e1.eqs, e2.eqs) && isequal(e1.affect, e2.affect)
8487
end
8588
Base.isempty(cb::SymbolicContinuousCallback) = isempty(cb.eqs)
8689
function Base.hash(cb::SymbolicContinuousCallback, s::UInt)
8790
s = foldr(hash, cb.eqs, init = s)
88-
foldr(hash, cb.affect, init = s)
91+
cb.affect isa AbstractVector ? foldr(hash, cb.affect, init = s) : hash(cb.affect, s)
8992
end
9093

9194
to_equation_vector(eq::Equation) = [eq]
@@ -116,6 +119,7 @@ equations(cb::SymbolicContinuousCallback) = cb.eqs
116119
function equations(cbs::Vector{<:SymbolicContinuousCallback})
117120
reduce(vcat, [equations(cb) for cb in cbs])
118121
end
122+
119123
affects(cb::SymbolicContinuousCallback) = cb.affect
120124
function affects(cbs::Vector{SymbolicContinuousCallback})
121125
reduce(vcat, [affects(cb) for cb in cbs])
@@ -129,8 +133,6 @@ function namespace_callback(cb::SymbolicContinuousCallback, s)::SymbolicContinuo
129133
namespace_affects(affects(cb), s))
130134
end
131135

132-
cb_add_context(cb::SymbolicContinuousCallback, s) = SymbolicContinuousCallback(equations(cb), af_add_context(affects(cb), s))
133-
134136
function continuous_events(sys::AbstractSystem)
135137
obs = get_continuous_events(sys)
136138
filter(!isempty, obs)

test/funcaffect.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,50 @@ prob = ODEProblem(s2, [resistor.v=> 10.0], (0, 2.01))
8080
sol = solve(prob, Tsit5())
8181
@test ctx[1] == 2
8282

83+
include("../examples/rc_model.jl")
8384

85+
function affect5!(integ, u,p,ctx)
86+
@test integ.u[u.capacitor₊v] 0.3
87+
integ.p[p.C] *= 200
88+
end
89+
90+
@named rc_model = ODESystem(rc_eqs, t, continuous_events=[[capacitor.v ~ 0.3]=>(affect5!, [capacitor.v], [capacitor.C => :C], nothing)])
91+
rc_model = compose(rc_model, [resistor, capacitor, source, ground])
92+
93+
sys = structural_simplify(rc_model)
94+
u0 = [capacitor.v => 0.0
95+
capacitor.p.i => 0.0
96+
resistor.v => 0.0]
97+
98+
prob = ODEProblem(sys, u0, (0, 10.0))
99+
sol = solve(prob, Rodas4())
100+
@test all(sol[rc_model.capacitor.v] .< 0.4)
101+
102+
function affect6!(integ, u,p,ctx)
103+
@test integ.u[u.v] 0.3
104+
integ.p[p.C] *= 200
105+
end
106+
107+
function Capacitor(; name, C = 1.0)
108+
@named oneport = OnePort()
109+
@unpack v, i = oneport
110+
ps = @parameters C = C
111+
D = Differential(t)
112+
eqs = [
113+
D(v) ~ i / C,
114+
]
115+
extend(ODESystem(eqs, t, [], ps; name = name, continuous_events=[[v ~ 0.3]=>(affect6!, [v], [C], nothing)]), oneport)
116+
end
117+
118+
@named capacitor = Capacitor(C = C)
119+
@named rc_model = ODESystem(rc_eqs, t)
120+
rc_model = compose(rc_model, [resistor, capacitor, source, ground])
121+
122+
sys = structural_simplify(rc_model)
123+
u0 = [capacitor.v => 0.0
124+
capacitor.p.i => 0.0
125+
resistor.v => 0.0]
126+
127+
prob = ODEProblem(sys, u0, (0, 10.0))
128+
sol = solve(prob, Rodas4())
129+
@test all(sol[rc_model.capacitor.v] .< 0.4)

0 commit comments

Comments
 (0)