Skip to content
Snippets Groups Projects
Commit 4a8464c6 authored by Florian Atteneder's avatar Florian Atteneder
Browse files

polish eos interface to be symmetric in inputs and be more

comprehensive in case functions are called with wrong arguments
parent 82a0e637
No related branches found
No related tags found
No related merge requests found
......@@ -7,8 +7,14 @@ import Parameters: @unpack
export AbstractEquationOfState, ColdEquationOfState, HotEquationOfState,
Polytrope, IdealGas, HybridEoS,
Derivative, Density, Pressure, Enthalpy, TotalEnergy, InternalEnergy,
SpeedOfSound, SquareSpeedOfSound, Enthalpy
Derivative, Density, Pressure, Enthalpy, TotalEnergy, InternalEnergy, Entropy,
SpeedOfSound, SquareSpeedOfSound
# TODO Replace AbstractEquationOfState by AbstractEoS
# TODO Replace HotEquationOfState by HotEoS
# TODO Replace ColdEquationOfState by ColdEoS
# TODO Replace TVariable by TVar
#######################################################################
......@@ -31,10 +37,10 @@ function (eos::AbstractEquationOfState)(
end
```
E.g. all equations of state are assumed to depend on two parameters.
E.g. all equations of state are assumed to depend on two parameters.
Allowed pairs of argument types `(TVariable_1, TVariable_2)` are
- `(Density, InternalEnergy)`,
- `(Density, Pressure)`,
- `(Density, InternalEnergy)`,
- `(Density, Pressure)`,
- `(InternalEnergy, Pressure)`,
and always in alphabetic order.
......@@ -43,10 +49,10 @@ and always in alphabetic order.
```jldoctest setup
julia> eos = IdealGas(gamma=1.4);
julia> rho = eos(Density, InternalEnergy, 1.0, Pressure, 1.0)
julia> rho = eos(Density, InternalEnergy, 1.0, Pressure, 1.0)
2.5
julia> e = eos(TotalEnergy, Density, 1.0, InternalEnergy, 1.0)
julia> e = eos(TotalEnergy, Density, 1.0, InternalEnergy, 1.0)
2.0
```
"""
......@@ -161,29 +167,52 @@ struct SquareSpeedOfSound <: TVariable end
#######################################################################
(::HotEquationOfState)(::Type{Pressure}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = TODO()
(::HotEquationOfState)(::Type{Density}, ::Type{InternalEnergy}, eps, ::Type{Pressure}, p) = TODO()
(::HotEquationOfState)(::Type{Enthalpy}, ::Type{Density}, rho, ::Type{Pressure}, p) = TODO()
(::HotEquationOfState)(::Type{InternalEnergy}, ::Type{Density}, rho, ::Type{Pressure}, p) = TODO()
(::HotEquationOfState)(::Type{Derivative{Pressure,Density}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = TODO()
(::HotEquationOfState)(::Type{Derivative{Pressure,InternalEnergy}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = TODO()
#### HotEquationOfState
# make eos arguments symmetric
# neat trick from https://discourse.julialang.org/t/is-multiple-dispatch-the-same-as-function-overloading/4145/5?u=fatteneder
(eos::HotEquationOfState)(TR, T1::Type{TT1}, a, T2::Type{TT2}, b) where {TT1<:TVariable,TT2<:TVariable} = eos(TR, T2, b, T1, a)
@nospecialize
# be specific about number of arguments
(eos::HotEquationOfState)(args...) = error("$(typeof(eos)) must be called with 5 arguments")
# fallback to not implemented error
# need two methods to disambig with symmetric definition above
(eos::HotEquationOfState)(TR::Type{<:TVariable}, T1::Type{<:TVariable}, a, T2, b) = error("$TR($T1,$T2) for $(typeof(eos)) not implemented")
(eos::HotEquationOfState)(TR::Type{<:TVariable}, T1::Type{TT1}, a, T2::Type{TT2}, b) where {TT1<:TVariable,TT2<:TVariable} = error("$TR($T1,$T2) for $(typeof(eos)) not implemented")
# error on duplicated argument types
(eos::HotEquationOfState)(TR::Type{<:TVariable}, T1::Type{T}, a, T2::Type{T}, b) where T<:TVariable = error("duplicated argument type found: $T")
(eos::HotEquationOfState)(TR::Type{T}, T1::Type{T}, a, T2, b) where T<:TVariable = error("duplicated argument type found: $T")
(eos::HotEquationOfState)(TR::Type{T}, T1::Type{T}, a, T2::Type{T}, b) where T<:TVariable = error("duplicated argument type found: $T")
@specialize
#### ColdEquationOfState
@nospecialize
# be specific about number of arguments
(eos::ColdEquationOfState)(args...) = error("$(typeof(eos)) must be called with 3 arguments")
# fallback to not implement error
(eos::ColdEquationOfState)(TR::Type{TTR}, T1::Type{TT1}, a) where {TTR<:TVariable,TT1<:TVariable}= error("$TR($T1) for $(typeof(eos)) not implemented")
(::ColdEquationOfState)(::Type{Pressure}, ::Type{Density}, rho) = TODO()
(::ColdEquationOfState)(::Type{Enthalpy}, ::Type{Density}, rho) = TODO()
(::ColdEquationOfState)(::Type{InternalEnergy}, ::Type{Density}, rho) = TODO()
(::ColdEquationOfState)(::Type{Derivative{Pressure,Density}}, ::Type{Density}, rho) = TODO()
(::ColdEquationOfState)(::Type{Derivative{Pressure,InternalEnergy}}, ::Type{Density}, rho) = TODO()
(::ColdEquationOfState)(::Type{Derivative{InternalEnergy,Density}}, ::Type{Density}, rho) = TODO()
# error on duplicated argument types
(eos::ColdEquationOfState)(TR::Type{T}, T1::Type{T}, a) where T<:TVariable = error("duplicated argument type found: $T")
@specialize
# for backwards compatibility
(eos::ColdEquationOfState)(::Type{Pressure}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Pressure, Density, rho)
(eos::ColdEquationOfState)(::Type{Density}, ::Type{InternalEnergy}, eps, ::Type{Pressure}, p) = eos(Density, Pressure, p)
(eos::ColdEquationOfState)(::Type{Enthalpy}, ::Type{Density}, rho, ::Type{Pressure}, p) = eos(Enthalpy, Density, rho)
(eos::ColdEquationOfState)(::Type{InternalEnergy}, ::Type{Density}, rho, ::Type{Pressure}, p) = eos(InternalEnergy, Pressure, p)
(eos::ColdEquationOfState)(::Type{Derivative{Pressure,Density}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Derivative{Pressure,Density}, Density, rho)
(eos::ColdEquationOfState)(::Type{Derivative{Pressure,InternalEnergy}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Derivative{Pressure,InternalEnergy}, Density, rho)
# # for backwards compatibility
# # TODO Can we deprecate these?
# (eos::ColdEquationOfState)(::Type{Pressure}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Pressure, Density, rho)
# (eos::ColdEquationOfState)(::Type{Density}, ::Type{InternalEnergy}, eps, ::Type{Pressure}, p) = eos(Density, Pressure, p)
# (eos::ColdEquationOfState)(::Type{Enthalpy}, ::Type{Density}, rho, ::Type{Pressure}, p) = eos(Enthalpy, Density, rho)
# (eos::ColdEquationOfState)(::Type{InternalEnergy}, ::Type{Density}, rho, ::Type{Pressure}, p) = eos(InternalEnergy, Pressure, p)
# (eos::ColdEquationOfState)(::Type{Derivative{Pressure,Density}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Derivative{Pressure,Density}, Density, rho)
# (eos::ColdEquationOfState)(::Type{Derivative{Pressure,InternalEnergy}}, ::Type{Density}, rho, ::Type{InternalEnergy}, eps) = eos(Derivative{Pressure,InternalEnergy}, Density, rho)
#######################################################################
......
function (eos::AbstractEquationOfState)(
#######################################################################
# HotEoS #
#######################################################################
function (eos::HotEquationOfState)(
::Type{Enthalpy},
::Type{Density}, rho, ::Type{InternalEnergy}, eps)
......@@ -7,7 +12,7 @@ function (eos::AbstractEquationOfState)(
end
function (eos::AbstractEquationOfState)(
function (eos::HotEquationOfState)(
::Type{SpeedOfSound},
::Type{Density}, rho, ::Type{InternalEnergy}, eps)
......@@ -16,7 +21,7 @@ function (eos::AbstractEquationOfState)(
end
function (eos::AbstractEquationOfState)(
function (eos::HotEquationOfState)(
::Type{SquareSpeedOfSound},
::Type{Density}, rho, ::Type{InternalEnergy}, eps)
......@@ -28,9 +33,61 @@ function (eos::AbstractEquationOfState)(
end
function (eos::AbstractEquationOfState)(
function (eos::HotEquationOfState)(
::Type{TotalEnergy},
::Type{Density}, rho, ::Type{InternalEnergy}, eps)
return rho * (1 + eps)
end
#######################################################################
# ColdEoS #
#######################################################################
function (eos::ColdEquationOfState)(
TR::Type{TTR},
T::Type{<:TVariable}, var) where TTR<:Union{Enthalpy,SpeedOfSound,SquareSpeedOfSound,TotalEnergy}
rho = eos(Density, T, var)
eos(TR, Density, rho)
end
function (eos::ColdEquationOfState)(
::Type{Enthalpy},
::Type{Density}, rho)
p = eos(Pressure, Density, rho)
return 1 + eps + p / rho
end
function (eos::ColdEquationOfState)(
::Type{SpeedOfSound},
::Type{Density}, rho)
cs2 = eos(SquareSpeedOfSound, Density, rho)
return sqrt(cs2)
end
function (eos::ColdEquationOfState)(
::Type{SquareSpeedOfSound},
::Type{Density}, rho)
chi = eos(Derivative{Pressure, Density}, Density, rho)
kappa = eos(Derivative{Pressure, InternalEnergy}, Density, rho)
p = eos(Pressure, Density, rho)
h = eos(Enthalpy, Density, rho)
return (chi + p / rho^2 * kappa) / h
end
function (eos::ColdEquationOfState)(
::Type{TotalEnergy},
::Type{Density}, rho)
eps = eos(InternalEnergy, Density, rho)
return rho * (1 + eps)
end
......@@ -6,9 +6,9 @@ Polytropic equation of state
p = K ρ^Γ
- `p` pressure
- `ρ` polytropic constant
- `ρ` density
- `K` polytropic constant
- `Γ` polytropic constant
- `Γ` polytropic exponent
"""
Base.@kwdef struct Polytrope <: ColdEquationOfState
K::Float64
......
@testset "EquationOfState" begin
@testset "Variables" begin
@testset "EquationOfState interfaces" begin
# Call all methods we expect an eqaution of state to implement at least once here.
for EOS in concretetypes(AbstractEquationOfState)
parameters = dg1d.parameters(:EquationOfState)
eos = EquationOfState.make_EquationOfState(parameters)
for eos in [ IdealGas(1.2), HybridEoS(Polytrope(1.0,2.0), 3.0) ]
rho = 1.0
eps = 1.0
p = eos(Pressure, Density, rho, InternalEnergy, eps)
h = eos(Enthalpy, Density, rho, InternalEnergy, eps)
if !(EOS <: HybridEoS)
eps = eos(InternalEnergy, Density, rho, Pressure, p)
end
dpdrho = eos(Derivative{Pressure, Density}, Density, rho, InternalEnergy, eps)
dpdrho = eos(Derivative{Pressure, InternalEnergy}, Density, rho, InternalEnergy, eps)
......@@ -25,10 +19,34 @@
cs2 = eos(SquareSpeedOfSound, Density, rho, InternalEnergy, eps)
e = eos(TotalEnergy, Density, rho, InternalEnergy, eps)
# call combinations we know should not be implemented
@test_throws MethodError eos(Enthalpy, Pressure, p, InternalEnergy, eps) # wrong argument ordering
# unknown derivative (but could in principle be implemented)
@test_throws MethodError eos(Derivative{Enthalpy, Pressure}, Density, rho, Pressure, p)
# duplicated arguments
@test_throws ErrorException eos(Pressure, Pressure, p, Density, rho)
@test_throws ErrorException eos(Pressure, Density, rho, Pressure, p)
# not 5 arguments
@test_throws ErrorException eos(Pressure, rho, Pressure, p)
end
for eos in [ Polytrope(1.0, 2.0) ]
rho = 1.0
eps = 1.0
p = eos(Pressure, Density, rho)
h = eos(Enthalpy, Density, rho)
dpdrho = eos(Derivative{Pressure, Density}, Density, rho)
dpdrho = eos(Derivative{Pressure, InternalEnergy}, Density, rho)
# derived quantities
h = eos(Enthalpy, Density, rho)
cs = eos(SpeedOfSound, Pressure, p)
cs2 = eos(SquareSpeedOfSound, Pressure, p)
e = eos(TotalEnergy, Density, rho)
# eos(Pressure, Pressure, p, Pressure, p)
@test_throws ErrorException eos(Pressure, Pressure, p)
@test_throws ErrorException eos(Density, Density, rho)
# not 3 arguments
@test_throws ErrorException eos(Pressure, rho, Pressure, p)
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment