@@ -317,7 +317,8 @@ const Affect = Union{AffectSystem, ImperativeAffect}
317317
318318"""
319319 SymbolicContinuousCallback(eqs::Vector{Equation}, affect = nothing, iv = nothing;
320- affect_neg = affect, initialize = nothing, finalize = nothing, rootfind = SciMLBase.LeftRootFind)
320+ affect_neg = affect, initialize = nothing, finalize = nothing,
321+ rootfind = SciMLBase.LeftRootFind, initialize_save_discretes = true)
321322
322323A [`ContinuousCallback`](@ref SciMLBase.ContinuousCallback) specified symbolically. Takes a vector of equations `eq`
323324as well as the positive-edge `affect` and negative-edge `affect_neg` that apply when *any* of `eq` are satisfied.
@@ -364,6 +365,9 @@ and combined with the remaining `Equation`s.
364365- Symbolic affects have reinitialization built in. In this case the algorithm will default to SciMLBase.NoInit(), and should **not** be provided.
365366- Functional and imperative affects will default to SciMLBase.CheckInit(), which will error if the system is not properly reinitialized after the callback. If your system is a DAE, pass in an algorithm like SciMLBase.BrownBasicFullInit() to properly re-initialize.
366367
368+ `initialize_save_discretes` is a flag indicating whether the discrete variables modified by this
369+ callback should be saved at the start of the integration (when the `initialize` runs).
370+
367371Initial and final affects can also be specified identically to positive and negative edge affects. Initialization affects
368372will run as soon as the solver starts, while finalization affects will be executed after termination.
369373"""
@@ -376,6 +380,7 @@ struct SymbolicContinuousCallback <: AbstractCallback
376380 rootfind:: Union{Nothing, SciMLBase.RootfindOpt}
377381 reinitializealg:: SciMLBase.DAEInitializationAlgorithm
378382 zero_crossing_id:: Symbol
383+ initialize_save_discretes:: Bool
379384end
380385
381386function SymbolicContinuousCallback (
@@ -387,6 +392,7 @@ function SymbolicContinuousCallback(
387392 rootfind = SciMLBase. LeftRootFind,
388393 reinitializealg = nothing ,
389394 zero_crossing_id = gensym (),
395+ initialize_save_discretes = true ,
390396 kwargs...
391397 )
392398 conditions = (conditions isa AbstractVector) ? conditions : [conditions]
@@ -408,7 +414,7 @@ function SymbolicContinuousCallback(
408414 SymbolicAffect (initialize; kwargs... ), SymbolicAffect (
409415 finalize; kwargs...
410416 ),
411- rootfind, reinitializealg, zero_crossing_id
417+ rootfind, reinitializealg, zero_crossing_id, initialize_save_discretes
412418 )
413419end # Default affect to nothing
414420
@@ -429,7 +435,8 @@ function complete(cb::SymbolicContinuousCallback; kwargs...)
429435 return SymbolicContinuousCallback (
430436 cb. conditions, make_affect (cb. affect; kwargs... ),
431437 make_affect (cb. affect_neg; kwargs... ), make_affect (cb. initialize; kwargs... ),
432- make_affect (cb. finalize; kwargs... ), cb. rootfind, cb. reinitializealg, cb. zero_crossing_id
438+ make_affect (cb. finalize; kwargs... ), cb. rootfind, cb. reinitializealg,
439+ cb. zero_crossing_id, cb. initialize_save_discretes
433440 )
434441end
435442
@@ -540,12 +547,13 @@ struct SymbolicDiscreteCallback <: AbstractCallback
540547 initialize:: Union{Affect, SymbolicAffect, Nothing}
541548 finalize:: Union{Affect, SymbolicAffect, Nothing}
542549 reinitializealg:: SciMLBase.DAEInitializationAlgorithm
550+ initialize_save_discretes:: Bool
543551end
544552
545553function SymbolicDiscreteCallback (
546554 condition:: Union{SymbolicT, Number, Vector{<:Number}} , affect = nothing ;
547555 initialize = nothing , finalize = nothing ,
548- reinitializealg = nothing , kwargs...
556+ reinitializealg = nothing , initialize_save_discretes = true , kwargs...
549557 )
550558 # Manual error check (to prevent events like `[X < 5.0] => [X ~ Pre(X) + 10.0]` from being created).
551559 (condition isa Vector) && (eltype (condition) <: Num ) &&
@@ -567,7 +575,8 @@ function SymbolicDiscreteCallback(
567575 return SymbolicDiscreteCallback (
568576 c, SymbolicAffect (affect; kwargs... ),
569577 SymbolicAffect (initialize; kwargs... ),
570- SymbolicAffect (finalize; kwargs... ), reinitializealg
578+ SymbolicAffect (finalize; kwargs... ), reinitializealg,
579+ initialize_save_discretes
571580 )
572581end # Default affect to nothing
573582
@@ -588,7 +597,8 @@ function complete(cb::SymbolicDiscreteCallback; kwargs...)
588597 return SymbolicDiscreteCallback (
589598 cb. conditions, make_affect (cb. affect; kwargs... ),
590599 make_affect (cb. initialize; kwargs... ),
591- make_affect (cb. finalize; kwargs... ), cb. reinitializealg
600+ make_affect (cb. finalize; kwargs... ), cb. reinitializealg,
601+ cb. initialize_save_discretes
592602 )
593603end
594604
@@ -809,15 +819,15 @@ function generate_continuous_callbacks(
809819 cbs = continuous_events (sys)
810820 isempty (cbs) && return nothing
811821 cb_classes = Dict{
812- Tuple{SciMLBase. RootfindOpt, SciMLBase. DAEInitializationAlgorithm},
822+ Tuple{SciMLBase. RootfindOpt, SciMLBase. DAEInitializationAlgorithm, Bool },
813823 Vector{SymbolicContinuousCallback},
814824 }()
815825
816826 # Sort the callbacks by their rootfinding method
817827 for cb in cbs
818828 _cbs = get! (
819829 () -> SymbolicContinuousCallback[],
820- cb_classes, (cb. rootfind, cb. reinitializealg)
830+ cb_classes, (cb. rootfind, cb. reinitializealg, cb . initialize_save_discretes )
821831 )
822832 push! (_cbs, cb)
823833 end
@@ -927,7 +937,7 @@ function generate_callback(cbs::Vector{SymbolicContinuousCallback}, sys; kwargs.
927937 return VectorContinuousCallback (
928938 trigger, affect, affect_neg, length (eqs); initialize, finalize,
929939 rootfind = cbs[1 ]. rootfind, initializealg = cbs[1 ]. reinitializealg,
930- saved_clock_partitions
940+ saved_clock_partitions, initialize_save_discretes = cbs[ 1 ] . initialize_save_discretes
931941 )
932942end
933943
@@ -964,23 +974,26 @@ function generate_callback(cb, sys; kwargs...)
964974 if is_timed && conditions (cb) isa AbstractVector
965975 return PresetTimeCallback (
966976 trigger, affect; initialize,
967- finalize, initializealg = cb. reinitializealg, saved_clock_partitions
977+ finalize, initializealg = cb. reinitializealg, saved_clock_partitions,
978+ initialize_save_discretes = cb. initialize_save_discretes
968979 )
969980 elseif is_timed
970981 return PeriodicCallback (
971982 affect, trigger; initialize, finalize, initializealg = cb. reinitializealg,
972- saved_clock_partitions
983+ saved_clock_partitions, initialize_save_discretes = cb . initialize_save_discretes
973984 )
974985 else
975986 return DiscreteCallback (
976987 trigger, affect; initialize,
977- finalize, initializealg = cb. reinitializealg, saved_clock_partitions
988+ finalize, initializealg = cb. reinitializealg, saved_clock_partitions,
989+ initialize_save_discretes = cb. initialize_save_discretes
978990 )
979991 end
980992 else
981993 return ContinuousCallback (
982994 trigger, affect, affect_neg; initialize, finalize,
983- rootfind = cb. rootfind, initializealg = cb. reinitializealg, saved_clock_partitions
995+ rootfind = cb. rootfind, initializealg = cb. reinitializealg, saved_clock_partitions,
996+ initialize_save_discretes = cb. initialize_save_discretes
984997 )
985998 end
986999end
0 commit comments