Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/equations/inviscid_burgers_1d.jl
2055 views
1
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).
2
# Since these FMAs can increase the performance of many numerical algorithms,
3
# we need to opt-in explicitly.
4
# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.
5
@muladd begin
6
#! format: noindent
7
8
@doc raw"""
9
InviscidBurgersEquation1D
10
11
The inviscid Burgers' equation
12
```math
13
\partial_t u + \frac{1}{2} \partial_1 u^2 = 0
14
```
15
in one space dimension.
16
"""
17
struct InviscidBurgersEquation1D <: AbstractInviscidBurgersEquation{1, 1} end
18
19
varnames(::typeof(cons2cons), ::InviscidBurgersEquation1D) = ("scalar",)
20
varnames(::typeof(cons2prim), ::InviscidBurgersEquation1D) = ("scalar",)
21
22
# Set initial conditions at physical location `x` for time `t`
23
"""
24
initial_condition_constant(x, t, equations::InviscidBurgersEquation1D)
25
26
A constant initial condition to test free-stream preservation.
27
"""
28
function initial_condition_constant(x, t, equation::InviscidBurgersEquation1D)
29
RealT = eltype(x)
30
return SVector(RealT(2))
31
end
32
33
"""
34
initial_condition_convergence_test(x, t, equations::InviscidBurgersEquation1D)
35
36
A smooth initial condition used for convergence tests.
37
"""
38
function initial_condition_convergence_test(x, t, equation::InviscidBurgersEquation1D)
39
RealT = eltype(x)
40
c = 2
41
A = 1
42
L = 1
43
f = 1.0f0 / L
44
omega = 2 * convert(RealT, pi) * f
45
scalar = c + A * sin(omega * (x[1] - t))
46
47
return SVector(scalar)
48
end
49
50
"""
51
source_terms_convergence_test(u, x, t, equations::InviscidBurgersEquation1D)
52
53
Source terms used for convergence tests in combination with
54
[`initial_condition_convergence_test`](@ref).
55
"""
56
@inline function source_terms_convergence_test(u, x, t,
57
equations::InviscidBurgersEquation1D)
58
# Same settings as in `initial_condition`
59
RealT = eltype(x)
60
c = 2
61
A = 1
62
L = 1
63
f = 1.0f0 / L
64
omega = 2 * convert(RealT, pi) * f
65
du = omega * A * cos(omega * (x[1] - t)) * (c - 1 + A * sin(omega * (x[1] - t)))
66
67
return SVector(du)
68
end
69
70
# Pre-defined source terms should be implemented as
71
# function source_terms_WHATEVER(u, x, t, equations::InviscidBurgersEquation1D)
72
73
# Calculate 1D flux for a single point
74
@inline function flux(u, orientation::Integer, equation::InviscidBurgersEquation1D)
75
return SVector(0.5f0 * u[1]^2)
76
end
77
78
# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation
79
@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,
80
equations::InviscidBurgersEquation1D)
81
u_L = u_ll[1]
82
u_R = u_rr[1]
83
84
return max(abs(u_L), abs(u_R))
85
end
86
87
# Calculate minimum and maximum wave speeds for HLL-type fluxes
88
@inline function min_max_speed_naive(u_ll, u_rr, orientation::Integer,
89
equations::InviscidBurgersEquation1D)
90
u_L = u_ll[1]
91
u_R = u_rr[1]
92
93
λ_min = min(u_L, u_R)
94
λ_max = max(u_L, u_R)
95
96
return λ_min, λ_max
97
end
98
99
@inline function max_abs_speeds(u, equation::InviscidBurgersEquation1D)
100
return (abs(u[1]),)
101
end
102
103
@doc raw"""
104
flux_ec(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)
105
106
Entropy-conserving, symmetric flux for the inviscid Burgers' equation.
107
```math
108
F(u_L, u_R) = \frac{u_L^2 + u_L u_R + u_R^2}{6}
109
```
110
"""
111
function flux_ec(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)
112
u_L = u_ll[1]
113
u_R = u_rr[1]
114
115
return SVector((u_L^2 + u_L * u_R + u_R^2) / 6)
116
end
117
118
"""
119
flux_godunov(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)
120
121
Godunov (upwind) numerical flux for the inviscid Burgers' equation.
122
See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,
123
section 4.1.5 and especially equation (4.16).
124
"""
125
function flux_godunov(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)
126
u_L = u_ll[1]
127
u_R = u_rr[1]
128
129
return SVector(0.5f0 * max(max(u_L, 0)^2, min(u_R, 0)^2))
130
end
131
132
# See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,
133
# section 4.2.5 and especially equation (4.34).
134
function flux_engquist_osher(u_ll, u_rr, orientation,
135
equation::InviscidBurgersEquation1D)
136
u_L = u_ll[1]
137
u_R = u_rr[1]
138
139
return SVector(0.5f0 * (max(u_L, 0)^2 + min(u_R, 0)^2))
140
end
141
142
"""
143
splitting_lax_friedrichs(u, orientation::Integer,
144
equations::InviscidBurgersEquation1D)
145
splitting_lax_friedrichs(u, which::Union{Val{:minus}, Val{:plus}}
146
orientation::Integer,
147
equations::InviscidBurgersEquation1D)
148
149
Naive local Lax-Friedrichs style flux splitting of the form `f⁺ = 0.5 (f + λ u)`
150
and `f⁻ = 0.5 (f - λ u)` where `λ = abs(u)`.
151
152
Returns a tuple of the fluxes "minus" (associated with waves going into the
153
negative axis direction) and "plus" (associated with waves going into the
154
positive axis direction). If only one of the fluxes is required, use the
155
function signature with argument `which` set to `Val{:minus}()` or `Val{:plus}()`.
156
157
!!! warning "Experimental implementation (upwind SBP)"
158
This is an experimental feature and may change in future releases.
159
"""
160
@inline function splitting_lax_friedrichs(u, orientation::Integer,
161
equations::InviscidBurgersEquation1D)
162
fm = splitting_lax_friedrichs(u, Val{:minus}(), orientation, equations)
163
fp = splitting_lax_friedrichs(u, Val{:plus}(), orientation, equations)
164
return fm, fp
165
end
166
167
@inline function splitting_lax_friedrichs(u, ::Val{:plus}, orientation::Integer,
168
equations::InviscidBurgersEquation1D)
169
f = 0.5f0 * u[1]^2
170
lambda = abs(u[1])
171
return SVector(0.5f0 * (f + lambda * u[1]))
172
end
173
174
@inline function splitting_lax_friedrichs(u, ::Val{:minus}, orientation::Integer,
175
equations::InviscidBurgersEquation1D)
176
f = 0.5f0 * u[1]^2
177
lambda = abs(u[1])
178
return SVector(0.5f0 * (f - lambda * u[1]))
179
end
180
181
# Convert conservative variables to primitive
182
@inline cons2prim(u, equation::InviscidBurgersEquation1D) = u
183
184
# Convert conservative variables to entropy variables
185
@inline cons2entropy(u, equation::InviscidBurgersEquation1D) = u
186
@inline entropy2cons(u, equation::InviscidBurgersEquation1D) = u
187
188
# Calculate entropy for a conservative state `cons`
189
@inline entropy(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2
190
@inline entropy(u, equation::InviscidBurgersEquation1D) = entropy(u[1], equation)
191
192
# Calculate total energy for a conservative state `cons`
193
@inline energy_total(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2
194
@inline function energy_total(u, equation::InviscidBurgersEquation1D)
195
energy_total(u[1], equation)
196
end
197
end # @muladd
198
199