Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/flow_coupler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ end
vol_v = V*molar_volume(eos, p, Temp, f.vapor)
vol_l = L*molar_volume(eos, p, Temp, f.liquid)
S_v = vol_v/(vol_v + vol_l)
return S_v
return convert(T, S_v)
end

"Compute molar volume of a flashed phase"
Expand Down
47 changes: 38 additions & 9 deletions src/flow_coupler_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,20 @@ function Base.convert(::Type{FlashedPhase{T, Vector{T}}}, ph::FlashedPhase{K, Ve
return FlashedPhase(mf, Z)
end

function Base.convert(::Type{FlashedPhase{T, A}}, ph::FlashedPhase) where {T, A<:AbstractVector{T}}
fractions = convert(A, map(x -> convert(T, x), ph.mole_fractions))
return FlashedPhase(fractions, convert(T, ph.Z))
end

"Type that holds liquid and vapor phase states together with their state"
struct FlashedMixture2Phase{T, A<:AbstractVector{T}, E}
struct FlashedMixture2Phase{T, A<:AbstractVector{T}, E, R}
state::PhaseState2Phase
K::E # Equilibrium constants
V::T # Vapor mole fraction
liquid::FlashedPhase{T, A}
vapor::FlashedPhase{T, A}
critical_distance::Float64
flash_cond::@NamedTuple{p::Float64, T::Float64, z::E}
critical_distance::R
flash_cond::NamedTuple{(:p, :T, :z), Tuple{R, R, E}}
flash_stability::StabilityReport
function FlashedMixture2Phase(state::PhaseState2Phase, K::K_t, V::V_t,
liquid::FlashedPhase{V_t, A}, vapor::FlashedPhase{V_t, A};
Expand All @@ -54,15 +59,18 @@ struct FlashedMixture2Phase{T, A<:AbstractVector{T}, E}
# The phase vector type is part of the result type. Infer it from the
# phases instead of using the keyword value as a type parameter.
vec_type === A || throw(ArgumentError("vec_type must match the phase vectors"))
R = eltype(K_t)
if ismissing(cond)
z0 = convert(K_t, fill(NaN, length(K)))
cond = (p = NaN, T = NaN, z = z0)
cond = (p = R(NaN), T = R(NaN), z = z0)
end
new{V_t, A, K_t}(state, K, V, liquid, vapor, critical_distance, cond, stability_report)
cond = (p = R(cond.p), T = R(cond.T), z = convert(K_t, cond.z))
new{V_t, A, K_t, R}(state, K, V, liquid, vapor,
R(critical_distance), cond, stability_report)
end
end

function Base.convert(::Type{FlashedMixture2Phase{T, Vector{T}, F}}, mixture::FlashedMixture2Phase{K, Vector{K}, F}) where {T<:ForwardDiff.Dual, K, F}
function Base.convert(::Type{FlashedMixture2Phase{T, Vector{T}, F, R}}, mixture::FlashedMixture2Phase{K, Vector{K}, F}) where {T<:ForwardDiff.Dual, K, F, R}
T_phase = FlashedPhase{T, Vector{T}}
liquid = convert(T_phase, mixture.liquid)
vapor = convert(T_phase, mixture.vapor)
Expand All @@ -84,9 +92,31 @@ function Base.convert(::Type{FlashedMixture2Phase{T, Vector{T}, F}}, mixture::Fl
return converted_mixture
end

function Base.convert(::Type{FlashedMixture2Phase{T, A, E, R}},
mixture::FlashedMixture2Phase) where {T, A<:AbstractVector{T}, E, R}
liquid = convert(FlashedPhase{T, A}, mixture.liquid)
vapor = convert(FlashedPhase{T, A}, mixture.vapor)
K = convert(E, mixture.K)
cond = mixture.flash_cond
flash_cond = (p = cond.p, T = cond.T, z = convert(E, cond.z))
return FlashedMixture2Phase(mixture.state, K, convert(T, mixture.V),
liquid, vapor;
vec_type = A,
critical_distance = mixture.critical_distance,
cond = flash_cond,
stability_report = mixture.flash_stability)
end

function Base.convert(::Type{FlashedMixture2Phase{T, A, E}},
mixture::FlashedMixture2Phase) where {T, A<:AbstractVector{T}, E}
R = eltype(E)
return convert(FlashedMixture2Phase{T, A, E, R}, mixture)
end

function FlashedMixture2Phase(state, K, V, x, y, Z_L, Z_V, b = NaN, cond = missing, stability = StabilityReport())
liquid = FlashedPhase(x, Z_L)
vapor = FlashedPhase(y, Z_V)
T = typeof(V)
liquid = FlashedPhase(map(a -> convert(T, a), x), convert(T, Z_L))
vapor = FlashedPhase(map(a -> convert(T, a), y), convert(T, Z_V))
return FlashedMixture2Phase(state, K, V, liquid, vapor,
vec_type = typeof(liquid.mole_fractions), critical_distance = b, cond = cond,
stability_report = stability)
Expand All @@ -95,7 +125,6 @@ end
function FlashedMixture2Phase(eos::AbstractEOS, T = Float64, T_num = Float64, b = NaN, cond = missing, stability = StabilityReport())
n = number_of_components(eos)
V = zero(T)
# K values are always doubles
K = zeros(T_num, n)
liquid = FlashedPhase(n, T)
vapor = FlashedPhase(n, T)
Expand Down
34 changes: 28 additions & 6 deletions src/static.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,47 @@ end
@inline immutable_flash_output(V, K, stability, ::Val{true}) = (V, K, stability)

"""Return an isbits representation of a mixture for accelerator kernels."""
function static_mixture(mixture::MultiComponentMixture{R, N}) where {R, N}
function static_mixture(mixture::MultiComponentMixture{R_old, N}; float_type = missing) where {R_old, N}
if ismissing(float_type)
R = R_old
properties = mixture.properties
else
R = float_type
C(x) = convert(R, x)
properties = map(
x -> MolecularProperty(
C(x.mw),
C(x.p_c),
C(x.T_c),
C(x.V_c),
C(x.ω)
),
mixture.properties
)
end
names = ntuple(_ -> nothing, Val(N))
bic = mixture.binary_interaction
if !isnothing(bic)
bic = SMatrix{N, N, R}(bic)
end
return MultiComponentMixture(mixture.properties; A_ij = bic, names = names, name = nothing)
return MultiComponentMixture(properties; A_ij = bic, names = names, name = nothing)
end

"""
make_eos_immutable(eos)

Convert a generic cubic EOS to an isbits representation for accelerator kernels.
"""
function make_eos_immutable(eos::GenericCubicEOS{T, R, N}) where {T, R, N}
function make_eos_immutable(eos::GenericCubicEOS{T, R, N}; float_type = missing) where {T, R, N}
mixture = static_mixture(eos.mixture)
volume_shift = eos.volume_shift
if !isnothing(volume_shift)
volume_shift = SVector{N, eltype(volume_shift)}(volume_shift)
if ismissing(float_type)
v_type = eltype(volume_shift)
else
v_type = float_type
end
volume_shift = SVector{N, v_type}(volume_shift)
end
return GenericCubicEOS(
eos.type,
Expand Down Expand Up @@ -135,8 +157,8 @@ end
return (A_ij = A_ij_static, A_i = A_i_static, B_i = B_i_static)
end

function make_eos_immutable(eos::KValuesEOS{T, R, N}) where {T, R, N}
mixture = static_mixture(eos.mixture)
function make_eos_immutable(eos::KValuesEOS{T, R, N}; float_type = missing) where {T, R, N}
mixture = static_mixture(eos.mixture; float_type = float_type)
evaluator = eos.K_values_evaluator
if evaluator isa AbstractVector
evaluator = SVector{N, eltype(evaluator)}(evaluator)
Expand Down
2 changes: 1 addition & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function lbc_viscosity(eos, p, temperature, ph::FlashedPhase{T}; coeff = (0.1023
# Final expression is compound and given in centi poise. We convert to Pa s
# instead for strict SI outputs.
mu = 1e-3*(mu_atm + mu_correction)
return mu::T
return convert(T, mu)
end

function atmospheric_mu_estimate(props, z::V, temperature) where V<:AbstractVector{T} where T
Expand Down
38 changes: 38 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,44 @@ end
@test phase_data(flashed, Val(:vapor)).mole_fractions === y
end

@testset "Float32 flashed mixture storage" begin
x = SVector(0.8f0, 0.2f0)
y = SVector(0.1f0, 0.9f0)
K = SVector(0.125, 4.5)
flashed = FlashedMixture2Phase(
MultiComponentFlash.two_phase_lv, K, 0.4f0,
x, y, 0.9, 1.1)
@test flashed.V isa Float32
@test flashed.liquid.Z isa Float32
@test eltype(flashed.liquid.mole_fractions) === Float32

widened = FlashedMixture2Phase(
MultiComponentFlash.two_phase_lv, K, 0.4,
SVector(0.8, 0.2), SVector(0.1, 0.9), 0.9, 1.1)
@test isbitstype(typeof(widened))
target = typeof(flashed)
converted = convert(target, widened)
@test converted.V isa Float32
@test converted.liquid.mole_fractions == x
@test isequal(converted.flash_cond.z, widened.flash_cond.z)

narrow_K = SVector(0.125f0, 4.5f0)
narrow = FlashedMixture2Phase(
MultiComponentFlash.two_phase_lv, narrow_K, 0.4f0,
x, y, 0.9f0, 1.1f0, Float32(NaN),
(p = 1.0f6, T = 300.0f0, z = narrow_K))
@test narrow.critical_distance isa Float32
@test isbitstype(typeof(narrow))
@test narrow.flash_cond.p isa Float32
@test narrow.flash_cond.T isa Float32
@test eltype(narrow.flash_cond.z) === Float32
converted_narrow = convert(typeof(narrow), widened)
@test converted_narrow.K == narrow_K
@test converted_narrow.flash_cond.p isa Float32
partial_target = FlashedMixture2Phase{Float32, typeof(x), typeof(narrow_K)}
@test convert(partial_target, widened) isa typeof(narrow)
end

using ForwardDiff
@testset "Static flashed mixture promotion" begin
x = @SVector [0.8, 0.2]
Expand Down
Loading