Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/src/equations/equation_of_state_vdw.jl
5586 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
VanDerWaals{RealT <: Real} <: AbstractEquationOfState
10
11
This defines the van der Waals equation of state
12
given by the pressure and internal energy relations
13
```math
14
p = \frac{\rho R T}{1 - \rho b} - a \rho^2, \quad e_{\text{internal}} = c_v T - a \rho
15
```
16
with ``c_v = \frac{R}{\gamma - 1}``. This corresponds to the "simple
17
van der Waals" fluid with constant `c_v`, which can be found on p28 of
18
<https://math.berkeley.edu/~evans/entropy.and.PDE.pdf>.
19
20
See also "An oscillation free shock-capturing method for compressible van
21
der Waals supercritical fluid flows" by Pantano, Saurel, and Schmitt (2017).
22
<https://doi.org/10.1016/j.jcp.2017.01.057>
23
"""
24
struct VanDerWaals{RealT <: Real} <: AbstractEquationOfState
25
# van der Waals specific parameters
26
a::RealT # molecular attraction
27
b::RealT # excluded volume or co-volume
28
29
# Standard thermodynamic gas parameters
30
gamma::RealT
31
R::RealT
32
cv::RealT
33
end
34
35
"""
36
VanDerWaals(; a = 174.64049524257663, b = 0.001381308696129041,
37
gamma = 5 / 3, R = 296.8390795484912)
38
39
By default, van der Waals parameters are for N2.
40
"""
41
function VanDerWaals(; a = 174.64049524257663, b = 0.001381308696129041,
42
gamma = 5 / 3, R = 296.8390795484912)
43
cv = R / (gamma - 1)
44
return VanDerWaals(promote(a, b, gamma, R, cv)...)
45
end
46
47
"""
48
pressure(V, T, eos::VanDerWaals)
49
50
Computes pressure for a van der Waals gas from specific volume `V` and temperature `T`,
51
see also [`NonIdealCompressibleEulerEquations1D`](@ref).
52
"""
53
function pressure(V, T, eos::VanDerWaals)
54
(; a, b, R) = eos
55
rho = inv(V)
56
p = rho * R * T / (1 - rho * b) - a * rho^2
57
return p
58
end
59
60
"""
61
energy_internal_specific(V, T, eos::VanDerWaals)
62
63
Computes internal energy for a van der Waals gas from specific volume `V` and temperature `T` as
64
``e_{\text{internal}} = c_v T - a \rho``.
65
"""
66
function energy_internal_specific(V, T, eos::VanDerWaals)
67
(; cv, a) = eos
68
rho = inv(V)
69
e_internal = cv * T - a * rho
70
return e_internal
71
end
72
73
function entropy_specific(V, T, eos::VanDerWaals)
74
(; cv, b, R) = eos
75
76
# The specific entropy is defined up to some reference value. The value
77
# s0 = -319.1595051898981 recovers the specific entropy defined in Clapeyron.jl
78
s = cv * log(T) + R * log(V - b)
79
return s
80
end
81
82
# This formula is taken from (A.26) in the paper "An oscillation free
83
# shock-capturing method for compressible van der Waals supercritical
84
# fluid flows" by Pantano, Saurel, and Schmitt (2017).
85
# https://doi.org/10.1016/j.jcp.2017.01.057
86
function speed_of_sound(V, T, eos::VanDerWaals)
87
(; a, b, gamma) = eos
88
rho = inv(V)
89
e_internal = energy_internal_specific(V, T, eos)
90
c2 = gamma * (gamma - 1) * (e_internal + rho * a) / (1 - rho * b)^2 - 2 * a * rho
91
return sqrt(c2)
92
end
93
94
# This is not a required interface function, but specializing it
95
# if an explicit function is available can improve performance.
96
# For general EOS, this is calculated via a Newton solve.
97
function temperature(V, e_internal, eos::VanDerWaals)
98
(; cv, a) = eos
99
rho = inv(V)
100
T = (e_internal + a * rho) / cv
101
return T
102
end
103
104
# This is not a required interface function, but specializing it
105
# if an explicit function is available can improve performance.
106
function calc_pressure_derivatives(V, T, eos::VanDerWaals)
107
(; a, b, R) = eos
108
rho = inv(V)
109
RT = R * T
110
one_minus_b_rho = (1 - b * rho)
111
dpdT_V = rho * R / one_minus_b_rho
112
dpdrho_T = (RT / one_minus_b_rho + (RT * b * rho) / (one_minus_b_rho^2) -
113
2 * a * rho)
114
return dpdT_V, -dpdrho_T / V^2
115
end
116
end # @muladd
117
118