Path: blob/main/src/equations/equation_of_state_vdw.jl
5586 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67@doc raw"""8VanDerWaals{RealT <: Real} <: AbstractEquationOfState910This defines the van der Waals equation of state11given by the pressure and internal energy relations12```math13p = \frac{\rho R T}{1 - \rho b} - a \rho^2, \quad e_{\text{internal}} = c_v T - a \rho14```15with ``c_v = \frac{R}{\gamma - 1}``. This corresponds to the "simple16van der Waals" fluid with constant `c_v`, which can be found on p28 of17<https://math.berkeley.edu/~evans/entropy.and.PDE.pdf>.1819See also "An oscillation free shock-capturing method for compressible van20der Waals supercritical fluid flows" by Pantano, Saurel, and Schmitt (2017).21<https://doi.org/10.1016/j.jcp.2017.01.057>22"""23struct VanDerWaals{RealT <: Real} <: AbstractEquationOfState24# van der Waals specific parameters25a::RealT # molecular attraction26b::RealT # excluded volume or co-volume2728# Standard thermodynamic gas parameters29gamma::RealT30R::RealT31cv::RealT32end3334"""35VanDerWaals(; a = 174.64049524257663, b = 0.001381308696129041,36gamma = 5 / 3, R = 296.8390795484912)3738By default, van der Waals parameters are for N2.39"""40function VanDerWaals(; a = 174.64049524257663, b = 0.001381308696129041,41gamma = 5 / 3, R = 296.8390795484912)42cv = R / (gamma - 1)43return VanDerWaals(promote(a, b, gamma, R, cv)...)44end4546"""47pressure(V, T, eos::VanDerWaals)4849Computes pressure for a van der Waals gas from specific volume `V` and temperature `T`,50see also [`NonIdealCompressibleEulerEquations1D`](@ref).51"""52function pressure(V, T, eos::VanDerWaals)53(; a, b, R) = eos54rho = inv(V)55p = rho * R * T / (1 - rho * b) - a * rho^256return p57end5859"""60energy_internal_specific(V, T, eos::VanDerWaals)6162Computes internal energy for a van der Waals gas from specific volume `V` and temperature `T` as63``e_{\text{internal}} = c_v T - a \rho``.64"""65function energy_internal_specific(V, T, eos::VanDerWaals)66(; cv, a) = eos67rho = inv(V)68e_internal = cv * T - a * rho69return e_internal70end7172function entropy_specific(V, T, eos::VanDerWaals)73(; cv, b, R) = eos7475# The specific entropy is defined up to some reference value. The value76# s0 = -319.1595051898981 recovers the specific entropy defined in Clapeyron.jl77s = cv * log(T) + R * log(V - b)78return s79end8081# This formula is taken from (A.26) in the paper "An oscillation free82# shock-capturing method for compressible van der Waals supercritical83# fluid flows" by Pantano, Saurel, and Schmitt (2017).84# https://doi.org/10.1016/j.jcp.2017.01.05785function speed_of_sound(V, T, eos::VanDerWaals)86(; a, b, gamma) = eos87rho = inv(V)88e_internal = energy_internal_specific(V, T, eos)89c2 = gamma * (gamma - 1) * (e_internal + rho * a) / (1 - rho * b)^2 - 2 * a * rho90return sqrt(c2)91end9293# This is not a required interface function, but specializing it94# if an explicit function is available can improve performance.95# For general EOS, this is calculated via a Newton solve.96function temperature(V, e_internal, eos::VanDerWaals)97(; cv, a) = eos98rho = inv(V)99T = (e_internal + a * rho) / cv100return T101end102103# This is not a required interface function, but specializing it104# if an explicit function is available can improve performance.105function calc_pressure_derivatives(V, T, eos::VanDerWaals)106(; a, b, R) = eos107rho = inv(V)108RT = R * T109one_minus_b_rho = (1 - b * rho)110dpdT_V = rho * R / one_minus_b_rho111dpdrho_T = (RT / one_minus_b_rho + (RT * b * rho) / (one_minus_b_rho^2) -1122 * a * rho)113return dpdT_V, -dpdrho_T / V^2114end115end # @muladd116117118