Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/equations/compressible_euler_multicomponent_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
CompressibleEulerMulticomponentEquations1D(; gammas, gas_constants)
10
11
Multicomponent version of the compressible Euler equations
12
```math
13
\frac{\partial}{\partial t}
14
\begin{pmatrix}
15
\rho v_1 \\ \rho e \\ \rho_1 \\ \rho_2 \\ \vdots \\ \rho_{n}
16
\end{pmatrix}
17
+
18
\frac{\partial}{\partial x}
19
\begin{pmatrix}
20
\rho v_1^2 + p \\ (\rho e +p) v_1 \\ \rho_1 v_1 \\ \rho_2 v_1 \\ \vdots \\ \rho_{n} v_1
21
\end{pmatrix}
22
23
=
24
\begin{pmatrix}
25
0 \\ 0 \\ 0 \\ 0 \\ \vdots \\ 0
26
\end{pmatrix}
27
```
28
for calorically perfect gas in one space dimension.
29
Here, ``\rho_i`` is the density of component ``i``, ``\rho=\sum_{i=1}^n\rho_i`` the sum of the individual ``\rho_i``,
30
``v_1`` the velocity, ``e`` the specific total energy **rather than** specific internal energy, and
31
```math
32
p = (\gamma - 1) \left( \rho e - \frac{1}{2} \rho v_1^2 \right)
33
```
34
the pressure,
35
```math
36
\gamma=\frac{\sum_{i=1}^n\rho_i C_{v,i}\gamma_i}{\sum_{i=1}^n\rho_i C_{v,i}}
37
```
38
total heat capacity ratio, ``\gamma_i`` heat capacity ratio of component ``i``,
39
```math
40
C_{v,i}=\frac{R}{\gamma_i-1}
41
```
42
specific heat capacity at constant volume of component ``i``.
43
44
In case of more than one component, the specific heat ratios `gammas` and the gas constants
45
`gas_constants` should be passed as tuples, e.g., `gammas=(1.4, 1.667)`.
46
47
The remaining variables like the specific heats at constant volume `cv` or the specific heats at
48
constant pressure `cp` are then calculated considering a calorically perfect gas.
49
"""
50
struct CompressibleEulerMulticomponentEquations1D{NVARS, NCOMP, RealT <: Real} <:
51
AbstractCompressibleEulerMulticomponentEquations{1, NVARS, NCOMP}
52
gammas::SVector{NCOMP, RealT}
53
gas_constants::SVector{NCOMP, RealT}
54
cv::SVector{NCOMP, RealT}
55
cp::SVector{NCOMP, RealT}
56
57
function CompressibleEulerMulticomponentEquations1D{NVARS, NCOMP, RealT}(gammas::SVector{NCOMP,
58
RealT},
59
gas_constants::SVector{NCOMP,
60
RealT}) where {
61
NVARS,
62
NCOMP,
63
RealT <:
64
Real
65
}
66
NCOMP >= 1 ||
67
throw(DimensionMismatch("`gammas` and `gas_constants` have to be filled with at least one value"))
68
69
cv = gas_constants ./ (gammas .- 1)
70
cp = gas_constants + gas_constants ./ (gammas .- 1)
71
72
new(gammas, gas_constants, cv, cp)
73
end
74
end
75
76
function CompressibleEulerMulticomponentEquations1D(; gammas, gas_constants)
77
_gammas = promote(gammas...)
78
_gas_constants = promote(gas_constants...)
79
RealT = promote_type(eltype(_gammas), eltype(_gas_constants),
80
typeof(gas_constants[1] / (gammas[1] - 1)))
81
__gammas = SVector(map(RealT, _gammas))
82
__gas_constants = SVector(map(RealT, _gas_constants))
83
84
NVARS = length(_gammas) + 2
85
NCOMP = length(_gammas)
86
87
return CompressibleEulerMulticomponentEquations1D{NVARS, NCOMP, RealT}(__gammas,
88
__gas_constants)
89
end
90
91
@inline function Base.real(::CompressibleEulerMulticomponentEquations1D{NVARS, NCOMP,
92
RealT}) where {
93
NVARS,
94
NCOMP,
95
RealT
96
}
97
RealT
98
end
99
100
function varnames(::typeof(cons2cons),
101
equations::CompressibleEulerMulticomponentEquations1D)
102
cons = ("rho_v1", "rho_e")
103
rhos = ntuple(n -> "rho" * string(n), Val(ncomponents(equations)))
104
return (cons..., rhos...)
105
end
106
107
function varnames(::typeof(cons2prim),
108
equations::CompressibleEulerMulticomponentEquations1D)
109
prim = ("v1", "p")
110
rhos = ntuple(n -> "rho" * string(n), Val(ncomponents(equations)))
111
return (prim..., rhos...)
112
end
113
114
# Set initial conditions at physical location `x` for time `t`
115
116
"""
117
initial_condition_convergence_test(x, t, equations::CompressibleEulerMulticomponentEquations1D)
118
119
A smooth initial condition used for convergence tests in combination with
120
[`source_terms_convergence_test`](@ref)
121
(and [`BoundaryConditionDirichlet(initial_condition_convergence_test)`](@ref) in non-periodic domains).
122
"""
123
function initial_condition_convergence_test(x, t,
124
equations::CompressibleEulerMulticomponentEquations1D)
125
RealT = eltype(x)
126
c = 2
127
A = convert(RealT, 0.1)
128
L = 2
129
f = 1.0f0 / L
130
omega = 2 * convert(RealT, pi) * f
131
ini = c + A * sin(omega * (x[1] - t))
132
133
v1 = 1
134
135
rho = ini
136
137
# Here we compute an arbitrary number of different rhos. (one rho is double the next rho while the sum of all rhos is 1)
138
prim_rho = SVector{ncomponents(equations), real(equations)}(2^(i - 1) * (1 - 2) *
139
rho / (1 -
140
2^ncomponents(equations))
141
for i in eachcomponent(equations))
142
143
prim1 = rho * v1
144
prim2 = rho^2
145
146
prim_other = SVector(prim1, prim2)
147
148
return vcat(prim_other, prim_rho)
149
end
150
151
"""
152
source_terms_convergence_test(u, x, t, equations::CompressibleEulerMulticomponentEquations1D)
153
154
Source terms used for convergence tests in combination with
155
[`initial_condition_convergence_test`](@ref)
156
(and [`BoundaryConditionDirichlet(initial_condition_convergence_test)`](@ref) in non-periodic domains).
157
"""
158
@inline function source_terms_convergence_test(u, x, t,
159
equations::CompressibleEulerMulticomponentEquations1D)
160
# Same settings as in `initial_condition`
161
RealT = eltype(u)
162
c = 2
163
A = convert(RealT, 0.1)
164
L = 2
165
f = 1.0f0 / L
166
omega = 2 * convert(RealT, pi) * f
167
168
gamma = totalgamma(u, equations)
169
170
x1, = x
171
si, co = sincos((t - x1) * omega)
172
tmp = (-((4 * si * A - 4 * c) + 1) * (gamma - 1) * co * A * omega) / 2
173
174
# Here we compute an arbitrary number of different rhos. (one rho is double the next rho while the sum of all rhos is 1
175
du_rho = SVector{ncomponents(equations), real(equations)}(0
176
for i in eachcomponent(equations))
177
178
du1 = tmp
179
du2 = tmp
180
181
du_other = SVector(du1, du2)
182
183
return vcat(du_other, du_rho)
184
end
185
186
"""
187
initial_condition_weak_blast_wave(x, t, equations::CompressibleEulerMulticomponentEquations1D)
188
189
A for multicomponent adapted weak blast wave adapted to multicomponent and taken from
190
- Sebastian Hennemann, Gregor J. Gassner (2020)
191
A provably entropy stable subcell shock capturing approach for high order split form DG
192
[arXiv: 2008.12044](https://arxiv.org/abs/2008.12044)
193
"""
194
function initial_condition_weak_blast_wave(x, t,
195
equations::CompressibleEulerMulticomponentEquations1D)
196
# From Hennemann & Gassner JCP paper 2020 (Sec. 6.3)
197
RealT = eltype(x)
198
inicenter = SVector(0)
199
x_norm = x[1] - inicenter[1]
200
r = abs(x_norm)
201
cos_phi = x_norm > 0 ? 1 : -1
202
203
prim_rho = SVector{ncomponents(equations), real(equations)}(r > 0.5f0 ?
204
2^(i - 1) * (1 - 2) /
205
(RealT(1) -
206
2^ncomponents(equations)) :
207
2^(i - 1) * (1 - 2) *
208
RealT(1.1691) /
209
(1 -
210
2^ncomponents(equations))
211
for i in eachcomponent(equations))
212
213
v1 = r > 0.5f0 ? zero(RealT) : convert(RealT, 0.1882) * cos_phi
214
p = r > 0.5f0 ? one(RealT) : convert(RealT, 1.245)
215
216
prim_other = SVector(v1, p)
217
218
return prim2cons(vcat(prim_other, prim_rho), equations)
219
end
220
221
# Calculate 1D flux for a single point
222
@inline function flux(u, orientation::Integer,
223
equations::CompressibleEulerMulticomponentEquations1D)
224
rho_v1, rho_e = u
225
226
rho = density(u, equations)
227
228
v1 = rho_v1 / rho
229
gamma = totalgamma(u, equations)
230
p = (gamma - 1) * (rho_e - 0.5f0 * rho * v1^2)
231
232
f_rho = densities(u, v1, equations)
233
f1 = rho_v1 * v1 + p
234
f2 = (rho_e + p) * v1
235
236
f_other = SVector(f1, f2)
237
238
return vcat(f_other, f_rho)
239
end
240
241
"""
242
flux_chandrashekar(u_ll, u_rr, orientation, equations::CompressibleEulerMulticomponentEquations1D)
243
244
Entropy conserving two-point flux by
245
- Ayoub Gouasmi, Karthik Duraisamy (2020)
246
"Formulation of Entropy-Stable schemes for the multicomponent compressible Euler equations"
247
[arXiv:1904.00972v3](https://arxiv.org/abs/1904.00972) [math.NA] 4 Feb 2020
248
"""
249
@inline function flux_chandrashekar(u_ll, u_rr, orientation::Integer,
250
equations::CompressibleEulerMulticomponentEquations1D)
251
# Unpack left and right state
252
@unpack gammas, gas_constants, cv = equations
253
rho_v1_ll, rho_e_ll = u_ll
254
rho_v1_rr, rho_e_rr = u_rr
255
rhok_mean = SVector{ncomponents(equations), real(equations)}(ln_mean(u_ll[i + 2],
256
u_rr[i + 2])
257
for i in eachcomponent(equations))
258
rhok_avg = SVector{ncomponents(equations), real(equations)}(0.5f0 * (u_ll[i + 2] +
259
u_rr[i + 2])
260
for i in eachcomponent(equations))
261
262
# Iterating over all partial densities
263
rho_ll = density(u_ll, equations)
264
rho_rr = density(u_rr, equations)
265
266
gamma_ll = totalgamma(u_ll, equations)
267
gamma_rr = totalgamma(u_rr, equations)
268
269
# extract velocities
270
v1_ll = rho_v1_ll / rho_ll
271
v1_rr = rho_v1_rr / rho_rr
272
v1_avg = 0.5f0 * (v1_ll + v1_rr)
273
v1_square = 0.5f0 * (v1_ll^2 + v1_rr^2)
274
v_sum = v1_avg
275
276
RealT = eltype(u_ll)
277
enth = zero(RealT)
278
help1_ll = zero(RealT)
279
help1_rr = zero(RealT)
280
281
for i in eachcomponent(equations)
282
enth += rhok_avg[i] * gas_constants[i]
283
help1_ll += u_ll[i + 2] * cv[i]
284
help1_rr += u_rr[i + 2] * cv[i]
285
end
286
287
T_ll = (rho_e_ll - 0.5f0 * rho_ll * (v1_ll^2)) / help1_ll
288
T_rr = (rho_e_rr - 0.5f0 * rho_rr * (v1_rr^2)) / help1_rr
289
T = 0.5f0 * (1 / T_ll + 1 / T_rr)
290
T_log = ln_mean(1 / T_ll, 1 / T_rr)
291
292
# Calculate fluxes depending on orientation
293
help1 = zero(RealT)
294
help2 = zero(RealT)
295
296
f_rho = SVector{ncomponents(equations), real(equations)}(rhok_mean[i] * v1_avg
297
for i in eachcomponent(equations))
298
for i in eachcomponent(equations)
299
help1 += f_rho[i] * cv[i]
300
help2 += f_rho[i]
301
end
302
f1 = (help2) * v1_avg + enth / T
303
f2 = (help1) / T_log - 0.5f0 * (v1_square) * (help2) + v1_avg * f1
304
305
f_other = SVector(f1, f2)
306
307
return vcat(f_other, f_rho)
308
end
309
310
"""
311
flux_ranocha(u_ll, u_rr, orientation_or_normal_direction,
312
equations::CompressibleEulerMulticomponentEquations1D)
313
314
Adaption of the entropy conserving and kinetic energy preserving two-point flux by
315
- Hendrik Ranocha (2018)
316
Generalised Summation-by-Parts Operators and Entropy Stability of Numerical Methods
317
for Hyperbolic Balance Laws
318
[PhD thesis, TU Braunschweig](https://cuvillier.de/en/shop/publications/7743)
319
See also
320
- Hendrik Ranocha (2020)
321
Entropy Conserving and Kinetic Energy Preserving Numerical Methods for
322
the Euler Equations Using Summation-by-Parts Operators
323
[Proceedings of ICOSAHOM 2018](https://doi.org/10.1007/978-3-030-39647-3_42)
324
"""
325
@inline function flux_ranocha(u_ll, u_rr, orientation::Integer,
326
equations::CompressibleEulerMulticomponentEquations1D)
327
# Unpack left and right state
328
@unpack gammas, gas_constants, cv = equations
329
rho_v1_ll, rho_e_ll = u_ll
330
rho_v1_rr, rho_e_rr = u_rr
331
rhok_mean = SVector{ncomponents(equations), real(equations)}(ln_mean(u_ll[i + 2],
332
u_rr[i + 2])
333
for i in eachcomponent(equations))
334
rhok_avg = SVector{ncomponents(equations), real(equations)}(0.5f0 * (u_ll[i + 2] +
335
u_rr[i + 2])
336
for i in eachcomponent(equations))
337
338
# Iterating over all partial densities
339
rho_ll = density(u_ll, equations)
340
rho_rr = density(u_rr, equations)
341
342
# Calculating gamma
343
gamma = totalgamma(0.5f0 * (u_ll + u_rr), equations)
344
inv_gamma_minus_one = 1 / (gamma - 1)
345
346
# extract velocities
347
v1_ll = rho_v1_ll / rho_ll
348
v1_rr = rho_v1_rr / rho_rr
349
v1_avg = 0.5f0 * (v1_ll + v1_rr)
350
velocity_square_avg = 0.5f0 * (v1_ll * v1_rr)
351
352
# density flux
353
f_rho = SVector{ncomponents(equations), real(equations)}(rhok_mean[i] * v1_avg
354
for i in eachcomponent(equations))
355
356
# helpful variables
357
RealT = eltype(u_ll)
358
f_rho_sum = zero(RealT)
359
help1_ll = zero(RealT)
360
help1_rr = zero(RealT)
361
enth_ll = zero(RealT)
362
enth_rr = zero(RealT)
363
for i in eachcomponent(equations)
364
enth_ll += u_ll[i + 2] * gas_constants[i]
365
enth_rr += u_rr[i + 2] * gas_constants[i]
366
f_rho_sum += f_rho[i]
367
help1_ll += u_ll[i + 2] * cv[i]
368
help1_rr += u_rr[i + 2] * cv[i]
369
end
370
371
# temperature and pressure
372
T_ll = (rho_e_ll - 0.5f0 * rho_ll * (v1_ll^2)) / help1_ll
373
T_rr = (rho_e_rr - 0.5f0 * rho_rr * (v1_rr^2)) / help1_rr
374
p_ll = T_ll * enth_ll
375
p_rr = T_rr * enth_rr
376
p_avg = 0.5f0 * (p_ll + p_rr)
377
inv_rho_p_mean = p_ll * p_rr * inv_ln_mean(rho_ll * p_rr, rho_rr * p_ll)
378
379
# momentum and energy flux
380
f1 = f_rho_sum * v1_avg + p_avg
381
f2 = f_rho_sum * (velocity_square_avg + inv_rho_p_mean * inv_gamma_minus_one) +
382
0.5f0 * (p_ll * v1_rr + p_rr * v1_ll)
383
f_other = SVector(f1, f2)
384
385
return vcat(f_other, f_rho)
386
end
387
388
# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation
389
@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,
390
equations::CompressibleEulerMulticomponentEquations1D)
391
rho_v1_ll, rho_e_ll = u_ll
392
rho_v1_rr, rho_e_rr = u_rr
393
394
# Calculate primitive variables and speed of sound
395
rho_ll = density(u_ll, equations)
396
rho_rr = density(u_rr, equations)
397
gamma_ll = totalgamma(u_ll, equations)
398
gamma_rr = totalgamma(u_rr, equations)
399
400
v_ll = rho_v1_ll / rho_ll
401
v_rr = rho_v1_rr / rho_rr
402
403
p_ll = (gamma_ll - 1) * (rho_e_ll - 0.5f0 * rho_ll * v_ll^2)
404
p_rr = (gamma_rr - 1) * (rho_e_rr - 0.5f0 * rho_rr * v_rr^2)
405
c_ll = sqrt(gamma_ll * p_ll / rho_ll)
406
c_rr = sqrt(gamma_rr * p_rr / rho_rr)
407
408
return max(abs(v_ll), abs(v_rr)) + max(c_ll, c_rr)
409
end
410
411
# Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive`
412
@inline function max_abs_speed(u_ll, u_rr, orientation::Integer,
413
equations::CompressibleEulerMulticomponentEquations1D)
414
rho_v1_ll, rho_e_ll = u_ll
415
rho_v1_rr, rho_e_rr = u_rr
416
417
# Calculate primitive variables and speed of sound
418
rho_ll = density(u_ll, equations)
419
rho_rr = density(u_rr, equations)
420
gamma_ll = totalgamma(u_ll, equations)
421
gamma_rr = totalgamma(u_rr, equations)
422
423
v_ll = rho_v1_ll / rho_ll
424
v_rr = rho_v1_rr / rho_rr
425
426
p_ll = (gamma_ll - 1) * (rho_e_ll - 0.5f0 * rho_ll * v_ll^2)
427
p_rr = (gamma_rr - 1) * (rho_e_rr - 0.5f0 * rho_rr * v_rr^2)
428
c_ll = sqrt(gamma_ll * p_ll / rho_ll)
429
c_rr = sqrt(gamma_rr * p_rr / rho_rr)
430
431
return max(abs(v_ll) + c_ll, abs(v_rr) + c_rr)
432
end
433
434
@inline function max_abs_speeds(u,
435
equations::CompressibleEulerMulticomponentEquations1D)
436
rho_v1, rho_e = u
437
438
rho = density(u, equations)
439
v1 = rho_v1 / rho
440
441
gamma = totalgamma(u, equations)
442
p = (gamma - 1) * (rho_e - 0.5f0 * rho * (v1^2))
443
c = sqrt(gamma * p / rho)
444
445
return (abs(v1) + c,)
446
end
447
448
# Convert conservative variables to primitive
449
@inline function cons2prim(u, equations::CompressibleEulerMulticomponentEquations1D)
450
rho_v1, rho_e = u
451
452
prim_rho = SVector{ncomponents(equations), real(equations)}(u[i + 2]
453
for i in eachcomponent(equations))
454
455
rho = density(u, equations)
456
v1 = rho_v1 / rho
457
gamma = totalgamma(u, equations)
458
459
p = (gamma - 1) * (rho_e - 0.5f0 * rho * (v1^2))
460
prim_other = SVector(v1, p)
461
462
return vcat(prim_other, prim_rho)
463
end
464
465
# Convert primitive to conservative variables
466
@inline function prim2cons(prim, equations::CompressibleEulerMulticomponentEquations1D)
467
@unpack cv, gammas = equations
468
v1, p = prim
469
470
RealT = eltype(prim)
471
472
cons_rho = SVector{ncomponents(equations), RealT}(prim[i + 2]
473
for i in eachcomponent(equations))
474
rho = density(prim, equations)
475
gamma = totalgamma(prim, equations)
476
477
rho_v1 = rho * v1
478
479
rho_e = p / (gamma - 1) + 0.5f0 * (rho_v1 * v1)
480
481
cons_other = SVector{2, RealT}(rho_v1, rho_e)
482
483
return vcat(cons_other, cons_rho)
484
end
485
486
# Convert conservative variables to entropy
487
@inline function cons2entropy(u, equations::CompressibleEulerMulticomponentEquations1D)
488
@unpack cv, gammas, gas_constants = equations
489
490
rho_v1, rho_e = u
491
492
rho = density(u, equations)
493
494
RealT = eltype(u)
495
help1 = zero(RealT)
496
gas_constant = zero(RealT)
497
for i in eachcomponent(equations)
498
help1 += u[i + 2] * cv[i]
499
gas_constant += gas_constants[i] * (u[i + 2] / rho)
500
end
501
502
v1 = rho_v1 / rho
503
v_square = v1^2
504
gamma = totalgamma(u, equations)
505
506
p = (gamma - 1) * (rho_e - 0.5f0 * rho * v_square)
507
s = log(p) - gamma * log(rho) - log(gas_constant)
508
rho_p = rho / p
509
T = (rho_e - 0.5f0 * rho * v_square) / (help1)
510
511
entrop_rho = SVector{ncomponents(equations), real(equations)}((cv[i] *
512
(1 - log(T)) +
513
gas_constants[i] *
514
(1 + log(u[i + 2])) -
515
v1^2 / (2 * T))
516
for i in eachcomponent(equations))
517
518
w1 = gas_constant * v1 * rho_p
519
w2 = gas_constant * (-rho_p)
520
521
entrop_other = SVector(w1, w2)
522
523
return vcat(entrop_other, entrop_rho)
524
end
525
526
# Convert entropy variables to conservative variables
527
@inline function entropy2cons(w, equations::CompressibleEulerMulticomponentEquations1D)
528
@unpack gammas, gas_constants, cv, cp = equations
529
T = -1 / w[2]
530
v1 = w[1] * T
531
cons_rho = SVector{ncomponents(equations), real(equations)}(exp(1 /
532
gas_constants[i] *
533
(-cv[i] *
534
log(-w[2]) -
535
cp[i] + w[i + 2] -
536
0.5f0 * w[1]^2 /
537
w[2]))
538
for i in eachcomponent(equations))
539
540
RealT = eltype(w)
541
rho = zero(RealT)
542
help1 = zero(RealT)
543
help2 = zero(RealT)
544
p = zero(RealT)
545
for i in eachcomponent(equations)
546
rho += cons_rho[i]
547
help1 += cons_rho[i] * cv[i] * gammas[i]
548
help2 += cons_rho[i] * cv[i]
549
p += cons_rho[i] * gas_constants[i] * T
550
end
551
u1 = rho * v1
552
gamma = help1 / help2
553
u2 = p / (gamma - 1) + 0.5f0 * rho * v1^2
554
cons_other = SVector(u1, u2)
555
return vcat(cons_other, cons_rho)
556
end
557
558
@inline function total_entropy(u, equations::CompressibleEulerMulticomponentEquations1D)
559
@unpack cv, gammas, gas_constants = equations
560
rho_v1, rho_e = u
561
rho = density(u, equations)
562
T = temperature(u, equations)
563
564
RealT = eltype(u)
565
total_entropy = zero(RealT)
566
for i in eachcomponent(equations)
567
total_entropy -= u[i + 2] * (cv[i] * log(T) - gas_constants[i] * log(u[i + 2]))
568
end
569
570
return total_entropy
571
end
572
573
@inline function temperature(u, equations::CompressibleEulerMulticomponentEquations1D)
574
@unpack cv, gammas, gas_constants = equations
575
576
rho_v1, rho_e = u
577
578
rho = density(u, equations)
579
580
RealT = eltype(u)
581
help1 = zero(RealT)
582
583
for i in eachcomponent(equations)
584
help1 += u[i + 2] * cv[i]
585
end
586
587
v1 = rho_v1 / rho
588
v_square = v1^2
589
T = (rho_e - 0.5f0 * rho * v_square) / help1
590
591
return T
592
end
593
594
"""
595
totalgamma(u, equations::CompressibleEulerMulticomponentEquations1D)
596
597
Function that calculates the total gamma out of all partial gammas using the
598
partial density fractions as well as the partial specific heats at constant volume.
599
"""
600
@inline function totalgamma(u, equations::CompressibleEulerMulticomponentEquations1D)
601
@unpack cv, gammas = equations
602
603
RealT = eltype(u)
604
help1 = zero(RealT)
605
help2 = zero(RealT)
606
607
for i in eachcomponent(equations)
608
help1 += u[i + 2] * cv[i] * gammas[i]
609
help2 += u[i + 2] * cv[i]
610
end
611
612
return help1 / help2
613
end
614
615
@inline function pressure(u, equations::CompressibleEulerMulticomponentEquations1D)
616
rho_v1, rho_e = u
617
618
rho = density(u, equations)
619
gamma = totalgamma(u, equations)
620
621
p = (gamma - 1) * (rho_e - 0.5f0 * (rho_v1^2) / rho)
622
623
return p
624
end
625
626
@inline function density(u, equations::CompressibleEulerMulticomponentEquations1D)
627
RealT = eltype(u)
628
rho = zero(RealT)
629
630
for i in eachcomponent(equations)
631
rho += u[i + 2]
632
end
633
634
return rho
635
end
636
637
@inline function densities(u, v, equations::CompressibleEulerMulticomponentEquations1D)
638
return SVector{ncomponents(equations), real(equations)}(u[i + 2] * v
639
for i in eachcomponent(equations))
640
end
641
642
@inline function velocity(u, equations::CompressibleEulerMulticomponentEquations1D)
643
rho = density(u, equations)
644
v1 = u[1] / rho
645
return v1
646
end
647
end # @muladd
648
649