FE-ISO12213-2-C


FE-ISO12213-2-C (Revised: July 28, 2010) is the C source code implementation of the International standard:

  • ISO 12213-2:2006: Natural gas - Calculation of compression factor -
    Part 2: Calculation using molar-composition analysis
The software is written in a C-language and embeds all the restrictions implied by ISO 12213-2:2006. The following is a brief description of a function (method), input/output parameters, ranges of applications, errors and an example of a main program in a c-source code.

Function prototype
The following is function prototype:

void iso12213x2( /* Output parameters */ unsigned long int *error_status, /* Error status */ float *sup_cal_value, /* Superior calorific value */ float *relative_density, /* Relative density */ float *compression, /* Compression (compressibility factor) */ float *density, /* Density [kg/m3] */ float *molar_density, /* Molar density [kg-mole/m3] */ float *mole_average, /* Mole average */ /* Input parameters */ float tepmerature_K, /* Temperature [K] */ float pressure_MPa, /* Pressure in [MPa] */ float x20, /* molar fraction of Argon */ float x19, /* molar fraction of Helium */ float x18, /* molar fraction of n-Decane */ float x17, /* molar fraction of n-Nonane */ float x16, /* molar fraction of n-Octane */ float x15, /* molar fraction of n-Heptane */ float x14, /* molar fraction of n-Hexane */ float x13, /* molar fraction of n-Pentane */ float x12, /* molar fraction of i-Pentane */ float x11, /* molar fraction of n-Butane */ float x10, /* molar fraction of i-Butane */ float x9, /* molar fraction of Oxygen */ float x8, /* molar fraction of Carbon Monoxide */ float x7, /* molar fraction of Hydrogen */ float x6, /* molar fraction of Hydrogen Sulfide */ float x5, /* molar fraction of Water */ float x4, /* molar fraction of Propane */ float x3, /* molar fraction of Ethane */ float x2, /* molar fraction of Carbon Dioxide */ float x1, /* molar fraction of Nitrogen */ float x0 /* molar fraction of Methane */ )


Description of input/output parameters, ranges of application and errors

Input parameters
Data typeParameter name Parameter descriptionUnit of measure
floatx0 molar fraction of Methanedimensionless
floatx1 molar fraction of Nitrogen"
floatx2 molar fraction of Carbon dioxide"
floatx3 molar fraction of Ethane"
floatx4 molar fraction of Propane"
floatx5 molar fraction of Water"
floatx6 molar fraction of Hydrogen sulfide"
floatx7 molar fraction of Hydrogen"
floatx8 molar fraction of Carbon monoxide"
floatx9 molar fraction of Oxygen"
floatx10 molar fraction of iso-Butane"
floatx11 molar fraction of n-Butane"
floatx12 molar fraction of i-Pentane"
floatx13 molar fraction of n-Pentane"
floatx14 molar fraction of n-Hexane"
floatx15 molar fraction of n-Heptane"
floatx16 molar fraction of n-Octane"
floatx17 molar fraction of n-Nonane"
floatx18 molar fraction of n-Decane"
floatx19 molar fraction of Helium"
floatx20 molar fraction of Argon"
floatpressure_MPa Pressure (absolute)MPa
floattemperature_K TemperatureK
Output parameters
floatmole_average gas mixture molar masskg/kmol
floatmolar_density gas mixture molar densitykg⋅mol/m3
floatdensity gas mixture densitykg/m3
floatcompression gas mixture compression factordimensionless
floatrelative density gas mixture relative densitydimensionless
floatsup_cal_value gas mixture superior calorific valueMJ/m3
longerror_status error statusdimensionless
Ranges of application implemented in FE-ISO12213-2-C
Parameter Unit of measure Normal range1) Wider range 2)
molar fraction of Methane dimensionless 0.70 to 1.00 0.50 to 1.00
molar fraction of Nitrogen " 0 to 0.20 0 to 0.50
molar fraction of Carbon dioxide " 0 to 0.20 0 to 0.30
molar fraction of Ethane " 0 to 0.10 0 to 0.20
molar fraction of Propane " 0 to 0.035 0 to 0.05
molar fraction of Water " 0 to 0.00015 0 to 0.00015
molar fraction of Hydrogen sulfide " 0 to 0.0002 0 to 0.0002
molar fraction of Hydrogen " 0 to 0.10 0 to 0.10
molar fraction of Carbon monoxide " 0 to 0.03 0 to 0.03
molar fraction of Oxigen " 0 to 0.0002 0 to 0.0002
molar fraction of butanes (n-Butane + i-Butane) " 0 to 0.015 0 to 0.015
molar fraction of pentanes (n-pentane + i-Pentane) " 0 to 0.005 0 to 0.005
molar fraction of hexanes (n-Hexane) " 0 to 0.001 0 to 0.001
molar fraction of heptanes (n-Heptane) " 0 to 0.0005 0 to 0.0005
molar fraction of octanes plus higher hydrocarbons (n-Octane, n-Nonane, n-Decane) " 0 to 0.0005 0 to 0.0005
molar fraction of Helium " 0 to 0.005 0 to 0.005
molar fraction of Argon " 0 to 0.0002 0 to 0.0002
Pressure (absolute) MPa 0 to 12 0 to 65
Temperature K 263 to 338 225 to 350
Relative density dimensionless 0.55 to 0.80 0.55 to 0.90
Superior calorific value MJ/m3 30 to 45 20 to 48
1) "Normal range" stands for Pipeline quality gas (see Section 4.4.1 of ISO 12213-2:2006).
2) "Wider range" stands for Wider range of application (see Section 4.4.2 of ISO 12213-2:2006).
The ranges of application denoted by "Wider range" are implemented in FE-ISO12213-2-C C-code
Errors and warnings
"long error_status" represents errors and warnings generated during program execution as follows:
Bit 0 =1 (0000001H) Error: There exist at least one molar fraction < 0 or > 1
Bit 1 =1 (0000002H) Error: The total sum of molar fractions <0.98 or >1.02
Bit 2 =1 (0000004H) Warning: Total sum of molar fractions is <0.999999 or >1.000001.
If set this bit only warns that the fractions have been normalized to give the total sum of molar fractions exactly equal to 1. If only bit 2 was set during the calculation the results are valid.
Bit 3 =1 (0000008H) Error: Mole fraction of Methane out of range.
Bit 4 =1 (0000010H) Error: Mole fraction of Nitrogen out of range.
Bit 5 =1 (0000020H) Error: Mole fraction of Carbon Dioxide out of range.
Bit 6 =1 (0000040H) Error: Mole fraction of Ethane out of range.
Bit 7 =1 (0000080H) Error: Mole fraction of Propane out of range.
Bit 8 =1 (0000100H) Error: Mole fraction of Water out of range.
Bit 9 =1 (0000200H) Error: Mole fraction of Hydrogen sulfide out of range.
Bit 10 =1 (0000400H) Error: Mole fraction of Hydrogen out of range.
Bit 11 =1 (0000800H) Error: Mole fraction of Carbon monoxide out of range.
Bit 12 =1 (0001000H) Error: Mole fraction of Oxygen out of range.
Bit 13 =1 (0002000H) Error: Mole fraction of Butanes) out of range.
Bit 14 =1 (0004000H) Error: Mole fraction of Pentanes out of range.
Bit 15 =1 (0008000H) Error: Mole fraction of Hexanes out of range.
Bit 16 =1 (0010000H) Error: Mole fraction of Heptanes out of range.
Bit 17 =1 (0020000H) Error: Mole fraction of Octanes plus higher hydrocarbons out of range.
Bit 18 =1 (0040000H) Error: Mole fraction of Helium out of range.
Bit 19 =1 (0080000H) Error: Mole fraction of Argon out of range.
Bit 20 =1 (0100000H) Error: Pressure (absolute) out of range.
Bit 21 =1 (0200000H) Error: Temperature out of range.
Bit 22 =1 (0400000H) Error: Relative density out of range.
Bit 23 =1 (0800000H) Error: Superior calorific value out of range.
Bit 24 =1 (1000000H) Error: OFF-LINE calculation failed.
Bit 25,... All higher order bits are unused
The results are valid if bits 0,...,24 are all cleared, or if only bit 2 was set during the calculation, otherwise the results are invalid, i.e. cleared.

Example of a main program "main.c" in C code calling the function "iso12213x2()"

The following example illustrates the call to iso12213x2() function from a main program. Input parameters yy[igas][0], ..., yy[igas][20] represent natural gas mixture molar fractions where igas = 0 denotes Gas 1, ..., igas =5 denotes Gas 6 (See table C.1 in Annex C of ISO 12213-2:2006), yy[21] represents pressure (6 MPa) and yy[22] represents temperature 310 K. The output results are saved in yy[23], ..., yy[28] and an error status in error, after the completion of the routine. The program prompts for the selection of the gas mixture, for the pressure and temperature and prints the results on the screen.

/* ******************* */ /* MAIN PROGRAM C-CODE */ /* ******************* */ #include "stdio.h" /* declaration of the function iso12213x2 */ void iso12213x2( /* output parameters */ unsigned long int *error_status, /* Error status */ float *sup_cal_value, /* Superior calorific value */ float *relative_density, /* Relative density */ float *compression, /* Compression (compressibility factor) */ float *density, /* Density [kg/m3] */ float *molar_density, /* Molar density [kg-mole/m3] */ float *mole_average, /* Mole average */ /* input parameters */ float tepmerature_K, /* Temperature [K] */ float pressure_MPa, /* Pressure in [MPa] */ float x20, /* molar fraction of Argon */ float x19, /* molar fraction of Helium */ float x18, /* molar fraction of n-Decane */ float x17, /* molar fraction of n-Nonane */ float x16, /* molar fraction of n-Octane */ float x15, /* molar fraction of n-Heptane */ float x14, /* molar fraction of n-Hexane */ float x13, /* molar fraction of n-Pentane */ float x12, /* molar fraction of i-Pentane */ float x11, /* molar fraction of n-Butane */ float x10, /* molar fraction of i-Butane */ float x9, /* molar fraction of Oxygen */ float x8, /* molar fraction of Carbon Monoxide */ float x7, /* molar fraction of Hydrogen */ float x6, /* molar fraction of Hydrogen Sulfide */ float x5, /* molar fraction of Water */ float x4, /* molar fraction of Propane */ float x3, /* molar fraction of Ethane */ float x2, /* molar fraction of Carbon Dioxide */ float x1, /* molar fraction of Nitrogen */ float x0 /* molar fraction of Methane */ ); void main(void) { unsigned short int i, j, igas; unsigned long int error; char ch; /* Array of input and output data */ float twodim[2][3] = { 11, 12, 13, 21, 22, 23 }; float yy[6][29] = { 0.965, 0.003, 0.006, 0.018, 0.0045, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.001, 0.0005, 0.0003, 0.0007, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.907, 0.031, 0.005, 0.045, 0.0084, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0015, 0.0003, 0.0004, 0.0004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.859, 0.01, 0.015, 0.085, 0.023, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0035, 0.0035, 0.0005, 0.0005, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.735, 0.1, 0.016, 0.033, 0.0074, 0.0, 0.0, 0.095, 0.01, 0.0, 0.0012, 0.0012, 0.0004, 0.0004, 0.0002, 0.0001, 0.0001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.812, 0.057, 0.076, 0.043, 0.009, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0015, 0.0015, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.826, 0.117, 0.011, 0.035, 0.0075, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0012, 0.0012, 0.0004, 0.0004, 0.0002, 0.0001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; char *text[29] = { "Methane ", "Nitrogen ", "Carbon Dioxide ", "Ethane ", "Propane ", "Water ", "Hydrogen Sulfide", "Hydrogen ", "Carbon Monoxide ", "Oxygen ", "iso-Butane ", "n-Butane ", "i-Pentane ", "n-Pentane ", "n-Hexane ", "n-Heptane ", "n-Octane ", "n-Nonane ", "n-Decane ", "Helium ", "Argon ", "Pressure [MPa] ", "Temperature [K] ", "Mole average ", "Molar density [kg-mole/m3]", "Density [kg/m3] ", "Compression ", "Relative density ", "Superior calorific value " }; for (j=0; ; ) { printf("\nINPUT PARAMETERS\n"); printf("%s", "Select gas composition (type number 1-6) = "); scanf("%d", &igas); if (igas > 6) igas = 6; igas -= 1; /* Enter parameters */ for (i=21; i<23; ++i) { printf("%s = ", text[i]); /* Enter parameter */ scanf("%f", &yy[igas][i]); } /* Print input parameters and results */ printf("\nI N P U T P A R A M E T E R S:"); /* Print gas selection */ printf("\n%s%d", "Selected gas = Gas", igas+1); /* Print mole fractions */ printf("\nMole fractions:"); for (i=0; i<10; ++i) { printf("\n%s = %f, %s = %f",text[2*i], yy[igas][2*i], text[2*i+1], \ yy[igas][2*i+1]); } printf("\n%s = %f",text[20], yy[igas][20]); /* Print pressure */ printf("\n%s = %f", text[21], yy[igas][21]); /* Print temperature */ printf("\n%s = %f", text[22], yy[igas][22]); printf("\n\nR E S U L T S"); /* call iso12213x2 routine */ iso12213x2(&error, &yy[igas][28], &yy[igas][27], &yy[igas][26], &yy[igas][25], \ &yy[igas][24], &yy[igas][23], yy[igas][22], yy[igas][21], \ yy[igas][20], yy[igas][19], yy[igas][18], yy[igas][17], yy[igas][16], \ yy[igas][15], yy[igas][14], yy[igas][13], yy[igas][12], yy[igas][11], \ yy[igas][10], yy[igas][9], yy[igas][8], yy[igas][7], yy[igas][6], \ yy[igas][5], yy[igas][4], yy[igas][3], yy[igas][2], yy[igas][1], \ yy[igas][0]); /* Print error flags as hexadecimal number */ printf("\nError(Hex) = %x", error); /* Print results */ for (i=0; i<6; ++i) { printf("\n%s = %f",text[28-i], yy[igas][28-i]); } printf("\nPress X to exit or anything else to continue: "); ch = getch(); if (( ch == 'X') || (ch == 'x')) break; } } /* ****************************** */ /* END OF THE MAIN PROGRAM C-CODE */ /* ****************************** */