The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Natural Gas Properties with ISO6976.2016

Overview

ISO6976.2016 implements the calculation method of ISO 6976:2016 “Natural Gas — Calculation of calorific values, density, relative density and Wobbe indices from composition”. Given a gas composition as mole fractions, it returns all combustion and volumetric properties together with their standard uncertainties, propagated according to Annex B of the standard.

Properties returned

Symbol Description Unit
M Molar mass kg/kmol
Z Compression factor
G_o, D_o Ideal-gas relative density and density —, kg/m³
G, u_G Real-gas relative density
D, u_D Real-gas density kg/m³
Hcg, u_Hcg Molar gross calorific value kJ/mol
Hcn, u_Hcn Molar net calorific value kJ/mol
Hmg, u_Hmg Mass-basis gross calorific value MJ/kg
Hmn, u_Hmn Mass-basis net calorific value MJ/kg
Hvg, u_Hvg Volumetric gross calorific value (real gas) MJ/m³
Hvn, u_Hvn Volumetric net calorific value (real gas) MJ/m³
Hvg_o, Hvn_o Ideal-gas volumetric calorific values MJ/m³
Wg, u_Wg Gross Wobbe index MJ/m³
Wn, u_Wn Net Wobbe index MJ/m³
Wg_o, Wn_o Ideal-gas Wobbe indices MJ/m³

Properties with a u_ prefix are standard uncertainties (k = 1) unless the coverage argument is set to a value other than 1.

Application limits

The calculation is valid only within the limits defined in ISO 6976:2016 §5:

Quick start

The simplest way to provide a composition is to construct a numeric vector of length 60 in the component order of ISO 6976:2016 Table A.2 (use componentNames() to see the full list):

x   <- numeric(60)   # all zeros
u_x <- numeric(60)   # all zero uncertainties
r_x <- diag(60)      # identity correlation matrix (no correlations)

# Fill in a simple two-component mixture: 95 % methane, 5 % nitrogen
x[componentIndex("methane")]  <- 0.95
x[componentIndex("nitrogen")] <- 0.05

# Assign standard uncertainties (0.05 mol/mol each)
u_x[componentIndex("methane")]  <- 0.0005
u_x[componentIndex("nitrogen")] <- 0.0005

res <- calculateProperties(x, u_x, r_x,
                           combustionTemperature = 25,
                           volumeTemperature     = 15)

cat("Molar mass              :", round(res$M,   4), "kg/kmol\n")
#> Molar mass              : 16.641 kg/kmol
cat("Compression factor Z    :", round(res$Z,   6), "\n")
#> Compression factor Z    : 0.998139
cat("Gross CV (volumetric)   :", round(res$Hvg, 4), "MJ/m³\n")
#> Gross CV (volumetric)   : 35.8484 MJ/m³
cat("  standard uncertainty  :", round(res$u_Hvg, 6), "MJ/m³\n")
#>   standard uncertainty  : 0.020476 MJ/m³
cat("Gross Wobbe index       :", round(res$Wg,  4), "MJ/m³\n")
#> Gross Wobbe index       : 47.261 MJ/m³
cat("  standard uncertainty  :", round(res$u_Wg, 6), "MJ/m³\n")
#>   standard uncertainty  : 0.026097 MJ/m³

Using the GasComponents class

For applications that build a composition incrementally — for example when reading chromatograph results component by component — the GasComponents R6 class provides named getters and setters:

gc <- GasComponents$new()

# Set fractions by name or by index
gc$setFraction("methane",  0.9234)
gc$setFraction("ethane",   0.0254)
gc$setFraction("propane",  0.0152)
gc$setFraction("nitrogen", 0.0103)
gc$setFraction("carbon dioxide", 0.0154)
gc$setFraction(1L, 0.9234)   # same as "methane"

# Set uncertainties
gc$setUncertainty("methane",        0.000332)
gc$setUncertainty("ethane",         0.000243)
gc$setUncertainty("propane",        0.000148)
gc$setUncertainty("nitrogen",       0.000195)
gc$setUncertainty("carbon dioxide", 0.000111)

# Retrieve a value
gc$getFraction("methane")
#> [1] 0.9234

# Pass directly to calculateProperties
res <- calculateProperties(gc$fractions, gc$uncertainties, gc$correlations,
                           combustionTemperature = 15,
                           volumeTemperature     = 15)
round(res$Hvg, 4)   # real-gas vol. gross CV [MJ/m³]
#> [1] 38.0053

Setting correlations

When a GC calibration provides a full covariance matrix, use setCorrelationMatrix() or setCorrelation() for individual pairs:

gc2 <- GasComponents$new()
gc2$setFractionArray(gc$fractions)
gc2$setUncertaintyArray(gc$uncertainties)

# Negative correlation between methane and ethane (typical for GC)
gc2$setCorrelation("methane", "ethane", -0.65)
gc2$getCorrelation("methane", "ethane")
#> [1] -0.65
gc2$getCorrelation("ethane", "methane")   # automatically symmetric
#> [1] -0.65

Reference conditions

ISO 6976:2016 defines properties at specified reference temperatures and a reference pressure. The package supports all temperature combinations in the standard:

data("example3", envir = environment())

# German/European standard: 25 °C combustion, 0 °C metering
r25_0 <- calculateProperties(example3$fractionArray, example3$uncertaintyArray,
                             example3$correlationMatrix,
                             combustionTemperature = 25,
                             volumeTemperature     = 0)

# UK/legacy standard: 15 °C / 15 °C
r15_15 <- calculateProperties(example3$fractionArray, example3$uncertaintyArray,
                              example3$correlationMatrix,
                              combustionTemperature = 15,
                              volumeTemperature     = 15)

cat("Hvg at 25/0 °C  :", round(r25_0$Hvg,  5), "MJ/m³\n")
#> Hvg at 25/0 °C  : 41.8936 MJ/m³
cat("Hvg at 15/15 °C :", round(r15_15$Hvg, 5), "MJ/m³\n")
#> Hvg at 15/15 °C : 39.73351 MJ/m³

Uncertainty and coverage factor

All u_ outputs are standard uncertainties (k = 1) by default. For expanded uncertainties at a given confidence level, set coverage = 2 (approximately 95 % for a normal distribution):

data("example1", envir = environment())

r_k1 <- calculateProperties(example1$fractionArray, example1$uncertaintyArray,
                             example1$correlationMatrix,
                             combustionTemperature = 15, volumeTemperature = 15,
                             coverage = 1)
r_k2 <- calculateProperties(example1$fractionArray, example1$uncertaintyArray,
                             example1$correlationMatrix,
                             combustionTemperature = 15, volumeTemperature = 15,
                             coverage = 2)

cat("Gross Wobbe index :", round(r_k1$Wg, 5), "MJ/m³\n")
#> Gross Wobbe index : 49.52936 MJ/m³
cat("  u (k=1)         :", round(r_k1$u_Wg, 6), "MJ/m³\n")
#>   u (k=1)         : 0.021675 MJ/m³
cat("  U (k=2, ~95%)   :", round(r_k2$u_Wg, 6), "MJ/m³\n")
#>   U (k=2, ~95%)   : 0.04335 MJ/m³

Verification against ISO 6976:2016 Annex D

The package ships with the four reference datasets from Annex D of the standard. The results below reproduce Table D.2 of ISO 6976:2016.

data("example1", envir = environment())
res <- calculateProperties(example1$fractionArray, example1$uncertaintyArray,
                           example1$correlationMatrix,
                           combustionTemperature = 15,
                           volumeTemperature     = 15,
                           coverage              = 1)

tab <- data.frame(
  Property = c("M [kg/kmol]", "Z", "Hcg [kJ/mol]", "u(Hcg)",
               "Hmg [MJ/kg]", "u(Hmg)", "Hvg [MJ/m\u00b3]", "u(Hvg)"),
  Computed = round(c(res$M,     res$Z,     res$Hcg,   res$u_Hcg,
                     res$Hmg,   res$u_Hmg, res$Hvg,   res$u_Hvg), 7),
  ISO_6976 = c(17.3884301, 0.99776224, 906.1799588, 0.615609872,
               52.113961,  0.024301,   38.410611,   0.026267)
)
knitr::kable(tab, align = "lrr")
Property Computed ISO_6976
M [kg/kmol] 17.3884301 17.3884301
Z 0.9977622 0.9977622
Hcg [kJ/mol] 906.1799588 906.1799588
u(Hcg) 0.6156099 0.6156099
Hmg [MJ/kg] 52.1139605 52.1139610
u(Hmg) 0.0243009 0.0243010
Hvg [MJ/m³] 38.4106112 38.4106110
u(Hvg) 0.0262668 0.0262670

Component reference

# All 60 components in table order
nms <- componentNames()
cat(paste(sprintf("%2d  %s", seq_along(nms), nms), collapse = "\n"), "\n")
#>  1  methane
#>  2  ethane
#>  3  propane
#>  4  n-butane
#>  5  isobutane
#>  6  n-pentane
#>  7  isopentane
#>  8  neopentane
#>  9  n-hexane
#> 10  2-methylpentane
#> 11  3-methylpentane
#> 12  2,2-dimethylbutane
#> 13  2,3-dimethylbutane
#> 14  n-heptane
#> 15  n-octane
#> 16  n-nonane
#> 17  n-decane
#> 18  ethylene
#> 19  propylene
#> 20  1-butene
#> 21  cis-2-butene
#> 22  trans-2-butene
#> 23  isobutylene
#> 24  1-pentene
#> 25  propadiene
#> 26  1,2-butadiene
#> 27  1,3-butadiene
#> 28  acetylene
#> 29  cyclopentane
#> 30  methylcyclopentane
#> 31  ethylcyclopentane
#> 32  cyclohexane
#> 33  methylcyclohexane
#> 34  ethylcyclohexane
#> 35  benzene
#> 36  toluene
#> 37  ethylbenzene
#> 38  o-xylene
#> 39  methanol
#> 40  methanethiol
#> 41  hydrogen
#> 42  water
#> 43  hydrogen sulphide
#> 44  ammonia
#> 45  hydrogen cyanide
#> 46  carbon monoxide
#> 47  carbonyl sulphide
#> 48  carbon disulphide
#> 49  helium
#> 50  neon
#> 51  argon
#> 52  nitrogen
#> 53  oxygen
#> 54  carbon dioxide
#> 55  sulphur dioxide
#> 56  n-undecane
#> 57  n-dodecane
#> 58  n-tridecane
#> 59  n-tetradecane
#> 60  n-pentadecane

Further reading

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.