7777# f.f2(p, q, pa, t) = p which is the Newton/Lagrange equations
7878# If called with different functions (which are possible in the Hamiltonian case)
7979# an exception is thrown to avoid silently calculate wrong results.
80- verify_f2 (f, p, q, pa, t, :: Any , :: C ) where {C <: HamiltonConstantCache } = f (p, q, pa, t)
81- function verify_f2 (f, res, p, q, pa, t, :: Any , :: C ) where {C <: HamiltonMutableCache }
80+ function verify_f2 (f, p, q, pa, t, :: Any ,
81+ :: C ) where {C <: Union{HamiltonConstantCache, VerletLeapfrogConstantCache} }
82+ f (p, q, pa, t)
83+ end
84+ function verify_f2 (f, res, p, q, pa, t, :: Any ,
85+ :: C ) where {C <: Union{HamiltonMutableCache, VerletLeapfrogCache} }
8286 f (res, p, q, pa, t)
8387end
8488
@@ -124,8 +128,8 @@ function store_symp_state!(integrator, ::OrdinaryDiffEqMutableCache, kdu, ku)
124128end
125129
126130function initialize! (integrator,
127- cache:: C ) where {C < :
128- Union{ HamiltonMutableCache, VelocityVerletCache}}
131+ cache:: C ) where {C <: Union {
132+ HamiltonMutableCache, VelocityVerletCache, VerletLeapfrogCache }}
129133 integrator. kshortsize = 2
130134 resize! (integrator. k, integrator. kshortsize)
131135 integrator. k[1 ] = integrator. fsalfirst
@@ -140,9 +144,8 @@ function initialize!(integrator,
140144end
141145
142146function initialize! (integrator,
143- cache:: C ) where {
144- C < :
145- Union{HamiltonConstantCache, VelocityVerletConstantCache}}
147+ cache:: C ) where {C <: Union {
148+ HamiltonConstantCache, VelocityVerletConstantCache, VerletLeapfrogConstantCache}}
146149 integrator. kshortsize = 2
147150 integrator. k = typeof (integrator. k)(undef, integrator. kshortsize)
148151
171174 # v(t+Δt) = v(t) + 1/2*(a(t)+a(t+Δt))*Δt
172175 du = duprev + dt * (half * ku + half * kdu)
173176
174- OrdinaryDiffEqCore. increment_nf! (integrator. stats, 2 )
177+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 1 )
175178 store_symp_state! (integrator, cache, du, u, kdu, du)
176179end
177180
@@ -186,13 +189,63 @@ end
186189 half = cache. half
187190 @. . broadcast= false u= uprev + dt * duprev + dtsq * (half * ku)
188191 f. f1 (kdu, duprev, u, p, t + dt)
189- OrdinaryDiffEqCore. increment_nf! (integrator. stats, 2 )
192+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 1 )
190193 # v(t+Δt) = v(t) + 1/2*(a(t)+a(t+Δt))*Δt
191194 @. . broadcast= false du= duprev + dt * (half * ku + half * kdu)
192195
193196 store_symp_state! (integrator, cache, kdu, du)
194197end
195198
199+ @muladd function perform_step! (integrator, cache:: VerletLeapfrogConstantCache ,
200+ repeat_step = false )
201+ @unpack t, dt, f, p = integrator
202+ duprev, uprev, kduprev, _ = load_symp_state (integrator)
203+
204+ # kick-drift-kick scheme of the Leapfrog method:
205+ # update velocity
206+ half = cache. half
207+ du = duprev + dt * half * kduprev
208+
209+ # update position
210+ tnew = t + half * dt
211+ ku = f. f2 (du, uprev, p, tnew)
212+ u = uprev + dt * ku
213+
214+ # update velocity
215+ tnew = tnew + half * dt
216+ kdu = f. f1 (du, u, p, tnew)
217+ du = du + dt * half * kdu
218+
219+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 1 )
220+ integrator. stats. nf2 += 1
221+ store_symp_state! (integrator, cache, du, u, kdu, ku)
222+ end
223+
224+ @muladd function perform_step! (integrator, cache:: VerletLeapfrogCache , repeat_step = false )
225+ @unpack t, dt, f, p = integrator
226+ duprev, uprev, kduprev, _ = load_symp_state (integrator)
227+ du, u, kdu, ku = alloc_symp_state (integrator)
228+
229+ # Kick-Drift-Kick scheme of the Verlet Leapfrog method:
230+ # update velocity
231+ half = cache. half
232+ @. . broadcast= false du= duprev + dt * half * kduprev
233+
234+ # update position
235+ tnew = t + half * dt
236+ f. f2 (ku, du, uprev, p, tnew)
237+ @. . broadcast= false u= uprev + dt * ku
238+
239+ # update velocity
240+ tnew = tnew + half * dt
241+ f. f1 (kdu, du, u, p, tnew)
242+ @. . broadcast= false du= du + dt * half * kdu
243+
244+ OrdinaryDiffEqCore. increment_nf! (integrator. stats, 1 )
245+ integrator. stats. nf2 += 1
246+ store_symp_state! (integrator, cache, kdu, ku)
247+ end
248+
196249@muladd function perform_step! (integrator, cache:: Symplectic2ConstantCache ,
197250 repeat_step = false )
198251 @unpack t, dt, f, p = integrator
0 commit comments