Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/docs/literate/src/files/DGMulti_1.jl
5591 views
1
#src # DG schemes via `DGMulti` solver
2
3
# [`DGMulti`](@ref) is a DG solver that allows meshes with simplex elements. The basic idea and
4
# implementation of this solver is explained in section ["Meshes"](@ref DGMulti).
5
# Here, we want to give some examples and a quick overview about the options with `DGMulti`.
6
7
# We start with a simple example we already used in the [tutorial about flux differencing](@ref fluxDiffExample).
8
# There, we implemented a simulation with [`initial_condition_weak_blast_wave`](@ref) for the
9
# 2D compressible Euler equations [`CompressibleEulerEquations2D`](@ref) and used the DG formulation
10
# with flux differencing using volume flux [`flux_ranocha`](@ref) and surface flux [`flux_lax_friedrichs`](@ref).
11
12
# Here, we want to implement the equivalent example, only now using the `DGMulti` solver
13
# instead of [`DGSEM`](@ref).
14
15
using OrdinaryDiffEqLowStorageRK
16
using Trixi
17
18
equations = CompressibleEulerEquations2D(1.4)
19
20
initial_condition = initial_condition_weak_blast_wave
21
22
# To use the Gauss-Lobatto nodes again, we choose `approximation_type=SBP()` in the solver.
23
# Since we want to start with a Cartesian domain discretized with squares, we use the element
24
# type `Quad()`.
25
dg = DGMulti(polydeg = 3,
26
element_type = Quad(),
27
approximation_type = SBP(),
28
surface_flux = flux_lax_friedrichs,
29
volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))
30
31
cells_per_dimension = (32, 32)
32
mesh = DGMultiMesh(dg,
33
cells_per_dimension, # initial_refinement_level = 5
34
coordinates_min = (-2.0, -2.0),
35
coordinates_max = (2.0, 2.0),
36
periodicity = true)
37
38
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,
39
boundary_conditions = boundary_condition_periodic)
40
tspan = (0.0, 0.4)
41
ode = semidiscretize(semi, tspan)
42
43
alive_callback = AliveCallback(alive_interval = 10)
44
analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))
45
callbacks = CallbackSet(analysis_callback, alive_callback);
46
47
# Run the simulation with the same time integration algorithm as before.
48
sol = solve(ode, RDPK3SpFSAL49(), abstol = 1.0e-6, reltol = 1.0e-6;
49
callback = callbacks, ode_default_options()...);
50
#-
51
using Plots
52
pd = PlotData2D(sol)
53
plot(pd)
54
#-
55
plot(pd["rho"])
56
plot!(getmesh(pd))
57
58
# This simulation is not as fast as the equivalent with `TreeMesh` since no special optimizations for
59
# quads (for instance tensor product structure) have been implemented. Figure 4 in ["Efficient implementation of modern entropy stable
60
# and kinetic energy preserving discontinuous Galerkin methods for conservation laws"](https://arxiv.org/abs/2112.10517)
61
# (2021) provides a nice runtime comparison between the different mesh types. On the other hand,
62
# the functions are more general and thus we have more option we can choose from.
63
64
# ## Simulation with Gauss nodes
65
# For instance, we can change the approximation type of our simulation.
66
using OrdinaryDiffEqLowStorageRK
67
using Trixi
68
equations = CompressibleEulerEquations2D(1.4)
69
initial_condition = initial_condition_weak_blast_wave
70
71
# We now use Gauss nodes instead of Gauss-Lobatto nodes which can be done for the element types
72
# `Quad()` and `Hex()`. Therefore, we set `approximation_type=GaussSBP()`. Alternatively, we
73
# can use a modal approach using the approximation type `Polynomial()`.
74
dg = DGMulti(polydeg = 3,
75
element_type = Quad(),
76
approximation_type = GaussSBP(),
77
surface_flux = flux_lax_friedrichs,
78
volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))
79
80
cells_per_dimension = (32, 32)
81
mesh = DGMultiMesh(dg,
82
cells_per_dimension, # initial_refinement_level = 5
83
coordinates_min = (-2.0, -2.0),
84
coordinates_max = (2.0, 2.0),
85
periodicity = true)
86
87
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,
88
boundary_conditions = boundary_condition_periodic)
89
tspan = (0.0, 0.4)
90
ode = semidiscretize(semi, tspan)
91
92
alive_callback = AliveCallback(alive_interval = 10)
93
analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))
94
callbacks = CallbackSet(analysis_callback, alive_callback);
95
96
sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,
97
ode_default_options()..., callback = callbacks);
98
#-
99
using Plots
100
pd = PlotData2D(sol)
101
plot(pd)
102
103
# ## Simulation with triangular elements
104
# Also, we can set another element type. We want to use triangles now.
105
using OrdinaryDiffEqLowStorageRK
106
using Trixi
107
equations = CompressibleEulerEquations2D(1.4)
108
initial_condition = initial_condition_weak_blast_wave
109
110
# Since there is no direct equivalent to Gauss-Lobatto nodes on triangles, the approximation type
111
# `SBP()` now uses Gauss-Lobatto nodes on faces and special nodes in the interior of the triangular.
112
# More details can be found in the documentation of
113
# [StartUpDG.jl](https://jlchan.github.io/StartUpDG.jl/dev/RefElemData/#RefElemData-based-on-SBP-finite-differences).
114
dg = DGMulti(polydeg = 3,
115
element_type = Tri(),
116
approximation_type = SBP(),
117
surface_flux = flux_lax_friedrichs,
118
volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))
119
120
cells_per_dimension = (32, 32)
121
mesh = DGMultiMesh(dg,
122
cells_per_dimension, # initial_refinement_level = 5
123
coordinates_min = (-2.0, -2.0),
124
coordinates_max = (2.0, 2.0),
125
periodicity = true)
126
127
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,
128
boundary_conditions = boundary_condition_periodic)
129
tspan = (0.0, 0.4)
130
ode = semidiscretize(semi, tspan)
131
132
alive_callback = AliveCallback(alive_interval = 10)
133
analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))
134
callbacks = CallbackSet(analysis_callback, alive_callback);
135
136
sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,
137
ode_default_options()..., callback = callbacks);
138
#-
139
using Plots
140
pd = PlotData2D(sol)
141
plot(pd)
142
#-
143
plot(pd["rho"])
144
plot!(getmesh(pd))
145
146
# ## Triangular meshes on non-Cartesian domains
147
# To use triangular meshes on a non-Cartesian domain, Trixi.jl uses the package [StartUpDG.jl](https://github.com/jlchan/StartUpDG.jl).
148
# The following example is based on [`elixir_euler_triangulate_pkg_mesh.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_triangulate_pkg_mesh.jl)
149
# and uses a pre-defined mesh from StartUpDG.jl.
150
using OrdinaryDiffEqLowStorageRK
151
using Trixi
152
153
# We want to simulate the smooth initial condition [`initial_condition_convergence_test`](@ref)
154
# with source terms [`source_terms_convergence_test`](@ref) for the 2D compressible Euler equations.
155
equations = CompressibleEulerEquations2D(1.4)
156
initial_condition = initial_condition_convergence_test
157
source_terms = source_terms_convergence_test
158
159
# We create the solver `DGMulti` with triangular elements (`Tri()`) as before.
160
dg = DGMulti(polydeg = 3, element_type = Tri(),
161
approximation_type = Polynomial(),
162
surface_flux = flux_lax_friedrichs,
163
volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))
164
165
# StartUpDG.jl provides for instance a pre-defined Triangulate geometry for a rectangular domain with
166
# hole `RectangularDomainWithHole`. Other pre-defined Triangulate geometries are e.g., `SquareDomain`,
167
# `Scramjet`, and `CircularDomain`.
168
meshIO = StartUpDG.triangulate_domain(StartUpDG.RectangularDomainWithHole());
169
170
# The pre-defined Triangulate geometry in StartUpDG has integer boundary tags. With [`DGMultiMesh`](@ref)
171
# we assign boundary faces based on these integer boundary tags and create a mesh compatible with Trixi.jl.
172
mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary => 1, :inner_boundary => 2))
173
#-
174
boundary_condition_convergence_test = BoundaryConditionDirichlet(initial_condition)
175
boundary_conditions = (; outer_boundary = boundary_condition_convergence_test,
176
inner_boundary = boundary_condition_convergence_test)
177
178
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,
179
source_terms = source_terms,
180
boundary_conditions = boundary_conditions)
181
182
tspan = (0.0, 0.2)
183
ode = semidiscretize(semi, tspan)
184
185
alive_callback = AliveCallback(alive_interval = 20)
186
analysis_callback = AnalysisCallback(semi, interval = 200, uEltype = real(dg))
187
callbacks = CallbackSet(alive_callback, analysis_callback);
188
189
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);
190
dt = 0.5 * estimate_dt(mesh, dg),
191
ode_default_options()...,
192
callback = callbacks);
193
#-
194
using Plots
195
pd = PlotData2D(sol)
196
plot(pd["rho"])
197
plot!(getmesh(pd))
198
199
# For more information, please have a look in the [StartUpDG.jl documentation](https://jlchan.github.io/StartUpDG.jl/stable/).
200
201
# ## Package versions
202
203
# These results were obtained using the following versions.
204
205
using InteractiveUtils
206
versioninfo()
207
208
using Pkg
209
Pkg.status(["Trixi", "StartUpDG", "OrdinaryDiffEqLowStorageRK", "Plots"],
210
mode = PKGMODE_MANIFEST)
211
212