Skip to content

Commit e574b7c

Browse files
author
Your Name
committed
LowStorageRK: unify 3Sp + 3SpFSAL families on generic perform_step
1 parent 4a3802c commit e574b7c

2 files changed

Lines changed: 167 additions & 179 deletions

File tree

lib/OrdinaryDiffEqLowStorageRK/src/generic_low_storage_perform_step.jl

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,158 @@ end
137137
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
138138
return nothing
139139
end
140+
141+
@muladd function _perform_step_oop!(integrator, tab::LowStorageRK3SpConstantCache)
142+
(; t, dt, uprev, u, f, p) = integrator
143+
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end) = tab
144+
145+
integrator.fsalfirst = f(uprev, p, t)
146+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
147+
integrator.k[1] = integrator.fsalfirst
148+
tmp = uprev
149+
u = tmp + β1 * dt * integrator.fsalfirst
150+
utilde = u
151+
if integrator.opts.adaptive
152+
utilde = bhat1 * dt * integrator.fsalfirst
153+
end
154+
155+
for i in eachindex(γ12end)
156+
k = f(u, p, t + c2end[i] * dt)
157+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
158+
tmp = tmp + δ2end[i] * u
159+
u = γ12end[i] * u + γ22end[i] * tmp + γ32end[i] * uprev + β2end[i] * dt * k
160+
if integrator.opts.adaptive
161+
utilde = utilde + bhat2end[i] * dt * k
162+
end
163+
end
164+
165+
if integrator.opts.adaptive
166+
atmp = calculate_residuals(
167+
utilde, uprev, u, integrator.opts.abstol,
168+
integrator.opts.reltol, integrator.opts.internalnorm, t
169+
)
170+
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
171+
end
172+
173+
integrator.u = u
174+
return nothing
175+
end
176+
177+
@muladd function _perform_step_iip!(integrator, cache, tab::LowStorageRK3SpConstantCache)
178+
(; t, dt, uprev, u, f, p) = integrator
179+
(; k, tmp, utilde, atmp, stage_limiter!, step_limiter!, thread) = cache
180+
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end) = tab
181+
182+
f(integrator.fsalfirst, uprev, p, t)
183+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
184+
@.. broadcast = false thread = thread tmp = uprev
185+
@.. broadcast = false thread = thread u = tmp + β1 * dt * integrator.fsalfirst
186+
if integrator.opts.adaptive
187+
@.. broadcast = false thread = thread utilde = bhat1 * dt * integrator.fsalfirst
188+
end
189+
190+
for i in eachindex(γ12end)
191+
stage_limiter!(u, integrator, p, t + c2end[i] * dt)
192+
f(k, u, p, t + c2end[i] * dt)
193+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
194+
@.. broadcast = false thread = thread tmp = tmp + δ2end[i] * u
195+
@.. broadcast = false thread = thread u = γ12end[i] * u + γ22end[i] * tmp +
196+
γ32end[i] * uprev + β2end[i] * dt * k
197+
if integrator.opts.adaptive
198+
@.. broadcast = false thread = thread utilde = utilde + bhat2end[i] * dt * k
199+
end
200+
end
201+
202+
stage_limiter!(u, integrator, p, t + dt)
203+
step_limiter!(u, integrator, p, t + dt)
204+
205+
if integrator.opts.adaptive
206+
calculate_residuals!(
207+
atmp, utilde, uprev, u, integrator.opts.abstol,
208+
integrator.opts.reltol, integrator.opts.internalnorm, t,
209+
thread
210+
)
211+
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
212+
end
213+
return nothing
214+
end
215+
216+
@muladd function _perform_step_oop!(integrator, tab::LowStorageRK3SpFSALConstantCache)
217+
(; t, dt, uprev, u, f, p) = integrator
218+
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end, bhatfsal) = tab
219+
220+
tmp = uprev
221+
u = tmp + β1 * dt * integrator.fsalfirst
222+
utilde = u
223+
if integrator.opts.adaptive
224+
utilde = bhat1 * dt * integrator.fsalfirst
225+
end
226+
227+
for i in eachindex(γ12end)
228+
k = f(u, p, t + c2end[i] * dt)
229+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
230+
tmp = tmp + δ2end[i] * u
231+
u = γ12end[i] * u + γ22end[i] * tmp + γ32end[i] * uprev + β2end[i] * dt * k
232+
if integrator.opts.adaptive
233+
utilde = utilde + bhat2end[i] * dt * k
234+
end
235+
end
236+
237+
integrator.fsallast = f(u, p, t + dt)
238+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
239+
240+
if integrator.opts.adaptive
241+
utilde = utilde + bhatfsal * dt * integrator.fsallast
242+
atmp = calculate_residuals(
243+
utilde, uprev, u, integrator.opts.abstol,
244+
integrator.opts.reltol, integrator.opts.internalnorm, t
245+
)
246+
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
247+
end
248+
249+
integrator.k[1] = integrator.fsalfirst
250+
integrator.k[2] = integrator.fsallast
251+
integrator.u = u
252+
return nothing
253+
end
254+
255+
@muladd function _perform_step_iip!(integrator, cache, tab::LowStorageRK3SpFSALConstantCache)
256+
(; t, dt, uprev, u, f, p) = integrator
257+
(; k, tmp, utilde, atmp, stage_limiter!, step_limiter!, thread) = cache
258+
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end, bhatfsal) = tab
259+
260+
@.. broadcast = false thread = thread tmp = uprev
261+
@.. broadcast = false thread = thread u = tmp + β1 * dt * integrator.fsalfirst
262+
if integrator.opts.adaptive
263+
@.. broadcast = false thread = thread utilde = bhat1 * dt * integrator.fsalfirst
264+
end
265+
266+
for i in eachindex(γ12end)
267+
stage_limiter!(u, integrator, p, t + c2end[i] * dt)
268+
f(k, u, p, t + c2end[i] * dt)
269+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
270+
@.. broadcast = false thread = thread tmp = tmp + δ2end[i] * u
271+
@.. broadcast = false thread = thread u = γ12end[i] * u + γ22end[i] * tmp +
272+
γ32end[i] * uprev + β2end[i] * dt * k
273+
if integrator.opts.adaptive
274+
@.. broadcast = false thread = thread utilde = utilde + bhat2end[i] * dt * k
275+
end
276+
end
277+
278+
stage_limiter!(u, integrator, p, t + dt)
279+
step_limiter!(u, integrator, p, t + dt)
280+
281+
f(k, u, p, t + dt)
282+
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
283+
284+
if integrator.opts.adaptive
285+
@.. broadcast = false thread = thread utilde = utilde + bhatfsal * dt * k
286+
calculate_residuals!(
287+
atmp, utilde, uprev, u, integrator.opts.abstol,
288+
integrator.opts.reltol, integrator.opts.internalnorm, t,
289+
thread
290+
)
291+
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
292+
end
293+
return nothing
294+
end

lib/OrdinaryDiffEqLowStorageRK/src/low_storage_rk_perform_step.jl

Lines changed: 12 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -77,223 +77,56 @@ function perform_step!(integrator, cache::LowStorageRK3SCache, repeat_step = fal
7777
return _perform_step_iip!(integrator, cache, cache.tab)
7878
end
7979

80-
# 3S+ low storage methods: 3S methods adding another memory location for the embedded method (non-FSAL version)
8180
function initialize!(integrator, cache::LowStorageRK3SpConstantCache)
82-
integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal
81+
integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t)
8382
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
8483
integrator.kshortsize = 1
8584
integrator.k = typeof(integrator.k)(undef, integrator.kshortsize)
86-
87-
# Avoid undefined entries if k is an array of arrays
8885
integrator.fsallast = zero(integrator.fsalfirst)
8986
return integrator.k[1] = integrator.fsalfirst
9087
end
9188

92-
@muladd function perform_step!(
93-
integrator, cache::LowStorageRK3SpConstantCache,
94-
repeat_step = false
95-
)
96-
(; t, dt, uprev, u, f, p) = integrator
97-
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end) = cache
98-
99-
# u1
100-
integrator.fsalfirst = f(uprev, p, t)
101-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
102-
integrator.k[1] = integrator.fsalfirst
103-
tmp = uprev
104-
u = tmp + β1 * dt * integrator.fsalfirst
105-
# Initialize utilde for JET
106-
utilde = u
107-
if integrator.opts.adaptive
108-
utilde = bhat1 * dt * integrator.fsalfirst
109-
end
110-
111-
# other stages
112-
for i in eachindex(γ12end)
113-
k = f(u, p, t + c2end[i] * dt)
114-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
115-
tmp = tmp + δ2end[i] * u
116-
u = γ12end[i] * u + γ22end[i] * tmp + γ32end[i] * uprev + β2end[i] * dt * k
117-
if integrator.opts.adaptive
118-
utilde = utilde + bhat2end[i] * dt * k
119-
end
120-
end
121-
122-
if integrator.opts.adaptive
123-
atmp = calculate_residuals(
124-
utilde, uprev, u, integrator.opts.abstol,
125-
integrator.opts.reltol, integrator.opts.internalnorm, t
126-
)
127-
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
128-
end
129-
130-
integrator.u = u
89+
function perform_step!(integrator, cache::LowStorageRK3SpConstantCache, repeat_step = false)
90+
return _perform_step_oop!(integrator, cache)
13191
end
13292

13393
function initialize!(integrator, cache::LowStorageRK3SpCache)
134-
(; k, fsalfirst) = cache
135-
13694
integrator.kshortsize = 1
13795
resize!(integrator.k, integrator.kshortsize)
13896
return integrator.k[1] = integrator.fsalfirst
13997
end
14098

141-
@muladd function perform_step!(integrator, cache::LowStorageRK3SpCache, repeat_step = false)
142-
(; t, dt, uprev, u, f, p) = integrator
143-
(; k, tmp, utilde, atmp, stage_limiter!, step_limiter!, thread) = cache
144-
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end) = cache.tab
145-
146-
# u1
147-
f(integrator.fsalfirst, uprev, p, t)
148-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
149-
@.. broadcast = false thread = thread tmp = uprev
150-
@.. broadcast = false thread = thread u = tmp + β1 * dt * integrator.fsalfirst
151-
if integrator.opts.adaptive
152-
@.. broadcast = false thread = thread utilde = bhat1 * dt * integrator.fsalfirst
153-
end
154-
155-
# other stages
156-
for i in eachindex(γ12end)
157-
stage_limiter!(u, integrator, p, t + c2end[i] * dt)
158-
f(k, u, p, t + c2end[i] * dt)
159-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
160-
@.. broadcast = false thread = thread tmp = tmp + δ2end[i] * u
161-
@.. broadcast = false thread = thread u = γ12end[i] * u + γ22end[i] * tmp +
162-
γ32end[i] * uprev + β2end[i] * dt * k
163-
if integrator.opts.adaptive
164-
@.. broadcast = false thread = thread utilde = utilde + bhat2end[i] * dt * k
165-
end
166-
end
167-
168-
stage_limiter!(u, integrator, p, t + dt)
169-
step_limiter!(u, integrator, p, t + dt)
170-
171-
if integrator.opts.adaptive
172-
calculate_residuals!(
173-
atmp, utilde, uprev, u, integrator.opts.abstol,
174-
integrator.opts.reltol, integrator.opts.internalnorm, t,
175-
thread
176-
)
177-
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
178-
end
99+
function perform_step!(integrator, cache::LowStorageRK3SpCache, repeat_step = false)
100+
return _perform_step_iip!(integrator, cache, cache.tab)
179101
end
180102

181-
# 3S+ FSAL low storage methods: 3S methods adding another memory location for the embedded method (FSAL version)
182103
function initialize!(integrator, cache::LowStorageRK3SpFSALConstantCache)
183-
integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal
104+
integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t)
184105
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
185106
integrator.kshortsize = 2
186107
integrator.k = typeof(integrator.k)(undef, integrator.kshortsize)
187-
188-
# Avoid undefined entries if k is an array of arrays
189108
integrator.fsallast = zero(integrator.fsalfirst)
190109
integrator.k[1] = integrator.fsalfirst
191110
return integrator.k[2] = integrator.fsallast
192111
end
193112

194-
@muladd function perform_step!(
195-
integrator, cache::LowStorageRK3SpFSALConstantCache,
196-
repeat_step = false
113+
function perform_step!(
114+
integrator, cache::LowStorageRK3SpFSALConstantCache, repeat_step = false
197115
)
198-
(; t, dt, uprev, u, f, p) = integrator
199-
(; γ12end, γ22end, γ32end, δ2end, β1, β2end, c2end, bhat1, bhat2end, bhatfsal) = cache
200-
201-
# u1
202-
tmp = uprev
203-
u = tmp + β1 * dt * integrator.fsalfirst
204-
# Initialize utilde for JET
205-
utilde = u
206-
if integrator.opts.adaptive
207-
utilde = bhat1 * dt * integrator.fsalfirst
208-
end
209-
210-
# other stages
211-
for i in eachindex(γ12end)
212-
k = f(u, p, t + c2end[i] * dt)
213-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
214-
tmp = tmp + δ2end[i] * u
215-
u = γ12end[i] * u + γ22end[i] * tmp + γ32end[i] * uprev + β2end[i] * dt * k
216-
if integrator.opts.adaptive
217-
utilde = utilde + bhat2end[i] * dt * k
218-
end
219-
end
220-
221-
# FSAL
222-
integrator.fsallast = f(u, p, t + dt)
223-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
224-
225-
if integrator.opts.adaptive
226-
utilde = utilde + bhatfsal * dt * integrator.fsallast
227-
atmp = calculate_residuals(
228-
utilde, uprev, u, integrator.opts.abstol,
229-
integrator.opts.reltol, integrator.opts.internalnorm, t
230-
)
231-
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
232-
end
233-
234-
integrator.k[1] = integrator.fsalfirst
235-
integrator.k[2] = integrator.fsallast
236-
integrator.u = u
116+
return _perform_step_oop!(integrator, cache)
237117
end
238118

239119
function initialize!(integrator, cache::LowStorageRK3SpFSALCache)
240-
(; k, fsalfirst) = cache
241-
242120
integrator.kshortsize = 2
243121
resize!(integrator.k, integrator.kshortsize)
244122
integrator.k[1] = integrator.fsalfirst
245123
integrator.k[2] = integrator.fsallast
246-
integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # FSAL for interpolation
124+
integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t)
247125
return OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
248126
end
249127

250-
@muladd function perform_step!(
251-
integrator, cache::LowStorageRK3SpFSALCache,
252-
repeat_step = false
253-
)
254-
(; t, dt, uprev, u, f, p) = integrator
255-
(; k, tmp, utilde, atmp, stage_limiter!, step_limiter!, thread) = cache
256-
(;
257-
γ12end, γ22end, γ32end, δ2end, β1, β2end,
258-
c2end, bhat1, bhat2end, bhatfsal,
259-
) = cache.tab
260-
261-
# u1
262-
@.. broadcast = false thread = thread tmp = uprev
263-
@.. broadcast = false thread = thread u = tmp + β1 * dt * integrator.fsalfirst
264-
if integrator.opts.adaptive
265-
@.. broadcast = false thread = thread utilde = bhat1 * dt * integrator.fsalfirst
266-
end
267-
268-
# other stages
269-
for i in eachindex(γ12end)
270-
stage_limiter!(u, integrator, p, t + c2end[i] * dt)
271-
f(k, u, p, t + c2end[i] * dt)
272-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
273-
@.. broadcast = false thread = thread tmp = tmp + δ2end[i] * u
274-
@.. broadcast = false thread = thread u = γ12end[i] * u + γ22end[i] * tmp +
275-
γ32end[i] * uprev + β2end[i] * dt * k
276-
if integrator.opts.adaptive
277-
@.. broadcast = false thread = thread utilde = utilde + bhat2end[i] * dt * k
278-
end
279-
end
280-
281-
stage_limiter!(u, integrator, p, t + dt)
282-
step_limiter!(u, integrator, p, t + dt)
283-
284-
# FSAL
285-
f(k, u, p, t + dt)
286-
OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1)
287-
288-
if integrator.opts.adaptive
289-
@.. broadcast = false thread = thread utilde = utilde + bhatfsal * dt * k
290-
calculate_residuals!(
291-
atmp, utilde, uprev, u, integrator.opts.abstol,
292-
integrator.opts.reltol, integrator.opts.internalnorm, t,
293-
thread
294-
)
295-
OrdinaryDiffEqCore.set_EEst!(integrator, integrator.opts.internalnorm(atmp, t))
296-
end
128+
function perform_step!(integrator, cache::LowStorageRK3SpFSALCache, repeat_step = false)
129+
return _perform_step_iip!(integrator, cache, cache.tab)
297130
end
298131

299132
# 2R+ low storage methods

0 commit comments

Comments
 (0)