Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/p4est_3d_dgsem/elixir_mhd_shockcapturing_subcell.jl
5586 views
1
using Trixi
2
3
###############################################################################
4
# semidiscretization of the compressible ideal GLM-MHD equations
5
6
equations = IdealGlmMhdEquations3D(1.4)
7
8
"""
9
initial_condition_blast_wave(x, t, equations::IdealGlmMhdEquations3D)
10
11
Weak magnetic blast wave setup taken from Section 6.1 of the paper:
12
- A. M. Rueda-Ramírez, S. Hennemann, F. J. Hindenlang, A. R. Winters, G. J. Gassner (2021)
13
An entropy stable nodal discontinuous Galerkin method for the resistive MHD
14
equations. Part II: Subcell finite volume shock capturing
15
[doi: 10.1016/j.jcp.2021.110580](https://doi.org/10.1016/j.jcp.2021.110580)
16
"""
17
function initial_condition_blast_wave(x, t, equations::IdealGlmMhdEquations3D)
18
# Center of the blast wave is selected for the domain [0, 3]^3
19
inicenter = (1.5, 1.5, 1.5)
20
x_norm = x[1] - inicenter[1]
21
y_norm = x[2] - inicenter[2]
22
z_norm = x[3] - inicenter[3]
23
r = sqrt(x_norm^2 + y_norm^2 + z_norm^2)
24
25
delta_0 = 0.1
26
r_0 = 0.3
27
lambda = exp(5.0 / delta_0 * (r - r_0))
28
29
p_inner = 0.9
30
p_outer = 5e-2
31
prim_inner = SVector(1.2, 0.1, 0.0, 0.1, p_inner, 1.0, 1.0, 1.0, 0.0)
32
prim_outer = SVector(1.2, 0.2, -0.4, 0.2, p_outer, 1.0, 1.0, 1.0, 0.0)
33
prim_vars = (prim_inner + lambda * prim_outer) / (1.0 + lambda)
34
35
return prim2cons(prim_vars, equations)
36
end
37
initial_condition = initial_condition_blast_wave
38
39
surface_flux = (flux_lax_friedrichs, flux_nonconservative_powell_local_symmetric)
40
volume_flux = (flux_hindenlang_gassner, flux_nonconservative_powell_local_symmetric)
41
polydeg = 3
42
basis = LobattoLegendreBasis(polydeg)
43
limiter_idp = SubcellLimiterIDP(equations, basis;
44
positivity_variables_cons = ["rho"],
45
positivity_variables_nonlinear = [pressure])
46
volume_integral = VolumeIntegralSubcellLimiting(limiter_idp;
47
volume_flux_dg = volume_flux,
48
volume_flux_fv = surface_flux)
49
solver = DGSEM(basis, surface_flux, volume_integral)
50
51
# Mapping as described in https://arxiv.org/abs/2012.12040 but with slightly less warping.
52
# The mapping will be interpolated at tree level, and then refined without changing
53
# the geometry interpolant.
54
function mapping(xi_, eta_, zeta_)
55
# Transform input variables between -1 and 1 onto [0,3]
56
xi = 1.5 * xi_ + 1.5
57
eta = 1.5 * eta_ + 1.5
58
zeta = 1.5 * zeta_ + 1.5
59
60
y = eta +
61
3 / 11 * (cos(1.5 * pi * (2 * xi - 3) / 3) *
62
cos(0.5 * pi * (2 * eta - 3) / 3) *
63
cos(0.5 * pi * (2 * zeta - 3) / 3))
64
65
x = xi +
66
3 / 11 * (cos(0.5 * pi * (2 * xi - 3) / 3) *
67
cos(2 * pi * (2 * y - 3) / 3) *
68
cos(0.5 * pi * (2 * zeta - 3) / 3))
69
70
z = zeta +
71
3 / 11 * (cos(0.5 * pi * (2 * x - 3) / 3) *
72
cos(pi * (2 * y - 3) / 3) *
73
cos(0.5 * pi * (2 * zeta - 3) / 3))
74
75
return SVector(x, y, z)
76
end
77
78
trees_per_dimension = (2, 2, 2)
79
mesh = P4estMesh(trees_per_dimension,
80
polydeg = 3,
81
mapping = mapping,
82
initial_refinement_level = 2,
83
periodicity = true)
84
85
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver;
86
boundary_conditions = boundary_condition_periodic)
87
88
###############################################################################
89
# ODE solvers, callbacks etc.
90
91
tspan = (0.0, 0.5)
92
ode = semidiscretize(semi, tspan)
93
94
summary_callback = SummaryCallback()
95
96
analysis_interval = 100
97
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)
98
99
alive_callback = AliveCallback(analysis_interval = analysis_interval)
100
101
save_solution = SaveSolutionCallback(interval = 100,
102
save_initial_solution = true,
103
save_final_solution = true,
104
solution_variables = cons2prim,
105
extra_node_variables = (:limiting_coefficient,))
106
107
cfl = 0.9
108
stepsize_callback = StepsizeCallback(cfl = cfl)
109
110
glm_speed_callback = GlmSpeedCallback(glm_scale = 0.5, cfl = cfl)
111
112
callbacks = CallbackSet(summary_callback,
113
analysis_callback,
114
alive_callback,
115
save_solution,
116
stepsize_callback,
117
glm_speed_callback)
118
119
###############################################################################
120
# run the simulation
121
stage_callbacks = (SubcellLimiterIDPCorrection(), BoundsCheckCallback())
122
123
sol = Trixi.solve(ode, Trixi.SimpleSSPRK33(stage_callbacks = stage_callbacks);
124
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
125
callback = callbacks);
126
127