This is Part 7 of a series.
In Part 6, I implemented and validated a way to modify the critical parameters of a pure fluid such that the results from a multiparameter Helmholtz EOS are unchanged. In this part, I'll examine the effect on mixtures containing helium.
The critical constants for 'classical' helium by Messerly et al. [1] are a great place to start. As noted in their Abstract
"This work is motivated by the use of corresponding-states models for mixtures containing helium (such as some natural gases) at higher temperatures where quantum effects are expected to be negligible."This is exactly the kind of use-case I want to investigate.
In our earlier work based on cubic equations of state [2], we focused exclusively on phase equilibrium data. However, as the GERG EOS framework is suitable for describing other properties such as density and speed of sound to within experimental uncertainty, I will begin with some density predictions for the binary system (methane + helium).
Hernández-Gómez et al. [3] published a large dataset of density for the (methane + helium) binary system. They found deviations from GERG-2008 EOS [4] reaching to −6.5%. The first thing I'll do is try to recreate their reported deviations; the following code reads in the density data and compares to the GERG-2008 EOS result:
@testset "Hernandez-Gomez density (methane+helium)" begin
methane = AdvancedThermo.get_fluid_component("methane")
helium = AdvancedThermo.get_fluid_component("helium")
mixture = AdvancedThermo.create_mixture([methane,helium])
file = "pdT_methane_helium.csv"
for row in CSV.File(file)
p = row.p*1.e6
T = row.T
x = [row.x1, 1-row.x1]
ρ = AdvancedThermo.ρ(mixture,p,T,x)
@info ρ, row.d, 100*(row.d-ρ)/ρ
end
end
The resultant deviations are very close to those reported in Tables 4 to 6 [3].
It will be easier to compare the effect of modifying the critical parameters by computing summary statistics. In Table 7 [3], the AAD, Bias, RMS and MaxD/% are reported. The statistics from my comparison are (number of digits shown is Julia default, not indicative of significance):
Statistic 0.95 CH4/0.05 He 0.9 CH4/0.1 He 0.5 CH4/0.5 He AAD 0.9977604282369299 1.7175297890168828 2.850436976092459 Bias -0.9977604282369299 -1.7175297890168828 -2.850436976092459 RMS 1.2212151347220386 2.0811094419285987 3.278473503055078 Max -2.0340834791463323 -3.5330612478008017 -6.441211529296846Note that the values for 95% methane and 90% methane differ from their Table 7 [3] because they used extra data from a prior publication [5]. However, it is gratifying to see the other results match.
For the model with modified critical parameters, I'll use the parameters from Messerly et al. [1]. The set-up is essentially the same as in Part 6; the key difference is that when the mixture is created, the binary interaction parameters need to be set to unity. The code for making the data comparison is:
@testset "Hernandez-Gomez density - critical constants (methane+helium)" begin
methane = AdvancedThermo.get_fluid_component("methane")
pc = 0.93e6
Tc = 13.0
ρc = 28.4e3
helium = AdvancedThermo.get_fluid_component("helium")
helium = AdvancedThermo.new_critical!(helium,pc,Tc,ρc)
mixture = AdvancedThermo.create_mixture([methane,helium])
mixture.γv[1,2] = mixture.γv[2,1] = 1.0
mixture.γT[1,2] = mixture.γT[2,1] = 1.0
file = "pdT_methane_helium.csv"
dev = zeros(283)
i = 0
for row in CSV.File(file)
p = row.p*1.e6
T = row.T
x = [row.x1, 1-row.x1]
ρ = AdvancedThermo.ρ(mixture,p,T,x)
i += 1
dev[i] = 100*(row.d-ρ)/ρ
end
# Print summary statistics
AAD95 = sum(abs.(dev[1:60]))/60
Bias95 = sum(dev[1:60])/60
RMS95 = sqrt(sum(dev[1:60].^2)/60)
Max95 = maximum(dev[1:60])>-minimum(dev[1:60]) ? maximum(dev[1:60]) : minimum(dev[1:60])
AAD90 = sum(abs.(dev[61:119]))/59
Bias90 = sum(dev[61:119])/59
RMS90 = sqrt(sum(dev[61:119].^2)/59)
Max90 = maximum(dev[61:119])>-minimum(dev[61:119]) ? maximum(dev[61:119]) : minimum(dev[61:119])
AAD50 = sum(abs.(dev[120:283]))/164
Bias50 = sum(dev[120:283])/164
RMS50 = sqrt(sum(dev[120:283].^2)/164)
Max50 = maximum(dev[120:283])>-minimum(dev[120:283]) ? maximum(dev[120:283]) : minimum(dev[120:283])
println("Statistic 0.95 CH4/0.05 He 0.9 CH4/0.1 He 0.5 CH4/0.5 He")
println("AAD $AAD95 $AAD90 $AAD50")
println("Bias $Bias95 $Bias90 $Bias50")
println("RMS $RMS95 $RMS90 $RMS50")
println("Max $Max95 $Max90 $Max50")
end
and the statistics are
Statistic 0.95 CH4/0.05 He 0.9 CH4/0.1 He 0.5 CH4/0.5 He AAD 4.297307697812139 6.526167267213767 3.014670748518208 Bias 4.297307697812139 6.526167267213767 3.014670748518208 RMS 4.845306516449933 7.366166894559518 3.594373906836211 Max 7.544565086586879 11.297293518608473 7.405915926226708All of the statistics are worse: this is a surprising result to me. I checked for obvious mistakes and couldn't find any. I hope that examining the VLE results leads to some insights.
Although the flash algorithm has some known issues (see Part 5), it may yet be adequate for flashing most of the mixture data and giving some hints as to what is going on. Running the following code modified from Part 5
@testset "pTxy data (methane+helium(modified Tc/ρc))" begin
methane = AdvancedThermo.get_fluid_component("methane")
pc = 0.93e6
Tc = 13.0
ρc = 28.4e3
helium = AdvancedThermo.get_fluid_component("helium")
helium = AdvancedThermo.new_critical!(helium,pc,Tc,ρc)
mixture = AdvancedThermo.create_mixture([methane,helium])
mixture.γv[1,2] = mixture.γv[2,1] = 1.0
mixture.γT[1,2] = mixture.γT[2,1] = 1.0
file = "pTxy_methane_helium.csv"
for row in CSV.File(file)
z = [0.5*(row.x1+row.y1), 0.5*(row.x2+row.y2)]
K = [row.y1/row.x1, row.y2/row.x2]
try
(x,y,β) = AdvancedThermo.flash_initial_K(mixture,row.p*1e3,row.T,z,K)
if β==0.0 || β==1.0
@info "Single phase - $(row.Reference) datum $(row.n)"
end
catch e
@info "Internal error - $(row.Reference) datum $(row.n)"
println(e.msg)
end
end
end
gives as output
[ Info: Internal error - Heck and Hiza, 1967 datum 4 log will only return a complex result if called with a complex argument. Try log(Complex(x)). [ Info: Single phase - Heck and Hiza, 1967 datum 5 [ Info: Internal error - Heck and Hiza, 1967 datum 11 log will only return a complex result if called with a complex argument. Try log(Complex(x)). [ Info: Single phase - Heck and Hiza, 1967 datum 13 [ Info: Single phase - Heck and Hiza, 1967 datum 21 [ Info: Single phase - Heck and Hiza, 1967 datum 26 [ Info: Single phase - Heck and Hiza, 1967 datum 28 [ Info: Internal error - DeVaney et al., 1971 datum 1 log will only return a complex result if called with a complex argument. Try log(Complex(x)). [ Info: Single phase - DeVaney et al., 1971 datum 4 [ Info: Single phase - DeVaney et al., 1971 datum 22 [ Info: Single phase - DeVaney et al., 1971 datum 24 [ Info: Single phase - DeVaney et al., 1971 datum 37 [ Info: Single phase - DeVaney et al., 1971 datum 38 [ Info: Single phase - Rhodes et al., 1971 datum 5There are a few more errors above than in Part 5 but most of the data where errors occurred are the same, meaning that there remain 111 data where the flash succeeds for both cases (see the file
pTxy_methane_helium_pruned.csv
in the zip below).
The code to generate some statistics based on those data looks like
@testset "pruned pTxy data (methane+helium)" begin
methane = AdvancedThermo.get_fluid_component("methane")
helium = AdvancedThermo.get_fluid_component("helium")
mixture = AdvancedThermo.create_mixture([methane,helium])
file = "pTxy_methane_helium_pruned.csv"
devK1 = zeros(111)
devK2 = zeros(111)
i = 0
for row in CSV.File(file)
z = [0.5*(row.x1+row.y1), 0.5*(row.x2+row.y2)]
K = [row.y1/row.x1, row.y2/row.x2]
try
(x,y,β) = AdvancedThermo.flash_initial_K(mixture,row.p*1e3,row.T,z,K)
if β==0.0 || β==1.0
# don't expect to encounter this with the pruned dataset
@info "Single phase - $(row.Reference) datum $(row.n)"
else
i += 1
devK1[i] = log(K[1]) - log(y[1]/x[1])
devK2[i] = log(K[2]) - log(y[2]/x[2])
#@info "K1=$(K[1]) K2=$(K[2]); y1=$(y[1]) x1=$(x[1]) K1=$(y[1]/x[1]) K2=$(y[2]/x[2])"
end
catch e
# don't expect to encounter this with the pruned dataset
@info "Internal error - $(row.Reference) datum $(row.n)"
println(e.msg)
end
end
(AADK1,BiasK1,RMSK1,MaxK1) = calculate_statistics(devK1)
(AADK2,BiasK2,RMSK2,MaxK2) = calculate_statistics(devK2)
println("Statistic lnK(methane) lnK(helium)")
println("AAD $AADK1 $AADK2")
println("Bias $BiasK1 $BiasK2")
println("RMS $RMSK1 $RMSK2")
println("Max $MaxK1 $MaxK2")
end
with a similar block for the scenario with modified critical parameters
based on Messerly et al. [1]. The resulting statistics are:
pruned pTxy data (methane+helium) Statistic lnK(methane) lnK(helium) AAD 0.37406249117338014 0.8629896248807529 Bias -0.3027384087993995 -0.5980902047142513 RMS 0.5842857458176463 5.416227356673016 Max 1.9583441558686754 -56.8171557982011 pruned pTxy data (methane+helium(modified Tc/ρc)) Statistic lnK(methane) lnK(helium) AAD 0.39529678667060447 8.089845336234148 Bias 0.39393776759098836 -8.089845336234148 RMS 0.5033200776369687 15.277498663484204 Max 1.9302763783863863 -109.38993501770257which leave little room for doubt that modifying the critical parameters worsens significantly the model predictions compared to the GERG-2008 EOS.
However, I'm not entirely convinced that the results I have are accurate. Plus, even if the Messerly et al. critical parameters don't yield any improvement, it doesn't mean that other critical parameters won't be better. So, in the next part, I'll try to verify the above results.
The code so far can be obtained by downloading the zip file.
[1] Messerly et al., J. Chem. Eng. Data, 2020, 65, 1028 (link to publisher)
[2] Rowland et al., J. Chem. Eng. Data, 2017, 62, 2799 (link to publisher)
[3] Hernández-Gómez et al., J. Chem. Thermodyn., 2016, 101, 168 (link to publisher)
[4] Kunz and Wagner, J. Chem. Eng. Data, 2012, 57, 3032 (link to publisher)
[5] Hernández-Gómez et al., J. Chem. Thermodyn., 2016, 96, 1 (link to publisher)
Go to Home | How to cite this page | Permalink to this page |