@@ -110,8 +110,13 @@ Contains a single callback whose `condition` is a continuous function. The callb
110
110
`affect!` satisfies the constraints (or else errors). It is not recommended that `NoInit()` is
111
111
used as that will lead to an unstable step following initialization. This warning can be
112
112
ignored for non-DAE ODEs.
113
+
114
+ # Extended help
115
+
116
+ - `discrete_save_idxs`: An iterable of timeseries indexes to save after the callback triggers. MTK-only
117
+ API
113
118
"""
114
- struct ContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R} < :
119
+ struct ContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R, DSI } < :
115
120
AbstractContinuousCallback
116
121
condition:: F1
117
122
affect!:: F2
@@ -127,20 +132,20 @@ struct ContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R} <:
127
132
reltol:: T2
128
133
repeat_nudge:: T3
129
134
initializealg:: T4
135
+ discrete_save_idxs:: DSI
130
136
function ContinuousCallback (condition:: F1 , affect!:: F2 , affect_neg!:: F3 ,
131
137
initialize:: F4 , finalize:: F5 , idxs:: I , rootfind,
132
138
interp_points, save_positions, dtrelax:: R , abstol:: T ,
133
- reltol:: T2 ,
134
- repeat_nudge:: T3 ,
135
- initializealg:: T4 = nothing ) where {F1, F2, F3, F4, F5, T, T2, T3, T4, I, R
139
+ reltol:: T2 , repeat_nudge:: T3 , initializealg:: T4 = nothing ,
140
+ discrete_save_idxs:: DSI = ()) where {F1, F2, F3, F4, F5, T, T2, T3, T4, I, R, DSI
136
141
}
137
142
_condition = prepare_function (condition)
138
- new {typeof(_condition), F2, F3, F4, F5, T, T2, T3, T4, I, R} (_condition,
143
+ new {typeof(_condition), F2, F3, F4, F5, T, T2, T3, T4, I, R, DSI } (_condition,
139
144
affect!, affect_neg!,
140
145
initialize, finalize, idxs, rootfind,
141
146
interp_points,
142
147
BitArray (collect (save_positions)),
143
- dtrelax, abstol, reltol, repeat_nudge, initializealg)
148
+ dtrelax, abstol, reltol, repeat_nudge, initializealg, discrete_save_idxs )
144
149
end
145
150
end
146
151
@@ -154,12 +159,13 @@ function ContinuousCallback(condition, affect!, affect_neg!;
154
159
dtrelax = 1 ,
155
160
abstol = 10 eps (), reltol = 0 ,
156
161
repeat_nudge = 1 // 100 ,
157
- initializealg = nothing )
162
+ initializealg = nothing ,
163
+ discrete_save_idxs = ())
158
164
ContinuousCallback (condition, affect!, affect_neg!, initialize, finalize,
159
165
idxs,
160
166
rootfind, interp_points,
161
167
save_positions,
162
- dtrelax, abstol, reltol, repeat_nudge, initializealg)
168
+ dtrelax, abstol, reltol, repeat_nudge, initializealg, discrete_save_idxs )
163
169
end
164
170
165
171
function ContinuousCallback (condition, affect!;
@@ -172,11 +178,11 @@ function ContinuousCallback(condition, affect!;
172
178
interp_points = 10 ,
173
179
dtrelax = 1 ,
174
180
abstol = 10 eps (), reltol = 0 , repeat_nudge = 1 // 100 ,
175
- initializealg = nothing )
181
+ initializealg = nothing , discrete_save_idxs = () )
176
182
ContinuousCallback (condition, affect!, affect_neg!, initialize, finalize, idxs,
177
183
rootfind, interp_points,
178
184
collect (save_positions),
179
- dtrelax, abstol, reltol, repeat_nudge, initializealg)
185
+ dtrelax, abstol, reltol, repeat_nudge, initializealg, discrete_save_idxs )
180
186
end
181
187
182
188
"""
@@ -219,8 +225,13 @@ multiple events.
219
225
- `len`: Number of callbacks chained. This is compulsory to be specified.
220
226
221
227
Rest of the arguments have the same meaning as in [`ContinuousCallback`](@ref).
228
+
229
+ # Extended help
230
+
231
+ - `discrete_save_idxs`: An iterable of `len` elements, where the `i`th element is an iterable of timeseries
232
+ indexes to save when the `i`th event triggers. MTK-only API.
222
233
"""
223
- struct VectorContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R} < :
234
+ struct VectorContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R, DSI } < :
224
235
AbstractContinuousCallback
225
236
condition:: F1
226
237
affect!:: F2
@@ -237,21 +248,24 @@ struct VectorContinuousCallback{F1, F2, F3, F4, F5, T, T2, T3, T4, I, R} <:
237
248
reltol:: T2
238
249
repeat_nudge:: T3
239
250
initializealg:: T4
251
+ discrete_save_idxs:: DSI
240
252
function VectorContinuousCallback (
241
253
condition:: F1 , affect!:: F2 , affect_neg!:: F3 , len:: Int ,
242
254
initialize:: F4 , finalize:: F5 , idxs:: I , rootfind,
243
255
interp_points, save_positions, dtrelax:: R ,
244
- abstol:: T , reltol:: T2 ,
245
- repeat_nudge :: T3 ,
246
- initializealg :: T4 = nothing ) where {F1, F2, F3, F4, F5, T, T2,
247
- T3, T4, I, R}
256
+ abstol:: T , reltol:: T2 , repeat_nudge :: T3 ,
257
+ initializealg :: T4 = nothing ,
258
+ discrete_save_idxs :: DSI = () ) where {F1, F2, F3, F4, F5, T, T2,
259
+ T3, T4, I, R, DSI }
248
260
_condition = prepare_function (condition)
249
- new {typeof(_condition), F2, F3, F4, F5, T, T2, T3, T4, I, R} (_condition,
261
+ new {typeof(_condition), F2, F3, F4, F5, T, T2, T3, T4, I, R, DSI} (
262
+ _condition,
250
263
affect!, affect_neg!, len,
251
264
initialize, finalize, idxs, rootfind,
252
265
interp_points,
253
266
BitArray (collect (save_positions)),
254
- dtrelax, abstol, reltol, repeat_nudge, initializealg)
267
+ dtrelax, abstol, reltol, repeat_nudge, initializealg,
268
+ discrete_save_idxs)
255
269
end
256
270
end
257
271
@@ -264,13 +278,13 @@ function VectorContinuousCallback(condition, affect!, affect_neg!, len;
264
278
interp_points = 10 ,
265
279
dtrelax = 1 ,
266
280
abstol = 10 eps (), reltol = 0 , repeat_nudge = 1 // 100 ,
267
- initializealg = nothing )
281
+ initializealg = nothing , discrete_save_idxs = () )
268
282
VectorContinuousCallback (condition, affect!, affect_neg!, len,
269
283
initialize, finalize,
270
284
idxs,
271
285
rootfind, interp_points,
272
286
save_positions, dtrelax,
273
- abstol, reltol, repeat_nudge, initializealg)
287
+ abstol, reltol, repeat_nudge, initializealg, discrete_save_idxs )
274
288
end
275
289
276
290
function VectorContinuousCallback (condition, affect!, len;
@@ -283,12 +297,12 @@ function VectorContinuousCallback(condition, affect!, len;
283
297
interp_points = 10 ,
284
298
dtrelax = 1 ,
285
299
abstol = 10 eps (), reltol = 0 , repeat_nudge = 1 // 100 ,
286
- initializealg = nothing )
300
+ initializealg = nothing , discrete_save_idxs = () )
287
301
VectorContinuousCallback (condition, affect!, affect_neg!, len, initialize, finalize,
288
302
idxs,
289
303
rootfind, interp_points,
290
304
collect (save_positions),
291
- dtrelax, abstol, reltol, repeat_nudge, initializealg)
305
+ dtrelax, abstol, reltol, repeat_nudge, initializealg, discrete_save_idxs )
292
306
end
293
307
294
308
"""
@@ -339,31 +353,39 @@ DiscreteCallback(condition, affect!;
339
353
`affect!` satisfies the constraints (or else errors). It is not recommended that `NoInit()` is
340
354
used as that will lead to an unstable step following initialization. This warning can be
341
355
ignored for non-DAE ODEs.
356
+
357
+ # Extended help
358
+
359
+ - `discrete_save_idxs`: An iterable of timeseries indexes to save after the callback triggers. MTK-only
360
+ API
342
361
"""
343
- struct DiscreteCallback{F1, F2, F3, F4, F5} <: AbstractDiscreteCallback
362
+ struct DiscreteCallback{F1, F2, F3, F4, F5, DSI } <: AbstractDiscreteCallback
344
363
condition:: F1
345
364
affect!:: F2
346
365
initialize:: F3
347
366
finalize:: F4
348
367
save_positions:: BitArray{1}
349
368
initializealg:: F5
369
+ discrete_save_idxs:: DSI
350
370
function DiscreteCallback (condition:: F1 , affect!:: F2 ,
351
371
initialize:: F3 , finalize:: F4 ,
352
372
save_positions,
353
- initializealg:: F5 = nothing ) where {F1, F2, F3, F4, F5}
373
+ initializealg:: F5 = nothing ,
374
+ discrete_save_idxs:: DSI = ()) where {F1, F2, F3, F4, F5, DSI}
354
375
_condition = prepare_function (condition)
355
- new {typeof(_condition), F2, F3, F4, F5} (_condition,
376
+ new {typeof(_condition), F2, F3, F4, F5, DSI } (_condition,
356
377
affect!, initialize, finalize,
357
378
BitArray (collect (save_positions)),
358
- initializealg)
379
+ initializealg, discrete_save_idxs )
359
380
end
360
381
end
361
382
function DiscreteCallback (condition, affect!;
362
383
initialize = INITIALIZE_DEFAULT, finalize = FINALIZE_DEFAULT,
363
384
save_positions = (true , true ),
364
- initializealg = nothing )
385
+ initializealg = nothing , discrete_save_idxs = () )
365
386
DiscreteCallback (
366
- condition, affect!, initialize, finalize, save_positions, initializealg)
387
+ condition, affect!, initialize, finalize, save_positions, initializealg,
388
+ discrete_save_idxs)
367
389
end
368
390
369
391
"""
420
442
split_callbacks ((cs... , d. continuous_callbacks... ), (ds... , d. discrete_callbacks... ),
421
443
args... )
422
444
end
445
+
446
+ function save_discretes! (integrator:: DEIntegrator , cb:: Union{ContinuousCallback, DiscreteCallback} ; skip_duplicates = false )
447
+ for idx in cb. discrete_save_idxs
448
+ save_discretes! (integrator, idx; skip_duplicates)
449
+ end
450
+ end
451
+
452
+ function save_discretes! (integrator:: DEIntegrator , cb:: VectorContinuousCallback )
453
+ isempty (cb. discrete_save_idxs) && return
454
+ for idx in eachindex (cb. discrete_save_idxs)
455
+ save_discretes! (integrator, cb, idx; skip_duplicates = true )
456
+ end
457
+ end
458
+
459
+ function save_discretes! (integrator:: DEIntegrator , cb:: VectorContinuousCallback , i; skip_duplicates = false )
460
+ isempty (cb. discrete_save_idxs) && return
461
+ for idx in cb. discrete_save_idxs[i]
462
+ save_discretes! (integrator, idx; skip_duplicates)
463
+ end
464
+ end
465
+
466
+ function _save_all_discretes! (integrator:: DEIntegrator , cb:: DECallback , cbs:: DECallback... )
467
+ save_discretes! (integrator, cb; skip_duplicates = true )
468
+ _save_all_discretes! (integrator, cbs... )
469
+ end
470
+
471
+ _save_all_discretes! (:: DEIntegrator ) = nothing
472
+
473
+ function save_discretes! (integrator:: DEIntegrator , cb:: CallbackSet ; kw... )
474
+ _save_all_discretes! (integrator, cb. continuous_callbacks... , cb. discrete_callbacks... )
475
+ end
0 commit comments