Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/examples/tree_3d_dgsem/elixir_navierstokes_viscous_shock.jl
5586 views
1
using OrdinaryDiffEqLowStorageRK
2
using Trixi
3
4
# This is the classic 1D viscous shock wave problem with analytical solution
5
# for a special value of the Prandtl number.
6
# The original references are:
7
#
8
# - R. Becker (1922)
9
# Stoßwelle und Detonation.
10
# [DOI: 10.1007/BF01329605](https://doi.org/10.1007/BF01329605)
11
#
12
# English translations:
13
# Impact waves and detonation. Part I.
14
# https://ntrs.nasa.gov/api/citations/19930090862/downloads/19930090862.pdf
15
# Impact waves and detonation. Part II.
16
# https://ntrs.nasa.gov/api/citations/19930090863/downloads/19930090863.pdf
17
#
18
# - M. Morduchow, P. A. Libby (1949)
19
# On a Complete Solution of the One-Dimensional Flow Equations
20
# of a Viscous, Head-Conducting, Compressible Gas
21
# [DOI: 10.2514/8.11882](https://doi.org/10.2514/8.11882)
22
#
23
#
24
# The particular problem considered here is described in
25
# - L. G. Margolin, J. M. Reisner, P. M. Jordan (2017)
26
# Entropy in self-similar shock profiles
27
# [DOI: 10.1016/j.ijnonlinmec.2017.07.003](https://doi.org/10.1016/j.ijnonlinmec.2017.07.003)
28
29
### Fixed parameters ###
30
31
# Special value for which nonlinear solver can be omitted
32
# Corresponds essentially to fixing the Mach number
33
alpha = 0.5
34
# We want kappa = cp * mu = mu_bar to ensure constant enthalpy
35
prandtl_number() = 3 / 4
36
37
### Free choices: ###
38
gamma() = 5 / 3
39
40
# In Margolin et al., the Navier-Stokes equations are given for an
41
# isotropic stress tensor τ, i.e., ∇ ⋅ τ = μ Δu
42
mu_isotropic() = 0.15
43
mu_bar() = mu_isotropic() / (gamma() - 1) # Re-scaled viscosity
44
45
rho_0() = 1
46
v() = 1 # Shock speed
47
48
domain_length = 4.0
49
50
### Derived quantities ###
51
52
Ma() = 2 / sqrt(3 - gamma()) # Mach number for alpha = 0.5
53
c_0() = v() / Ma() # Speed of sound ahead of the shock
54
55
# From constant enthalpy condition
56
p_0() = c_0()^2 * rho_0() / gamma()
57
58
l() = mu_bar() / (rho_0() * v()) * 2 * gamma() / (gamma() + 1) # Appropriate length scale
59
60
"""
61
initial_condition_viscous_shock(x, t, equations)
62
63
Classic 1D viscous shock wave problem with analytical solution
64
for a special value of the Prandtl number.
65
The version implemented here is described in
66
- L. G. Margolin, J. M. Reisner, P. M. Jordan (2017)
67
Entropy in self-similar shock profiles
68
[DOI: 10.1016/j.ijnonlinmec.2017.07.003](https://doi.org/10.1016/j.ijnonlinmec.2017.07.003)
69
"""
70
function initial_condition_viscous_shock(x, t, equations)
71
y = x[1] - v() * t # Translated coordinate
72
73
# Coordinate transformation. See eq. (33) in Margolin et al. (2017)
74
chi = 2 * exp(y / (2 * l()))
75
76
w = 1 + 1 / (2 * chi^2) * (1 - sqrt(1 + 2 * chi^2))
77
78
rho = rho_0() / w
79
u = v() * (1 - w)
80
p = p_0() * 1 / w * (1 + (gamma() - 1) / 2 * Ma()^2 * (1 - w^2))
81
82
return prim2cons(SVector(rho, u, 0, 0, p), equations)
83
end
84
initial_condition = initial_condition_viscous_shock
85
86
###############################################################################
87
# semidiscretization of the ideal compressible Navier-Stokes equations
88
89
equations = CompressibleEulerEquations3D(gamma())
90
91
# Trixi implements the stress tensor in deviatoric form, thus we need to
92
# convert the "isotropic viscosity" to the "deviatoric viscosity"
93
mu_deviatoric() = mu_bar() * 3 / 4
94
equations_parabolic = CompressibleNavierStokesDiffusion3D(equations, mu = mu_deviatoric(),
95
Prandtl = prandtl_number(),
96
gradient_variables = GradientVariablesPrimitive())
97
98
solver = DGSEM(polydeg = 3, surface_flux = flux_hlle)
99
100
coordinates_min = (-domain_length / 2, -domain_length / 2, -domain_length / 2)
101
coordinates_max = (domain_length / 2, domain_length / 2, domain_length / 2)
102
103
mesh = TreeMesh(coordinates_min, coordinates_max,
104
initial_refinement_level = 3,
105
periodicity = (false, true, true),
106
n_cells_max = 100_000)
107
108
### Inviscid boundary conditions ###
109
110
# Prescribe pure influx based on initial conditions
111
function boundary_condition_inflow(u_inner, orientation, direction, x, t,
112
surface_flux_function,
113
equations::CompressibleEulerEquations3D)
114
u_cons = initial_condition_viscous_shock(x, t, equations)
115
return flux(u_cons, orientation, equations)
116
end
117
118
# Completely free outflow
119
function boundary_condition_outflow(u_inner, orientation, direction, x, t,
120
surface_flux_function,
121
equations::CompressibleEulerEquations3D)
122
# Calculate the boundary flux entirely from the internal solution state
123
return flux(u_inner, orientation, equations)
124
end
125
126
boundary_conditions = (; x_neg = boundary_condition_inflow,
127
x_pos = boundary_condition_outflow,
128
y_neg = boundary_condition_periodic,
129
y_pos = boundary_condition_periodic,
130
z_neg = boundary_condition_periodic,
131
z_pos = boundary_condition_periodic)
132
133
### Viscous boundary conditions ###
134
# For the viscous BCs, we use the known analytical solution
135
velocity_bc = NoSlip() do x, t, equations_parabolic
136
return Trixi.velocity(initial_condition_viscous_shock(x,
137
t,
138
equations_parabolic),
139
equations_parabolic)
140
end
141
142
heat_bc = Isothermal() do x, t, equations_parabolic
143
return Trixi.temperature(initial_condition_viscous_shock(x,
144
t,
145
equations_parabolic),
146
equations_parabolic)
147
end
148
149
boundary_condition_parabolic = BoundaryConditionNavierStokesWall(velocity_bc, heat_bc)
150
151
boundary_conditions_parabolic = (x_neg = boundary_condition_parabolic,
152
x_pos = boundary_condition_parabolic,
153
y_neg = boundary_condition_periodic,
154
y_pos = boundary_condition_periodic,
155
z_neg = boundary_condition_periodic,
156
z_pos = boundary_condition_periodic)
157
158
semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),
159
initial_condition, solver;
160
boundary_conditions = (boundary_conditions,
161
boundary_conditions_parabolic))
162
163
###############################################################################
164
# ODE solvers, callbacks etc.
165
166
# Create ODE problem with time span `tspan`
167
tspan = (0.0, 0.5)
168
ode = semidiscretize(semi, tspan)
169
170
summary_callback = SummaryCallback()
171
172
alive_callback = AliveCallback(alive_interval = 10)
173
174
analysis_interval = 100
175
analysis_callback = AnalysisCallback(semi, interval = analysis_interval)
176
177
# For this setup, both hyperbolic and parabolic timestep restrictions are relevant, i.e.,
178
# may not be increased beyond the given values.
179
stepsize_callback = StepsizeCallback(cfl = 0.4,
180
cfl_parabolic = 0.2)
181
182
callbacks = CallbackSet(summary_callback, alive_callback, analysis_callback,
183
stepsize_callback)
184
185
###############################################################################
186
# run the simulation
187
188
# Use time integrator tailored to compressible Navier-Stokes
189
sol = solve(ode, CKLLSRK95_4S(), adaptive = false, dt = 1.0,
190
save_everystep = false, callback = callbacks);
191
192