Path: blob/main/src/time_integration/methods_2N.jl
2055 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67# Abstract base type for time integration schemes of storage class `2N`8abstract type SimpleAlgorithm2N <: AbstractTimeIntegrationAlgorithm end910"""11CarpenterKennedy2N54()1213The following structures and methods provide a minimal implementation of14the low-storage explicit Runge-Kutta method of1516- Carpenter, Kennedy (1994)17Fourth-order 2N-storage Runge-Kutta schemes (Solution 3)18URL: https://ntrs.nasa.gov/citations/1994002844419File: https://ntrs.nasa.gov/api/citations/19940028444/downloads/19940028444.pdf2021using the same interface as OrdinaryDiffEq.jl.22"""23struct CarpenterKennedy2N54 <: SimpleAlgorithm2N24a::SVector{5, Float64}25b::SVector{5, Float64}26c::SVector{5, Float64}2728function CarpenterKennedy2N54()29a = SVector(0.0,30567301805773.0 / 1357537059087.0,312404267990393.0 / 2016746695238.0,323550918686646.0 / 2091501179385.0,331275806237668.0 / 842570457699.0)34b = SVector(1432997174477.0 / 9575080441755.0,355161836677717.0 / 13612068292357.0,361720146321549.0 / 2090206949498.0,373134564353537.0 / 4481467310338.0,382277821191437.0 / 14882151754819.0)39c = SVector(0.0,401432997174477.0 / 9575080441755.0,412526269341429.0 / 6820363962896.0,422006345519317.0 / 3224310063776.0,432802321613138.0 / 2924317926251.0)4445new(a, b, c)46end47end4849"""50CarpenterKennedy2N43()5152The following structures and methods provide a minimal implementation of53the low-storage explicit Runge-Kutta method of5455- Carpenter, Kennedy (1994)56Third-order 2N-storage Runge-Kutta schemes with error control57URL: https://ntrs.nasa.gov/citations/1994002844458File: https://ntrs.nasa.gov/api/citations/19940028444/downloads/19940028444.pdf5960using the same interface as OrdinaryDiffEq.jl.61"""62struct CarpenterKennedy2N43 <: SimpleAlgorithm2N63a::SVector{4, Float64}64b::SVector{4, Float64}65c::SVector{4, Float64}6667function CarpenterKennedy2N43()68a = SVector(0, 756391 / 934407, 36441873 / 15625000, 1953125 / 1085297)69b = SVector(8 / 141, 6627 / 2000, 609375 / 1085297, 198961 / 526383)70c = SVector(0, 8 / 141, 86 / 125, 1)7172new(a, b, c)73end74end7576# This struct is needed to fake https://github.com/SciML/OrdinaryDiffEq.jl/blob/0c2048a502101647ac35faabd80da8a5645beac7/src/integrators/type.jl#L177mutable struct SimpleIntegratorOptions{Callback}78callback::Callback # callbacks; used in Trixi.jl79adaptive::Bool # whether the algorithm is adaptive; ignored80dtmax::Float64 # ignored81maxiters::Int # maximal number of time steps82tstops::Vector{Float64} # tstops from https://diffeq.sciml.ai/v6.8/basics/common_solver_opts/#Output-Control-1; ignored83end8485function SimpleIntegratorOptions(callback, tspan; maxiters = typemax(Int), kwargs...)86SimpleIntegratorOptions{typeof(callback)}(callback, false, Inf, maxiters,87[last(tspan)])88end8990# This struct is needed to fake https://github.com/SciML/OrdinaryDiffEq.jl/blob/0c2048a502101647ac35faabd80da8a5645beac7/src/integrators/type.jl#L7791# This implements the interface components described at92# https://diffeq.sciml.ai/v6.8/basics/integrator/#Handing-Integrators-193# which are used in Trixi.jl.94mutable struct SimpleIntegrator2N{RealT <: Real, uType <: AbstractVector,95Params, Sol, F, Alg,96SimpleIntegratorOptions} <: AbstractTimeIntegrator97u::uType98du::uType99u_tmp::uType100t::RealT101dt::RealT # current time step102dtcache::RealT # ignored103iter::Int # current number of time steps (iteration)104p::Params # will be the semidiscretization from Trixi.jl105sol::Sol # faked106f::F # `rhs!` of the semidiscretization107alg::Alg # SimpleAlgorithm2N108opts::SimpleIntegratorOptions109finalstep::Bool # added for convenience110end111112function init(ode::ODEProblem, alg::SimpleAlgorithm2N;113dt, callback::Union{CallbackSet, Nothing} = nothing, kwargs...)114u = copy(ode.u0)115du = similar(u)116u_tmp = similar(u)117t = first(ode.tspan)118iter = 0119integrator = SimpleIntegrator2N(u, du, u_tmp, t, dt, zero(dt), iter, ode.p,120(prob = ode,), ode.f, alg,121SimpleIntegratorOptions(callback, ode.tspan;122kwargs...), false)123124initialize_callbacks!(callback, integrator)125126return integrator127end128129function step!(integrator::SimpleIntegrator2N)130@unpack prob = integrator.sol131@unpack alg = integrator132t_end = last(prob.tspan)133callbacks = integrator.opts.callback134135@assert !integrator.finalstep136if isnan(integrator.dt)137error("time step size `dt` is NaN")138end139140limit_dt!(integrator, t_end)141142# one time step143integrator.u_tmp .= 0144for stage in eachindex(alg.c)145t_stage = integrator.t + integrator.dt * alg.c[stage]146integrator.f(integrator.du, integrator.u, prob.p, t_stage)147148a_stage = alg.a[stage]149b_stage_dt = alg.b[stage] * integrator.dt150@trixi_timeit timer() "Runge-Kutta step" begin151@threaded for i in eachindex(integrator.u)152integrator.u_tmp[i] = integrator.du[i] -153integrator.u_tmp[i] * a_stage154integrator.u[i] += integrator.u_tmp[i] * b_stage_dt155end156end157end158integrator.iter += 1159integrator.t += integrator.dt160161@trixi_timeit timer() "Step-Callbacks" handle_callbacks!(callbacks, integrator)162163check_max_iter!(integrator)164165return nothing166end167168# get a cache where the RHS can be stored169get_tmp_cache(integrator::SimpleIntegrator2N) = (integrator.u_tmp,)170171# some algorithms from DiffEq like FSAL-ones need to be informed when a callback has modified u172u_modified!(integrator::SimpleIntegrator2N, ::Bool) = false173174# stop the time integration175function terminate!(integrator::SimpleIntegrator2N)176integrator.finalstep = true177empty!(integrator.opts.tstops)178179return nothing180end181182# used for AMR183function Base.resize!(integrator::SimpleIntegrator2N, new_size)184resize!(integrator.u, new_size)185resize!(integrator.du, new_size)186resize!(integrator.u_tmp, new_size)187188return nothing189end190end # @muladd191192193