@@ -8,6 +8,18 @@ Return number of components for the underlying mixture of the EOS.
88"""
99number_of_components (e:: AbstractEOS ) = number_of_components (e. mixture)
1010
11+ forces_per_phase (eos:: GenericCubicEOS ) = false
12+
13+ function get_phase (cond)
14+ return get (cond, :phase , :unknown ):: Symbol
15+ end
16+
17+ function set_phase (cond, phase:: Symbol , throw:: Bool = false )
18+ if throw && haskey (cond, :phase ) && cond. phase != :unknown
19+ throw (ArgumentError (" Phase state already set to $(cond. phase) , cannot change to $phase ." ))
20+ end
21+ return (p = cond. p, T = cond. T, z = cond. z, phase = phase)
22+ end
1123
1224function static_coefficients (:: AbstractGeneralizedCubic )
1325 return (0.4274802327 , 0.08664035 , 0.0 , 1.0 )
@@ -23,67 +35,32 @@ function weight_ai(eos::GenericCubicEOS{T, R}, cond, i) where {T<:AbstractGenera
2335 return eos. ω_a* T_r^ (- 1 / 2 )
2436end
2537
26- # PengRobinson specialization
27- function static_coefficients (:: AbstractPengRobinson )
28- return (0.457235529 , 0.077796074 , 1.0 + sqrt (2 ), 1.0 - sqrt (2 ))
29- end
30-
31- function weight_ai (eos:: GenericCubicEOS{T} , cond, i) where T<: AbstractPengRobinson
32- mix = eos. mixture
33- m = molecular_property (mix, i)
34- a = acentric_factor (m)
35- T_r = reduced_temperature (mix, cond, i)
36- tmp = (1.0 + (0.37464 + 1.54226 * a - 0.26992 * a* a)* (1 - T_r^ 0.5 ))
37- return eos. ω_a* (tmp* tmp)
38- end
38+ # Peng Robinson and variants
39+ include (" eos/peng_robinson.jl" )
40+ include (" eos/peng_robinson_corrected.jl" )
41+ include (" eos/soreide_whitson.jl" )
42+ # Soave Redlich-Kwong
43+ include (" eos/soave_redlich_kwong.jl" )
44+ # Zudkevitch-Joffe
45+ include (" eos/zudkevitch_joffe.jl" )
3946
40- function weight_ai (eos:: GenericCubicEOS{PengRobinsonCorrected} , cond, i)
41- mix = eos. mixture
42- m = molecular_property (mix, i)
43- a = acentric_factor (m)
44- T_r = reduced_temperature (mix, cond, i)
45- aa = a* a
46- if a > 0.49
47- # Use alternate expression.
48- D = (0.379642 + 1.48503 * a - 0.164423 * aa + 0.016666 * a* aa)
49- else
50- # Use standard expression.
51- D = (0.37464 + 1.54226 * a - 0.26992 * aa)
52- end
53- tmp = 1.0 + D* (1.0 - T_r^ 0.5 )
54- return eos. ω_a* (tmp* tmp);
47+ # Generic part
48+ Base. @propagate_inbounds function binary_interaction (eos:: AbstractEOS , i:: Int , j:: Int , cond)
49+ return binary_interaction (eos. mixture, i, j)
5550end
5651
57- # ZudkevitchJoffe
58- function weight_ai (eos:: GenericCubicEOS{ZudkevitchJoffe} , cond, i)
59- zj = eos. type
60- mix = eos. mixture
61- T = cond. T
62- T_r = reduced_temperature (mix, cond, i)
63- return eos. ω_a* zj. F_a (T, i)* T_r^ (- 0.5 )
52+ Base. @propagate_inbounds function binary_interaction (mixture:: MultiComponentMixture{R} , i, j) where {R}
53+ return binary_interaction (mixture. binary_interaction, i, j):: R
6454end
6555
66- function weight_bi (eos:: GenericCubicEOS{ZudkevitchJoffe} , cond, i)
67- zj = eos. type
68- T = cond. T
69- return eos. ω_b* zj. F_b (T, i)
56+ function binary_interaction (:: Nothing , i, j)
57+ return 0.0
7058end
7159
72- # SoaveRedlichKwong
73- function weight_ai (eos:: GenericCubicEOS{SoaveRedlichKwong} , cond, i)
74- mix = eos. mixture
75- m = molecular_property (mix, i)
76- a = acentric_factor (m)
77- T_r = reduced_temperature (mix, cond, i)
78- return eos. ω_a* (1 + (0.48 + 1.574 * a - 0.176 * a^ 2 )* (1 - T_r^ (1 / 2 )))^ 2 ;
60+ Base. @propagate_inbounds function binary_interaction (B:: AbstractMatrix , i, j)
61+ return B[i, j]
7962end
8063
81- # Generic part
82- binary_interaction (eos:: AbstractEOS , i, j) = binary_interaction (eos. mixture, i, j)
83- binary_interaction (mixture:: MultiComponentMixture{R} , i, j) where {R} = binary_interaction (mixture. binary_interaction, i, j):: R
84- binary_interaction (:: Nothing , i, j) = 0.0
85- Base. @propagate_inbounds binary_interaction (B:: AbstractMatrix , i, j) = B[i, j]
86-
8764"""
8865 mixture_compressibility_factor(eos, cond, [forces, scalars, phase])
8966
@@ -93,21 +70,31 @@ provided if they are already known.
9370The compressibility factor adjusts the ideal gas law to account for non-linear behavior: ``pV = nRTZ``
9471"""
9572
96- function mixture_compressibility_factor (eos:: AbstractCubicEOS , cond,
97- forces = force_coefficients (eos, cond),
98- scalars = force_scalars (eos, cond, forces),
99- phase = :unknown )
73+ function mixture_compressibility_factor (
74+ eos:: AbstractCubicEOS ,
75+ cond,
76+ forces = force_coefficients (eos, cond),
77+ scalars = force_scalars (eos, cond, forces),
78+ phase = missing
79+ )
80+ if ! ismissing (phase)
81+ cond = set_phase (cond, phase)
82+ end
10083 poly = eos_polynomial (eos, forces, scalars)
10184 roots = solve_roots (eos, poly)
102- r = pick_root (eos, roots, cond, forces, scalars, phase )
85+ r = pick_root (eos, roots, cond, forces, scalars)
10386 return r
10487end
10588
10689minimum_allowable_root (eos:: AbstractCubicEOS , forces, scalars) = scalars. B
10790minimum_allowable_root (eos, forces, scalars) = 1e-16
10891
109- @inline pick_root (eos, roots:: Real , cond, forces, scalars, phase = :unknown ) = roots
110- function pick_root (eos, roots, cond, forces, scalars, phase = :unknown )
92+ @inline function pick_root (eos, roots:: Real , cond, forces, scalars)
93+ return roots
94+ end
95+
96+ function pick_root (eos, roots, cond, forces, scalars)
97+ phase = get_phase (cond)
11198 r_ϵ = minimum_allowable_root (eos, forces, scalars)
11299 max_r = maximum (roots)
113100 min_r = minimum ((x) -> x > r_ϵ ? x : Inf , roots)
@@ -160,7 +147,23 @@ function force_coefficients(eos::AbstractCubicEOS, cond; static_size = false)
160147 B_i = zeros (eT, n)
161148 end
162149 coeff = (A_ij = A_ij, A_i = A_i, B_i = B_i)
163- force_coefficients! (coeff, eos, cond)
150+ update_force_coefficients! (coeff, eos, cond)
151+ return coeff
152+ end
153+
154+ function get_force_coefficients (forces, eos, cond)
155+ if forces_per_phase (eos)
156+ phase = get_phase (cond)
157+ if phase == :liquid
158+ return forces. liquid
159+ elseif phase == :vapor
160+ return forces. vapor
161+ else
162+ error (" Forces per phase are only supported for liquid and vapor phases, not $phase ." )
163+ end
164+ else
165+ return forces
166+ end
164167end
165168
166169"""
@@ -170,10 +173,22 @@ In-place update of force coefficients.
170173
171174See also [`force_coefficients`](@ref)
172175"""
173- function force_coefficients! (coeff, eos:: AbstractCubicEOS , arg... )
174- update_attractive_linear! (coeff. A_i, eos, arg... )
175- update_attractive_quadratic! (coeff. A_ij, coeff. A_i, eos, arg... )
176- update_repulsive! (coeff. B_i, eos, arg... )
176+ function force_coefficients! (coeff, eos:: AbstractCubicEOS , cond)
177+ if forces_per_phase (eos)
178+ cond = set_phase (cond, :liquid )
179+ update_force_coefficients! (coeff. liquid, eos, cond)
180+ cond = set_phase (cond, :vapor )
181+ update_force_coefficients! (coeff. vapor, eos, cond)
182+ else
183+ update_force_coefficients! (coeff, eos, cond)
184+ end
185+ return coeff
186+ end
187+
188+ function update_force_coefficients! (coeff, eos:: AbstractCubicEOS , cond)
189+ update_attractive_linear! (coeff. A_i, eos, cond)
190+ update_attractive_quadratic! (coeff. A_ij, coeff. A_i, eos, cond)
191+ update_repulsive! (coeff. B_i, eos, cond)
177192 return coeff
178193end
179194
@@ -201,7 +216,7 @@ function update_attractive_quadratic!(A_ij, A_i, eos::AbstractCubicEOS, cond)
201216 T = eltype (A_i)
202217 for i = 1 : N
203218 @inbounds for j = i: N
204- a = sqrt (A_i[i]* A_i[j])* (one (T) - binary_interaction (eos, i, j))
219+ a = sqrt (A_i[i]* A_i[j])* (one (T) - binary_interaction (eos, i, j, cond ))
205220 a:: T
206221 A_ij[i, j] = a
207222 A_ij[j, i] = a
227242Compute EOS specific scalars for the current conditions based on the forces.
228243"""
229244function force_scalars (eos:: AbstractCubicEOS , cond, forces)
230- return cubic_scalars (forces. A_ij, forces. B_i, cond. z)
245+ f = get_force_coefficients (forces, eos, cond)
246+ return cubic_scalars (f. A_ij, f. B_i, cond. z)
231247end
232248
233249function cubic_scalars (A_ij, Bv, z)
@@ -279,7 +295,8 @@ Base.@propagate_inbounds function component_fugacity_coefficient(eos::AbstractCu
279295 # NOTE: This returns ln(ψ), not ψ!
280296 m1 = eos. m_1
281297 m2 = eos. m_2
282- return component_fugacity_coefficient_cubic (m1, m2, cond. z, Z, scalars. A, scalars. B, forces. A_ij, forces. B_i, i)
298+ f = get_force_coefficients (forces, eos, cond)
299+ return component_fugacity_coefficient_cubic (m1, m2, cond. z, Z, scalars. A, scalars. B, f. A_ij, f. B_i, i)
283300end
284301
285302Base. @propagate_inbounds function component_fugacity_coefficient_cubic (m1, m2, x, Z, A, B, A_mat, B_i, i)
0 commit comments