@@ -82,14 +82,24 @@ callback = SplitIntegrationCallback(CarpenterKennedy2N54(williamson_condition=fa
8282│ stage_coupling: ……………………………………… true │
8383│ predict_positions: ……………………………… true │
8484│ dt: ……………………………………………………………………… 1.0 │
85- │ callback: ……………………………………………………… StepsizeCallback(is_constant=true, cfl_number=1.6) │
85+ │ callback: ……………………………………………………… CallbackSet{Tuple{}, Tuple{Discr…pdateAveragedVelocityCallback)) │
8686└──────────────────────────────────────────────────────────────────────────────────────────────────┘
8787```
8888"""
8989function SplitIntegrationCallback (alg; stage_coupling= false , predict_positions= true ,
9090 kwargs... )
91+ # Add lightweight callback to (potentially) update the averaged velocity
92+ # during the split integration.
93+ if haskey (kwargs, :callback )
94+ # Note that `CallbackSet`s can be nested
95+ kwargs = (; kwargs... ,
96+ callback= CallbackSet (values (kwargs). callback,
97+ UpdateAveragedVelocityCallback ()))
98+ else
99+ kwargs = (; kwargs... , callback= UpdateAveragedVelocityCallback ())
100+ end
91101 split_integration_callback = SplitIntegrationCallback (alg, stage_coupling,
92- predict_positions, kwargs)
102+ predict_positions, pairs ( kwargs) )
93103
94104 # The first one is the `condition`, the second the `affect!`
95105 return DiscreteCallback (split_integration_callback, split_integration_callback,
@@ -522,3 +532,53 @@ function Base.show(io::IO, ::MIME"text/plain",
522532 summary_box (io, " SplitIntegrationCallback" , setup)
523533 end
524534end
535+
536+ # === Non-public callback for updating the averaged velocity ===
537+ # When no split integration is used, this is done from the `UpdateCallback`.
538+ # With split integration, we use this lightweight callback to avoid updating the systems.
539+ function UpdateAveragedVelocityCallback ()
540+ # The first one is the `condition`, the second the `affect!`
541+ return DiscreteCallback (update_averaged_velocity_callback!,
542+ update_averaged_velocity_callback!,
543+ initialize= (initialize_averaged_velocity_callback!),
544+ save_positions= (false , false ))
545+ end
546+
547+ # `initialize`
548+ function initialize_averaged_velocity_callback! (cb, vu_ode, t, integrator)
549+ v_ode, u_ode = vu_ode. x
550+ semi = integrator. p. semi
551+
552+ foreach_system (semi) do system
553+ initialize_averaged_velocity! (system, v_ode, semi, t)
554+ end
555+
556+ return cb
557+ end
558+
559+ # `condition`
560+ function update_averaged_velocity_callback! (u, t, integrator)
561+ return true
562+ end
563+
564+ # `affect!`
565+ function update_averaged_velocity_callback! (integrator)
566+ t_new = integrator. t
567+ semi = integrator. p. semi
568+ v_ode, u_ode = integrator. u. x
569+
570+ foreach_system (semi) do system
571+ compute_averaged_velocity! (system, v_ode, semi, t_new)
572+ end
573+
574+ # Tell OrdinaryDiffEq that `integrator.u` has not been modified
575+ u_modified! (integrator, false )
576+
577+ return integrator
578+ end
579+
580+ function Base. show (io:: IO ,
581+ cb:: DiscreteCallback{typeof(update_averaged_velocity_callback!)} )
582+ @nospecialize cb # reduce precompilation time
583+ print (io, " UpdateAveragedVelocityCallback" )
584+ end
0 commit comments