FE-ISO12213-3-C


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

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


Description of functions, struct, parameters, ranges of applications and errors

Functions
Function 1 void iso12213x3(struct iso12213 *);
Function 2 void sgerg1(struct iso12213 *);
Struct
struct iso12213{fpnp p; fpnp t; fpnp mfrCO2; fpnp mfrH2; fpnp rd; fpnp scv; fpnp zf; fpnp d; fpnp md; fpnp mm; long es;};
Input parameters
Data typeParameter name Parameter descriptionUnit of measure
fpnp1)p Pressure (absolute)bar
fpnpt Temperature°C
fpnpmfrCO2 Mole fraction of CO2-
fpnpscv Superior calorific valueMJ/m3
fpnprd Relative density-
fpnpmfrH2 Mole fraction of H2"
Output parameters
fpnpmm Gas mixture molar masskg/kmol
fpnpmd Gas mixture molar densitykg⋅mol/m3
fpnpd Gas mixture densitykg/m3
fpnpzf Gas mixture compressibility factor-
longes Error status2)-
1)
"fpnp" stands for floating point number precision. It can be defined as single or double precision floating point number. See header file below.
Ranges of application implemented in FE-ISO12213-3-C
Parameter Unit of measure Normal range Wider range
p: Pressure (absolute) MPa 10-7 to 12 10-7 to 12
t: Temperature K 263 to 338 263 to 338
rd: Relative density - 0.55 to 0.80 0.50 to 1.00
scv: Superior calorific value MJ/m3 30.0 to 45.0 20.0 to 48.0
mfrCO2: Molar fraction of Carbon dioxide - 0 to 0.20 0 to 0.30
mfrCO2: Molar fraction of Hydrogen - 0 to 0.10 0 to 0.10
"Normal range" stands for Pipeline quality gas (see Section 4.4.1 of ISO 12213-3:2006).
"Wider range" stands for Wider range of application (see Section 4.4.2 of ISO 12213-3:2006).
The ranges of application denoted by "Wider range" are implemented in FE-ISO12213-3-C C-code
Errors
2) Error status "long es" represents errors generated during program execution as follows:
Bit 0 =1 (0000001H) Error: Pressure (absolute) out of range.
Bit 1 =1 (0000002H) Error: Temperature out of range.
Bit 2 =1 (0000004H) Error: d>(0.55+0.97⋅mfrCO2-0.45⋅mfrH2).
Bit 3 =1 (0000008H) Error: No convergence in iteration with molar heating value.
Bit 4 =1 (0000010H) Error: No convergence in iteration with the second virial coefficient.
Bit 5 =1 (0000020H) Error: Calculated mole fraction of N2 (mfrN2) out of range i.e. -0.01>mfrN2>0.5.
Bit 6 =1 (0000040H) Error: The sum of mole fractions of N2 (mfrN2) and CO2 (mfrCO2) out of range: (mfrN2+mfrCO2)<0.5.
Bit 7 =1 (0000080H) Error: The internal consistency of the input data for the third iteration loop does not satisfy the condition relating relative density and mole fractions:
d>(0.55+0.4⋅mfrN2+0.97⋅mfrCO2-0.45⋅mfrH2.
Bit 8 =1 (0000100H) Error: No solution - square root of negative value (B11⋅B33<0).
Bit 9 =1 (0000200H) Error: No solution - exponentiation of negative value.
Bit 10 =1 (0000400H) Error: No convergence.
Bit 11 =1 (0000800H) Error: Mole fraction of Carbon dioxide <0 or >0.3.
Bit 12 =1 (0001000H) Error: Mole fraction of Hydrogen <0 or >0.1.
Bit 13 =1 (0002000H) Error: Superior calorific value <20 MJ/m3 or >48 MJ/m3.
Bit 14 =1 (0004000H) Error: Relative density <0.55 or >0.9.
Bit 14 =1 (0008000H) Error: incorrect key code entered.
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.

Header file

#include "stdio.h" #include "math.h" /* IN CASE OF SINGLE FLOATING POINT NUMBER PRECISION */ /* #define fpnp float */ /* IN CASE OF Double FLOATING POINT NUMBER PRECISION */ /* #define fpnp double */ #define fpnp double /* declaration of the structure */ struct iso12213 { /* INPUT PARAMETERS */ fpnp p; /* Pressure in [bar] */ fpnp t; /* Temperature in [degC] */ fpnp mfrCO2; /* mole fraction of CO2 */ fpnp mfrH2; /* mole fraction of H2 */ fpnp rd; /* relative density */ fpnp scv; /* superior calorific value [MJ/m^3] */ /* OUTPUT PARAMETERS */ unsigned long int es; /* Error status */ fpnp zf; /* Compression (compressibility factor) */ fpnp d; /* Density in [kg/m3] */ fpnp md; /* Molar density [kg-mole/m3] */ fpnp mm; /* Molar mass */ }; /* declaration of the function iso12213x3.c */ void iso12213x3(struct iso12213 *); /* declaration of the function sgerg1 */ void sgerg1(struct iso12213 *);


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

The following example illustrates the call to iso12213x3() function from a main program. The program defines an array of 10 structs i.e. 10 different ISO-12213-3 input/output data sets. The program prompts for the selection of the predefined calculation examples (Gas1 to Gas 6) given in ISO-12213-3 or for the manual setup of input parameters. If ISO-12213-3 calculation example is selected the program transfers the 10 sets of input parameters to the corresponding structs in the array. After the execution the program prints the results depending on the selected mode. If the corresponding calculation example is selected the program calculates and displays the 10 compression factors corresponding to the selected gas mixture. In case of manual setup program first prompts for input parameters and then calculates the results and prints the input parameters and the results on the screen.

/* ******************* */ /* MAIN PROGRAM C-CODE */ /* ******************* */ #include "iso12213x3.h" void main(void) { struct iso12213 iso[10], *isox; /* 'isox' is a pointer to a structure 'iso' */ unsigned short int j, ii, ix, idx; char ch; char *text[11] = { "Pressure in bar ", "Tempreature in degC ", "mfrCO2 ", "mfrH2 ", "Relative density ", "Superior cal. value ", "Error ststus ", "Compression ", "Density ", "Molar density ", "Molar Mass " }; /* ISO-12213-3 examples */ /* p, t, mfrCO2, mfrH2, rd, scv */ fpnp xx[60][6] = { 60, -3.15, 0.006, 0.000, 0.581, 40.66, 60, 6.85, 0.006, 0.000, 0.581, 40.66, 60, 16.85, 0.006, 0.000, 0.581, 40.66, 60, 36.85, 0.006, 0.000, 0.581, 40.66, 60, 56.85, 0.006, 0.000, 0.581, 40.66, 120, -3.15, 0.006, 0.000, 0.581, 40.66, 120, 6.85, 0.006, 0.000, 0.581, 40.66, 120,16.85, 0.006, 0.000, 0.581, 40.66, 120, 36.85, 0.006, 0.000, 0.581, 40.66, 120, 56.85, 0.006, 0.000, 0.581, 40.66, 60, -3.15, 0.005, 0.000, 0.609, 40.62, 60, 6.85, 0.005, 0.000, 0.609, 40.62, 60, 16.85, 0.005, 0.000, 0.609, 40.62, 60, 36.85, 0.005, 0.000, 0.609, 40.62, 60, 56.85, 0.005, 0.000, 0.609, 40.62, 120, -3.15, 0.005, 0.000, 0.609, 40.62, 120, 6.85, 0.005, 0.000, 0.609, 40.62, 120,16.85, 0.005, 0.000, 0.609, 40.62, 120, 36.85, 0.005, 0.000, 0.609, 40.62, 120, 56.85, 0.005, 0.000, 0.609, 40.62, 60, -3.15, 0.015, 0.000, 0.650, 43.53, 60, 6.85, 0.015, 0.000, 0.650, 43.53, 60, 16.85, 0.015, 0.000, 0.650, 43.53, 60, 36.85, 0.015, 0.000, 0.650, 43.53, 60, 56.85, 0.015, 0.000, 0.650, 43.53, 120, -3.15, 0.015, 0.000, 0.650, 43.53, 120, 6.85, 0.015, 0.000, 0.650, 43.53, 120,16.85, 0.015, 0.000, 0.650, 43.53, 120, 36.85, 0.015, 0.000, 0.650, 43.53, 120, 56.85, 0.015, 0.000, 0.650, 43.53, 60, -3.15, 0.016, 0.095, 0.599, 34.16, 60, 6.85, 0.016, 0.095, 0.599, 34.16, 60, 16.85, 0.016, 0.095, 0.599, 34.16, 60, 36.85, 0.016, 0.095, 0.599, 34.16, 60, 56.85, 0.016, 0.095, 0.599, 34.16, 120, -3.15, 0.016, 0.095, 0.599, 34.16, 120, 6.85, 0.016, 0.095, 0.599, 34.16, 120,16.85, 0.016, 0.095, 0.599, 34.16, 120, 36.85, 0.016, 0.095, 0.599, 34.16, 120, 56.85, 0.016, 0.095, 0.599, 34.16, 60, -3.15, 0.076, 0.000, 0.686, 36.64, 60, 6.85, 0.076, 0.000, 0.686, 36.64, 60, 16.85, 0.076, 0.000, 0.686, 36.64, 60, 36.85, 0.076, 0.000, 0.686, 36.64, 60, 56.85, 0.076, 0.000, 0.686, 36.64, 120, -3.15, 0.076, 0.000, 0.686, 36.64, 120, 6.85, 0.076, 0.000, 0.686, 36.64, 120,16.85, 0.076, 0.000, 0.686, 36.64, 120, 36.85, 0.076, 0.000, 0.686, 36.64, 120, 56.85, 0.076, 0.000, 0.686, 36.64, 60, -3.15, 0.011, 0.000, 0.644, 36.58, 60, 6.85, 0.011, 0.000, 0.644, 36.58, 60, 16.85, 0.011, 0.000, 0.644, 36.58, 60, 36.85, 0.011, 0.000, 0.644, 36.58, 60, 56.85, 0.011, 0.000, 0.644, 36.58, 120, -3.15, 0.011, 0.000, 0.644, 36.58, 120, 6.85, 0.011, 0.000, 0.644, 36.58, 120,16.85, 0.011, 0.000, 0.644, 36.58, 120, 36.85, 0.011, 0.000, 0.644, 36.58, 120, 56.85, 0.011, 0.000, 0.644, 36.58 }; for (j=0; ; ) { ii=0; printf("\n\nSelect input parameter setup '0' or ISO-12213-3 gas example '1-6'."; printf("\n Type number between 0 and 6: "); scanf("%d", &(ii)); if(ii>0 && ii<=6) { idx = (ii-1)*10; for (ix=0; ix<=9; ix++) { iso[ix].p=xx[ix+idx][0]; iso[ix].t=xx[ix+idx][1]; iso[ix].mfrCO2=xx[ix+idx][2]; iso[ix].mfrH2=xx[ix+idx][3]; iso[ix].rd=xx[ix+idx][4]; iso[ix].scv=xx[ix+idx][5]; } } else { printf("%s = ", text[0]); scanf("%lf", &(iso[0].p)); printf("%s = ", text[1]); scanf("%lf", &(iso[0].t)); printf("%s = ", text[2]); scanf("%lf", &(iso[0].mfrCO2)); printf("%s = ", text[3]); scanf("%lf", &(iso[0].mfrH2)); printf("%s = ", text[4]); scanf("%lf", &(iso[0].rd)); printf("%s = ", text[4]); scanf("%lf", &(iso[0].scv)); } if(ii>0 && ii<=6) { printf("\nCOMPRESSION FACTOR (ISO-12213-3, Table C.1): Gas %d", ii); for (ix=0; ix<=9; ix++) { isox = &iso[ix]; /* Put the address of the 'iso' structure into 'isox' */ iso12213x3(isox); /* Call function by passing the pointer to structure */ printf("\nZ%d = %lf",ix+1, iso[ix].zf); } } else { isox = &iso[0]; /* Put the address of 'iso' structure into 'isox' */ iso12213x3(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:"); printf("\n%s = %lf",text[0], iso[0].p); printf("\n%s = %lf",text[1], iso[0].t); printf("\n%s = %lf",text[2], iso[0].mfrCO2); printf("\n%s = %lf",text[3], iso[0].mfrH2); printf("\n%s = %lf",text[4], iso[0].rd); printf("\n%s = %lf",text[5], iso[0].scv); printf("\nO U T P U T P A R A M E T E R S:"); printf("\n%s = %xH",text[6], iso[0].es); printf("\n%s = %lf",text[7], iso[0].zf); printf("\n%s = %lf",text[8], iso[0].d); printf("\n%s = %lf",text[9], iso[0].md); printf("\n%s = %lf",text[10], iso[0].mm); } 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 */ /* ****************************** */