Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/p4est_2d_dgsem/elixir_euler_subsonic_constant.jl
2055 views
1
using OrdinaryDiffEqSSPRK
2
using Trixi
3
using LinearAlgebra: norm
4
5
###############################################################################
6
## Semidiscretization of the compressible Euler equations
7
8
equations = CompressibleEulerEquations2D(1.4)
9
polydeg = 3
10
solver = DGSEM(polydeg = polydeg, surface_flux = flux_lax_friedrichs)
11
12
@inline function initial_condition_subsonic(x_, t, equations::CompressibleEulerEquations2D)
13
rho, v1, v2, p = (0.5313, 0.0, 0.0, 0.4)
14
15
prim = SVector(rho, v1, v2, p)
16
return prim2cons(prim, equations)
17
end
18
19
initial_condition = initial_condition_subsonic
20
21
# Calculate the boundary flux from the inner state while using the pressure from the outer state
22
# when the flow is subsonic (which is always the case in this example).
23
24
# If the naive approach of only using the inner state is used, the errors increase with the
25
# increase of refinement level, see https://github.com/trixi-framework/Trixi.jl/issues/2530
26
# These errors arise from the corner points in this test.
27
28
# See the reference below for a discussion on inflow/outflow boundary conditions. The subsonic
29
# outflow boundary conditions are discussed in Section 2.3.
30
#
31
# - Jan-Reneé Carlson (2011)
32
# Inflow/Outflow Boundary Conditions with Application to FUN3D.
33
# [NASA TM 20110022658](https://ntrs.nasa.gov/citations/20110022658)
34
@inline function boundary_condition_outflow_general(u_inner,
35
normal_direction::AbstractVector, x, t,
36
surface_flux_function,
37
equations::CompressibleEulerEquations2D)
38
39
# This would be for the general case where we need to check the magnitude of the local Mach number
40
norm_ = norm(normal_direction)
41
# Normalize the vector without using `normalize` since we need to multiply by the `norm_` later
42
normal = normal_direction / norm_
43
44
# Rotate the internal solution state
45
u_local = Trixi.rotate_to_x(u_inner, normal, equations)
46
47
# Compute the primitive variables
48
rho_local, v_normal, v_tangent, p_local = cons2prim(u_local, equations)
49
50
# Compute local Mach number
51
a_local = sqrt(equations.gamma * p_local / rho_local)
52
Mach_local = abs(v_normal / a_local)
53
if Mach_local <= 1.0 # The `if` is not needed in this elixir but kept for generality
54
# In general, `p_local` need not be available from the initial condition
55
p_local = pressure(initial_condition_subsonic(x, t, equations), equations)
56
end
57
58
# Create the `u_surface` solution state where the local pressure is possibly set from an external value
59
prim = SVector(rho_local, v_normal, v_tangent, p_local)
60
u_boundary = prim2cons(prim, equations)
61
u_surface = Trixi.rotate_from_x(u_boundary, normal, equations)
62
63
# Compute the flux using the appropriate mixture of internal / external solution states
64
return flux(u_surface, normal_direction, equations)
65
end
66
67
boundary_conditions = Dict(:x_neg => boundary_condition_outflow_general,
68
:x_pos => boundary_condition_outflow_general,
69
:y_neg => boundary_condition_outflow_general,
70
:y_pos => boundary_condition_outflow_general)
71
72
coordinates_min = (0.0, 0.0)
73
coordinates_max = (1.0, 1.0)
74
75
trees_per_dimension = (1, 1)
76
77
mesh = P4estMesh(trees_per_dimension, polydeg = polydeg,
78
coordinates_min = coordinates_min, coordinates_max = coordinates_max,
79
initial_refinement_level = 3,
80
periodicity = false)
81
82
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,
83
boundary_conditions = boundary_conditions)
84
85
###############################################################################
86
## ODE solvers, callbacks etc.
87
88
tspan = (0.0, 0.25)
89
ode = semidiscretize(semi, tspan)
90
91
summary_callback = SummaryCallback()
92
93
analysis_interval = 1000
94
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)
95
96
alive_callback = AliveCallback(analysis_interval = 100)
97
98
save_solution = SaveSolutionCallback(interval = 100,
99
save_initial_solution = true,
100
save_final_solution = true,
101
solution_variables = cons2prim)
102
103
stepsize_callback = StepsizeCallback(cfl = 0.5)
104
105
callbacks = CallbackSet(summary_callback,
106
analysis_callback, alive_callback,
107
save_solution,
108
stepsize_callback)
109
110
###############################################################################
111
## Run the simulation
112
sol = solve(ode, SSPRK54();
113
dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
114
save_everystep = false, callback = callbacks);
115
116