iso12213x3.c - Instructions for use

Revision: July 28, 2010

 

E-mail: ivan.maric@felib.com

 

iso12213x3 is the C source code implementation of the International standard:

ISO 12213-3:2006: Calculation of compression factor

Part 2: Calculation using physical properties

 

The software is written in a C-language and embeds all the restrictions implied by ISO-12213-3.

The following is a brief description of a header the corresponding input/output parameters and an example of a main program in a c-source code.

 

 

Header file: iso12213x3.h

 

#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 *);

 

 

Input/output parameters

 

// The input/output parameters are defined by struct iso12213 - see header file

// iso12213x3.h

// Input parameters (the ranges of application are given below):

// double/float mfrCO2 - mole fraction CO2

// double/float scv - superior calorific value [MJ/m^3]

// double/float rd - relative density

// double/float mfrH2  - mole fraction H2

// double/float p - Pressure [bar]

// double/float t - Temperature [C]

// Results:

// The function iso12213x3() - calculates the following parameters:

// double mm - Natural gas mixture molar mass (mole average)

// double md - Molar density [kg-mole/m^3]

// double d - Density [kg/m^3]

// double zf - Compression (compressibility factor)

// long es - Error status

 

// Before calling the function 'iso12213x3' the input parameters should be set

// to valid values. Upon completion of the routine the results will be valid if no

// errors were encountered (see more detailed description below).

 

// Ranges of application for compression factor calculation

// with the SGERG-88 equation - ISO-12213-3:1997(E):

 

// A: pipeline quality natural gas

// B: wider ranges of application

 

//                                                       A                 B

// p: absolute pressure [bar]                    0.000001to 120   0.000001 to 120

// t: temperature [C]                             -23.0 to 65.0     -23.0 to 65.0

// rd: relative density []                          0.55 to 0.80      0.55 to 0.90

// scv: superior calorific value [MJ/m^3] ***)      30.0 to 45.0      20.0 to 48.0

// mfrCO2: mole fraction of carbon dioxide           0.0 to 0.20       0.0 to 0.30

// mfrH2: mole fraction of hydrogen                  0.0 to 0.10       0.0 to 0.10

 

// ***) metering at: 0 C, 1.01325 bar; combustion at: 25.0 C, 1.01325 bar.

 

// Upon completion of the calculation the function 'iso12213x3'() sets a

// long integer representing the error status (es) in the following way:

 

// Bit 0   =1 (0001H) if pressure <0.000001 bar or > 120.0 bar, otherwise =0.

// Bit 1   =1 (0002H) if temperature <-23.0 C or > 65.0 C, otherwise =0.

// Bit 2   =1 (0004H) if d>(0.55+0.97*mfrCO2-0.45*mfrH2), otherwise =0.

//                       d - density

//                       mfrCO2 - mole fraction for CO2

//                       mfrH2  - mole fraction for H2

// Bit 3   =1 (0008H) if no convergence in iteration with molar heating value,

//                       otherwise =0.

// Bit 4   =1 (0010H) if no convergence in iteration with the second virial

//                       coefficient, otherwise =0.

// Bit 5   =1 (0020H) if calculated mole fraction of N2 (mfrN2) out of range:

//                       -0.01<mfrN2<0.5, otherwise =0.

// Bit 6   =1 (0040H) if The sum of mole fractions of N2 (mfrN2) and CO2 (mfrCO2)

//                       out of range: (mfrN2+mfrCO2)<0.5, otherwise =0.

// Bit 7   =1 (0080H) if 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), otherwise =0.

// Bit 8   =1 (0200H) if no solution - square root of negative value (B11*B33<0),

//                       otherwise =0.

// Bit 9   =1 (0100H) if no solution - exponentiation of negative value,

//                       otherwise =0.

// Bit 10  =1 (0400H) if no convergence, otherwise =0.

// Bit 11  =1 (0800H) if mole fraction of Carbon dioxide <0 or > 0.3, otherwise =0.

// Bit 12  =1 (1000H) if mole fraction of Hydrogen <0 or >0.1, otherwise =0.

// Bit 13  =1 (2000H) if superior calorific value <20 MJ/m3 or > 48 MJ/m3, otherwise =0.

// Bit 14  =1 (4000H) if relative density < 0.55 or > 0.9, otherwise =0.

// Bit 24  =1 (1000000H) if incorrect key code entered

// All other bits are unused

 

// The error status is a long number representing all the errors encountered

// in the calculation.

// If bits 0,...,14 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.

 

 

Example of a main program in C code calling the iso12213x3 function

 

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.

 

/* **************************************** */

/* THE BEGINNING OF THE 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'.\n Type number between 0 and 6: ");

               scanf("%d", &(ii));

               if(ii>0 && ii<=6) {

//                     ii=ii-1;

                       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;

        }

}

 

/* ********************************** */

/* THE END OF THE MAIN PROGRAM C-CODE */

/* ********************************** */