Skip to content

Commit

Permalink
Put module types first in load order
Browse files Browse the repository at this point in the history
  • Loading branch information
moyner committed Oct 20, 2023
1 parent 0265098 commit 9a21c63
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 271 deletions.
13 changes: 10 additions & 3 deletions src/MultiComponentFlash.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@

module MultiComponentFlash
using LinearAlgebra, ForwardDiff, StaticArrays, Roots
# Constants.
const MINIMUM_COMPOSITION = 1e-10
const IDEAL_GAS_CONSTANT = 8.3144598
# Load types first
include("mixture_types.jl")
include("eos_types.jl")
include("flash_types.jl")
include("flow_coupler_types.jl")
# Types that define specific cubic equations of state
export SoaveRedlichKwong, RedlichKwong, PengRobinson, PengRobinsonCorrected, ZudkevitchJoffe
# The generic cubic form that supports the above
export GenericCubicEOS, number_of_components
export GenericCubicEOS
export number_of_components
# Flash interfaces
export flash_2ph, flash_2ph!, flash_storage
export stability_2ph, stability_2ph!
Expand Down Expand Up @@ -32,8 +41,6 @@ module MultiComponentFlash
export lbc_viscosity, lbc_viscosities
export set_partials, set_partials_phase_mole_fractions!, set_partials_vapor_fraction

const MINIMUM_COMPOSITION = 1e-10
const IDEAL_GAS_CONSTANT = 8.3144598
include("mixtures.jl")
include("kvalues.jl")
include("rachford_rice.jl")
Expand Down
102 changes: 0 additions & 102 deletions src/eos.jl
Original file line number Diff line number Diff line change
@@ -1,108 +1,6 @@
abstract type AbstractEOS end
abstract type AbstractCubicEOS <: AbstractEOS end

@inline reduced_pT(mix, c, i) = (reduced_pressure(mix, c, i), reduced_temperature(mix, c, i))
@inline reduced_pT(eos::AbstractEOS, c, i) = (reduced_pressure(eos.mixture, c, i), reduced_temperature(eos.mixture, c, i))

"""
GenericCubicEOS is an implementation of generalized cubic equations of state.
Many popular cubic equations can be written in a single form with a few changes in
definitions for the terms (they are, after all, all cubic in form). References:
1. [Cubic Equations of State-Which? by J.J. Martin](https://doi.org/10.1021/i160070a001)
2. [Simulation of Gas Condensate Reservoir Performance by K.H. Coats](https://doi.org/10.2118/10512-PA)
"""
struct GenericCubicEOS{T, R, N, V} <: AbstractCubicEOS
type::T
mixture::MultiComponentMixture{R, N}
m_1::R
m_2::R
ω_a::R
ω_b::R
volume_shift::V
end

"""
Abstract base type for generalized cubics.
Any subtype may override the any of following internal functions to alter the EOS:
* static_coefficients
* weight_ai
* weight_bi
In addition, the GenericCubicEOS is parametric on the specific cubic type for further
dispatch modifications.
"""
abstract type AbstractGeneralizedCubic end


abstract type AbstractPengRobinson <: AbstractGeneralizedCubic end

"""
Specializes the GenericCubicEOS to the Peng-Robinson cubic equation of state.
"""
struct PengRobinson <: AbstractPengRobinson end


"""
Specializes the GenericCubicEOS to Peng-Robinson modified for large acentric factors
"""
struct PengRobinsonCorrected <: AbstractPengRobinson end


"""
Specializes the GenericCubicEOS to the Zudkevitch-Joffe cubic equation of state.
The Zudkevitch-Joffe equations of state allows for per-component functions of
temperature that modify the `weight_ai` and `weight_bi` functions. These additional
fitting parameters allows for more flexibility when matching complex mixtures.
"""
struct ZudkevitchJoffe <: AbstractGeneralizedCubic
F_a
F_b
function ZudkevitchJoffe(; F_a = (T, c_i) -> 1.0, F_b = (T, c_i) -> 1.0)
new(F_a, F_b)
end
end

"""
Specializes the GenericCubicEOS to the Soave-Redlich-Kwong cubic equation of state.
"""
struct SoaveRedlichKwong <: AbstractGeneralizedCubic end
"""
Specializes the GenericCubicEOS to the Redlich-Kwong cubic equation of state.
"""
struct RedlichKwong <: AbstractGeneralizedCubic end

"""
GenericCubicEOS(mixture, [type = PengRobinson()])
Instantiate a generic cubic equation-of-state for a `MultiComponentMixture` and
a specified EOS.
Currently supported choices for type:
1. `PengRobinson` (default)
2. `ZudkevitchJoffe`
3. `RedlichKwong`
4. `SoaveRedlichKwong`
"""
function GenericCubicEOS(mixture, type = PengRobinson(); kwarg...)
ω_a, ω_b, m_1, m_2 = static_coefficients(type)
setup = (ω_a = ω_a, ω_b = ω_b, m_1 = m_1, m_2 = m_2, type = type)
return GenericCubicEOS(setup, mixture; kwarg...)
end

function GenericCubicEOS(setup::NamedTuple, mixture; volume_shift = nothing)
if !isnothing(volume_shift)
@assert length(volume_shift) == number_of_components(mixture) "Volume shift must have one value per component."
end
return GenericCubicEOS(setup.type, mixture, setup.m_1, setup.m_2, setup.ω_a, setup.ω_b, volume_shift)
end

"""
number_of_components(eos)
Expand Down
100 changes: 100 additions & 0 deletions src/eos_types.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
abstract type AbstractEOS end
abstract type AbstractCubicEOS <: AbstractEOS end

"""
GenericCubicEOS is an implementation of generalized cubic equations of state.
Many popular cubic equations can be written in a single form with a few changes in
definitions for the terms (they are, after all, all cubic in form). References:
1. [Cubic Equations of State-Which? by J.J. Martin](https://doi.org/10.1021/i160070a001)
2. [Simulation of Gas Condensate Reservoir Performance by K.H. Coats](https://doi.org/10.2118/10512-PA)
"""
struct GenericCubicEOS{T, R, N, V} <: AbstractCubicEOS
type::T
mixture::MultiComponentMixture{R, N}
m_1::R
m_2::R
ω_a::R
ω_b::R
volume_shift::V
end

"""
Abstract base type for generalized cubics.
Any subtype may override the any of following internal functions to alter the EOS:
* static_coefficients
* weight_ai
* weight_bi
In addition, the GenericCubicEOS is parametric on the specific cubic type for further
dispatch modifications.
"""
abstract type AbstractGeneralizedCubic end


abstract type AbstractPengRobinson <: AbstractGeneralizedCubic end

"""
Specializes the GenericCubicEOS to the Peng-Robinson cubic equation of state.
"""
struct PengRobinson <: AbstractPengRobinson end


"""
Specializes the GenericCubicEOS to Peng-Robinson modified for large acentric factors
"""

struct PengRobinsonCorrected <: AbstractPengRobinson end
"""
Specializes the GenericCubicEOS to the Zudkevitch-Joffe cubic equation of state.
The Zudkevitch-Joffe equations of state allows for per-component functions of
temperature that modify the `weight_ai` and `weight_bi` functions. These additional
fitting parameters allows for more flexibility when matching complex mixtures.
"""
struct ZudkevitchJoffe <: AbstractGeneralizedCubic
F_a
F_b
function ZudkevitchJoffe(; F_a = (T, c_i) -> 1.0, F_b = (T, c_i) -> 1.0)
new(F_a, F_b)
end
end

"""
Specializes the GenericCubicEOS to the Soave-Redlich-Kwong cubic equation of state.
"""
struct SoaveRedlichKwong <: AbstractGeneralizedCubic end
"""
Specializes the GenericCubicEOS to the Redlich-Kwong cubic equation of state.
"""
struct RedlichKwong <: AbstractGeneralizedCubic end

"""
GenericCubicEOS(mixture, [type = PengRobinson()])
Instantiate a generic cubic equation-of-state for a `MultiComponentMixture` and
a specified EOS.
Currently supported choices for type:
1. `PengRobinson` (default)
2. `ZudkevitchJoffe`
3. `RedlichKwong`
4. `SoaveRedlichKwong`
"""
function GenericCubicEOS(mixture, type = PengRobinson(); kwarg...)
ω_a, ω_b, m_1, m_2 = static_coefficients(type)
setup = (ω_a = ω_a, ω_b = ω_b, m_1 = m_1, m_2 = m_2, type = type)
return GenericCubicEOS(setup, mixture; kwarg...)
end

function GenericCubicEOS(setup::NamedTuple, mixture; volume_shift = nothing)
if !isnothing(volume_shift)
@assert length(volume_shift) == number_of_components(mixture) "Volume shift must have one value per component."
end
return GenericCubicEOS(setup.type, mixture, setup.m_1, setup.m_2, setup.ω_a, setup.ω_b, volume_shift)
end
42 changes: 0 additions & 42 deletions src/flash.jl
Original file line number Diff line number Diff line change
@@ -1,46 +1,4 @@

"Abstract type for all flash types"
abstract type AbstractFlash end
"Abstract type for all flash types that use Newton in some form"
abstract type AbstractNewtonFlash <: AbstractFlash end

"""
Flash method that uses successive subtition.
Unconditionally convergent, does not require derivatives, but is very slow around critical regions.
See also: [`flash_2ph!`](@ref), [`NewtonFlash`](@ref) [`SSINewtonFlash`](@ref)
"""
struct SSIFlash <: AbstractFlash end

"""
NewtonFlash([dMax = 0.2])
Flash using Newton's method for zero solve.
Only conditionally convergent, but has better convergence rate than SSI.
# Arguments
- `dMax`: dampening factor for the newton iteration
See also: [`flash_2ph!`](@ref), [`SSIFlash`](@ref) [`SSINewtonFlash`](@ref)
"""
@Base.kwdef struct NewtonFlash <: AbstractNewtonFlash
dMax::Float64 = 0.2
end

"""
SSINewtonFlash([swap_iter = 5,dMax = 0.2])
Perform a number of SSI iterations, followed by Newton until convergence.
See also: [`flash_2ph!`](@ref), [`SSIFlash`](@ref) [`NewtonFlash`](@ref)
"""
@Base.kwdef struct SSINewtonFlash <: AbstractNewtonFlash
swap_iter::Int = 5
dMax::Float64 = 0.2
end

"""
flash_2ph(eos, c, [K], [V]; <keyword arguments>)
Expand Down
42 changes: 42 additions & 0 deletions src/flash_types.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"Abstract type for all flash types"
abstract type AbstractFlash end
"Abstract type for all flash types that use Newton in some form"
abstract type AbstractNewtonFlash <: AbstractFlash end

"""
Flash method that uses successive subtition.
Unconditionally convergent, does not require derivatives, but is very slow around critical regions.
See also: [`flash_2ph!`](@ref), [`NewtonFlash`](@ref) [`SSINewtonFlash`](@ref)
"""
struct SSIFlash <: AbstractFlash end

"""
NewtonFlash([dMax = 0.2])
Flash using Newton's method for zero solve.
Only conditionally convergent, but has better convergence rate than SSI.
# Arguments
- `dMax`: dampening factor for the newton iteration
See also: [`flash_2ph!`](@ref), [`SSIFlash`](@ref) [`SSINewtonFlash`](@ref)
"""
@Base.kwdef struct NewtonFlash <: AbstractNewtonFlash
dMax::Float64 = 0.2
end

"""
SSINewtonFlash([swap_iter = 5,dMax = 0.2])
Perform a number of SSI iterations, followed by Newton until convergence.
See also: [`flash_2ph!`](@ref), [`SSIFlash`](@ref) [`NewtonFlash`](@ref)
"""
@Base.kwdef struct SSINewtonFlash <: AbstractNewtonFlash
swap_iter::Int = 5
dMax::Float64 = 0.2
end

48 changes: 0 additions & 48 deletions src/flow_coupler.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export PhaseState2Phase, liquid_phase_present, vapor_phase_present, two_phases_present, phase_data

@enum PhaseState2Phase two_phase_lv single_phase_l single_phase_v unknown_phase_state_lv

@inline liquid_phase_present(state::PhaseState2Phase) = state == two_phase_lv || state == single_phase_l
@inline vapor_phase_present(state::PhaseState2Phase) = state == two_phase_lv || state == single_phase_v
@inline two_phases_present(state::PhaseState2Phase) = state == two_phase_lv
Expand All @@ -22,50 +18,6 @@ function phase_is_present(label, phase_state::PhaseState2Phase)
return present
end

"Type that holds values for a flashed phase (mole fractions + compressibility factor)"
struct FlashedPhase{T, A<:AbstractVector{T}}
mole_fractions::A
Z::T
function FlashedPhase(mole_fractions::AbstractVector, Z::Real)
new{typeof(Z), typeof(mole_fractions)}(mole_fractions, Z)
end
end

function FlashedPhase(n::Integer, T::DataType = Float64)
x = zeros(T, n)
Z = zero(T)
return FlashedPhase(x, Z)
end

"Type that holds liquid and vapor phase states together with their state"
struct FlashedMixture2Phase{T, A<:AbstractVector{T}, E}
state::PhaseState2Phase
K::E # Equilibrium constants
V::T # Vapor mole fraction
liquid::FlashedPhase{T, A}
vapor::FlashedPhase{T, A}
function FlashedMixture2Phase(state::PhaseState2Phase, K::K_t, V::V_t, liquid, vapor; vec_type = Vector{V_t}) where {V_t, K_t}
new{V_t, vec_type, K_t}(state, K, V, liquid, vapor)
end
end

function FlashedMixture2Phase(state, K, V, x, y, Z_L, Z_V)
liquid = FlashedPhase(x, Z_L)
vapor = FlashedPhase(y, Z_V)
return FlashedMixture2Phase(state, K, V, liquid, vapor)
end

function FlashedMixture2Phase(eos::AbstractEOS, T = Float64, T_num = Float64)
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)

return FlashedMixture2Phase(unknown_phase_state_lv, K, V, liquid, vapor)
end

function flashed_mixture_2ph(eos, cond, K = initial_guess_K(eos, cond); method = SSIFlash(), kwarg...)
# Convenience function for getting flashed phases
S = flash_storage(eos, cond, method = method)
Expand Down
Loading

0 comments on commit 9a21c63

Please sign in to comment.