diff --git a/src/EquationOfState/EquationOfState.jl b/src/EquationOfState/EquationOfState.jl index a1d8d33cc2a3ae0ae2ddc0b1d5139502494fec46..0e847a227f1544e1ead796dac1f7bae3d56e47fa 100644 --- a/src/EquationOfState/EquationOfState.jl +++ b/src/EquationOfState/EquationOfState.jl @@ -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) ####################################################################### diff --git a/src/EquationOfState/derived_variables.jl b/src/EquationOfState/derived_variables.jl index 49fe6c32c0d8b8685ea2f49ed448bd3b3a537310..dd9486a6040d1920f961d04b9daa2fa4b4215762 100644 --- a/src/EquationOfState/derived_variables.jl +++ b/src/EquationOfState/derived_variables.jl @@ -1,4 +1,9 @@ -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 diff --git a/src/EquationOfState/polytrope.jl b/src/EquationOfState/polytrope.jl index 7a56ec3278aa88642736f8b21a642dd161577b43..8c8f8130742e327de6dc1a8075fe476c21e2fb1e 100644 --- a/src/EquationOfState/polytrope.jl +++ b/src/EquationOfState/polytrope.jl @@ -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 diff --git a/test/dg1dTests/src/test_EquationOfState.jl b/test/dg1dTests/src/test_EquationOfState.jl index 9cbec77c27fe09f3379710e14f4a8ac9a1bc2691..06c4a739a470160d130996a7a8f1d7e02d6675a9 100644 --- a/test/dg1dTests/src/test_EquationOfState.jl +++ b/test/dg1dTests/src/test_EquationOfState.jl @@ -1,21 +1,15 @@ @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