Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/semidiscretization/semidiscretization_euler_gravity.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
"""
9
ParametersEulerGravity(; background_density=0.0,
10
gravitational_constant=1.0,
11
cfl=1.0,
12
resid_tol=1.0e-4,
13
n_iterations_max=10^4,
14
timestep_gravity=timestep_gravity_erk52_3Sstar!)
15
16
Set up parameters for the gravitational part of a [`SemidiscretizationEulerGravity`](@ref).
17
18
# Arguments
19
- `background_density<:Real`: Constant background/reference density ρ₀ which is subtracted from the (Euler) density
20
in the RHS source term computation of the gravity solver.
21
- `gravitational_constant<:Real`: Gravitational constant G which needs to be in consistent units with the
22
density and velocity fields.
23
- `cfl<:Real`: CFL number used for the pseudo-time stepping to advance the hyperbolic diffusion equations into steady state.
24
- `resid_tol<:Real`: Absolute tolerance for the residual of the hyperbolic diffusion equations which are solved to
25
(approximately) steady state.
26
- `n_iterations_max::Int`: Maximum number of iterations of the pseudo-time gravity solver.
27
If `n_iterations <= 0` the solver will iterate until the residual is less or equal `resid_tol`.
28
This can cause an infinite loop if the solver does not converge!
29
- `timestep_gravity`: Function to advance the gravity solver by one pseudo-time step.
30
There are three optimized methods available:
31
1) `timestep_gravity_erk51_3Sstar!` (first-order),
32
2) `timestep_gravity_erk52_3Sstar!` (second-order),
33
3) `timestep_gravity_erk53_3Sstar!` (third-order).
34
Additionally, `timestep_gravity_carpenter_kennedy_erk54_2N!` (fourth-order) can be used.
35
"""
36
struct ParametersEulerGravity{RealT <: Real, TimestepGravity}
37
background_density :: RealT # aka rho0
38
gravitational_constant :: RealT # aka G
39
cfl :: RealT # CFL number for the gravity solver
40
resid_tol :: RealT # Hyp.-Diff. Eq. steady state tolerance
41
n_iterations_max :: Int # Max. number of iterations of the pseudo-time gravity solver
42
timestep_gravity :: TimestepGravity
43
end
44
45
function ParametersEulerGravity(; background_density = 0.0,
46
gravitational_constant = 1.0,
47
cfl = 1.0,
48
resid_tol = 1.0e-4,
49
n_iterations_max = 10^4,
50
timestep_gravity = timestep_gravity_erk52_3Sstar!)
51
background_density, gravitational_constant, cfl, resid_tol = promote(background_density,
52
gravitational_constant,
53
cfl, resid_tol)
54
ParametersEulerGravity(background_density, gravitational_constant, cfl, resid_tol,
55
n_iterations_max, timestep_gravity)
56
end
57
58
function Base.show(io::IO, parameters::ParametersEulerGravity)
59
@nospecialize parameters # reduce precompilation time
60
61
print(io, "ParametersEulerGravity(")
62
print(io, "background_density=", parameters.background_density)
63
print(io, ", gravitational_constant=", parameters.gravitational_constant)
64
print(io, ", cfl=", parameters.cfl)
65
print(io, ", n_iterations_max=", parameters.n_iterations_max)
66
print(io, ", timestep_gravity=", parameters.timestep_gravity)
67
print(io, ")")
68
end
69
function Base.show(io::IO, ::MIME"text/plain", parameters::ParametersEulerGravity)
70
@nospecialize parameters # reduce precompilation time
71
72
if get(io, :compact, false)
73
show(io, parameters)
74
else
75
setup = [
76
"background density (ρ₀)" => parameters.background_density,
77
"gravitational constant (G)" => parameters.gravitational_constant,
78
"CFL (gravity)" => parameters.cfl,
79
"max. #iterations" => parameters.n_iterations_max,
80
"time integrator" => parameters.timestep_gravity
81
]
82
summary_box(io, "ParametersEulerGravity", setup)
83
end
84
end
85
86
"""
87
SemidiscretizationEulerGravity
88
89
A struct containing everything needed to describe a spatial semidiscretization
90
of a the compressible Euler equations with self-gravity, reformulating the
91
Poisson equation for the gravitational potential as steady-state problem of
92
the hyperbolic diffusion equations.
93
- Michael Schlottke-Lakemper, Andrew R. Winters, Hendrik Ranocha, Gregor J. Gassner (2020)
94
"A purely hyperbolic discontinuous Galerkin approach for self-gravitating gas dynamics"
95
[arXiv: 2008.10593](https://arXiv.org/abs/2008.10593)
96
"""
97
struct SemidiscretizationEulerGravity{SemiEuler, SemiGravity,
98
Parameters <: ParametersEulerGravity, Cache} <:
99
AbstractSemidiscretization
100
semi_euler :: SemiEuler
101
semi_gravity :: SemiGravity
102
parameters :: Parameters
103
performance_counter :: PerformanceCounter
104
gravity_counter :: PerformanceCounter
105
cache :: Cache
106
107
function SemidiscretizationEulerGravity{SemiEuler, SemiGravity, Parameters, Cache}(semi_euler::SemiEuler,
108
semi_gravity::SemiGravity,
109
parameters::Parameters,
110
cache::Cache) where {
111
SemiEuler,
112
SemiGravity,
113
Parameters <:
114
ParametersEulerGravity,
115
Cache
116
}
117
@assert ndims(semi_euler) == ndims(semi_gravity)
118
@assert typeof(semi_euler.mesh) == typeof(semi_gravity.mesh)
119
@assert polydeg(semi_euler.solver) == polydeg(semi_gravity.solver)
120
121
performance_counter = PerformanceCounter()
122
gravity_counter = PerformanceCounter()
123
124
new(semi_euler, semi_gravity, parameters, performance_counter, gravity_counter,
125
cache)
126
end
127
end
128
129
"""
130
SemidiscretizationEulerGravity(semi_euler::SemiEuler, semi_gravity::SemiGravity, parameters)
131
132
Construct a semidiscretization of the compressible Euler equations with self-gravity.
133
`parameters` should be given as [`ParametersEulerGravity`](@ref).
134
"""
135
function SemidiscretizationEulerGravity(semi_euler::SemiEuler,
136
semi_gravity::SemiGravity,
137
parameters) where
138
{Mesh,
139
SemiEuler <:
140
SemidiscretizationHyperbolic{Mesh, <:AbstractCompressibleEulerEquations},
141
SemiGravity <:
142
SemidiscretizationHyperbolic{Mesh, <:AbstractHyperbolicDiffusionEquations}}
143
u_ode = compute_coefficients(zero(real(semi_gravity)), semi_gravity)
144
du_ode = similar(u_ode)
145
# Registers for gravity solver, tailored to the 2N and 3S* methods implemented below
146
u_tmp1_ode = similar(u_ode)
147
u_tmp2_ode = similar(u_ode)
148
cache = (; u_ode, du_ode, u_tmp1_ode, u_tmp2_ode)
149
150
SemidiscretizationEulerGravity{typeof(semi_euler), typeof(semi_gravity),
151
typeof(parameters), typeof(cache)}(semi_euler,
152
semi_gravity,
153
parameters, cache)
154
end
155
156
function remake(semi::SemidiscretizationEulerGravity;
157
uEltype = real(semi.semi_gravity.solver),
158
semi_euler = semi.semi_euler,
159
semi_gravity = semi.semi_gravity,
160
parameters = semi.parameters)
161
semi_euler = remake(semi_euler, uEltype = uEltype)
162
semi_gravity = remake(semi_gravity, uEltype = uEltype)
163
164
# Recreate cache, i.e., registers for u with e.g. AD datatype
165
u_ode = compute_coefficients(zero(real(semi_gravity)), semi_gravity)
166
du_ode = similar(u_ode)
167
u_tmp1_ode = similar(u_ode)
168
u_tmp2_ode = similar(u_ode)
169
cache = (; u_ode, du_ode, u_tmp1_ode, u_tmp2_ode)
170
171
SemidiscretizationEulerGravity{typeof(semi_euler), typeof(semi_gravity),
172
typeof(parameters), typeof(cache)}(semi_euler,
173
semi_gravity,
174
parameters, cache)
175
end
176
177
function Base.show(io::IO, semi::SemidiscretizationEulerGravity)
178
@nospecialize semi # reduce precompilation time
179
180
print(io, "SemidiscretizationEulerGravity using")
181
print(io, semi.semi_euler)
182
print(io, ", ", semi.semi_gravity)
183
print(io, ", ", semi.parameters)
184
print(io, ", cache(")
185
for (idx, key) in enumerate(keys(semi.cache))
186
idx > 1 && print(io, " ")
187
print(io, key)
188
end
189
print(io, "))")
190
end
191
192
function Base.show(io::IO, mime::MIME"text/plain", semi::SemidiscretizationEulerGravity)
193
@nospecialize semi # reduce precompilation time
194
195
if get(io, :compact, false)
196
show(io, semi)
197
else
198
summary_header(io, "SemidiscretizationEulerGravity")
199
summary_line(io, "semidiscretization Euler",
200
semi.semi_euler |> typeof |> nameof)
201
show(increment_indent(io), mime, semi.semi_euler)
202
summary_line(io, "semidiscretization gravity",
203
semi.semi_gravity |> typeof |> nameof)
204
show(increment_indent(io), mime, semi.semi_gravity)
205
summary_line(io, "parameters", semi.parameters |> typeof |> nameof)
206
show(increment_indent(io), mime, semi.parameters)
207
summary_footer(io)
208
end
209
end
210
211
# The compressible Euler semidiscretization is considered to be the main semidiscretization.
212
# The hyperbolic diffusion equations part is only used internally to update the gravitational
213
# potential during an rhs! evaluation of the flow solver.
214
@inline function mesh_equations_solver_cache(semi::SemidiscretizationEulerGravity)
215
mesh_equations_solver_cache(semi.semi_euler)
216
end
217
218
@inline Base.ndims(semi::SemidiscretizationEulerGravity) = ndims(semi.semi_euler)
219
220
@inline Base.real(semi::SemidiscretizationEulerGravity) = real(semi.semi_euler)
221
222
# computes the coefficients of the initial condition
223
@inline function compute_coefficients(t, semi::SemidiscretizationEulerGravity)
224
compute_coefficients!(semi.cache.u_ode, t, semi.semi_gravity)
225
compute_coefficients(t, semi.semi_euler)
226
end
227
228
# computes the coefficients of the initial condition and stores the Euler part in `u_ode`
229
@inline function compute_coefficients!(u_ode, t, semi::SemidiscretizationEulerGravity)
230
compute_coefficients!(semi.cache.u_ode, t, semi.semi_gravity)
231
compute_coefficients!(u_ode, t, semi.semi_euler)
232
end
233
234
@inline function calc_error_norms(func, u, t, analyzer,
235
semi::SemidiscretizationEulerGravity, cache_analysis)
236
calc_error_norms(func, u, t, analyzer, semi.semi_euler, cache_analysis)
237
end
238
239
# Coupled Euler and gravity solver at each Runge-Kutta stage,
240
# corresponding to Algorithm 2 in Schlottke-Lakemper et al. (2020),
241
# https://dx.doi.org/10.1016/j.jcp.2021.110467
242
function rhs!(du_ode, u_ode, semi::SemidiscretizationEulerGravity, t)
243
@unpack semi_euler, semi_gravity, cache = semi
244
245
u_euler = wrap_array(u_ode, semi_euler)
246
du_euler = wrap_array(du_ode, semi_euler)
247
u_gravity = wrap_array(cache.u_ode, semi_gravity)
248
n_elements = size(u_euler)[end]
249
250
time_start = time_ns()
251
252
# standard semidiscretization of the compressible Euler equations
253
@trixi_timeit timer() "Euler solver" rhs!(du_ode, u_ode, semi_euler, t)
254
255
# compute gravitational potential and forces
256
@trixi_timeit timer() "gravity solver" update_gravity!(semi, u_ode)
257
258
# add gravitational source source_terms to the Euler part
259
if ndims(semi_euler) == 1
260
@threaded for element in 1:n_elements
261
@views @. du_euler[2, .., element] -= u_euler[1, .., element] *
262
u_gravity[2, .., element]
263
@views @. du_euler[3, .., element] -= u_euler[2, .., element] *
264
u_gravity[2, .., element]
265
end
266
elseif ndims(semi_euler) == 2
267
@threaded for element in 1:n_elements
268
@views @. du_euler[2, .., element] -= u_euler[1, .., element] *
269
u_gravity[2, .., element]
270
@views @. du_euler[3, .., element] -= u_euler[1, .., element] *
271
u_gravity[3, .., element]
272
@views @. du_euler[4, .., element] -= (u_euler[2, .., element] *
273
u_gravity[2, .., element] +
274
u_euler[3, .., element] *
275
u_gravity[3, .., element])
276
end
277
elseif ndims(semi_euler) == 3
278
@threaded for element in 1:n_elements
279
@views @. du_euler[2, .., element] -= u_euler[1, .., element] *
280
u_gravity[2, .., element]
281
@views @. du_euler[3, .., element] -= u_euler[1, .., element] *
282
u_gravity[3, .., element]
283
@views @. du_euler[4, .., element] -= u_euler[1, .., element] *
284
u_gravity[4, .., element]
285
@views @. du_euler[5, .., element] -= (u_euler[2, .., element] *
286
u_gravity[2, .., element] +
287
u_euler[3, .., element] *
288
u_gravity[3, .., element] +
289
u_euler[4, .., element] *
290
u_gravity[4, .., element])
291
end
292
else
293
error("Number of dimensions $(ndims(semi_euler)) not supported.")
294
end
295
296
runtime = time_ns() - time_start
297
put!(semi.performance_counter, runtime)
298
299
return nothing
300
end
301
302
# TODO: Taal refactor, add some callbacks or so within the gravity update to allow investigating/optimizing it
303
function update_gravity!(semi::SemidiscretizationEulerGravity, u_ode)
304
@unpack semi_euler, semi_gravity, parameters, gravity_counter, cache = semi
305
306
u_euler = wrap_array(u_ode, semi_euler)
307
u_gravity = wrap_array(cache.u_ode, semi_gravity)
308
du_gravity = wrap_array(cache.du_ode, semi_gravity)
309
310
# set up main loop
311
finalstep = false
312
@unpack n_iterations_max, cfl, resid_tol, timestep_gravity = parameters
313
iter = 0
314
tau = zero(real(semi_gravity.solver)) # Pseudo-time
315
316
# iterate gravity solver until convergence or maximum number of iterations are reached
317
@unpack equations = semi_gravity
318
while !finalstep
319
dtau = @trixi_timeit timer() "calculate dtau" begin
320
cfl * max_dt(u_gravity, tau, semi_gravity.mesh,
321
have_constant_speed(equations), equations,
322
semi_gravity.solver, semi_gravity.cache)
323
end
324
325
# evolve solution by one pseudo-time step
326
time_start = time_ns()
327
timestep_gravity(cache, u_euler, tau, dtau, parameters, semi_gravity)
328
runtime = time_ns() - time_start
329
put!(gravity_counter, runtime)
330
331
# update iteration counter
332
iter += 1
333
tau += dtau
334
335
# check if we reached the maximum number of iterations
336
if n_iterations_max > 0 && iter >= n_iterations_max
337
@warn "Max iterations reached: Gravity solver failed to converge!" residual=maximum(abs,
338
@views du_gravity[1,
339
..,
340
:]) tau=tau dtau=dtau
341
finalstep = true
342
end
343
344
# this is an absolute tolerance check
345
if maximum(abs, @views du_gravity[1, .., :]) <= resid_tol
346
finalstep = true
347
end
348
end
349
350
return nothing
351
end
352
353
# Integrate gravity solver for 2N-type low-storage schemes
354
function timestep_gravity_2N!(cache, u_euler, tau, dtau, gravity_parameters,
355
semi_gravity,
356
a, b, c)
357
G = gravity_parameters.gravitational_constant
358
rho0 = gravity_parameters.background_density
359
grav_scale = -4.0 * pi * G
360
361
# Note that `u_ode` is `u_gravity` in `rhs!` above
362
@unpack u_ode, du_ode, u_tmp1_ode = cache
363
n_elements = size(u_euler)[end]
364
365
u_tmp1_ode .= zero(eltype(u_tmp1_ode))
366
du_gravity = wrap_array(du_ode, semi_gravity)
367
368
for stage in eachindex(c)
369
tau_stage = tau + dtau * c[stage]
370
371
# rhs! has the source term for the harmonic problem
372
# We don't need a `@trixi_timeit timer() "rhs!"` here since that's already
373
# included in the `rhs!` call.
374
rhs!(du_ode, u_ode, semi_gravity, tau_stage)
375
376
# Source term: Jeans instability OR coupling convergence test OR blast wave
377
# put in gravity source term proportional to Euler density
378
# OBS! subtract off the background density ρ_0 (spatial mean value)
379
# Note: Adding to `du_gravity` is essentially adding to `du_ode`!
380
@threaded for element in 1:n_elements
381
@views @. du_gravity[1, .., element] += grav_scale *
382
(u_euler[1, .., element] - rho0)
383
end
384
385
a_stage = a[stage]
386
b_stage_dtau = b[stage] * dtau
387
@trixi_timeit timer() "Runge-Kutta step" begin
388
@threaded for idx in eachindex(u_ode)
389
u_tmp1_ode[idx] = du_ode[idx] - u_tmp1_ode[idx] * a_stage
390
u_ode[idx] += u_tmp1_ode[idx] * b_stage_dtau
391
end
392
end
393
end
394
395
return nothing
396
end
397
398
function timestep_gravity_carpenter_kennedy_erk54_2N!(cache, u_euler, tau, dtau,
399
gravity_parameters, semi_gravity)
400
# Coefficients for Carpenter's 5-stage 4th-order low-storage Runge-Kutta method
401
a = SVector(0.0,
402
567301805773.0 / 1357537059087.0,
403
2404267990393.0 / 2016746695238.0,
404
3550918686646.0 / 2091501179385.0,
405
1275806237668.0 / 842570457699.0)
406
b = SVector(1432997174477.0 / 9575080441755.0,
407
5161836677717.0 / 13612068292357.0,
408
1720146321549.0 / 2090206949498.0,
409
3134564353537.0 / 4481467310338.0,
410
2277821191437.0 / 14882151754819.0)
411
c = SVector(0.0,
412
1432997174477.0 / 9575080441755.0,
413
2526269341429.0 / 6820363962896.0,
414
2006345519317.0 / 3224310063776.0,
415
2802321613138.0 / 2924317926251.0)
416
417
timestep_gravity_2N!(cache, u_euler, tau, dtau, gravity_parameters, semi_gravity,
418
a, b, c)
419
end
420
421
# Integrate gravity solver for 3S*-type low-storage schemes
422
function timestep_gravity_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
423
semi_gravity,
424
gamma1, gamma2, gamma3, beta, delta, c)
425
G = gravity_parameters.gravitational_constant
426
rho0 = gravity_parameters.background_density
427
grav_scale = -4 * G * pi
428
429
# Note that `u_ode` is `u_gravity` in `rhs!` above
430
@unpack u_ode, du_ode, u_tmp1_ode, u_tmp2_ode = cache
431
n_elements = size(u_euler)[end]
432
433
u_tmp1_ode .= zero(eltype(u_tmp1_ode))
434
u_tmp2_ode .= u_ode
435
du_gravity = wrap_array(du_ode, semi_gravity)
436
437
for stage in eachindex(c)
438
tau_stage = tau + dtau * c[stage]
439
440
# rhs! has the source term for the harmonic problem
441
# We don't need a `@trixi_timeit timer() "rhs!"` here since that's already
442
# included in the `rhs!` call.
443
rhs!(du_ode, u_ode, semi_gravity, tau_stage)
444
445
# Source term: Jeans instability OR coupling convergence test OR blast wave
446
# put in gravity source term proportional to Euler density
447
# OBS! subtract off the background density ρ_0 around which the Jeans instability is perturbed
448
# Note: Adding to `du_gravity` is essentially adding to `du_ode`!
449
@threaded for element in 1:n_elements
450
@views @. du_gravity[1, .., element] += grav_scale *
451
(u_euler[1, .., element] - rho0)
452
end
453
454
delta_stage = delta[stage]
455
gamma1_stage = gamma1[stage]
456
gamma2_stage = gamma2[stage]
457
gamma3_stage = gamma3[stage]
458
beta_stage_dtau = beta[stage] * dtau
459
@trixi_timeit timer() "Runge-Kutta step" begin
460
@threaded for idx in eachindex(u_ode)
461
# See Algorithm 1 (3S* method) in Schlottke-Lakemper et al. (2020)
462
u_tmp1_ode[idx] += delta_stage * u_ode[idx]
463
u_ode[idx] = (gamma1_stage * u_ode[idx] +
464
gamma2_stage * u_tmp1_ode[idx] +
465
gamma3_stage * u_tmp2_ode[idx] +
466
beta_stage_dtau * du_ode[idx])
467
end
468
end
469
end
470
471
return nothing
472
end
473
474
# First-order, 5-stage, 3S*-storage optimized method
475
function timestep_gravity_erk51_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
476
semi_gravity)
477
# New 3Sstar coefficients optimized for polynomials of degree polydeg=3
478
# and examples/parameters_hypdiff_lax_friedrichs.toml
479
# 5 stages, order 1
480
gamma1 = SVector(0.0000000000000000E+00, 5.2910412316555866E-01,
481
2.8433964362349406E-01, -1.4467571130907027E+00,
482
7.5592215948661057E-02)
483
gamma2 = SVector(1.0000000000000000E+00, 2.6366970460864109E-01,
484
3.7423646095836322E-01, 7.8786901832431289E-01,
485
3.7754129043053775E-01)
486
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
487
0.0000000000000000E+00, 8.0043329115077388E-01,
488
1.3550099149374278E-01)
489
beta = SVector(1.9189497208340553E-01, 5.4506406707700059E-02,
490
1.2103893164085415E-01, 6.8582252490550921E-01,
491
8.7914657211972225E-01)
492
delta = SVector(1.0000000000000000E+00, 7.8593091509463076E-01,
493
1.2639038717454840E-01, 1.7726945920209813E-01,
494
0.0000000000000000E+00)
495
c = SVector(0.0000000000000000E+00, 1.9189497208340553E-01, 1.9580448818599061E-01,
496
2.4241635859769023E-01, 5.0728347557552977E-01)
497
498
timestep_gravity_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
499
semi_gravity,
500
gamma1, gamma2, gamma3, beta, delta, c)
501
end
502
503
# Second-order, 5-stage, 3S*-storage optimized method
504
function timestep_gravity_erk52_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
505
semi_gravity)
506
# New 3Sstar coefficients optimized for polynomials of degree polydeg=3
507
# and examples/parameters_hypdiff_lax_friedrichs.toml
508
# 5 stages, order 2
509
gamma1 = SVector(0.0000000000000000E+00, 5.2656474556752575E-01,
510
1.0385212774098265E+00, 3.6859755007388034E-01,
511
-6.3350615190506088E-01)
512
gamma2 = SVector(1.0000000000000000E+00, 4.1892580153419307E-01,
513
-2.7595818152587825E-02, 9.1271323651988631E-02,
514
6.8495995159465062E-01)
515
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
516
0.0000000000000000E+00, 4.1301005663300466E-01,
517
-5.4537881202277507E-03)
518
beta = SVector(4.5158640252832094E-01, 7.5974836561844006E-01,
519
3.7561630338850771E-01, 2.9356700007428856E-02,
520
2.5205285143494666E-01)
521
delta = SVector(1.0000000000000000E+00, 1.3011720142005145E-01,
522
2.6579275844515687E-01, 9.9687218193685878E-01,
523
0.0000000000000000E+00)
524
c = SVector(0.0000000000000000E+00, 4.5158640252832094E-01, 1.0221535725056414E+00,
525
1.4280257701954349E+00, 7.1581334196229851E-01)
526
527
timestep_gravity_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
528
semi_gravity,
529
gamma1, gamma2, gamma3, beta, delta, c)
530
end
531
532
# Third-order, 5-stage, 3S*-storage optimized method
533
function timestep_gravity_erk53_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
534
semi_gravity)
535
# New 3Sstar coefficients optimized for polynomials of degree polydeg=3
536
# and examples/parameters_hypdiff_lax_friedrichs.toml
537
# 5 stages, order 3
538
gamma1 = SVector(0.0000000000000000E+00, 6.9362208054011210E-01,
539
9.1364483229179472E-01, 1.3129305757628569E+00,
540
-1.4615811339132949E+00)
541
gamma2 = SVector(1.0000000000000000E+00, 1.3224582239681788E+00,
542
2.4213162353103135E-01, -3.8532017293685838E-01,
543
1.5603355704723714E+00)
544
gamma3 = SVector(0.0000000000000000E+00, 0.0000000000000000E+00,
545
0.0000000000000000E+00, 3.8306787039991996E-01,
546
-3.5683121201711010E-01)
547
beta = SVector(8.4476964977404881E-02, 3.0834660698015803E-01,
548
3.2131664733089232E-01, 2.8783574345390539E-01,
549
8.2199204703236073E-01)
550
delta = SVector(1.0000000000000000E+00, -7.6832695815481578E-01,
551
1.2497251501714818E-01, 1.4496404749796306E+00,
552
0.0000000000000000E+00)
553
c = SVector(0.0000000000000000E+00, 8.4476964977404881E-02, 2.8110631488732202E-01,
554
5.7093842145029405E-01, 7.2999896418559662E-01)
555
556
timestep_gravity_3Sstar!(cache, u_euler, tau, dtau, gravity_parameters,
557
semi_gravity,
558
gamma1, gamma2, gamma3, beta, delta, c)
559
end
560
561
# TODO: Taal decide, where should specific parts like these be?
562
@inline function save_solution_file(u_ode, t, dt, iter,
563
semi::SemidiscretizationEulerGravity,
564
solution_callback,
565
element_variables = Dict{Symbol, Any}();
566
system = "")
567
# If this is called already as part of a multi-system setup (i.e., system is non-empty),
568
# we build a combined system name
569
if !isempty(system)
570
system_euler = system * "_euler"
571
system_gravity = system * "_gravity"
572
else
573
system_euler = "euler"
574
system_gravity = "gravity"
575
end
576
577
u_euler = wrap_array_native(u_ode, semi.semi_euler)
578
filename_euler = save_solution_file(u_euler, t, dt, iter,
579
mesh_equations_solver_cache(semi.semi_euler)...,
580
solution_callback, element_variables,
581
system = system_euler)
582
583
u_gravity = wrap_array_native(semi.cache.u_ode, semi.semi_gravity)
584
filename_gravity = save_solution_file(u_gravity, t, dt, iter,
585
mesh_equations_solver_cache(semi.semi_gravity)...,
586
solution_callback, element_variables,
587
system = system_gravity)
588
589
return filename_euler, filename_gravity
590
end
591
592
@inline function (amr_callback::AMRCallback)(u_ode,
593
semi::SemidiscretizationEulerGravity,
594
t, iter; kwargs...)
595
passive_args = ((semi.cache.u_ode,
596
mesh_equations_solver_cache(semi.semi_gravity)...),)
597
has_changed = amr_callback(u_ode, mesh_equations_solver_cache(semi.semi_euler)...,
598
semi, t, iter;
599
kwargs..., passive_args = passive_args)
600
601
if has_changed
602
new_length = length(semi.cache.u_ode)
603
resize!(semi.cache.du_ode, new_length)
604
resize!(semi.cache.u_tmp1_ode, new_length)
605
resize!(semi.cache.u_tmp2_ode, new_length)
606
end
607
608
return has_changed
609
end
610
end # @muladd
611
612