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.
| 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.
The calculation is valid only within the limits defined in ISO 6976:2016 §5:
combustionTemperature): 0, 15, 15.55, 20, or 25 °CvolumeTemperature): 0, 15, 15.55, or 20 °Cpressure): 90–110
kPa (default 101.325 kPa)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³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.0053When 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.65ISO 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³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³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 |
# 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?calculateProperties — full parameter documentation and
output table.?GasComponents — R6 class reference.?example1 through ?example3_ex — dataset
documentation.