7878# If called with different functions (which are possible in the Hamiltonian case)
7979# an exception is thrown to avoid silently calculate wrong results.
8080function verify_f2 (f, p, q, pa, t, :: Any ,
81- :: C ) where {C <: Union{HamiltonConstantCache, VerletLeapfrogConstantCache} }
81+ :: C ) where {C <: Union {HamiltonConstantCache, VerletLeapfrogConstantCache,
82+ LeapfrogDriftKickDriftConstantCache}}
8283 f (p, q, pa, t)
8384end
8485function verify_f2 (f, res, p, q, pa, t, :: Any ,
85- :: C ) where {C <: Union{HamiltonMutableCache, VerletLeapfrogCache} }
86+ :: C ) where {C <: Union {HamiltonMutableCache, VerletLeapfrogCache,
87+ LeapfrogDriftKickDriftCache}}
8688 f (res, p, q, pa, t)
8789end
8890
@@ -128,8 +130,8 @@ function store_symp_state!(integrator, ::OrdinaryDiffEqMutableCache, kdu, ku)
128130end
129131
130132function initialize! (integrator,
131- cache:: C ) where {C <: Union {
132- HamiltonMutableCache, VelocityVerletCache, VerletLeapfrogCache }}
133+ cache:: C ) where {C <: Union {HamiltonMutableCache, VelocityVerletCache,
134+ VerletLeapfrogCache, LeapfrogDriftKickDriftCache }}
133135 integrator. kshortsize = 2
134136 resize! (integrator. k, integrator. kshortsize)
135137 integrator. k[1 ] = integrator. fsalfirst
@@ -144,8 +146,8 @@ function initialize!(integrator,
144146end
145147
146148function initialize! (integrator,
147- cache:: C ) where {C <: Union {
148- HamiltonConstantCache, VelocityVerletConstantCache, VerletLeapfrogConstantCache }}
149+ cache:: C ) where {C <: Union {HamiltonConstantCache, VelocityVerletConstantCache,
150+ VerletLeapfrogConstantCache, LeapfrogDriftKickDriftConstantCache }}
149151 integrator. kshortsize = 2
150152 integrator. k = typeof (integrator. k)(undef, integrator. kshortsize)
151153
226228 duprev, uprev, kduprev, _ = load_symp_state (integrator)
227229 du, u, kdu, ku = alloc_symp_state (integrator)
228230
229- # Kick-Drift-Kick scheme of the Verlet Leapfrog method:
231+ # kick-drift-kick scheme of the Leapfrog method:
230232 # update velocity
231233 half = cache. half
232234 @. . broadcast= false du= duprev + dt * half * kduprev
246248 store_symp_state! (integrator, cache, kdu, ku)
247249end
248250
251+ @muladd function perform_step! (integrator, cache:: LeapfrogDriftKickDriftConstantCache ,
252+ repeat_step = false )
253+ @unpack t, dt, f, p = integrator
254+ duprev, uprev, _, _ = load_symp_state (integrator)
255+
256+ # drift-kick-drift scheme of the Leapfrog method, allowing for f1 to depend on v:
257+ # update position half step
258+ half = cache. half
259+ ku = f. f2 (duprev, uprev, p, t)
260+ u = uprev + dt * half * ku
261+
262+ # update velocity half step
263+ kdu = f. f1 (duprev, u, p, t)
264+ du = duprev + dt * half * kdu
265+
266+ # full step
267+ tnew = t + half * dt
268+
269+ # update velocity (add to previous full step velocity)
270+ # note that this extra step is only necessary if f1 depends on v/du (or t)
271+ kdu = f. f1 (du, u, p, tnew)
272+ du = duprev + dt * kdu
273+
274+ # update position (add to half step position)
275+ ku = f. f2 (du, u, p, tnew)
276+ u = u + dt * half * ku
277+
278+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 2 )
279+ integrator. stats. nf2 += 2
280+ store_symp_state! (integrator, cache, du, u, kdu, ku)
281+ end
282+
283+ @muladd function perform_step! (integrator, cache:: LeapfrogDriftKickDriftCache ,
284+ repeat_step = false )
285+ @unpack t, dt, f, p = integrator
286+ duprev, uprev, _, _ = load_symp_state (integrator)
287+ du, u, kdu, ku = alloc_symp_state (integrator)
288+
289+ # drift-kick-drift scheme of the Leapfrog method, allowing for f1 to depend on v:
290+ # update position half step
291+ half = cache. half
292+ f. f2 (ku, duprev, uprev, p, t)
293+ @. . broadcast= false u= uprev + dt * half * ku
294+
295+ # update velocity half step
296+ f. f1 (kdu, duprev, u, p, t)
297+ @. . broadcast= false du= duprev + dt * half * kdu
298+
299+ # full step
300+ tnew = t + half * dt
301+
302+ # update velocity (add to previous full step velocity)
303+ # note that this extra step is only necessary if f1 depends on v/du (or t)
304+ f. f1 (kdu, du, u, p, tnew)
305+ @. . broadcast= false du= duprev + dt * kdu
306+
307+ # update position (add to half step position)
308+ f. f2 (ku, du, u, p, tnew)
309+ @. . broadcast= false u= u + dt * half * ku
310+
311+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 2 )
312+ integrator. stats. nf2 += 2
313+ store_symp_state! (integrator, cache, kdu, ku)
314+ end
315+
249316@muladd function perform_step! (integrator, cache:: Symplectic2ConstantCache ,
250317 repeat_step = false )
251318 @unpack t, dt, f, p = integrator
0 commit comments