FE-ISO20765-2-C


FE-ISO20765-2-C (Revised: January 10, 2018) is the C source code implementation of the International standard:

  • ISO 20765-2:2015(E): Natural gas - Calculation of thermodynamic properties
    Part 2: Single phase properties (gas, liquid and dense fluid) for for extended ranges of application
The software is written in a C-language and embeds all the restrictions implied by ISO-20765-2:2015(E). 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 iso20765x2(short iCalc, struct iso20765x2 *iso0);
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 iso20765x2{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 (ISO-20765-2:2015, Table 5) and pipeline quality mole fractions ranges (ISO-20765-2:2015, Table 6)
  • RAP=1 - ISO-20765-2:2015 full P,T range (Table 5) and intermediate quality mole fractions ranges (Table 6)
  • RAP=2 - P,T range and no limitations on mole fractions 0≤xx[i]≤1
Mole fraction ranges defined by RAP=2 are not in accordance with ISO-20765-2:2015. It can be used only for software testing purposes (e.g. examples given in Annex G of ISO-20765-2:2015), 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 — n-Butane
double xx[6] Mole fraction of — Isobutane
double xx[7] Mole fraction of — n-Pentane
double xx[8] Mole fraction of — Isopentane
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] Mass-based 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] Compression 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-ISO20765-2-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
n-Butane + Isobutane 0 to 0.015 0 to 0.06 0 to 1.00
n-Pentane + Isopentane 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.99999 or >1.00001.
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 "iso20765x2.h"

#include "stdio.h" #include "math.h" // declaration of the structure struct iso20765x2 { // 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 iso20765x2(short iCalc, struct iso20765x2 *);


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

The following example illustrates the call to void iso20765x2(short iCalc, struct iso20765x2 *iso0) 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 (Gas1 to Gas 6) given in Annex G of ISO-20765-2:2015(E), Table G.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 G of ISO 20765-2:2015(E), Table G.1 and G.3.

/* ******************* */ /* MAIN PROGRAM C-CODE */ /* ******************* */ #include "iso20765x2.h" void main(void) { struct iso20765x2 iso, *isox; /* 'isox' is a pointer to a structure 'iso' */ short j, ii, ix, iCalc; char ch; char *text[43] = { "Methane ", "Nitrogen ", "Carbon Dioxide ", "Ethane ", "Propane ", "n-Butane ", "Isobutane ", "n-Pentane ", "Isopentane ", "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 " }; /* ISO-20765-2, Annex G, Table G.1: example calculations Gas1,..., Gas6 */ /* Molar fractions of natural gas components: */ /* Methane, Nitrogen, Carbon diox., Ethane, Propane, n-Butane, Isobutane, */ /* n-Pentane, Isopentane, n-Hexane, n-Heptane, n-Octane, n-Nonane, n-Decane, */ /* Hydrogen, Oxygen, Carbon monoxide, Water, Hydrogen sulfide, Helium, Argon */ double mf[8][21] = { 0.796000, 0.100000, 0.010000, 0.057000, 0.020000, 0.005000, 0.005000, 0.002000, 0.002000, 0.001000, 0.001000, 0.001000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.650000, 0.065000, 0.190000, 0.010000, 0.010000, 0.010000, 0.010000, 0.010000, 0.010000, 0.010000, 0.020000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.005000, 0.000000, 0.720000, 0.010000, 0.010000, 0.150000, 0.010000, 0.010000, 0.010000, 0.010000, 0.010000, 0.020000, 0.010000, 0.010000, 0.000000, 0.000000, 0.000000, 0.010000, 0.010000, 0.000000, 0.000000, 0.000000, 0.000000, 0.550000, 0.000000, 0.000000, 0.000000, 0.100000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.200000, 0.049990, 0.100000, 0.000010, 0.000000, 0.000000, 0.000000, 0.000000, 0.250000, 0.150000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.100000, 0.100000, 0.100000, 0.000000, 0.100000, 0.100000, 0.100000, 0.000000, 0.000000, 0.000000, 0.000000, 0.100000, 0.100000, 0.100000, 0.100000, 0.100000, 0.100000, 0.100000, 0.100000, 0.100000, 0.050000, 0.000000, 0.000000, 0.000000, 0.050000, 0.000000, 0.000000, 0.000000, }; 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\nSelect input parameter setup '0' or ISO-20765-2 gas mixture '1-6'."); printf("\n Type number between 0 and 6: "); scanf("%d", &(ii)); if(ii>0 && ii<=6) { for (ix=0; ix<=20; ix++) { iso.xx[ix]=mf[ii-1][ix]; printf("\n%s = %lf", text[ix], iso.xx[ix]); } printf("\nGas %d:\n", ii); if(iCalc==0) { printf("%s = ", text[21]); scanf("%lf", &(iso.xx[21])); } else if(iCalc==1) { printf("%s = ", text[25]); scanf("%lf", &(iso.xx[25])); } else if(iCalc==2) { printf("%s = ", text[27]); scanf("%lf", &(iso.xx[27])); } printf("%s = ", text[22]); scanf("%lf", &(iso.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", &(iso.RAP)); } else { printf("\nMole fraction of:\n"); for (ix=0; ix<=20; ix++) { printf("%s = ", text[ix]); scanf("%lf", &(iso.xx[ix])); } if(iCalc==0) { printf("%s = ", text[21]); scanf("%lf", &(iso.xx[21])); } else if(iCalc==1) { printf("%s = ", text[25]); scanf("%lf", &(iso.xx[25])); } else if(iCalc==2) { printf("%s = ", text[27]); scanf("%lf", &(iso.xx[27])); } printf("%s = ", text[22]); scanf("%lf", &(iso.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", &(iso.RAP)); } if(iso.RAP < 0 || iso.RAP > 2) {iso.RAP=2;} isox = &iso; // Put the address of 'iso' structure into 'isox' iso20765x2(iCalc, isox); // 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==21) { 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], iso.xx[25]); } else if(iCalc==2 && ix==21) { printf("\n%s = %f",text[27], iso.xx[27]); } else { printf("\n%s = %f",text[ix], iso.xx[ix]); } } if(iso.RAP==0) { printf("\nRAP=%d: Normal P,T range and mole fractions ranges for pipeline gas quality range", iso.RAP); } else if(iso.RAP==1) { printf("\nRAP=%d: Full P,T range and mole fractions ranges for intermediate gas quality range", iso.RAP); } else { printf("\nRAP=%d: Full P,T range and no range limitations for mole fractions", iso.RAP); } printf("\nO U T P U T P A R A M E T E R S:"); printf("\n%s = %xH",text[42], iso.es); for (ix=23; ix<=41; ix++) { if(iCalc==1 && ix==25) { printf("\n%s = %f",text[21], iso.xx[21]); } else if(iCalc==2 && ix==27) { printf("\n%s = %f",text[21], iso.xx[21]); } else { printf("\n%s = %f",text[ix], iso.xx[ix]); } } 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 */ /* ****************************** */