FE-AGA8-Part2-C


FE-AGA8-Part2-C (Revised: July 15, 2021) is the C source code implementation of:

  • AGA8 Report No. 8, Part 2
    Thermodynamic Properties of Natural Gas and Related Gases -
    GERG–2008 Equation of State
    First Edition April 2017
The software is written in a C-language and embeds all the restrictions implied by AGA8 Report No. 8, Part 2. The following is a brief description of a function (method), input/output parameters and header file with an example of a main program in a c-source code.

Description of function, parameters and errors

Function
Function declaration void aga8part2(short iCalc, struct aga8part2 *aga0);
short iCalc Defines the following three types of calculation
iCalc=0 Calculation method based on: absolute pressure in MPa, temperature in K, and mole fractions of 21 natural gas components
iCalc=1 Calculation method based on: density in kg/m3, temperature in K, and mole fractions of 21 natural gas components
iCalc=2 Calculation method based on: reduced density, temperature in K, and mole fractions of 21 natural gas components
Struct aga8part2{double xx[42]; long es; short RAP;}
INPUT parameters common to all three calculation methods defined by "short iCalc"
short RAP 1) Ranges of application:
  • RAP=0 - Normal P,T range (AGA8 Report No. 8, Part 2:2017, Table 6) and pipeline quality mole fractions ranges (AGA8 Report No. 8, Part 2:2017, Table 5)
  • RAP=1 - Full P,T range (AGA8 Report No. 8, Part 2:2017, Table 6) and intermediate quality mole fractions ranges (AGA8 Report No. 8, Part 2:2017, Table 5)
  • RAP=2 - Full P,T range (AGA8 Report No. 8, Part 2:2017, Table 6) and no limitations on mole fractions 0≤xx[i]≤1
Mole fraction ranges defined by RAP=2 are not in accordance with AGA8 Report No. 8, Part 2:2017. It can be used only for software testing purposes (e.g. examples given in Annex G of AGA8 Report No. 8, Part 2:2017), when the mole fraction ranges defined by RAP=0 or RAP=1 are not satisfied.
double xx[0] Mole fraction of — Methane
double xx[1] Mole fraction of — Nitrogen
double xx[2] Mole fraction of — Carbon Dioxide
double xx[3] Mole fraction of — Ethane
double xx[4] Mole fraction of — Propane
double xx[5] Mole fraction of — i-Butane
double xx[6] Mole fraction of — n-Butane
double xx[7] Mole fraction of — i-Pentane
double xx[8] Mole fraction of — n-Pentane
double xx[9] Mole fraction of — n-Hexane
double xx[10] Mole fraction of — n-Heptane
double xx[11] Mole fraction of — n-Octane
double xx[12] Mole fraction of — n-Nonane
double xx[13] Mole fraction of — n-Decane
double xx[14] Mole fraction of — Hydrogen
double xx[15] Mole fraction of — Oxygen
double xx[16] Mole fraction of — Carbon-monoxide
double xx[17] Mole fraction of — Water
double xx[18] Mole fraction of — Hydrogen-sulfide
double xx[19] Mole fraction of — Helium
double xx[20] Mole fraction of — Argon
double xx[22] Temperature in K
INPUT parameters or RESULTS, depending on the calculation method selected by "short iCalc"
double xx[21] Pressure (absolute) in MPa - INPUT if iCalc=0 and RESULT if iCalc=1 or iCalc=2
double xx[25] Density in kg/m3 - INPUT if iCalc=1 and RESULT if iCalc=0 or iCalc=2
double xx[27] Reduced density - INPUT if iCalc=2 and RESULT if iCalc=0 or iCalc=1
RESULTS common to all three calculation methods defined by "short iCalc"
double xx[23] Molar mass [kg/kmol]
double xx[24] Molar density [kmol/m3]
double xx[26] Compressibility factor
double xx[28] Molar Gibbs free energy [kJ/kmol]
double xx[29] Molar internal energy [kJ/kmol]
double xx[30] Specific internal energy [kJ/kg]
double xx[31] Molar Enthalpy [kJ/kmol]
double xx[32] Specific enthalpy [kJ/kg]
double xx[33] Molar entropy [kJ/(kmol⋅K)]
double xx[34] Specific entropy [kJ/(kg⋅K)]
double xx[35] Molar isochoric heat capacity [kJ/(kmol⋅K)]
double xx[36] Specific isochoric heat capacity [kJ/(kg⋅K)]
double xx[37] Molar isobaric heat capacity [kJ/(kmol⋅K)]
double xx[38] Specific isobaric heat capacity [kJ/(kg⋅K)]
double xx[39] Joule-Thomson coefficient [K/MPa]
double xx[40] Isentropic exponent []
double xx[41] Speed of sound [m/s]
long es 2) Error status after completion of the calculation method
1) short RAP RAP - Ranges of application implemented in FE-AGA8-Part2-C
Parameter RAP=0 RAP=1 RAP=2
Pressure (absolute) in MPa >0 to 35 >0 to 70 >0 to 70
Temperature in K 90 to 450 60 to 700 60 to 700
Reduced density 5⋅10-9 to 6.00 5⋅10-9 to 6.00 5⋅10-9 to 6.00
Mole fractions ranges
Methane 0.7 to 1.00 0.3 to 1.00 0 to 1.00
Nitrogen 0 to 0.20 0 to 0.55 0 to 1.00
Carbon dioxide 0 to 0.20 0 to 0.30 0 to 1.00
Ethane 0 to 0.10 0 to 0.25 0 to 1.00
Propane 0 to 0.035 0 to 0.14 0 to 1.00
i-Butane + n-Butane 0 to 0.015 0 to 0.06 0 to 1.00
i-Pentane + n-Pentane 0 to 0.005 0 to 0.005 0 to 1.00
n-Hexane 0 to 0.001 0 to 0.002 0 to 1.00
n-Heptane 0 to 0.0005 0 to 0.001 0 to 1.00
Octane + Nonane + Decane 0 to 0.0005 0 to 0.0005 0 to 1.00
Hydrogen 0 to 0.10 0 to 0.40 0 to 1.00
Oxigen 0 to 0.0002 0 to 0.02 0 to 1.00
Carbon monoxide 0 to 0.03 0 to 0.13 0 to 1.00
Water 0 to 0.00015 0 to 0.0002 0 to 1.00
Hydrogen sulfide 0 to 0.0002 0 to 0.27 0 to 1.00
Helium 0 to 0.005 0 to 0.005 0 to 1.00
Argon 0 to 0.0002 0 to 0.0005 0 to 1.00
2) long es long es - Error status after completion of the calculation method
Error/Warning bit Description of Error/Warning
Bit 0 =1 (000001H) Error: There exist at least one molar fraction < 0.
Bit 1 =1 (000002H) Error: The total sum of molar fractions <0.999999 or >1.000001.
Bit 2 =1 (000004H) Warning: Temperature T<200 K.
If only this bit is set, it warns that the calculated thermodynamic properties may be invalid, but the calculated volumetric properties (reduced density, mass density and comression factor) are valid.
Bit 3 =1 (000008H) Error: Mole fraction of Methane out of range defined by RAP.
Bit 4 =1 (000010H) Error: Mole fraction of Nitrogen out of range defined by RAP.
Bit 5 =1 (000020H) Error: Mole fraction of Carbon Dioxide out of range defined by RAP.
Bit 6 =1 (000040H) Error: Mole fraction of Ethane out of range defined by RAP.
Bit 7 =1 (000080H) Error: Mole fraction of Propane out of range defined by RAP.
Bit 8 =1 (000100H) Error: Mole fraction of (n-Butane + i-Butane) out of range defined by RAP.
Bit 9 =1 (000200H) Error: Mole fraction of (n-pentane + i-Pentane) out of range defined by RAP.
Bit 10 =1 (000400H) Error: Mole fraction of n-Hexane out of range defined by RAP.
Bit 11 =1 (000800H) Error: Mole fraction of n-Heptane out of range defined by RAP.
Bit 12 =1 (001000H) Error: Mole fraction of (n-Octane + n-Nonane, n-Decane) out of range defined by RAP.
Bit 13 =1 (002000H) Error: Mole fraction of Hydrogen out of range defined by RAP.
Bit 14 =1 (004000H) Error: Mole fraction of Oxygen out of range defined by RAP.
Bit 15 =1 (008000H) Error: Mole fraction of Carbon monoxide out of range defined by RAP.
Bit 16 =1 (010000H) Error: Mole fraction of Water out of range defined by RAP defined by RAP.
Bit 17 =1 (020000H) Error: Mole fraction of Hydrogen sulfide out of range defined by RAP.
Bit 18 =1 (040000H) Error: Mole fraction of Helium out of range defined by RAP.
Bit 19 =1 (080000H) Error: Mole fraction of Argon out of range defined by RAP.
Bit 20 =1 (100000H) Error: Pressure (absolute) out of range defined by RAP.
Bit 21 =1 (200000H) Error: Temperature out of range defined by RAP.
Bit 22 =1 (400000H) Error: No solution to reduced density or reduced density out of range defined by RAP.
All higher order bits are unused
Error status (es) is a long number representing all the errors encountered in the calculation. If bits 0,...,22 are all cleared, or if only bit 2 was set during the calculation, the results are valid, otherwise the results are invalid, i.e. cleared.

Header file "aga8part2.h"

#include "stdio.h" #include "math.h" // declaration of the structure struct aga8part2 { // Input/output parameters double xx[42]; // Parameters in floating point format long es; // Error status short RAP; // Index for the selected ranges of application }; // declaration of the function void aga8part2(short iCalc, struct aga8part2 *);


Example of a main program "main.c" in C code calling the function "aga8part2(iCalc, agax)"

The following example illustrates the call to void aga8part2(short iCalc, struct aga8part2 *aga0) function from a main program. The main program defines a struct for input/output data. The program prompts for the type of the calculation and for the selection of the natural gas mixture given in Annex B of AGA8 Report No. 8, Part 2, Table B.1, or for the manual setup of input parameters. The program then transfers the input parameters to the corresponding struct. After the execution the program prints both the input parameters and the results on the screen in accordance with the selected calculation type. The calculated results can be compared easily with the calculation examples given in Annex B of AGA8 Report No. 8, Part 2, Table B.2.

/* **************************************** */ /* THE BEGINNING OF THE MAIN PROGRAM C-CODE */ /* **************************************** */ #include "aga8part2.h" void main(void) { struct aga8part2 aga, *agax; /* 'aga8x' is a pointer to a structure 'aga8' */ short j, ii, ix, igas, iCalc; char ch; char *text[43] = { "Methane ", "Nitrogen ", "Carbon Dioxide ", "Ethane ", "Propane ", "i-Butane ", "n-Butane ", "i-Pentane ", "n-Pentane ", "n-Hexane ", "n-Heptane ", "n-Octane ", "n-Nonane ", "n-Decane ", "Hidrogen ", "Oxigen ", "Carbon monoxide ", "Water ", "Hydrogen Sulfide ", "Helium ", "Argon ", "Pressure [MPa] ", "Temperature [K] ", "Molar mass of the mixture [kg/kmol] ", "Molar density [kmol/m3] ", "Density [kg/m3] ", "Compression factor ", "Reduced density ", "Molar Gibs free energy g[kJ/kmol] ", "Molar internal energy [kJ/kmol] ", "Specific internal energy [kJ/kg] ", "Molar enthalpy [kJ/kmol] ", "Specific enthalpy [kJ/kg] ", "Molar entropy [kJ/(kmol*K)} ", "Specific entropy [kJ/(kg*K)] ", "Molar isochoric heat capacity [kJ/(kmol*K)] ", "Specific isochoric heat capacity [kJ/(kg*K)] ", "Molar isobaric heat capacity [kJ/(kmol*K)] ", "Specific isobaric heat capacity [kJ/(kg*K)] ", "Joule-Thomson coefficient [K/MPa] ", "Isentropic exponent ", "Speed of sound m/s ", "Error status " }; char *gas[12] = { "Mole fractions setup", "AGA8-Part-2: Gulf coast", "AGA-Part-2: Amarillo", "AGA-Part-2: Ekofisk", "AGA-Part-2: High N2", "AGA-Part-2: High CO2-N2", "ISO20765-2: Gas 1", "ISO20765-2: Gas 2", "ISO20765-2: Gas 3", "ISO20765-2: Gas 4", "ISO20765-2: Gas 5", "ISO20765-2: Gas 6" }; /* AGA8-Part-2:2017 and ISO20765-2:2015 example calculations */ /* Molar fractions of natural gas components: */ /* Methane, Nitrogen, Carbon diox., Ethane, Propane, i-Butane, n-Butane, */ /* i-Pentane, n-Pentane, n-Hexane, n-Heptane, n-Octane, n-Nonane, n-Decane, */ /* Hydrogen, Oxygen, Carbon monoxide, Water, Hydrogen sulfide, Helium, Argon */ double mf[11][21] = { /* Gulf coast */ 0.965222, 0.002595, 0.005956, 0.018186, 0.004596, 0.000977, 0.001007, 0.000473, 0.000324, 0.000664, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., /* Amarillo */ 0.906724, 0.031284, 0.004676, 0.045279, 0.00828, 0.001037, 0.001563, 0.000321, 0.000443, 0.000393, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., /* Ekofisk */ 0.859063, 0.010068, 0.014954, 0.084919, 0.023015, 0.003486, 0.003506, 0.000509, 0.00048, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., /* High N2 */ 0.81441, 0.13465, 0.00985, 0.033, 0.00605, 0.001, 0.00104, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., /* High CO2-N2 */ 0.81212, 0.05702, 0.07585, 0.04303, 0.00895, 0.00151, 0.00152, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., /* ISO20765-2: Gas 1 */ 0.796, 0.1, 0.01, 0.057, 0.02, 0.005, 0.005, 0.002, 0.002, 0.001, 0.001, 0.001, 0., 0., 0., 0., 0., 0., 0., 0., 0., /* ISO20765-2: Gas 2 */ 0.65, 0.065, 0.19, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0., 0., 0., 0., 0., 0., 0., 0., 0.005, 0., /* ISO20765-2: Gas 3 */ 0.72, 0.01, 0.01, 0.15, 0.01, 0.01, 0.01, 0.01, 0.01, 0.02, 0.01, 0.01, 0., 0., 0., 0.01, 0.01, 0., 0., 0., 0., /* ISO20765-2: Gas 4 */ 0.55, 0., 0., 0., 0.1, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.2, 0.04999, 0.1, 0.00001, 0., 0., 0., /* ISO20765-2: Gas 5 */ 0., 0.25, 0.15, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.1, 0.1, 0.1, 0., 0.1, 0.1, 0.1, /* ISO20765-2: Gas 6 */ 0., 0., 0., 0., 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05, 0., 0., 0., 0.05, 0., 0., 0. }; for (j=0; ; ) { ii=0; for(ix=0;;) { printf("\n\nSelect the corresponding calculation based on:"); printf("\n0 - Pressure, temperature and mole fractions"); printf("\n1 - Density, temperature and mole fractions"); printf("\n2 - Reduced density, temperature and mole fractions"); printf("\nType the number 0,1 or 2: "); scanf("%d", &(iCalc)); if(iCalc>=0 && iCalc<=2) { break; } } printf("\n\nEnter mole fractions or select the corresponding\n"); printf("AGA8-Part2:2017 or ISO20765-2:2015 gas composition example:\n"); for (igas=0; igas<=11; igas++) { printf("Enter '%d' to select %s \n", igas, gas[igas]); } printf("\nType number between 0 and 11: "); scanf("%d", &(ii)); if(ii>0 && ii<=11) { printf("\n%s\n", gas[ii]); for (ix=0; ix<=20; ix++) { aga.xx[ix]=mf[ii-1][ix]; printf("%s = %lf\n", text[ix], aga.xx[ix]); } if(iCalc==0) { printf("%s = ", text[21]); scanf("%lf", &(aga.xx[21])); } else if(iCalc==1) { printf("%s = ", text[25]); scanf("%lf", &(aga.xx[25])); } else if(iCalc==2) { printf("%s = ", text[27]); scanf("%lf", &(aga.xx[27])); } printf("%s = ", text[22]); scanf("%lf", &(aga.xx[22])); printf("\nSelect the prespecified ranges of application (RAP):"); printf("\nType 0 if normal P,T range and mole fractions ranges for pipeline gas quality,"); printf("\nType 1 if full P,T range and mole fractions ranges for intermediate gas quality,"); printf("\nType 2 if full P,T range and no range limitations for mole fractions:\nRAP = "); scanf("%d", &(aga.RAP)); } else { printf("\n%s selected \n", gas[ii]); //printf("\nMole fraction of:\n"); for (ix=0; ix<=20; ix++) { printf("%s = ", text[ix]); scanf("%lf", &(aga.xx[ix])); } if(iCalc==0) { printf("%s = ", text[21]); scanf("%lf", &(aga.xx[21])); } else if(iCalc==1) { printf("%s = ", text[25]); scanf("%lf", &(aga.xx[25])); } else if(iCalc==2) { printf("%s = ", text[27]); scanf("%lf", &(aga.xx[27])); } printf("%s = ", text[22]); scanf("%lf", &(aga.xx[22])); printf("\nSelect the prespecified ranges of application (RAP)!"); printf("\nType 0 if normal P,T range and mole fractions ranges for pipeline gas quality,"); printf("\nType 1 if full P,T range and mole fractions ranges for intermediate gas quality,"); printf("\nType 2 if full P,T range and no range limitations for mole fractions:\nRAP = "); scanf("%d", &(aga.RAP)); } if(aga.RAP < 0 || aga.RAP > 2) {aga.RAP=2;} agax = &aga; // Put the address of 'aga' structure into 'agax' aga8part2(iCalc, agax); // Call function by passing the pointer to structure // Print input parameters printf("\nI N P U T P A R A M E T E R S:"); if(iCalc==0) { printf("\nP,T and molar fractions based calculation"); } else if(iCalc==1) { printf("\nD,T and molar fractions based calculation"); } if(iCalc==2) { printf("\nReducd density,T and molar fractions based calculation"); } for (ix=0; ix<=22; ix++) { if(iCalc==1 && ix==21) { printf("\n%s = %f",text[25], aga.xx[25]); } else if(iCalc==2 && ix==21) { printf("\n%s = %f",text[27], aga.xx[27]); } else { printf("\n%s = %f",text[ix], aga.xx[ix]); } } if(aga.RAP==0) { printf("\nRAP=%d: Normal P,T range and mole fractions ranges for pipeline gas quality range", aga.RAP); } else if(aga.RAP==1) { printf("\nRAP=%d: Full P,T range and mole fractions ranges for intermediate gas quality range", aga.RAP); } else { printf("\nRAP=%d: Full P,T range and no range limitations for mole fractions", aga.RAP); } printf("\nO U T P U T P A R A M E T E R S:"); printf("\n%s = %xH",text[42], aga.es); for (ix=23; ix<=41; ix++) { if(iCalc==1 && ix==25) { printf("\n%s = %f",text[21], aga.xx[21]); } else if(iCalc==2 && ix==27) { printf("\n%s = %f",text[21], aga.xx[21]); } else { printf("\n%s = %f",text[ix], aga.xx[ix]); } } printf("\nPress X to exit or anything else to continue: "); ch = getch(); if (( ch == 'X') || (ch == 'x')) { break; } } } /* ********************************** */ /* THE END OF THE MAIN PROGRAM C-CODE */ /* ********************************** */