Skip to content

Commit 49d48b8

Browse files
committed
MutatingFunctionalAffect test cases
1 parent f151e42 commit 49d48b8

File tree

1 file changed

+149
-11
lines changed

1 file changed

+149
-11
lines changed

test/symbolic_events.jl

Lines changed: 149 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,117 @@ affect_neg = [x ~ 1]
227227
@test e[].affect == affect
228228
end
229229

230+
@testset "MutatingFunctionalAffect constructors" begin
231+
fmfa(o, x, i, c) = nothing
232+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa)
233+
@test m isa ModelingToolkit.MutatingFunctionalAffect
234+
@test m.f == fmfa
235+
@test m.obs == []
236+
@test m.obs_syms == []
237+
@test m.modified == []
238+
@test m.mod_syms == []
239+
@test m.ctx === nothing
240+
241+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (;))
242+
@test m isa ModelingToolkit.MutatingFunctionalAffect
243+
@test m.f == fmfa
244+
@test m.obs == []
245+
@test m.obs_syms == []
246+
@test m.modified == []
247+
@test m.mod_syms == []
248+
@test m.ctx === nothing
249+
250+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (; x))
251+
@test m isa ModelingToolkit.MutatingFunctionalAffect
252+
@test m.f == fmfa
253+
@test isequal(m.obs, [x])
254+
@test m.obs_syms == [:x]
255+
@test m.modified == []
256+
@test m.mod_syms == []
257+
@test m.ctx === nothing
258+
259+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (; y=x))
260+
@test m isa ModelingToolkit.MutatingFunctionalAffect
261+
@test m.f == fmfa
262+
@test isequal(m.obs, [x])
263+
@test m.obs_syms == [:y]
264+
@test m.modified == []
265+
@test m.mod_syms == []
266+
@test m.ctx === nothing
267+
268+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa; observed=(; y=x))
269+
@test m isa ModelingToolkit.MutatingFunctionalAffect
270+
@test m.f == fmfa
271+
@test isequal(m.obs, [x])
272+
@test m.obs_syms == [:y]
273+
@test m.modified == []
274+
@test m.mod_syms == []
275+
@test m.ctx === nothing
276+
277+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa; modified=(; x))
278+
@test m isa ModelingToolkit.MutatingFunctionalAffect
279+
@test m.f == fmfa
280+
@test isequal(m.obs, [])
281+
@test m.obs_syms == []
282+
@test isequal(m.modified, [x])
283+
@test m.mod_syms == [:x]
284+
@test m.ctx === nothing
285+
286+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa; modified=(; y=x))
287+
@test m isa ModelingToolkit.MutatingFunctionalAffect
288+
@test m.f == fmfa
289+
@test isequal(m.obs, [])
290+
@test m.obs_syms == []
291+
@test isequal(m.modified, [x])
292+
@test m.mod_syms == [:y]
293+
@test m.ctx === nothing
294+
295+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (; x), (; x))
296+
@test m isa ModelingToolkit.MutatingFunctionalAffect
297+
@test m.f == fmfa
298+
@test isequal(m.obs, [x])
299+
@test m.obs_syms == [:x]
300+
@test isequal(m.modified, [x])
301+
@test m.mod_syms == [:x]
302+
@test m.ctx === nothing
303+
304+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (; y=x), (; y=x))
305+
@test m isa ModelingToolkit.MutatingFunctionalAffect
306+
@test m.f == fmfa
307+
@test isequal(m.obs, [x])
308+
@test m.obs_syms == [:y]
309+
@test isequal(m.modified, [x])
310+
@test m.mod_syms == [:y]
311+
@test m.ctx === nothing
312+
313+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa; modified=(; y=x), observed=(; y=x))
314+
@test m isa ModelingToolkit.MutatingFunctionalAffect
315+
@test m.f == fmfa
316+
@test isequal(m.obs, [x])
317+
@test m.obs_syms == [:y]
318+
@test isequal(m.modified, [x])
319+
@test m.mod_syms == [:y]
320+
@test m.ctx === nothing
321+
322+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa; modified=(; y=x), observed=(; y=x), ctx=3)
323+
@test m isa ModelingToolkit.MutatingFunctionalAffect
324+
@test m.f == fmfa
325+
@test isequal(m.obs, [x])
326+
@test m.obs_syms == [:y]
327+
@test isequal(m.modified, [x])
328+
@test m.mod_syms == [:y]
329+
@test m.ctx === 3
330+
331+
m = ModelingToolkit.MutatingFunctionalAffect(fmfa, (; x), (; x), 3)
332+
@test m isa ModelingToolkit.MutatingFunctionalAffect
333+
@test m.f == fmfa
334+
@test isequal(m.obs, [x])
335+
@test m.obs_syms == [:x]
336+
@test isequal(m.modified, [x])
337+
@test m.mod_syms == [:x]
338+
@test m.ctx === 3
339+
end
340+
230341
##
231342

232343
@named sys = ODESystem(eqs, t, continuous_events = [x ~ 1])
@@ -912,27 +1023,54 @@ end
9121023

9131024
@testset "Quadrature" begin
9141025
@variables theta(t) omega(t)
915-
params = @parameters qA=0 qB=0
1026+
params = @parameters qA=0 qB=0 hA=0 hB=0 cnt=0
9161027
eqs = [
9171028
D(theta) ~ omega
918-
omega ~ sin(0.5*t)
1029+
omega ~ 1.0
9191030
]
920-
qAevt = ModelingToolkit.SymbolicContinuousCallback([cos(1000 * theta) ~ 0],
921-
ModelingToolkit.MutatingFunctionalAffect(modified=(; qA)) do x, o, i, c
1031+
function decoder(oldA, oldB, newA, newB)
1032+
state = (oldA, oldB, newA, newB)
1033+
if state == (0, 0, 1, 0) || state == (1, 0, 1, 1) || state == (1, 1, 0, 1) || state == (0, 1, 0, 0)
1034+
return 1
1035+
elseif state == (0, 0, 0, 1) || state == (0, 1, 1, 1) || state == (1, 1, 1, 0) || state == (1, 0, 0, 0)
1036+
return -1
1037+
elseif state == (0, 0, 0, 0) || state == (0, 1, 0, 1) || state == (1, 0, 1, 0) || state == (1, 1, 1, 1)
1038+
return 0
1039+
else
1040+
return 0 # err is interpreted as no movement
1041+
end
1042+
end
1043+
# todo: warn about dups
1044+
# todo: warn if a variable appears in both observed and modified
1045+
qAevt = ModelingToolkit.SymbolicContinuousCallback([cos(100 * theta) ~ 0],
1046+
ModelingToolkit.MutatingFunctionalAffect((; qB), (; qA, hA, hB, cnt)) do x, o, i, c
1047+
x.hA = x.qA
1048+
x.hB = o.qB
9221049
x.qA = 1
1050+
x.cnt += decoder(x.hA, x.hB, x.qA, o.qB)
9231051
end,
924-
affect_neg = ModelingToolkit.MutatingFunctionalAffect(modified=(; qA)) do x, o, i, c
1052+
affect_neg = ModelingToolkit.MutatingFunctionalAffect((; qB), (; qA, hA, hB, cnt)) do x, o, i, c
1053+
x.hA = x.qA
1054+
x.hB = o.qB
9251055
x.qA = 0
926-
end)
927-
qBevt = ModelingToolkit.SymbolicContinuousCallback([cos(1000 * theta + π/2) ~ 0],
928-
ModelingToolkit.MutatingFunctionalAffect(modified=(; qB)) do x, o, i, c
1056+
x.cnt += decoder(x.hA, x.hB, x.qA, o.qB)
1057+
end; rootfind=SciMLBase.RightRootFind)
1058+
qBevt = ModelingToolkit.SymbolicContinuousCallback([cos(100 * theta - π/2) ~ 0],
1059+
ModelingToolkit.MutatingFunctionalAffect((; qA), (; qB, hA, hB, cnt)) do x, o, i, c
1060+
x.hA = o.qA
1061+
x.hB = x.qB
9291062
x.qB = 1
1063+
x.cnt += decoder(x.hA, x.hB, o.qA, x.qB)
9301064
end,
931-
affect_neg = ModelingToolkit.MutatingFunctionalAffect(modified=(; qB)) do x, o, i, c
1065+
affect_neg = ModelingToolkit.MutatingFunctionalAffect((; qA), (; qB, hA, hB, cnt)) do x, o, i, c
1066+
x.hA = o.qA
1067+
x.hB = x.qB
9321068
x.qB = 0
933-
end)
1069+
x.cnt += decoder(x.hA, x.hB, o.qA, x.qB)
1070+
end; rootfind=SciMLBase.RightRootFind)
9341071
@named sys = ODESystem(eqs, t, [theta, omega], params; continuous_events = [qAevt, qBevt])
9351072
ss = structural_simplify(sys)
936-
prob = ODEProblem(ss, [theta => 0.0], (0.0, 1.0))
1073+
prob = ODEProblem(ss, [theta => 0.0], (0.0, pi))
9371074
sol = solve(prob, Tsit5(); dtmax=0.01)
1075+
@test sol[cnt] == 197 # we get 2 pulses per phase cycle (cos 0 crossing) and we go to 100 cycles; we miss a few due to the initial state
9381076
end

0 commit comments

Comments
 (0)