Skip to content

Commit 7ab6da5

Browse files
committed
improve performance of callback set creation
1 parent 2d87eab commit 7ab6da5

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

docs/src/callbacks.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ as a general reference.
1111
This page is introducing the general concepts, for a hands on example of a simulation with callbacks
1212
refer to the [Cascading Failure](@ref) example.
1313

14+
!!! warning
15+
The `ODEProblem` contains a reference to exactly one copy of the *flat parameter array*.
16+
If you use callbacks to change those parameters (as we often do), it is advised to
17+
`copy` the parameter array before passing it to the ODEProblem!
18+
Also, this means you need to be careful when using the same `prob` for multiple subsequent
19+
`solve` calls, as the initial state of the `prob` object might have changed!
1420

1521
## Component-based Callback functions
1622
In practice, events often act locally, meaning they only depend and act on a

src/callbacks.jl

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,21 @@ function get_callbacks(nw::Network)
209209
elseif length(cbbs) == 1
210210
return to_callback(only(cbbs))
211211
else
212-
CallbackSet(to_callback.(cbbs)...)
212+
# we split in discrete and continous manually, otherwise the CallbackSet
213+
# construction can take forever
214+
discrete_cb = []
215+
continous_cb = []
216+
for batch in cbbs
217+
cb = to_callback(batch)
218+
if cb isa SciMLBase.AbstractContinuousCallback
219+
push!(continous_cb, cb)
220+
elseif cb isa SciMLBase.AbstractDiscreteCallback
221+
push!(discrete_cb, cb)
222+
else
223+
error("Unknown callback type, should never be reached. Please report this issue.")
224+
end
225+
end
226+
CallbackSet(Tuple(continous_cb), Tuple(discrete_cb));
213227
end
214228
end
215229

@@ -443,15 +457,15 @@ end
443457
####
444458
#### wrapping of discrete callbacks
445459
####
446-
struct DiscreteCallbackWrapper{N,ST,T} <: CallbackWrapper
447-
nw::N
460+
struct DiscreteCallbackWrapper{ST,T} <: CallbackWrapper
461+
nw::Network
448462
component::ST
449463
callback::T
450464
function DiscreteCallbackWrapper(nw, component, callback)
451465
@assert nw isa Network
452466
@assert component isa SymbolicIndex
453467
@assert callback isa Union{DiscreteComponentCallback, PresetTimeComponentCallback}
454-
new{typeof(nw),typeof(component),typeof(callback)}(nw, component, callback)
468+
new{typeof(component),typeof(callback)}(nw, component, callback)
455469
end
456470
end
457471

@@ -463,7 +477,7 @@ function to_callback(dcw::DiscreteCallbackWrapper)
463477
DiscreteCallback(cond, affect; kwargs...)
464478
end
465479
# generate a PresetTimeCallback from a DiscreteCallbackWrapper
466-
function to_callback(dcw::DiscreteCallbackWrapper{<:Any,<:Any,<:PresetTimeComponentCallback})
480+
function to_callback(dcw::DiscreteCallbackWrapper{<:Any,<:PresetTimeComponentCallback})
467481
kwargs = dcw.callback.kwargs
468482
affect = _batch_affect(dcw)
469483
ts = dcw.callback.ts

0 commit comments

Comments
 (0)