Path: blob/main/src/time_integration/methods_3Sstar.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 `3S*`8abstract type SimpleAlgorithm3Sstar <: AbstractTimeIntegrationAlgorithm end910"""11HypDiffN3Erk3Sstar52()1213Five stage, second-order accurate explicit Runge-Kutta scheme with stability region optimized for14the hyperbolic diffusion equation with LLF flux and polynomials of degree polydeg=3.15"""16struct HypDiffN3Erk3Sstar52 <: SimpleAlgorithm3Sstar17gamma1::SVector{5, Float64}18gamma2::SVector{5, Float64}19gamma3::SVector{5, Float64}20beta::SVector{5, Float64}21delta::SVector{5, Float64}22c::SVector{5, Float64}2324function HypDiffN3Erk3Sstar52()25gamma1 = SVector(0.0000000000000000E+00, 5.2656474556752575E-01,261.0385212774098265E+00, 3.6859755007388034E-01,27-6.3350615190506088E-01)28gamma2 = SVector(1.0000000000000000E+00, 4.1892580153419307E-01,29-2.7595818152587825E-02, 9.1271323651988631E-02,306.8495995159465062E-01)31gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,320.0000000000000000E+00, 4.1301005663300466E-01,33-5.4537881202277507E-03)34beta = SVector(4.5158640252832094E-01, 7.5974836561844006E-01,353.7561630338850771E-01, 2.9356700007428856E-02,362.5205285143494666E-01)37delta = SVector(1.0000000000000000E+00, 1.3011720142005145E-01,382.6579275844515687E-01, 9.9687218193685878E-01,390.0000000000000000E+00)40c = SVector(0.0000000000000000E+00, 4.5158640252832094E-01,411.0221535725056414E+00, 1.4280257701954349E+00,427.1581334196229851E-01)4344new(gamma1, gamma2, gamma3, beta, delta, c)45end46end4748"""49ParsaniKetchesonDeconinck3Sstar94()5051- Parsani, Ketcheson, Deconinck (2013)52Optimized explicit RK schemes for the spectral difference method applied to wave propagation problems53[DOI: 10.1137/120885899](https://doi.org/10.1137/120885899)54"""55struct ParsaniKetchesonDeconinck3Sstar94 <: SimpleAlgorithm3Sstar56gamma1::SVector{9, Float64}57gamma2::SVector{9, Float64}58gamma3::SVector{9, Float64}59beta::SVector{9, Float64}60delta::SVector{9, Float64}61c::SVector{9, Float64}6263function ParsaniKetchesonDeconinck3Sstar94()64gamma1 = SVector(0.0000000000000000E+00, -4.6556413837561301E+00,65-7.7202649689034453E-01, -4.0244202720632174E+00,66-2.1296873883702272E-02, -2.4350219407769953E+00,671.9856336960249132E-02, -2.8107894116913812E-01,681.6894354373677900E-01)69gamma2 = SVector(1.0000000000000000E+00, 2.4992627683300688E+00,705.8668202764174726E-01, 1.2051419816240785E+00,713.4747937498564541E-01, 1.3213458736302766E+00,723.1196363453264964E-01, 4.3514189245414447E-01,732.3596980658341213E-01)74gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,750.0000000000000000E+00, 7.6209857891449362E-01,76-1.9811817832965520E-01, -6.2289587091629484E-01,77-3.7522475499063573E-01, -3.3554373281046146E-01,78-4.5609629702116454E-02)79beta = SVector(2.8363432481011769E-01, 9.7364980747486463E-01,803.3823592364196498E-01, -3.5849518935750763E-01,81-4.1139587569859462E-03, 1.4279689871485013E+00,821.8084680519536503E-02, 1.6057708856060501E-01,832.9522267863254809E-01)84delta = SVector(1.0000000000000000E+00, 1.2629238731608268E+00,857.5749675232391733E-01, 5.1635907196195419E-01,86-2.7463346616574083E-02, -4.3826743572318672E-01,871.2735870231839268E+00, -6.2947382217730230E-01,880.0000000000000000E+00)89c = SVector(0.0000000000000000E+00, 2.8363432481011769E-01,905.4840742446661772E-01, 3.6872298094969475E-01,91-6.8061183026103156E-01, 3.5185265855105619E-01,921.6659419385562171E+00, 9.7152778807463247E-01,939.0515694340066954E-01)9495new(gamma1, gamma2, gamma3, beta, delta, c)96end97end9899"""100ParsaniKetchesonDeconinck3Sstar32()101102- Parsani, Ketcheson, Deconinck (2013)103Optimized explicit RK schemes for the spectral difference method applied to wave propagation problems104[DOI: 10.1137/120885899](https://doi.org/10.1137/120885899)105"""106struct ParsaniKetchesonDeconinck3Sstar32 <: SimpleAlgorithm3Sstar107gamma1::SVector{3, Float64}108gamma2::SVector{3, Float64}109gamma3::SVector{3, Float64}110beta::SVector{3, Float64}111delta::SVector{3, Float64}112c::SVector{3, Float64}113114function ParsaniKetchesonDeconinck3Sstar32()115gamma1 = SVector(0.0000000000000000E+00, -1.2664395576322218E-01,1161.1426980685848858E+00)117gamma2 = SVector(1.0000000000000000E+00, 6.5427782599406470E-01,118-8.2869287683723744E-02)119gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,1200.0000000000000000E+00)121beta = SVector(7.2366074728360086E-01, 3.4217876502651023E-01,1223.6640216242653251E-01)123delta = SVector(1.0000000000000000E+00, 7.2196567116037724E-01,1240.0000000000000000E+00)125c = SVector(0.0000000000000000E+00, 7.2366074728360086E-01,1265.9236433182015646E-01)127128new(gamma1, gamma2, gamma3, beta, delta, c)129end130end131132mutable struct SimpleIntegrator3Sstar{RealT <: Real, uType <: AbstractVector,133Params, Sol, F, Alg,134SimpleIntegratorOptions} <: AbstractTimeIntegrator135u::uType136du::uType137u_tmp1::uType138u_tmp2::uType139t::RealT140dt::RealT # current time step141dtcache::RealT # ignored142iter::Int # current number of time step (iteration)143p::Params # will be the semidiscretization from Trixi.jl144sol::Sol # faked145f::F # `rhs!` of the semidiscretization146alg::Alg # SimpleAlgorithm3Sstar147opts::SimpleIntegratorOptions148finalstep::Bool # added for convenience149end150151function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;152dt, callback::Union{CallbackSet, Nothing} = nothing, kwargs...)153u = copy(ode.u0)154du = similar(u)155u_tmp1 = similar(u)156u_tmp2 = similar(u)157t = first(ode.tspan)158iter = 0159integrator = SimpleIntegrator3Sstar(u, du, u_tmp1, u_tmp2, t, dt, zero(dt), iter,160ode.p,161(prob = ode,), ode.f, alg,162SimpleIntegratorOptions(callback,163ode.tspan;164kwargs...), false)165166initialize_callbacks!(callback, integrator)167168return integrator169end170171function step!(integrator::SimpleIntegrator3Sstar)172@unpack prob = integrator.sol173@unpack alg = integrator174t_end = last(prob.tspan)175callbacks = integrator.opts.callback176177@assert !integrator.finalstep178if isnan(integrator.dt)179error("time step size `dt` is NaN")180end181182limit_dt!(integrator, t_end)183184# one time step185integrator.u_tmp1 .= zero(eltype(integrator.u_tmp1))186integrator.u_tmp2 .= integrator.u187for stage in eachindex(alg.c)188t_stage = integrator.t + integrator.dt * alg.c[stage]189prob.f(integrator.du, integrator.u, prob.p, t_stage)190191delta_stage = alg.delta[stage]192gamma1_stage = alg.gamma1[stage]193gamma2_stage = alg.gamma2[stage]194gamma3_stage = alg.gamma3[stage]195beta_stage_dt = alg.beta[stage] * integrator.dt196@trixi_timeit timer() "Runge-Kutta step" begin197@threaded for i in eachindex(integrator.u)198integrator.u_tmp1[i] += delta_stage * integrator.u[i]199integrator.u[i] = (gamma1_stage * integrator.u[i] +200gamma2_stage * integrator.u_tmp1[i] +201gamma3_stage * integrator.u_tmp2[i] +202beta_stage_dt * integrator.du[i])203end204end205end206integrator.iter += 1207integrator.t += integrator.dt208209@trixi_timeit timer() "Step-Callbacks" handle_callbacks!(callbacks, integrator)210211check_max_iter!(integrator)212213return nothing214end215216# get a cache where the RHS can be stored217function get_tmp_cache(integrator::SimpleIntegrator3Sstar)218return (integrator.u_tmp1, integrator.u_tmp2)219end220221# some algorithms from DiffEq like FSAL-ones need to be informed when a callback has modified u222u_modified!(integrator::SimpleIntegrator3Sstar, ::Bool) = false223224# stop the time integration225function terminate!(integrator::SimpleIntegrator3Sstar)226integrator.finalstep = true227empty!(integrator.opts.tstops)228229return nothing230end231232# used for AMR233function Base.resize!(integrator::SimpleIntegrator3Sstar, new_size)234resize!(integrator.u, new_size)235resize!(integrator.du, new_size)236resize!(integrator.u_tmp1, new_size)237resize!(integrator.u_tmp2, new_size)238239return nothing240end241end # @muladd242243244