Advanced Thermodynamics

advancedthermo.com

Thermodynamic properties of natural gas mixtures containing helium - Part 7

18 July 2021

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.441211529296846
Note 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.405915926226708
All 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 5
There 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.38993501770257
which 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.

References

[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