Skip to content

Commit cba534b

Browse files
DanielDoehringbennibolmranocha
authored
Simplify time integrators (#2481)
* start working on relaxation RK * start doc * docstrings + clean up * spell out * docstrings, remove secant * examples * tests * typo * increase allowed allocs * typo * test printing/show routines * rename to `u_tmp` * comment * reduce elixirs and tests * rename more explicitly * fmt * document * add sciml base * comments and format * more tests * docs * fix docs * refactor simple ssp * fix * test resize * remove unused resize! * Apply suggestions from code review * Apply suggestions from code review * Update src/time_integration/relaxation_methods/entropy_relaxation.jl * Apply suggestions from code review * Apply suggestions from code review * shorten * test * test vals * fix tet * R-RK: Newton and Sub-Diagonal * fmt * docs * Simplify Time Integrators * clean up docs * revisit * fix CI * Directly call `resize!` with `semi` and `volume_integral` * Update README.md Co-authored-by: Hendrik Ranocha <[email protected]> * Update docs/src/index.md Co-authored-by: Hendrik Ranocha <[email protected]> * remove sciml odeprob * Update src/time_integration/time_integration.jl Co-authored-by: Hendrik Ranocha <[email protected]> --------- Co-authored-by: bennibolm <[email protected]> Co-authored-by: Hendrik Ranocha <[email protected]>
1 parent 1d4bea9 commit cba534b

File tree

10 files changed

+128
-221
lines changed

10 files changed

+128
-221
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ installation and postprocessing procedures. Its features include:
4646
* [Explicit low-storage Runge-Kutta time integration](https://diffeq.sciml.ai/latest/solvers/ode_solve/#Low-Storage-Methods)
4747
* [Strong stability preserving methods](https://diffeq.sciml.ai/latest/solvers/ode_solve/#Explicit-Strong-Stability-Preserving-Runge-Kutta-Methods-for-Hyperbolic-PDEs-(Conservation-Laws))
4848
* CFL-based and error-based time step control
49+
* Custom explicit time integration schemes
50+
* Maximized linear stability via paired explicit Runge-Kutta methods
4951
* Native support for differentiable programming
5052
* Forward mode automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)
5153
* Periodic and weakly-enforced boundary conditions

docs/src/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ installation and postprocessing procedures. Its features include:
4242
* [Explicit low-storage Runge-Kutta time integration](https://diffeq.sciml.ai/latest/solvers/ode_solve/#Low-Storage-Methods)
4343
* [Strong stability preserving methods](https://diffeq.sciml.ai/latest/solvers/ode_solve/#Explicit-Strong-Stability-Preserving-Runge-Kutta-Methods-for-Hyperbolic-PDEs-(Conservation-Laws))
4444
* CFL-based and error-based time step control
45+
* Custom explicit time integration schemes
46+
* Maximized linear stability via paired explicit Runge-Kutta methods
4547
* Native support for differentiable programming
4648
* Forward mode automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl)
4749
* Periodic and weakly-enforced boundary conditions

docs/src/time_integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,4 @@ Then, the stable CFL number can be computed as described above.
215215

216216
- [`Trixi.PairedExplicitRK2`](@ref): Second-order PERK method with at least two stages.
217217
- [`Trixi.PairedExplicitRK3`](@ref): Third-order PERK method with at least three stages.
218-
- [`Trixi.PairedExplicitRK4`](@ref): Fourth-order PERK method with at least five stages.
218+
- [`Trixi.PairedExplicitRK4`](@ref): Fourth-order PERK method with at least five stages.

src/solvers/dg.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,18 @@ function Base.show(io::IO, mime::MIME"text/plain",
265265
end
266266
end
267267

268+
# Required to be able to run `SimpleSSPRK33` without `VolumeIntegralSubcellLimiting`
269+
Base.resize!(semi, volume_integral::AbstractVolumeIntegral, new_size) = nothing
270+
271+
function Base.resize!(semi, volume_integral::VolumeIntegralSubcellLimiting, new_size)
272+
# Resize container antidiffusive_fluxes
273+
resize!(semi.cache.antidiffusive_fluxes, new_size)
274+
275+
# Resize container subcell_limiter_coefficients
276+
@unpack limiter = volume_integral
277+
resize!(limiter.cache.subcell_limiter_coefficients, new_size)
278+
end
279+
268280
# TODO: FD. Should this definition live in a different file because it is
269281
# not strictly a DG method?
270282
"""

src/time_integration/methods_2N.jl

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#! format: noindent
77

88
# Abstract base type for time integration schemes of storage class `2N`
9-
abstract type SimpleAlgorithm2N end
9+
abstract type SimpleAlgorithm2N <: AbstractTimeIntegrationAlgorithm end
1010

1111
"""
1212
CarpenterKennedy2N54()
@@ -75,25 +75,25 @@ struct CarpenterKennedy2N43 <: SimpleAlgorithm2N
7575
end
7676

7777
# This struct is needed to fake https://github.com/SciML/OrdinaryDiffEq.jl/blob/0c2048a502101647ac35faabd80da8a5645beac7/src/integrators/type.jl#L1
78-
mutable struct SimpleIntegrator2NOptions{Callback}
78+
mutable struct SimpleIntegratorOptions{Callback}
7979
callback::Callback # callbacks; used in Trixi.jl
8080
adaptive::Bool # whether the algorithm is adaptive; ignored
8181
dtmax::Float64 # ignored
8282
maxiters::Int # maximal number of time steps
8383
tstops::Vector{Float64} # tstops from https://diffeq.sciml.ai/v6.8/basics/common_solver_opts/#Output-Control-1; ignored
8484
end
8585

86-
function SimpleIntegrator2NOptions(callback, tspan; maxiters = typemax(Int), kwargs...)
87-
SimpleIntegrator2NOptions{typeof(callback)}(callback, false, Inf, maxiters,
88-
[last(tspan)])
86+
function SimpleIntegratorOptions(callback, tspan; maxiters = typemax(Int), kwargs...)
87+
SimpleIntegratorOptions{typeof(callback)}(callback, false, Inf, maxiters,
88+
[last(tspan)])
8989
end
9090

9191
# This struct is needed to fake https://github.com/SciML/OrdinaryDiffEq.jl/blob/0c2048a502101647ac35faabd80da8a5645beac7/src/integrators/type.jl#L77
9292
# This implements the interface components described at
9393
# https://diffeq.sciml.ai/v6.8/basics/integrator/#Handing-Integrators-1
9494
# which are used in Trixi.jl.
9595
mutable struct SimpleIntegrator2N{RealT <: Real, uType, Params, Sol, F, Alg,
96-
SimpleIntegrator2NOptions} <: AbstractTimeIntegrator
96+
SimpleIntegratorOptions} <: AbstractTimeIntegrator
9797
u::uType
9898
du::uType
9999
u_tmp::uType
@@ -105,19 +105,10 @@ mutable struct SimpleIntegrator2N{RealT <: Real, uType, Params, Sol, F, Alg,
105105
sol::Sol # faked
106106
f::F # `rhs!` of the semidiscretization
107107
alg::Alg # SimpleAlgorithm2N
108-
opts::SimpleIntegrator2NOptions
108+
opts::SimpleIntegratorOptions
109109
finalstep::Bool # added for convenience
110110
end
111111

112-
# Forward integrator.stats.naccept to integrator.iter (see GitHub PR#771)
113-
function Base.getproperty(integrator::SimpleIntegrator2N, field::Symbol)
114-
if field === :stats
115-
return (naccept = getfield(integrator, :iter),)
116-
end
117-
# general fallback
118-
return getfield(integrator, field)
119-
end
120-
121112
function init(ode::ODEProblem, alg::SimpleAlgorithm2N;
122113
dt, callback::Union{CallbackSet, Nothing} = nothing, kwargs...)
123114
u = copy(ode.u0)
@@ -127,8 +118,8 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm2N;
127118
iter = 0
128119
integrator = SimpleIntegrator2N(u, du, u_tmp, t, dt, zero(dt), iter, ode.p,
129120
(prob = ode,), ode.f, alg,
130-
SimpleIntegrator2NOptions(callback, ode.tspan;
131-
kwargs...), false)
121+
SimpleIntegratorOptions(callback, ode.tspan;
122+
kwargs...), false)
132123

133124
# initialize callbacks
134125
if callback isa CallbackSet
@@ -143,31 +134,6 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm2N;
143134
return integrator
144135
end
145136

146-
# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1
147-
function solve(ode::ODEProblem, alg::SimpleAlgorithm2N;
148-
dt, callback = nothing, kwargs...)
149-
integrator = init(ode, alg, dt = dt, callback = callback; kwargs...)
150-
151-
# Start actual solve
152-
solve!(integrator)
153-
end
154-
155-
function solve!(integrator::SimpleIntegrator2N)
156-
@unpack prob = integrator.sol
157-
158-
integrator.finalstep = false
159-
160-
@trixi_timeit timer() "main loop" while !integrator.finalstep
161-
step!(integrator)
162-
end # "main loop" timer
163-
164-
finalize_callbacks(integrator)
165-
166-
return TimeIntegratorSolution((first(prob.tspan), integrator.t),
167-
(prob.u0, integrator.u),
168-
integrator.sol.prob)
169-
end
170-
171137
function step!(integrator::SimpleIntegrator2N)
172138
@unpack prob = integrator.sol
173139
@unpack alg = integrator
@@ -225,22 +191,11 @@ function step!(integrator::SimpleIntegrator2N)
225191
end
226192

227193
# get a cache where the RHS can be stored
228-
get_du(integrator::SimpleIntegrator2N) = integrator.du
229194
get_tmp_cache(integrator::SimpleIntegrator2N) = (integrator.u_tmp,)
230195

231196
# some algorithms from DiffEq like FSAL-ones need to be informed when a callback has modified u
232197
u_modified!(integrator::SimpleIntegrator2N, ::Bool) = false
233198

234-
# used by adaptive timestepping algorithms in DiffEq
235-
function set_proposed_dt!(integrator::SimpleIntegrator2N, dt)
236-
integrator.dt = dt
237-
end
238-
239-
# Required e.g. for `glm_speed_callback`
240-
function get_proposed_dt(integrator::SimpleIntegrator2N)
241-
return integrator.dt
242-
end
243-
244199
# stop the time integration
245200
function terminate!(integrator::SimpleIntegrator2N)
246201
integrator.finalstep = true

src/time_integration/methods_3Sstar.jl

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#! format: noindent
77

88
# Abstract base type for time integration schemes of storage class `3S*`
9-
abstract type SimpleAlgorithm3Sstar end
9+
abstract type SimpleAlgorithm3Sstar <: AbstractTimeIntegrationAlgorithm end
1010

1111
"""
1212
HypDiffN3Erk3Sstar52()
@@ -130,23 +130,8 @@ struct ParsaniKetchesonDeconinck3Sstar32 <: SimpleAlgorithm3Sstar
130130
end
131131
end
132132

133-
mutable struct SimpleIntegrator3SstarOptions{Callback}
134-
callback::Callback # callbacks; used in Trixi.jl
135-
adaptive::Bool # whether the algorithm is adaptive; ignored
136-
dtmax::Float64 # ignored
137-
maxiters::Int # maximal number of time steps
138-
tstops::Vector{Float64} # tstops from https://diffeq.sciml.ai/v6.8/basics/common_solver_opts/#Output-Control-1; ignored
139-
end
140-
141-
function SimpleIntegrator3SstarOptions(callback, tspan; maxiters = typemax(Int),
142-
kwargs...)
143-
SimpleIntegrator3SstarOptions{typeof(callback)}(callback, false, Inf, maxiters,
144-
[last(tspan)])
145-
end
146-
147133
mutable struct SimpleIntegrator3Sstar{RealT <: Real, uType, Params, Sol, F, Alg,
148-
SimpleIntegrator3SstarOptions} <:
149-
AbstractTimeIntegrator
134+
SimpleIntegratorOptions} <: AbstractTimeIntegrator
150135
u::uType
151136
du::uType
152137
u_tmp1::uType
@@ -159,19 +144,10 @@ mutable struct SimpleIntegrator3Sstar{RealT <: Real, uType, Params, Sol, F, Alg,
159144
sol::Sol # faked
160145
f::F # `rhs!` of the semidiscretization
161146
alg::Alg # SimpleAlgorithm3Sstar
162-
opts::SimpleIntegrator3SstarOptions
147+
opts::SimpleIntegratorOptions
163148
finalstep::Bool # added for convenience
164149
end
165150

166-
# Forward integrator.stats.naccept to integrator.iter (see GitHub PR#771)
167-
function Base.getproperty(integrator::SimpleIntegrator3Sstar, field::Symbol)
168-
if field === :stats
169-
return (naccept = getfield(integrator, :iter),)
170-
end
171-
# general fallback
172-
return getfield(integrator, field)
173-
end
174-
175151
function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;
176152
dt, callback::Union{CallbackSet, Nothing} = nothing, kwargs...)
177153
u = copy(ode.u0)
@@ -183,9 +159,9 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;
183159
integrator = SimpleIntegrator3Sstar(u, du, u_tmp1, u_tmp2, t, dt, zero(dt), iter,
184160
ode.p,
185161
(prob = ode,), ode.f, alg,
186-
SimpleIntegrator3SstarOptions(callback,
187-
ode.tspan;
188-
kwargs...), false)
162+
SimpleIntegratorOptions(callback,
163+
ode.tspan;
164+
kwargs...), false)
189165

190166
# initialize callbacks
191167
if callback isa CallbackSet
@@ -200,31 +176,6 @@ function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;
200176
return integrator
201177
end
202178

203-
# Fakes `solve`: https://diffeq.sciml.ai/v6.8/basics/overview/#Solving-the-Problems-1
204-
function solve(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;
205-
dt, callback = nothing, kwargs...)
206-
integrator = init(ode, alg, dt = dt, callback = callback; kwargs...)
207-
208-
# Start actual solve
209-
solve!(integrator)
210-
end
211-
212-
function solve!(integrator::SimpleIntegrator3Sstar)
213-
@unpack prob = integrator.sol
214-
215-
integrator.finalstep = false
216-
217-
@trixi_timeit timer() "main loop" while !integrator.finalstep
218-
step!(integrator)
219-
end # "main loop" timer
220-
221-
finalize_callbacks(integrator)
222-
223-
return TimeIntegratorSolution((first(prob.tspan), integrator.t),
224-
(prob.u0, integrator.u),
225-
integrator.sol.prob)
226-
end
227-
228179
function step!(integrator::SimpleIntegrator3Sstar)
229180
@unpack prob = integrator.sol
230181
@unpack alg = integrator
@@ -288,24 +239,13 @@ function step!(integrator::SimpleIntegrator3Sstar)
288239
end
289240

290241
# get a cache where the RHS can be stored
291-
get_du(integrator::SimpleIntegrator3Sstar) = integrator.du
292242
function get_tmp_cache(integrator::SimpleIntegrator3Sstar)
293243
(integrator.u_tmp1, integrator.u_tmp2)
294244
end
295245

296246
# some algorithms from DiffEq like FSAL-ones need to be informed when a callback has modified u
297247
u_modified!(integrator::SimpleIntegrator3Sstar, ::Bool) = false
298248

299-
# used by adaptive timestepping algorithms in DiffEq
300-
function set_proposed_dt!(integrator::SimpleIntegrator3Sstar, dt)
301-
integrator.dt = dt
302-
end
303-
304-
# Required e.g. for `glm_speed_callback`
305-
function get_proposed_dt(integrator::SimpleIntegrator3Sstar)
306-
return integrator.dt
307-
end
308-
309249
# stop the time integration
310250
function terminate!(integrator::SimpleIntegrator3Sstar)
311251
integrator.finalstep = true

0 commit comments

Comments
 (0)