Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/tree_2d_dgsem/elixir_euler_blob_amr.jl
2055 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
###############################################################################
5
# semidiscretization of the compressible Euler equations
6
gamma = 5 / 3
7
equations = CompressibleEulerEquations2D(gamma)
8
9
"""
10
initial_condition_blob(x, t, equations::CompressibleEulerEquations2D)
11
12
The blob test case taken from
13
- Agertz et al. (2006)
14
Fundamental differences between SPH and grid methods
15
[arXiv: astro-ph/0610051](https://arxiv.org/abs/astro-ph/0610051)
16
"""
17
function initial_condition_blob(x, t, equations::CompressibleEulerEquations2D)
18
# blob test case, see Agertz et al. https://arxiv.org/pdf/astro-ph/0610051.pdf
19
# other reference: https://doi.org/10.1111/j.1365-2966.2007.12183.x
20
# change discontinuity to tanh
21
# typical domain is rectangular, we change it to a square
22
# resolution 128^2, 256^2
23
# domain size is [-20.0,20.0]^2
24
# gamma = 5/3 for this test case
25
RealT = eltype(x)
26
R = 1 # radius of the blob
27
# background density
28
dens0 = 1
29
Chi = convert(RealT, 10) # density contrast
30
# reference time of characteristic growth of KH instability equal to 1.0
31
tau_kh = 1
32
tau_cr = tau_kh / convert(RealT, 1.6) # crushing time
33
# determine background velocity
34
velx0 = 2 * R * sqrt(Chi) / tau_cr
35
vely0 = 0
36
Ma0 = convert(RealT, 2.7) # background flow Mach number Ma=v/c
37
c = velx0 / Ma0 # sound speed
38
# use perfect gas assumption to compute background pressure via the sound speed c^2 = gamma * pressure/density
39
p0 = c * c * dens0 / equations.gamma
40
# initial center of the blob
41
inicenter = [-15, 0]
42
x_rel = x - inicenter
43
r = sqrt(x_rel[1]^2 + x_rel[2]^2)
44
# steepness of the tanh transition zone
45
slope = 2
46
# density blob
47
dens = dens0 +
48
(Chi - 1) * 0.5f0 * (1 + (tanh(slope * (r + R)) - (tanh(slope * (r - R)) + 1)))
49
# velocity blob is zero
50
velx = velx0 -
51
velx0 * 0.5f0 * (1 + (tanh(slope * (r + R)) - (tanh(slope * (r - R)) + 1)))
52
return prim2cons(SVector(dens, velx, vely0, p0), equations)
53
end
54
initial_condition = initial_condition_blob
55
56
# Up to version 0.13.0, `max_abs_speed_naive` was used as the default wave speed estimate of
57
# `const flux_lax_friedrichs = FluxLaxFriedrichs(), i.e., `FluxLaxFriedrichs(max_abs_speed = max_abs_speed_naive)`.
58
# In the `StepsizeCallback`, though, the less diffusive `max_abs_speeds` is employed which is consistent with `max_abs_speed`.
59
# Thus, we exchanged in PR#2458 the default wave speed used in the LLF flux to `max_abs_speed`.
60
# To ensure that every example still runs we specify explicitly `FluxLaxFriedrichs(max_abs_speed_naive)`.
61
# We remark, however, that the now default `max_abs_speed` is in general recommended due to compliance with the
62
# `StepsizeCallback` (CFL-Condition) and less diffusion.
63
surface_flux = FluxLaxFriedrichs(max_abs_speed_naive)
64
volume_flux = flux_ranocha
65
basis = LobattoLegendreBasis(4)
66
67
indicator_sc = IndicatorHennemannGassner(equations, basis,
68
alpha_max = 0.4,
69
alpha_min = 0.0001,
70
alpha_smooth = true,
71
variable = pressure)
72
73
volume_integral = VolumeIntegralShockCapturingHG(indicator_sc;
74
volume_flux_dg = volume_flux,
75
volume_flux_fv = surface_flux)
76
77
solver = DGSEM(basis, surface_flux, volume_integral)
78
79
coordinates_min = (-20.0, -20.0)
80
coordinates_max = (20.0, 20.0)
81
82
mesh = TreeMesh(coordinates_min, coordinates_max,
83
initial_refinement_level = 6,
84
n_cells_max = 100_000)
85
86
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver)
87
88
###############################################################################
89
# ODE solvers, callbacks etc.
90
91
tspan = (0.0, 8.0)
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
106
amr_indicator = IndicatorHennemannGassner(semi,
107
alpha_max = 1.0,
108
alpha_min = 0.0001,
109
alpha_smooth = false,
110
variable = Trixi.density)
111
amr_controller = ControllerThreeLevelCombined(semi, amr_indicator, indicator_sc,
112
base_level = 4,
113
med_level = 0, med_threshold = 0.0003, # med_level = current level
114
max_level = 7, max_threshold = 0.003,
115
max_threshold_secondary = indicator_sc.alpha_max)
116
amr_callback = AMRCallback(semi, amr_controller,
117
interval = 1,
118
adapt_initial_condition = true,
119
adapt_initial_condition_only_refine = true)
120
121
stepsize_callback = StepsizeCallback(cfl = 0.25)
122
123
callbacks = CallbackSet(summary_callback,
124
analysis_callback, alive_callback,
125
save_solution,
126
amr_callback, stepsize_callback)
127
128
###############################################################################
129
# run the simulation
130
131
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);
132
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
133
ode_default_options()..., callback = callbacks);
134
135