Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/time_integration/methods_3Sstar.jl
2055 views
1
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
2
# Since these FMAs can increase the performance of many numerical algorithms,
3
# we need to opt-in explicitly.
4
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
5
@muladd begin
6
#! format: noindent
7
8
# Abstract base type for time integration schemes of storage class `3S*`
9
abstract type SimpleAlgorithm3Sstar <: AbstractTimeIntegrationAlgorithm end
10
11
"""
12
HypDiffN3Erk3Sstar52()
13
14
Five stage, second-order accurate explicit Runge-Kutta scheme with stability region optimized for
15
the hyperbolic diffusion equation with LLF flux and polynomials of degree polydeg=3.
16
"""
17
struct HypDiffN3Erk3Sstar52 <: SimpleAlgorithm3Sstar
18
gamma1::SVector{5, Float64}
19
gamma2::SVector{5, Float64}
20
gamma3::SVector{5, Float64}
21
beta::SVector{5, Float64}
22
delta::SVector{5, Float64}
23
c::SVector{5, Float64}
24
25
function HypDiffN3Erk3Sstar52()
26
gamma1 = SVector(0.0000000000000000E+00, 5.2656474556752575E-01,
27
1.0385212774098265E+00, 3.6859755007388034E-01,
28
-6.3350615190506088E-01)
29
gamma2 = SVector(1.0000000000000000E+00, 4.1892580153419307E-01,
30
-2.7595818152587825E-02, 9.1271323651988631E-02,
31
6.8495995159465062E-01)
32
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
33
0.0000000000000000E+00, 4.1301005663300466E-01,
34
-5.4537881202277507E-03)
35
beta = SVector(4.5158640252832094E-01, 7.5974836561844006E-01,
36
3.7561630338850771E-01, 2.9356700007428856E-02,
37
2.5205285143494666E-01)
38
delta = SVector(1.0000000000000000E+00, 1.3011720142005145E-01,
39
2.6579275844515687E-01, 9.9687218193685878E-01,
40
0.0000000000000000E+00)
41
c = SVector(0.0000000000000000E+00, 4.5158640252832094E-01,
42
1.0221535725056414E+00, 1.4280257701954349E+00,
43
7.1581334196229851E-01)
44
45
new(gamma1, gamma2, gamma3, beta, delta, c)
46
end
47
end
48
49
"""
50
ParsaniKetchesonDeconinck3Sstar94()
51
52
- Parsani, Ketcheson, Deconinck (2013)
53
Optimized explicit RK schemes for the spectral difference method applied to wave propagation problems
54
[DOI: 10.1137/120885899](https://doi.org/10.1137/120885899)
55
"""
56
struct ParsaniKetchesonDeconinck3Sstar94 <: SimpleAlgorithm3Sstar
57
gamma1::SVector{9, Float64}
58
gamma2::SVector{9, Float64}
59
gamma3::SVector{9, Float64}
60
beta::SVector{9, Float64}
61
delta::SVector{9, Float64}
62
c::SVector{9, Float64}
63
64
function ParsaniKetchesonDeconinck3Sstar94()
65
gamma1 = SVector(0.0000000000000000E+00, -4.6556413837561301E+00,
66
-7.7202649689034453E-01, -4.0244202720632174E+00,
67
-2.1296873883702272E-02, -2.4350219407769953E+00,
68
1.9856336960249132E-02, -2.8107894116913812E-01,
69
1.6894354373677900E-01)
70
gamma2 = SVector(1.0000000000000000E+00, 2.4992627683300688E+00,
71
5.8668202764174726E-01, 1.2051419816240785E+00,
72
3.4747937498564541E-01, 1.3213458736302766E+00,
73
3.1196363453264964E-01, 4.3514189245414447E-01,
74
2.3596980658341213E-01)
75
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
76
0.0000000000000000E+00, 7.6209857891449362E-01,
77
-1.9811817832965520E-01, -6.2289587091629484E-01,
78
-3.7522475499063573E-01, -3.3554373281046146E-01,
79
-4.5609629702116454E-02)
80
beta = SVector(2.8363432481011769E-01, 9.7364980747486463E-01,
81
3.3823592364196498E-01, -3.5849518935750763E-01,
82
-4.1139587569859462E-03, 1.4279689871485013E+00,
83
1.8084680519536503E-02, 1.6057708856060501E-01,
84
2.9522267863254809E-01)
85
delta = SVector(1.0000000000000000E+00, 1.2629238731608268E+00,
86
7.5749675232391733E-01, 5.1635907196195419E-01,
87
-2.7463346616574083E-02, -4.3826743572318672E-01,
88
1.2735870231839268E+00, -6.2947382217730230E-01,
89
0.0000000000000000E+00)
90
c = SVector(0.0000000000000000E+00, 2.8363432481011769E-01,
91
5.4840742446661772E-01, 3.6872298094969475E-01,
92
-6.8061183026103156E-01, 3.5185265855105619E-01,
93
1.6659419385562171E+00, 9.7152778807463247E-01,
94
9.0515694340066954E-01)
95
96
new(gamma1, gamma2, gamma3, beta, delta, c)
97
end
98
end
99
100
"""
101
ParsaniKetchesonDeconinck3Sstar32()
102
103
- Parsani, Ketcheson, Deconinck (2013)
104
Optimized explicit RK schemes for the spectral difference method applied to wave propagation problems
105
[DOI: 10.1137/120885899](https://doi.org/10.1137/120885899)
106
"""
107
struct ParsaniKetchesonDeconinck3Sstar32 <: SimpleAlgorithm3Sstar
108
gamma1::SVector{3, Float64}
109
gamma2::SVector{3, Float64}
110
gamma3::SVector{3, Float64}
111
beta::SVector{3, Float64}
112
delta::SVector{3, Float64}
113
c::SVector{3, Float64}
114
115
function ParsaniKetchesonDeconinck3Sstar32()
116
gamma1 = SVector(0.0000000000000000E+00, -1.2664395576322218E-01,
117
1.1426980685848858E+00)
118
gamma2 = SVector(1.0000000000000000E+00, 6.5427782599406470E-01,
119
-8.2869287683723744E-02)
120
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
121
0.0000000000000000E+00)
122
beta = SVector(7.2366074728360086E-01, 3.4217876502651023E-01,
123
3.6640216242653251E-01)
124
delta = SVector(1.0000000000000000E+00, 7.2196567116037724E-01,
125
0.0000000000000000E+00)
126
c = SVector(0.0000000000000000E+00, 7.2366074728360086E-01,
127
5.9236433182015646E-01)
128
129
new(gamma1, gamma2, gamma3, beta, delta, c)
130
end
131
end
132
133
mutable struct SimpleIntegrator3Sstar{RealT <: Real, uType <: AbstractVector,
134
Params, Sol, F, Alg,
135
SimpleIntegratorOptions} <: AbstractTimeIntegrator
136
u::uType
137
du::uType
138
u_tmp1::uType
139
u_tmp2::uType
140
t::RealT
141
dt::RealT # current time step
142
dtcache::RealT # ignored
143
iter::Int # current number of time step (iteration)
144
p::Params # will be the semidiscretization from Trixi.jl
145
sol::Sol # faked
146
f::F # `rhs!` of the semidiscretization
147
alg::Alg # SimpleAlgorithm3Sstar
148
opts::SimpleIntegratorOptions
149
finalstep::Bool # added for convenience
150
end
151
152
function init(ode::ODEProblem, alg::SimpleAlgorithm3Sstar;
153
dt, callback::Union{CallbackSet, Nothing} = nothing, kwargs...)
154
u = copy(ode.u0)
155
du = similar(u)
156
u_tmp1 = similar(u)
157
u_tmp2 = similar(u)
158
t = first(ode.tspan)
159
iter = 0
160
integrator = SimpleIntegrator3Sstar(u, du, u_tmp1, u_tmp2, t, dt, zero(dt), iter,
161
ode.p,
162
(prob = ode,), ode.f, alg,
163
SimpleIntegratorOptions(callback,
164
ode.tspan;
165
kwargs...), false)
166
167
initialize_callbacks!(callback, integrator)
168
169
return integrator
170
end
171
172
function step!(integrator::SimpleIntegrator3Sstar)
173
@unpack prob = integrator.sol
174
@unpack alg = integrator
175
t_end = last(prob.tspan)
176
callbacks = integrator.opts.callback
177
178
@assert !integrator.finalstep
179
if isnan(integrator.dt)
180
error("time step size `dt` is NaN")
181
end
182
183
limit_dt!(integrator, t_end)
184
185
# one time step
186
integrator.u_tmp1 .= zero(eltype(integrator.u_tmp1))
187
integrator.u_tmp2 .= integrator.u
188
for stage in eachindex(alg.c)
189
t_stage = integrator.t + integrator.dt * alg.c[stage]
190
prob.f(integrator.du, integrator.u, prob.p, t_stage)
191
192
delta_stage = alg.delta[stage]
193
gamma1_stage = alg.gamma1[stage]
194
gamma2_stage = alg.gamma2[stage]
195
gamma3_stage = alg.gamma3[stage]
196
beta_stage_dt = alg.beta[stage] * integrator.dt
197
@trixi_timeit timer() "Runge-Kutta step" begin
198
@threaded for i in eachindex(integrator.u)
199
integrator.u_tmp1[i] += delta_stage * integrator.u[i]
200
integrator.u[i] = (gamma1_stage * integrator.u[i] +
201
gamma2_stage * integrator.u_tmp1[i] +
202
gamma3_stage * integrator.u_tmp2[i] +
203
beta_stage_dt * integrator.du[i])
204
end
205
end
206
end
207
integrator.iter += 1
208
integrator.t += integrator.dt
209
210
@trixi_timeit timer() "Step-Callbacks" handle_callbacks!(callbacks, integrator)
211
212
check_max_iter!(integrator)
213
214
return nothing
215
end
216
217
# get a cache where the RHS can be stored
218
function get_tmp_cache(integrator::SimpleIntegrator3Sstar)
219
return (integrator.u_tmp1, integrator.u_tmp2)
220
end
221
222
# some algorithms from DiffEq like FSAL-ones need to be informed when a callback has modified u
223
u_modified!(integrator::SimpleIntegrator3Sstar, ::Bool) = false
224
225
# stop the time integration
226
function terminate!(integrator::SimpleIntegrator3Sstar)
227
integrator.finalstep = true
228
empty!(integrator.opts.tstops)
229
230
return nothing
231
end
232
233
# used for AMR
234
function Base.resize!(integrator::SimpleIntegrator3Sstar, new_size)
235
resize!(integrator.u, new_size)
236
resize!(integrator.du, new_size)
237
resize!(integrator.u_tmp1, new_size)
238
resize!(integrator.u_tmp2, new_size)
239
240
return nothing
241
end
242
end # @muladd
243
244