Appendix G: C example code (cademo1.c)

For explanatory notes on this example program, please refer to Appendix F.


/* Note that this program contains target calculations, which cannot be performed with the 'light' version of ChemApp */
/*
Please also read the notes regarding the use of ChemApp with C/C++, which are contained in a separate file.
Please direct any questions about this program or the results it produces on your machine to:
GTT-Technologies Kaiserstrasse 100 52134 Herzogenrath Germany
Phone: +49-2407-59533 Fax: +49-2407-59661 E-mail: support@gtt-technologies.de WWW: http://www.gtt-technologies.de/
*/

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "cacint.h"
/* --------------------------------------------------------------------- * Func : abortprog * --------------------------------------------------------------------- * Subject : If a ChemApp error occurs, this function reports the error number and the routine it occurred in before it exits the program. * * --------------------------------------------------------------------- */ void abortprog(int lineno, char sr_name[10], LI error_no) {
fprintf(stdout,"\nChemApp error no. %li occurred when calling %s.\n" "Aborting on line %i of %s .\n", error_no, sr_name, lineno, __FILE__); exit(error_no); }



/* --------------------------------------------------------------------- * Func : main * --------------------------------------------------------------------- * Subject : Main body of program * * --------------------------------------------------------------------- */ int main() {
/* Declaration of variables to be used in the program */
/* Every integer variable that is to be used in an invocation of a ChemApp subroutine has to be of type "LI". "LI" is defined in cacint.h and is usually an abbreviation for "long int". Similarly, every real variable for use with ChemApp subroutines has to be of type "DB", which is usually an abbreviation for "double" */

/* Declarations of integer variables for use with ChemApp: */
/* An all-purpose integer variable */ LI lint,
/* Integer variables which hold the index number of phases, phase constituents, and sublattices */ indexp, indexc, indexl,

/* The standard error code return variable */ noerr,
/* A variable that is set to the version number of ChemApp */ cavers,
/* This variable is used in conjunction with tqlite to determine whether the program is linked to the regular or the 'light' version of ChemApp. In the latter case, target calculations are left out. */ islite,
/* A number of integer variables to return the information from tqsize */ lia,lib,lic,lid,lie,lif,lig,lih,lii,lij,lik,
/* A similar set of integer variables to return the information from tqused */ ldia,ldib,ldic,ldid,ldie,ldif,ldig,ldih,ldii,ldij,ldik,
/* An integer that will contain the index number of a condition set */ numcon,
/* An integer that will contain the number of phases in the data-file loaded */ nphase,
/* An integer that will hold the number of phase constituents in the gas phase */ npcgas,
/* An integer that will contain the number of system components */ nscom,
/* Integers that will contain the number of sublattices, and the number of sublattice contituents of a particular sublattice */ nsl, nslcon,
/* Two integers used for one-dimensional phase mapping calculations, one to indicate whether we need to make more calls to tqmap/tqmapl */ icont,
/* And another one to keep track of the number of results we obtained */ resno,
/* An integer that holds the FORTRAN unit number under which the thermochemical data-files will be opened */ unitno,
/* An integer that holds the FORTRAN unit number to which the ChemApp error messages are written by default */ errorunit,
/* Variables to store information from various transparent file header fields */ tfhver, tfhvnw[3], tfhvnr[3], tfhdtc[6], tfhdte[6],
/* These integers will be used to store the HASP dongle id, plus the ChemApp expiration month and year */ haspid, edmon, edyear;
/* Declarations of real variables for use with ChemApp: */
/* An all-purpose real variable */ DB d1,
/* An array of two real variables... */ darray2[2],
/* ...and one of 30 */ darray30[30],
/* ...and one for which memory will be allocated dynamically to be just of the right size */ *darray,
/* A variable to hold the molecular mass of a system component (see tqstsc) or a phase constituent (see tqstpc) */ wmass,
/* This particular array of two real variables will contain the temperature and pressure of a stream to be defined with tqsttp */ tp[2];

/* Declarations of string variables for use with ChemApp: */

/* Every "name" used in conjuction with ChemApp, whether it is the name of a phase, a system component, a phase constituent, or a stream, can be up to 24 characters in length (Exceptions are the subroutine tqerr, as well as the subroutines tqgtrh, tqgtid, tqgtnm, tqgtpi, and tqwstr, which all pass or return strings longer than 24 characters). This means that in C/C++, these strings have to be 25 characters long, due to the trailing null character (\0). TQSTRLEN is defined in cacint.h to be 25. Thus, if you define all your strings to be used with ChemApp using TQSTRLEN, you can be sure that they will have the right length. Another way to do this is to use the macro "TQSTRING(x)", as defined in cacint.h, which expands to "char x[TQSTRLEN]". */
/* an all-purpose static string for ChemApp */ char dstr[TQSTRLEN],
/* A pointer to a string, before it can be used, sufficient memory has to be allocated */ *dstrptr,
/* Character strings that will hold names of phases, phase constituents, system components, mixture model names, as well as sublattatices and their constituents */
pname[TQSTRLEN], cname[TQSTRLEN], mname[TQSTRLEN],
/* The following variable is an array of 4 strings. It will be used with tqcsc, which is the only ChemApp subroutine that takes a character array as input. Please note that the last string element of such an array for use with tqcsc must be an extra empty string, this is due to the peculiarities of exchanging strings between FORTRAN and C code. This is why we declare the following array to have 4 elements, although we will only have 3 system components. */ newsc[4][TQSTRLEN];
/* Using the macro TQSTRING to declare a string variable for ChemApp*/ TQSTRING(dstr2);
/* The next three character strings are used to hold information about the copy of ChemApp used. */ char id[255], name[80], pid[TQSTRLEN];
/* Variables to store information from various transparent file header fields */ char tfhid[255], tfhusr[80],tfhnwp[40],tfhnrp[40],tfhrem[80];

/* This character variable will be used to store the HASP dongle type */ char haspt[TQSTRLEN];

/* Declaration of various other variables: */ int i;

/* Print the program title and its ID */ printf("\nThis is cademo1, a C program to test ChemApp and its" " C Interface.\n\n");

Output:
This is cademo1, a C program to test ChemApp and its C Interface.

/* Allocate memory for the dynamic string variable dstrptr. By using TQSTRLEN, we make sure it has the right length. */ dstrptr = malloc(TQSTRLEN);
/* Initialise ChemApp */ tqini(&noerr);
/* After all following invocations of ChemApp subroutines, the error variable will be checked for a non-zero value, in which case an error has occurred and the program is aborted */ if (noerr) abortprog(__LINE__,"tqini",noerr);

/* Print the copyright string. The way to do this is to first call the subroutine tqcprt, which copies the copyright string into the ChemApp-internal error buffer string: */ tqcprt(&noerr); if (noerr) abortprog(__LINE__,"tqcprt",noerr);
/* Then do what is usually done to retrieve an error message: call tqerr to retrieve it. The variable TQERRMSG is declared in cacint.c as TQERRMSG[3][80] for this purpose:*/
tqerr((CHP)TQERRMSG,&noerr); /* Note that an explicit typecast has been used in the above call to tqerr to avoid compiler warnings about TQERRMSG being an incompatible pointer type ("CHP" is declared in cacint.h to be an abbreviation for "char*") */
if (noerr) abortprog(__LINE__,"tqerr",noerr);
/* To print out the message, loop over the three strings of TQERRMSG: */ for(i=0;i<3;i++) printf("%s\n",TQERRMSG[i]);

Output:
 This program contains ChemApp
 Copyright GTT-Technologies, Kaiserstrasse 100, D-52134 Herzogenrath, Germany
 http://www.gtt-technologies.de

/* Get version number of ChemApp*/ tqvers(&cavers,&noerr); if (noerr) abortprog(__LINE__,"tqvers",noerr); printf("\nChemApp version is: %li\n\n", cavers);
/* Get array sizes */ tqsize(&lia,&lib,&lic,&lid,&lie,&lif,&lig,&lih,&lii,&lij,&lik,&noerr); if (noerr) abortprog(__LINE__,"tqsize",noerr); printf("Internal array sizes of this version of ChemApp,\n" "maximum number of:\n" "constituents: %li\n" "system components: %li\n" "mixture phases: %li\n" "excess Gibbs energy coefficients for " "a mixture phase: %li\n" "excess magnetic coefficients for " "a mixture phase: %li\n" "sublattices for a mixture phase: %li\n" "constituents of a sublattice: %li\n" "oxide constituents of a phase described by the " "Gaye-Kapoor-Frohberg\n" " or modified quasichemical formalisms: %li\n" "Gibbs energy/heat capacity equations for " "a constituent: %li\n" "Gibbs energy/heat capacity equations: %li\n" "constituents with P,T-dependent " "molar volumes: %li\n\n", lia,lib,lic,lid,lie,lif,lig,lih,lii,lij,lik);

Output:
ChemApp version is: 502

Internal array sizes of this version of ChemApp, maximum number of: constituents: 300 system components: 15 mixture phases: 20 excess Gibbs energy coefficients for a mixture phase: 199 excess magnetic coefficients for a mixture phase: 99 sublattices for a mixture phase: 5 constituents of a sublattice: 12 oxide constituents of a phase described by the Gaye-Kapoor-Frohberg or modified quasichemical formalisms: 15 Gibbs energy/heat capacity equations for a constituent: 20 Gibbs energy/heat capacity equations: 900 constituents with P,T-dependent molar volumes: 300


/* Get value for input/output option */
/* Determine which FORTRAN unit is used by default by tqrfil for reading the thermochemical data-file */ tqgio("FILE", &unitno, &noerr); if (noerr) abortprog(__LINE__,"tqgio",noerr); printf("The thermochemical data will be read from the file " "associated with unit %li\n\n", unitno);

Output:
The thermochemical data will be read from the file associated with unit 10

/* Open data-file for reading */ /* Note that tqopna is used to open the thermochemical data-file, instead of a standard C library routine like fopen. The reason is that it is necessary to associate the data-file with a particular FORTRAN unit number (10 by default, see above) so that the FORTRAN subroutine tqrfil can read from the correct file */ tqopna("cosi.dat",unitno,&noerr); if (noerr) abortprog(__LINE__,"tqopna",noerr);
/* Read data-file */ tqrfil(&noerr); if (noerr) abortprog(__LINE__,"tqrfil",noerr);
/* Close data-file */ /* Again, the routine for closing the data-file is not a standard C library routine like fclose, but a special one to make sure the file that was previously opened under the unit number specified is closed */ tqclos(unitno,&noerr); if (noerr) abortprog(__LINE__,"tqclos",noerr);
/*C*# */
/* tqused is used to find out to what extent the thermochemical data storage space in the internal arrays of ChemApp (as reported by tqsize) are occupied by the currently loaded thermochemical system. */ tqused(&ldia,&ldib,&ldic,&ldid,&ldie,&ldif,&ldig,&ldih,&ldii, &ldij,&ldik,&noerr); if (noerr) abortprog(__LINE__,"tqused",noerr);
/* As an example, check how many Gibbs energy/heat capacity equations are currently being used. */ printf("Actual number of Gibbs energy/heat capacity equations " "used (tqused): %li\n", ldij); printf("Maximum number available in this version of ChemApp " "(tqsize): %li\n", lij);

Output:
Actual number of Gibbs energy/heat capacity equations used (tqused): 35
Maximum number available in this version of ChemApp (tqsize): 900


/* Get system units */ tqgsu("Pressure",dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgsu",noerr); printf("Pressure unit: %s\n", dstr);
tqgsu("Volume",dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgsu",noerr); printf("Volume unit: %s\n", dstr);
tqgsu("Temperature",dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgsu",noerr); printf("Temperature unit: %s\n", dstr);
tqgsu("Energy",dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgsu",noerr); printf("Energy unit: %s\n", dstr);
/* Change system unit */ /* Here we change the unit for the quantity "amount" to gram, mainly so that when we call tqstsc further down, we get the molecular mass expressed in the unit g/mol */ tqcsu("Amount","gram", &noerr); if (noerr) abortprog(__LINE__,"tqcsu",noerr); printf("Amount unit set to gram\n\n");

Output:
Pressure unit: bar
Volume unit: dm3
Temperature unit: K
Energy unit: J
Amount unit set to gram


/* Get number of system components */ tqnosc(&nscom,&noerr); if (noerr) abortprog(__LINE__,"tqnosc",noerr); printf("Number of system components: %li\n\n", nscom);
/* Get stoichiometry of system component */ /* Note that the array used (darray30) is much bigger than needed, which doesn't matter to ChemApp, as long as it is big enough. */ tqstsc(1,darray30,&wmass,&noerr); if (noerr) abortprog(__LINE__,"tqstsc",noerr);
/* Here the array elements are printed, which describe the stoichiometry of the system component. This particular piece of information is not too useful though, since the array contains all zeros, except for a "1.0" at the position of the system component we specified */ printf("Stoichiometry of system component 1: "); for (i=1;i<=nscom;i++) printf("%f ", darray30[i-1]);
/* Had we not changed the amount unit from the default value "mol" to "gram", we would receive a value of 1.0 for wmass. The reason is that the molecular mass is always output using the unit [current amount unit]/mol. If the current amount unit happens to be mol, the value for wmass will be 1.0 */ printf("\nMolecular mass in g/mol: %f\n", wmass);

/* Get name of system component #1 */ tqgnsc(1,dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgnsc",noerr); printf("Name of system component 1: %s\n", dstr);
/* Get index number of system component */ /* This is the reverse of the above, using the name of the system component to get its index number */ tqinsc(dstr, &lint, &noerr); if (noerr) abortprog(__LINE__,"tqinsc",noerr); printf("Index number of system component %s is: %li\n\n",dstr,lint);

Output:
Number of system components: 3

Stoichiometry of system component 1: 1.000000 0.000000 0.000000 Molecular mass in g/mol: 12.011000 Name of system component 1: C Index number of system component C is: 1


/* Change system components */ /* tqcsc is the only ChemApp subroutine which takes an array of strings as input. The array contains as many strings as there are system components in the data-file, plus an extra one is needed when programming in C, which has to be empty. */
/* The system components are changed to SiO, SiC, and CO. */ strcpy(newsc[0], "SiO"); strcpy(newsc[1], "SiC"); strcpy(newsc[2], "CO");
/* Don't forget: The last string of the string array that will be passed to tqcsc has to be empty! */ strcpy(newsc[3], "");
tqcsc((CHP)newsc,&noerr); /* Note that an explicit typecast has been used in the above call to tqcsc to avoid compiler warnings about newsc being an incompatible pointer type */
if (noerr)abortprog(__LINE__,"tqcsc",noerr); printf("System components changed to SiO-SiC-CO.\n");

/* Print names of new system components */ for (lint = 1; lint <= nscom; lint++) { tqgnsc(lint,dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgnsc",noerr); printf("Name of new system component %li: %s\n", lint, dstr); }
/* Get stoichiometry of system component #1 */ tqstsc(1,darray30,&d1,&noerr); if (noerr) abortprog(__LINE__,"tqstsc",noerr);
/* Note that the stoichiometry of the system component #1 does not change, as compared to the first call to tqstsc before the system components have been altered: */ printf("Stoichiometry of system component 1: "); for (i=1;i<=nscom;i++) printf("%f ", darray30[i-1]); /* What changes of course is the molecular mass: */ printf("\nMolecular mass in g/mol: %f\n\n", d1);

Output:
System components changed to SiO-SiC-CO.
Name of new system component 1: SiO
Name of new system component 2: SiC
Name of new system component 3: CO
Stoichiometry of system component 1: 1.000000 0.000000 0.000000 
Molecular mass in g/mol: 44.085400



/* Get number of phases */ tqnop(&nphase,&noerr); if (noerr) abortprog(__LINE__,"tqnop",noerr); printf("Number of phases: %li\n", nphase);

/* Get name of phase #1 */ tqgnp(1,dstr,&noerr); if (noerr) abortprog(__LINE__,"tqgnp",noerr); printf("Name of phase 1: %s\n", dstr);

/* Get index number of phase */ /* This is the reverse of the above, using the name of the phase to get its index number */ tqinp(dstr,&lint,&noerr); if (noerr) abortprog(__LINE__,"tqinp",noerr); printf("Index number of phase %s is: %li\n",dstr,lint);

/* Get model name of phase */ tqmodl(1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqmodl",noerr); printf("Model name of phase 1: %s\n",dstr);
/* Whereas above we asked for the model name of the first phase in the data-file, which is normally a mixture phase (gas phase), we now ask for the model name of the last phase in the data-file (nphase, as determined by a call to tqnop). This is typically a stoichiometric condensed phase, in which case the string "PURE" is returned as the model name*/ tqmodl(nphase, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqmodl",noerr); printf("Model name of phase %li: %s\n\n",nphase,dstr);

/* Get number of phase constituents of phase #1 */ tqnopc(1, &npcgas, &noerr); if (noerr) abortprog(__LINE__,"tqnopc",noerr); printf("Number of phase constituents in phase 1: %li\n", npcgas);
/* Get name of phase constituent */ tqgnpc(1, 1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgnpc",noerr); printf("Name of phase constituent 1 of phase 1: %s\n", dstr);

/* Get index number of phase constituent */ /* This is the reverse of the above, using the name of the phase constituent to get its index number */ tqinpc(dstr, 1, &lint, &noerr); if (noerr) abortprog(__LINE__,"tqinpc",noerr); printf("Index number of phase constituent %s is: %li\n",dstr,lint);
/* Check whether the phase constituent can be used as incoming species (note that there are only few cases, and only for certain mixture phase models, where this might not be permitted)*/ tqpcis(1, 1, &lint, &noerr); if (noerr) abortprog(__LINE__,"tqpcis",noerr); if (lint == 0) printf("Usage of %s as incoming species is not permitted.\n", dstr); else printf("Usage of %s as incoming species is o.k.\n", dstr);
/* Get stoichiometry of phase constituent */ /* tqstpc is a subroutine similar to tqstsc, except that with tqstpc, the returned stoichiometry array contains valuable information. This stoichiometry array represents the stoichiometry matrix for a phase constituent, as described in the ChemApp manual*/ tqstpc(1, 1, darray30, &wmass, &noerr); if (noerr) abortprog(__LINE__,"tqstpc",noerr); printf("Stoichiometry of phase constituent 1 in phase 1 is: "); for (i=1;i<=nscom;i++) printf("%f ", darray30[i-1]); printf("\nMolecular mass: %f\n\n", wmass);

Output:
Number of phases: 8
Name of phase 1: GAS
Index number of phase GAS is: 1
Model name of phase 1: IDMX
Model name of phase 8: PURE

Number of phase constituents in phase 1: 15 Name of phase constituent 1 of phase 1: C Index number of phase constituent C is: 1 Usage of C as incoming species is o.k. Stoichiometry of phase constituent 1 in phase 1 is: -0.500000 0.500000 0.500000 Molecular mass: 12.011000

/* The system components are changed back to the original set of C, O, and Si, since we don't need the modified set of system components (SiO, SiC, and CO) any longer. */
strcpy(newsc[0], "C"); strcpy(newsc[1], "O"); strcpy(newsc[2], "Si"); strcpy(newsc[3], "");
tqcsc((CHP)newsc,&noerr); if (noerr)abortprog(__LINE__,"tqcsc",noerr); printf("System components changed back to C-O-Si.\n");

Output:
System components changed back to C-O-Si.

/* Changing the status of phases and phase constituents */ /* Change status of phase #1 */ tqcsp(1, "eliminated", &noerr); if (noerr) abortprog(__LINE__,"tqcsp",noerr); printf("Status of phase 1 set to 'eliminated'\n");
/* Get status of phase #1 */ tqgsp(1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgsp",noerr); printf("Status of phase 1 is: %s \n", dstr);
/* Change status of phase #1 */ tqcsp(1, "entered", &noerr); if (noerr) abortprog(__LINE__,"tqcsp",noerr); printf("Status of phase 1 set to 'entered'\n");
/* Get status of phase #1 */ tqgsp(1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgsp",noerr); printf("Status of phase 1 is: %s \n", dstr);

Output:
Status of phase 1 set to 'eliminated'
Status of phase 1 is: ELIMINATED 
Status of phase 1 set to 'entered'
Status of phase 1 is: ENTERED


/* Change status of phase constituent #1 of phase #1 */ tqcspc(1, 1, "dormant", &noerr); if (noerr) abortprog(__LINE__,"tqcspc",noerr); printf("Status of constituent 1 of phase 1 set to 'dormant'\n");
/* Get status of phase constituent #1 of phase #1 */ tqgspc(1, 1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgspc",noerr); printf("Status of constituent 1 of phase 1 is: %s \n", dstr);
/* Change status of phase constituent #1 of phase #1 */ tqcspc(1, 1, "entered", &noerr); if (noerr) abortprog(__LINE__,"tqcspc",noerr); printf("Status of constituent 1 of phase 1 set to 'entered'\n");
/* Get status of phase constituent #1 of phase #1 */ tqgspc(1, 1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgspc",noerr); printf("Status of constituent 1 of phase 1 is: %s \n\n", dstr);

Output:
Status of constituent 1 of phase 1 set to 'dormant'
Status of constituent 1 of phase 1 is: DORMANT 
Status of constituent 1 of phase 1 set to 'entered'
Status of constituent 1 of phase 1 is: ENTERED

printf("\n\nCalculations using global conditions:\n\n");
/* Set equilibrium conditions */
/* When setting equilibrium conditions with tqsetc, the currently set units for the various quantities (pressure, amount, etc.) apply. Thus, in the following call, the incoming amount ("ia") of phase constituent #4 of phase #1 is set to 1.0 gram. */ tqsetc("ia ", 1, 4, 1.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);

/* Change system unit */ /* Now we change the amount unit back to "mol". This does not affect any previously set values. The amount of phase constituent #4 of phase #1 we set above is still 1.0 gram, and is not changed to 1.0 mol! */ tqcsu("Amount","mol", &noerr); if (noerr) abortprog(__LINE__,"tqcsu",noerr); printf("Amount unit set to mol\n\n");

Output:

Calculations using global conditions:
Amount unit set to mol

/* Since we changed the amount unit to "mol", the call to tqsetc below inputs 3.0 mol of constituent #12 of phase #1 */ tqsetc("ia ", 1, 12, 3.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* Now we input 8 mol of constituent #8 of phase #1 */ tqsetc("ia ", 1, 8, 2.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* Remove equilibrium condition */ /* This call to tqremc demonstrates how the parameter "numcon" is used, which is returned with every call to tqsetc: The previously defined condition is removed again */ tqremc(numcon, &noerr); if (noerr) abortprog(__LINE__,"tqremc",noerr);
/* Set temperature */ /* Here tqsetc is used to enter the temperature. Since we didn't change the default temperature unit, it is still Kelvin ("K") */ tqsetc("t ", 0, 0, 1800.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);

/* Change limit of target variables */ /* The next call demonstrates how tqclim is used. Normally though calls to tqclim are only necessary under special circumstances */ tqclim("plow", 1e-49, &noerr); if (noerr) abortprog(__LINE__,"tqclim",noerr);

/* Display present settings */ /* tqshow outputs the conditions which are active at this point */ printf("\n\nCurrently active conditions:\n"); printf("\n\n**** Begin output table produced by tqshow\n");
/* Depending on the type of ChemApp object code used (e.g. statically linked OBJ code vs. dynamic link library), and possibly also depending on the compiler/platform/operating system used, it might be necessary to use fflush(NULL) to flush the output buffers in order to synchronise the output of the standard C calls and the output through FORTRAN units: */ fflush(NULL); tqshow(&noerr); fflush(NULL); printf("\n**** End output table produced by tqshow\n\n\n"); if (noerr) abortprog(__LINE__,"tqshow",noerr); printf("\n\n");

Output:

Currently active conditions:

**** Begin output table produced by tqshow
TARGET LIMITS: Pressure/bar : 1.00000E-49 1.00000E+07 Volume/dm3 : 1.00000E-07 1.00000E+50 Temperature/K: 298.15 6000.00
T = 1800.00 K P = 1.00000E+00 bar
STREAM CONSTITUENT CO/GAS/ AMOUNT/mol = 3.57010E-02 Si3/GAS/ AMOUNT/mol = 3.00000E+00
**** End output table produced by tqshow


/* Calculate equilibrium */ /* A simple call to tqce or tqcel is sufficient to calculate the equilibrium. All input parameters to tqce and tqcel are only significant if target calculations are performed. */ darray2[0]=0.0; tqce(" ",0,0,darray2,&noerr); if (noerr) abortprog(__LINE__,"tqce",noerr);

/* Calculate and list equilibrium */ /* tqcel calculates the equilibrium just like tqce, with the only difference that a ChemSage-type result table is written to the file/unit associated with 'LIST' (see tqgio/tqcio)*/ printf("\n\n**** Begin output table produced by tqcel\n"); fflush(NULL); tqcel(" ",0,0,darray2,&noerr); fflush(NULL); printf("\n**** End output table produced by tqcel\n\n\n"); if (noerr) abortprog(__LINE__,"tqcel",noerr);

Output:

**** Begin output table produced by tqcel
T = 1800.00 K P = 1.00000E+00 bar V = 0.00000E+00 dm3
STREAM CONSTITUENTS AMOUNT/mol CO/GAS/ 3.5701E-02 Si3/GAS/ 3.0000E+00
EQUIL AMOUNT MOLE FRACTION FUGACITY PHASE: GAS mol bar SiO 0.0000E+00 9.1172E-01 4.1405E-02 CO 0.0000E+00 8.8214E-02 4.0062E-03 Si 0.0000E+00 6.7137E-05 3.0490E-06 CO2 0.0000E+00 1.1335E-06 5.1478E-08 Si2C 0.0000E+00 7.0003E-07 3.1792E-08 Si2 0.0000E+00 4.5031E-07 2.0451E-08 SiO2 0.0000E+00 1.1236E-07 5.1026E-09 Si3 0.0000E+00 1.0170E-07 4.6188E-09 SiC 0.0000E+00 7.3913E-12 3.3567E-13 O 0.0000E+00 7.2737E-12 3.3033E-13 C 0.0000E+00 1.2567E-13 5.7072E-15 O2 0.0000E+00 1.6031E-16 7.2803E-18 C2 0.0000E+00 9.7381E-17 4.4225E-18 C3 0.0000E+00 4.0495E-17 1.8391E-18 O3 0.0000E+00 8.7034E-33 3.9526E-34 TOTAL: 0.0000E+00 1.0000E+00 4.5415E-02 mol ACTIVITY Si 8.9464E+00 1.0000E+00 SiC 3.5701E-02 1.0000E+00 SiO2(cristobalite) 1.7851E-02 1.0000E+00 SiO2(tridymite) 0.0000E+00 9.9970E-01 SiO2(liquid) 0.0000E+00 9.3907E-01 SiO2(quartz) T 0.0000E+00 9.1491E-01 C 0.0000E+00 2.2526E-02 ******************************************************************** Cp_EQUIL H_EQUIL S_EQUIL G_EQUIL V_EQUIL J.K-1 J J.K-1 J dm3 ******************************************************************** 2.46520E+02 7.84578E+05 8.41507E+02 -7.30135E+05 0.00000E+00
Mole fraction of system components: GAS C 4.4110E-02 O 4.9998E-01 Si 4.5591E-01
Data on 1 constituent marked with 'T' are extrapolated outside their valid temperature range
**** End output table produced by tqcel


/* Once an equilibrium has been calculated using tqce/tqcel, subsequent calculations can be performed using tqcen/tqcenl, which speeds up the equilibrium calculation by taking results from the previous calculation as initial estimates */ tqsetc("t ", 0, 0, 1850.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
tqcen(" ",0,0,darray2,&noerr); if (noerr) abortprog(__LINE__,"tqcen",noerr);
tqsetc("t ", 0, 0, 1900.0,&numcon,&noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* Similar to tqcel, tqcenl also provides a ChemSage output table */ printf("\n\n**** Begin output table produced by tqcenl\n"); fflush(NULL); tqcenl(" ",0,0,darray2,&noerr); fflush(NULL); printf("\n**** End output table produced by tqcenl\n\n\n"); if (noerr) abortprog(__LINE__,"tqcenl",noerr);

/* Change value of input/output option */ /* Redirect the output from tqcel to a file using tqcio with the option "LIST"*/ /* The following call to tqcio will redirect the output of ChemApp subroutines like tqcel and tqshow to the FORTRAN unit number 21. Note that only certain values for the unit number are permitted (see the ChemApp manual entry for tqcio) */ tqcio("LIST", 21, &noerr); if (noerr) abortprog(__LINE__,"tqcio",noerr);
/* Note that at this point, no file has been associated with unit number 21 yet! This is done with the subsequent call to tqopen:*/ tqopen("result",21,&noerr); if (noerr) abortprog(__LINE__,"tqopen",noerr); printf("Output of next call to tqcel will be written to " "file \"result\"\n");
/* tqwstr can be used to write user-defined text to the unit numbers associated with "LIST" and "ERROR". This subroutine is especially useful for non-FORTRAN programs. */ tqwstr("LIST", "Output from tqcel (ChemSage result table):", &noerr); if (noerr) abortprog(__LINE__,"tqwstr",noerr);
/* Now the ChemSage-type result table output by the following routine is written to the file "result": */ tqcel(" ",0,0,darray2,&noerr); if (noerr) abortprog(__LINE__,"tqcel",noerr);

/* Close the file associated with unit number 21 again... */ tqclos(21,&noerr); if (noerr) abortprog(__LINE__,"tqclos",noerr);
/* ...and redirect the output of routines like tqcel and tqshow back to unit number 6, which is the default and associated with stdout: */ tqcio("LIST", 6, &noerr); if (noerr) abortprog(__LINE__,"tqcio",noerr); printf("Output of subsequent calls to tqcel and tqshow will go " "to stdout again\n\n");

Output:

**** Begin output table produced by tqcenl
T = 1900.00 K P = 1.00000E+00 bar V = 0.00000E+00 dm3
STREAM CONSTITUENTS AMOUNT/mol CO/GAS/ 3.5701E-02 Si3/GAS/ 3.0000E+00
EQUIL AMOUNT MOLE FRACTION FUGACITY PHASE: GAS mol bar SiO 0.0000E+00 8.5125E-01 1.2301E-01 CO 0.0000E+00 1.4866E-01 2.1481E-02 Si 0.0000E+00 8.4025E-05 1.2142E-05 CO2 0.0000E+00 3.7718E-06 5.4503E-07 Si2C 0.0000E+00 1.4416E-06 2.0832E-07 Si2 0.0000E+00 7.4859E-07 1.0817E-07 SiO2 0.0000E+00 2.7664E-07 3.9975E-08 Si3 0.0000E+00 1.6036E-07 2.3173E-08 SiC 0.0000E+00 3.6804E-11 5.3182E-12 O 0.0000E+00 2.9557E-11 4.2711E-12 C 0.0000E+00 7.5814E-13 1.0955E-13 O2 0.0000E+00 1.3988E-15 2.0213E-16 C2 0.0000E+00 1.3301E-15 1.9220E-16 C3 0.0000E+00 7.2884E-16 1.0532E-16 O3 0.0000E+00 6.6967E-31 9.6770E-32 TOTAL: 0.0000E+00 1.0000E+00 1.4450E-01 mol ACTIVITY Si 8.9464E+00 1.0000E+00 SiC 3.5701E-02 1.0000E+00 SiO2(cristobalite) 1.7851E-02 1.0000E+00 SiO2(tridymite) 0.0000E+00 9.9918E-01 SiO2(liquid) 0.0000E+00 9.7125E-01 SiO2(quartz) T 0.0000E+00 9.0635E-01 C 0.0000E+00 3.4700E-02 ******************************************************************** Cp_EQUIL H_EQUIL S_EQUIL G_EQUIL V_EQUIL J.K-1 J J.K-1 J dm3 ******************************************************************** 2.46541E+02 8.09231E+05 8.54837E+02 -8.14958E+05 0.00000E+00
Mole fraction of system components: GAS C 7.4334E-02 O 4.9998E-01 Si 4.2569E-01
Data on 1 constituent marked with 'T' are extrapolated outside their valid temperature range
**** End output table produced by tqcenl

Output of next call to tqcel will be written to file "result" Output of subsequent calls to tqcel and tqshow will go to stdout again


/* Get and display results */
/* First, we get the fraction of the first phase constituent of the first phase. We get also its name with tqgnpc, this time we use the string variable "dstr2" which we declared using the macro "TQSTRING". Since the current amount unit is "mol", we get the "mole fraction" (as opposed to "mass fraction") */
tqgnsc(1, dstr2, &noerr); if (noerr) abortprog(__LINE__,"tqgnsc",noerr); tqgetr("xp ", 1, 1, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); printf("Mole fraction of system component %s in the GAS phase: %f\n\n", dstr2, d1);

Output:
Mole fraction of system component C in the GAS phase: 0.074334


/* Now get the equilibrium amount of the same constituent */ tqgetr("a ",1,1,&d1,&noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); printf("Equilibrium amount of %s in the GAS phase: %f\n\n", dstr2, d1);

Output:
Equilibrium amount of C in the GAS phase: 0.000000
  /* Note that the result is zero, because the gas phase is not
     considered stable. The reason is that we are using the default
     ambient pressure of 1 bar for the calculations, and from the
     result table produced with the previous call to tqcel or the
     subsequent call to tqgetr we see that the activity of the gas
     phase is less than unity, which means it is not considered
     stable, and thus the equilibrium amounts of all its phase
     constituents are zero. */

/* Using the option "ac", tqgetr retrieves activities, in this case the activity (fugacity) of the gas phase */ tqgetr("ac ",1, 0, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); printf("Activity of the GAS phase: %f\n\n", d1);

Output:
Activity of the GAS phase: 0.144503


/* Now tqgetr is used in a way that causes it to return an array. In this case, we are going to retrieve an array that contains the fugacities of all constituents of the gas phase. First, we need an array that has enough room for all the results.*/
/* With an earlier call to tqnopc we determined the number of constituents in the gas phase and stored it in npcgas. Thus we can use this number to allocate enough memory for the array:*/
if (!(darray = calloc(npcgas, sizeof(DB)))) { printf("Not enough memory available for dynamic allocation!\n"); exit(1); }

/* Get the fugacities:*/ tqgetr("ac", 1, -1, darray, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr);
/* Print them out, together with the names of the constituents (note that these values correspond to the last column of the result table previously output with tqcel):*/
printf("\nFugacities of all gas phase constituents:\n");
/* Note that the 0th element of the array contains the fugacity of the 1st constituent of the gas phase. That's why the call to tqgnpc has to use "lint+1" instead of "lint"! */ for (lint = 0; lint < npcgas; lint++) {
tqgnpc(1, lint+1, dstr, &noerr); if (noerr) abortprog(__LINE__,"tqgnpc",noerr);
printf("%5s: %g\n", dstr, darray[lint]); }

Output:
Fugacities of all gas phase constituents:
    C: 1.09553e-13
   C2: 1.92202e-16
   C3: 1.0532e-16
   CO: 0.0214813
  CO2: 5.45033e-07
    O: 4.27106e-12
   O2: 2.02127e-16
   O3: 9.67695e-32
   Si: 1.21418e-05
  Si2: 1.08174e-07
 Si2C: 2.08321e-07
  Si3: 2.31727e-08
  SiC: 5.31822e-12
  SiO: 0.123008
 SiO2: 3.99754e-08
  printf("\n\n");

/* Recycle the memory */ free(darray);

/* Get thermodynamic data of a phase constituent */ tqgdpc("G", 1, 1, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgdpc",noerr); printf("The (dimensionless) value of G for " "constituent 1 of phase 1 is: %f\n\n\n", d1);

Output:

The (dimensionless) value of G for constituent 1 of phase 1 is: 23.825850

/* Note that when retrieving CP, H, S, or G using tqgdpc, the values are returned "dimensionless", which means they might have to be multiplied by R*T. Since the default amount unit is mol, results are returned for 1 mol. Note also that care has to be taken if a temperature unit different from Kelvin has been used. Refer to the manual entry of tqgdpc for a more detailed example. */

/* Check if we are working with the 'light' version. If we do, omit the following target calculation(s). */ tqlite(&islite, &noerr); if (islite) { printf("*** Target calculations have been omitted here,\n" "*** since they are not possible with the\n" "*** 'light' version of ChemApp.\n\n"); } else {

/* Perform a target calculation. This example demonstrates how to have ChemApp find the temperature at which a certain phase becomes stable. */
/* We want to have ChemApp calculate the temperature at which the phase "SiO2(liquid)" becomes stable. First, determine the index number of this phase (note that it is allowed to abbreviate its name, as long as it is unambiguous):*/ tqinp("SiO2(liq", &lint, &noerr); if (noerr) abortprog(__LINE__,"tqinp",noerr);
/* Next, define the formation target :*/ tqsetc("a", lint, 0, 0.0, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* Then call tqcel to calculate the equilibrium, and pass it the information about the target variable (we want ChemApp to vary the _temperature_ until the phase is stable): */
printf("Performing a phase target calculation\n" "Phase target: formation of SiO2(liquid)\n" "Target variable: Temperature\n");
darray2[0] = 2000.0; printf("\n\n**** Begin output table produced by tqcel\n"); fflush(NULL); tqcel("t",0,0,darray2,&noerr); fflush(NULL); printf("\n**** End output table produced by tqcel\n\n\n");

Output:
Performing a phase target calculation
Phase target: formation of SiO2(liquid)
Target variable: Temperature


**** Begin output table produced by tqcel
*T = 1995.99 K P = 1.00000E+00 bar V = 0.00000E+00 dm3
STREAM CONSTITUENTS AMOUNT/mol CO/GAS/ 3.5701E-02 Si3/GAS/ 3.0000E+00
EQUIL AMOUNT MOLE FRACTION FUGACITY PHASE: GAS mol bar SiO 0.0000E+00 7.7442E-01 3.1442E-01 CO 0.0000E+00 2.2547E-01 9.1542E-02 Si 0.0000E+00 9.8748E-05 4.0093E-05 CO2 0.0000E+00 1.0313E-05 4.1873E-06 Si2C 0.0000E+00 2.5977E-06 1.0547E-06 Si2 0.0000E+00 1.1230E-06 4.5595E-07 SiO2 0.0000E+00 5.8253E-07 2.3651E-07 Si3 0.0000E+00 2.2928E-07 9.3089E-08 SiC 0.0000E+00 1.4260E-10 5.7898E-11 O 0.0000E+00 9.6352E-11 3.9120E-11 C 0.0000E+00 3.4767E-12 1.4116E-12 C2 0.0000E+00 1.2342E-14 5.0109E-15 O2 0.0000E+00 8.8186E-15 3.5804E-15 C3 0.0000E+00 8.5734E-15 3.4809E-15 O3 0.0000E+00 2.7760E-29 1.1271E-29 TOTAL: 0.0000E+00 1.0000E+00 4.0601E-01 mol ACTIVITY Si 8.9464E+00 1.0000E+00 SiC 3.5701E-02 1.0000E+00 SiO2(cristobalite) 1.7851E-02 1.0000E+00 SiO2(liquid) 0.0000E+00 1.0000E+00 SiO2(tridymite) T 0.0000E+00 9.9861E-01 SiO2(quartz) T 0.0000E+00 8.9882E-01 C 0.0000E+00 5.0396E-02 ******************************************************************** Cp_EQUIL H_EQUIL S_EQUIL G_EQUIL V_EQUIL J.K-1 J J.K-1 J dm3 ******************************************************************** 2.46559E+02 8.32897E+05 8.66988E+02 -8.97600E+05 0.00000E+00
Mole fraction of system components: GAS C 1.1274E-01 O 4.9998E-01 Si 3.8728E-01
Data on 2 constituents marked with 'T' are extrapolated outside their valid temperature range
**** End output table produced by tqcel
  if (noerr) abortprog(__LINE__,"tqcel",noerr);
  darray2[0] = 0.0;

/* Note that in the resulting ChemSage table, the temperature is marked with an asterisk, meaning that it has been calculated by ChemApp, and the activity of SiO2(liquid) is unity, whereas its equilibrium amount is zero, meaning it just forms at this temperature*/
/* Retrieve the calculated temperature:*/ tqgetr("t", 0, 0, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); printf("Calculated formation temperature of SiO2(liquid): %g\n\n", d1);

Output:
Calculated formation temperature of SiO2(liquid): 1995.99


/* One-dimensional phase mapping calculations. The example below demonstrates how to locate all phase transitions in a given temperature range. */
/* One-dimensional phase mapping calculations are only possible with version 3.x and later of ChemApp. */ printf("Performing one-dimensional phase mapping calculations\n");
/* Initialise the variable to zero that holds the number of times tqmap found results */ resno = 0;
/* Remove all previous conditions */ tqremc(-2, &noerr); if (noerr) abortprog(__LINE__,"tqremc",noerr);
/* Determine the index number for the phase SiO2(quartz) */ tqinp("SiO2(quartz)", &lint, &noerr); if (noerr) abortprog(__LINE__,"tqinp",noerr);
/* Enter one mol of SiO2 */ tqsetc("IA", lint, 0, 1.0, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* The temperature search interval is supposed to range from 300 to 3000 K: */ darray2[0] = 300.0; darray2[1] = 3000.0;
/* First call to tqmap, note the "f" ("first") in the option parameter */ tqmap("tf", 0, 0, darray2, &icont, &noerr); if (noerr) abortprog(__LINE__,"tqmap",noerr);
/* The variable resno keeps track of the number of times we call tqmap: */ resno++;
/* Retrieve and print the temperature, which we know is darray2[0]: */ tqgetr("t", 0, 0, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); printf("*** Lower interval boundary: %g K\n", d1);
/* For as long as icont is positive, we need to make further calls to tqmap */ while (icont) {
/* tqmap is called again. Note the "n" ("next") in the option parameter. If we are at the first phase boundary (resno is still 2), we call tqmapl for a change to produce a ChemSage output table... */ if (resno == 2) { printf("*** ChemSage result table " "for the first phase boundary found:\n"); fflush(NULL); tqmapl("tn", 0, 0, darray2, &icont, &noerr); fflush(NULL); if (noerr) abortprog(__LINE__,"tqmapl",noerr); printf("\n");
/* ...otherwise we just call tqmap: */ } else { tqmap("tn", 0, 0, darray2, &icont, &noerr); if (noerr) abortprog(__LINE__,"tqmap",noerr); } resno++;
/* Get the temperature... */ tqgetr("t", 0, 0, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr);
/* ...and print the entry for the result table. If we have called tqmap twice already, we know that we found a phase boundary. If not, we have retrieved the temperature value of the upper interval boundary (darray2[1]): */
if (resno > 2) { printf("*** Phase boundary found at %g K\n", d1); } else { printf("*** Upper interval boundary: %g K\n", d1); } }

Output:
Performing one-dimensional phase mapping calculations
*** Lower interval boundary: 300 K
*** Upper interval boundary: 3000 K
*** ChemSage result table for the first phase boundary found:

*T = 1140.10 K P = 1.00000E+00 bar V = 0.00000E+00 dm3
STREAM CONSTITUENTS AMOUNT/mol SiO2(quartz) 1.0000E+00
EQUIL AMOUNT MOLE FRACTION FUGACITY PHASE: GAS mol bar SiO 0.0000E+00 6.2502E-01 4.4829E-16 O2 0.0000E+00 2.5088E-01 1.7994E-16 O 0.0000E+00 1.2327E-01 8.8415E-17 SiO2 0.0000E+00 8.3208E-04 5.9681E-19 Si 0.0000E+00 4.4651E-15 3.2026E-30 O3 0.0000E+00 2.4636E-19 1.7670E-34 Si2 0.0000E+00 5.5659E-36 3.9921E-51 Si3 0.0000E+00 NOT CALCD. 6.4667E-69 TOTAL: 0.0000E+00 1.0000E+00 7.1725E-16 mol ACTIVITY SiO2(quartz) 1.0000E+00 1.0000E+00 SiO2(tridymite) 0.0000E+00 1.0000E+00 SiO2(cristobalite) 0.0000E+00 9.9398E-01 SiO2(liquid) 0.0000E+00 6.4439E-01 Si 0.0000E+00 2.5802E-17 ******************************************************************** Cp_EQUIL H_EQUIL S_EQUIL G_EQUIL V_EQUIL J.K-1 J J.K-1 J dm3 ******************************************************************** 7.04991E+01 -8.55398E+05 1.25413E+02 -9.98382E+05 0.00000E+00
Mole fraction of system components: GAS O 6.6667E-01 Si 3.3333E-01
*** Phase boundary found at 1140.1 K *** Phase boundary found at 1738.28 K *** Phase boundary found at 1995.99 K

/* With the above example the temperatures of all phase boundaries in a system which contains 1 mol of SiO2 have been calculated. Thus the phase boundaries determined reflect the stability ranges of the various modifications of SiO2. Also note that the first two temperatures determined are _no_ phase boundaries, but the lower and upper limit of the search interval (darray2[0] and darray2[1]). */
}
/* Since from now on we will be using streams instead of global conditions, we first remove all conditions and targets set up to this point. Note that using a "-1" instead of the "-2" in the call to tqremc would also reset ChemApp to default units and values.*/ tqremc(-2, &noerr); if (noerr) abortprog(__LINE__,"tqremc",noerr);

printf("\n\nCalculations using streams:\n\n");
/* Set name and temperature for a stream via the array tp, which will be passed to tqsttp when each of the streams is created. */ tp[0] = 1000.0; tp[1] = 1.0;
/* Create 3 streams: */ tqsttp("stream1", tp, &noerr); if (noerr) abortprog(__LINE__,"tqsttp",noerr); tqsttp("stream2", tp, &noerr); if (noerr) abortprog(__LINE__,"tqsttp",noerr); tqsttp("stream3", tp, &noerr); if (noerr) abortprog(__LINE__,"tqsttp",noerr);
/* Set constituent amounts for each stream */ tqstca("stream1", 1, 4, 1.0,&noerr); if (noerr) abortprog(__LINE__,"tqstca",noerr); tqstca("stream2", 1, 12, 3.0,&noerr); if (noerr) abortprog(__LINE__,"tqstca",noerr); tqstca("stream3", 1, 8, 2.0,&noerr); if (noerr) abortprog(__LINE__,"tqstca",noerr);
/* Remove the last stream */ tqstrm("stream3", &noerr); if (noerr) abortprog(__LINE__,"tqstrm",noerr);
/* Set equilibrium temperature */ tqstec("t ", 0, 1800.0, &noerr); if (noerr) abortprog(__LINE__,"tqstec",noerr);
/* Calculate and list equilibrium */ printf("\n\n**** Begin output table produced by tqcel\n"); fflush(NULL); tqcel(" ",0,0,darray2,&noerr); fflush(NULL); printf("\n**** End output table produced by tqcel\n\n\n");

Output:

Calculations using streams:

**** Begin output table produced by tqcel
T = 1800.00 K P = 1.00000E+00 bar V = 0.00000E+00 dm3
STREAM CONSTITUENTS AMOUNT/mol TEMPERATURE/K PRESSURE/bar STREAM CO/GAS/ 1.0000E+00 1000.00 1.0000E+00 2 Si3/GAS/ 3.0000E+00 1000.00 1.0000E+00 3
EQUIL AMOUNT MOLE FRACTION FUGACITY PHASE: GAS mol bar SiO 0.0000E+00 9.1172E-01 4.1405E-02 CO 0.0000E+00 8.8214E-02 4.0062E-03 Si 0.0000E+00 6.7137E-05 3.0490E-06 CO2 0.0000E+00 1.1335E-06 5.1478E-08 Si2C 0.0000E+00 7.0003E-07 3.1792E-08 Si2 0.0000E+00 4.5031E-07 2.0451E-08 SiO2 0.0000E+00 1.1236E-07 5.1026E-09 Si3 0.0000E+00 1.0170E-07 4.6188E-09 SiC 0.0000E+00 7.3913E-12 3.3567E-13 O 0.0000E+00 7.2737E-12 3.3033E-13 C 0.0000E+00 1.2567E-13 5.7072E-15 O2 0.0000E+00 1.6031E-16 7.2803E-18 C2 0.0000E+00 9.7381E-17 4.4225E-18 C3 0.0000E+00 4.0495E-17 1.8391E-18 O3 0.0000E+00 8.7034E-33 3.9526E-34 TOTAL: 0.0000E+00 1.0000E+00 4.5415E-02 mol ACTIVITY Si 7.5000E+00 1.0000E+00 SiC 1.0000E+00 1.0000E+00 SiO2(cristobalite) 5.0000E-01 1.0000E+00 SiO2(tridymite) 0.0000E+00 9.9970E-01 SiO2(liquid) 0.0000E+00 9.3907E-01 SiO2(quartz) T 0.0000E+00 9.1491E-01 C 0.0000E+00 2.2526E-02 ******************************************************************** DELTA_Cp DELTA_H DELTA_S DELTA_G DELTA_V J.K-1 J J.K-1 J dm3 ******************************************************************** 7.76666E+01 -1.68039E+06 -3.77532E+02 -2.00297E+06 -3.32581E+02
Mole fraction of system components: GAS C 4.4110E-02 O 4.9998E-01 Si 4.5591E-01
Data on 1 constituent marked with 'T' are extrapolated outside their valid temperature range
**** End output table produced by tqcel
  if (noerr) abortprog(__LINE__,"tqcel",noerr);

/* Get thermodynamic properties of a stream (note that as of version 3.2.0 of ChemApp, tqstxp can also be called _before_ the equilibrium calculation) */ tqstxp("stream1", "H", &d1, &noerr); if (noerr) abortprog(__LINE__,"tqstxp",noerr);
printf("Enthalpy of \"stream1\": %g\n\n", d1);

Output:
Enthalpy of "stream1": -88842.4


printf("\nDemonstrating the use of ChemApp " "subroutines involving sublattices.\n\n"); /* To demonstrate the subroutines dealing with sublattices, a different data-file (subl-ex.dat) needs to be loaded. This data-file contains an extract of the system Co-Cr-Fe: the phase SIGMA:30, which is modelled according to the sublattice formalism, and the BCC phase, described by a Redlich-Kister polynomial. Both phases are each included twice, to account for miscibility gaps. */
tqopna("subl-ex.dat", unitno, &noerr); if (noerr) abortprog(__LINE__,"tqopna",noerr);
/* Read data-file */ tqrfil(&noerr); if (noerr) abortprog(__LINE__,"tqrfil",noerr);
/* Close data-file */ tqclos(unitno, &noerr); if (noerr) abortprog(__LINE__,"tqclos",noerr);
/* The first of the two identical copies of the SIGMA:30 phase, which ChemApp calls SIGMA:30#1, will be investigated with respect to the number of sublattices, the number of sublattice constituents on each sublattice, and the names of the sublattice constituents. */
/* Get the index number for the phase SIGMA:30#1 */ strcpy(pname, "SIGMA:30#1"); tqinp(pname, &indexp, &noerr); if (noerr) abortprog(__LINE__,"tqinp",noerr);
/* Get the number of sublattices */ tqnosl(indexp, &nsl, &noerr); if (noerr) abortprog(__LINE__,"tqnosl",noerr); printf("%s has %li sublattices\n",pname, nsl);

Output:
Demonstrating the use of ChemApp subroutines involving sublattices.

SIGMA:30#1 has 3 sublattices

/* Loop over all sublattices */ for (indexl = 1; indexl<=nsl; indexl++) {
/* Get the number of sublattice constituents */ tqnolc(indexp, indexl, &nslcon, &noerr); if (noerr) abortprog(__LINE__,"tqnolc",noerr); printf("Sublattice %li has %li constituents with the following names:\n", indexl, nslcon);
/* Get the name of each sublattice constituent */ for (indexc = 1; indexc<=nslcon; indexc++) { tqgnlc(indexp, indexl ,indexc, cname, &noerr); if (noerr) abortprog(__LINE__,"tqgnlc",noerr);
/* The reverse (getting the index number for the name of the sublattice constituent just retrieved), is rather superfluous here, and only used to demonstrate the call to tqinlc: */ tqinlc(cname, indexp, indexl, &lint, &noerr); if (noerr) abortprog(__LINE__,"tqinlc",noerr); printf(" %li: %s\n", lint, cname); } }

Output:
Sublattice 1 has 2 constituents with the following names:
   1: Co
   2: Fe
Sublattice 2 has 1 constituents with the following names:
   1: Cr
Sublattice 3 has 3 constituents with the following names:
   1: Co
   2: Cr
   3: Fe


/* Set the temperature to 1000 K */ tqsetc("T", 0, 0, 1000.0, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
/* Set the incoming amounts to 0.25 mol Co, 0.25 mol Cr, and 0.5 mol Fe */ tqinsc("Co", &indexc, &noerr); if (noerr) abortprog(__LINE__,"tqinsc",noerr); tqsetc("ia", 0, indexc, 0.25, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
tqinsc("Cr", &indexc, &noerr); if (noerr) abortprog(__LINE__,"tqinsc",noerr); tqsetc("ia", 0, indexc, 0.25, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
tqinsc("Fe", &indexc, &noerr); if (noerr) abortprog(__LINE__,"tqinsc",noerr); tqsetc("ia", 0, indexc, 0.50, &numcon, &noerr); if (noerr) abortprog(__LINE__,"tqsetc",noerr);
printf("\nCalculate the equilibrium, " "get information on the stable sublattice phases.\n\n");
/* Calculate the equilibrium */ darray2[0]=0.0; tqce(" ", 0, 0, darray2, &noerr); if (noerr) abortprog(__LINE__,"tqce",noerr);
/* Get information on the stable sublattice phases. */
/* Loop over all phases, and if a phase is stable and a sublattice phase, print information about the sublattices */ tqnop(&nphase, &noerr); if (noerr) abortprog(__LINE__,"tqnop",noerr); for (indexp = 1; indexp<=nphase; indexp++) {
/* Check if the phase is stable, otherwise we don't need to consider it */ tqgetr("a", indexp, 0, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgetr",noerr); if (d1 > 0) {
/* Get the name and model of the phase */ tqgnp(indexp, pname, &noerr); if (noerr) abortprog(__LINE__,"tqgnp",noerr); tqmodl(indexp, mname, &noerr); if (noerr) abortprog(__LINE__,"tqmodl",noerr);
/* If the model name of the phase starts with 'SUB' we have a sublattice phase */ if (strncmp(mname, "SUB", 3) == 0) {
/* Print a header similar to the one in the ChemSage output table */ printf("Mole fraction of the sublattice constituents in %s\n", pname);
/* Get the number of sublattices */ tqnosl(indexp, &nsl, &noerr); if (noerr) abortprog(__LINE__,"tqnosl",noerr);
/* Loop over all sublattices */ for (indexl=1; indexl<=nsl; indexl++) {
printf("Sublattice %li\n", indexl); /* Get the number of sublattice constituents */ tqnolc(indexp, indexl, &nslcon, &noerr); if (noerr) abortprog(__LINE__,"tqnolc",noerr);
for (indexc=1; indexc<=nslcon; indexc++) { /* Get the name of each sublattice constituent... */ tqgnlc(indexp, indexl, indexc, cname, &noerr); if (noerr) abortprog(__LINE__,"tqgnlc",noerr);
/* ... and its mole fraction in the sublattice */ tqgtlc(indexp, indexl, indexc, &d1, &noerr); if (noerr) abortprog(__LINE__,"tqgtlc",noerr);
printf("%-25s %f\n", cname, d1); } } } } } printf("\n");

Output:
Calculate the equilibrium, get information on the stable sublattice phases.

Mole fraction of the sublattice constituents in SIGMA:30#1 Sublattice 1 Co 0.542377 Fe 0.457623 Sublattice 2 Cr 1.000000 Sublattice 3 Co 0.109259 Cr 0.691920 Fe 0.198821


/* The following section demonstrates the use of subroutines that were introduced in ChemApp V4.0.0 to support "transparent data-files" */
/* Retrieve the licensee's user ID */ tqgtid(id, &noerr); if (noerr) abortprog(__LINE__,"tqgtid",noerr);
/* Retrieve the licensee's name */ tqgtnm(name, &noerr); if (noerr) abortprog(__LINE__,"tqgtnm",noerr);
/* Retrieve the program ID */ tqgtpi(pid, &noerr); if (noerr) abortprog(__LINE__,"tqgtpi",noerr);
/* Print all three */ printf("Licensee's user ID: %s\n", id); printf("Licensee's name : %s\n", name); printf("Program ID : %s\n\n", pid);

Output:
Licensee's user ID: 5001
Licensee's name   : GTT - Technologies
Program ID        : CAFU

/* The following pieces of information are only meaningful if a version of ChemApp is used that requires a dongle (hardware key). Get the HASP dongle type and id */ tqgthi(haspt, &haspid, &noerr); if (noerr) abortprog(__LINE__,"tqgthi",noerr);
/* Get the ChemApp license expiration date (month and year) */ tqgted(&edmon, &edyear, &noerr); if (noerr) abortprog(__LINE__,"tqgted",noerr);
/* Print info if HASP dongle is used: */ if (haspid) { printf("HASP dongle type : %s\n", haspt); printf("HASP dongle id : %li\n", haspid); printf("ChemApp license expiration date (month/year): %li/%li\n", edmon, edyear); } else { printf("This ChemApp version does not require a " "HASP hardware key (dongle)\n"); }

Output:
This ChemApp version does not require a HASP hardware key (dongle)


/* Get the default unit number associated with error output */ tqgio("ERROR", &errorunit, &noerr); if (noerr) abortprog(__LINE__,"tqgio",noerr);
/* Turn off automatic error reporting for the next call to tqcio. */ tqcio("ERROR", 0, &noerr); if (noerr) abortprog(__LINE__,"tqcio",noerr);
/* The following section is only executed if the file "cosiex.cst", a sample thermochemical data-file in transparent format, is present. It is not included in regular distributions of ChemApp */
tqopnt("cosiex.cst",unitno,&lint);
/* Turn automatic error reporting back on. */ tqcio("ERROR", errorunit, &noerr); if (noerr) abortprog(__LINE__,"tqcio",noerr);
if (lint) { printf("Skipping transparent file subroutines, since file " "'cosiex.cst' cannot be read\n"); } else {
/* Read data-file */ tqrcst(&noerr); if (noerr) abortprog(__LINE__,"tqrcst",noerr);
/* Close data-file */ /* Again, the routine for closing the data-file is not a standard C library routine like fclose, but a special one to make sure the file that was previously opened under the unit number specified is closed. Both tqopnb and tqclos are not actually a part of ChemApp itself, but of ChemApp's C interface. */ tqclos(unitno,&noerr); if (noerr) abortprog(__LINE__,"tqclos",noerr);
/* Once the transparent data-file has been read, information on its header can be retrieved.*/ tqgtrh(&tfhver, tfhnwp, tfhvnw, tfhnrp, tfhvnr, tfhdtc, tfhdte, tfhid, tfhusr, tfhrem, &noerr); if (noerr) abortprog(__LINE__,"tqgtrh",noerr);
printf("Version number of the transparent file header format: %li\n", tfhver); printf("Name of the program which wrote the data-file: %s\n", tfhnwp); printf("Version number of the writing program: %li.%li.%li\n", tfhvnw[0],tfhvnw[1],tfhvnw[2]); printf("Programs which are permitted to read the data-file: %s\n", tfhnrp); printf("Min. version number of the reading program: %li.%li.%li\n", tfhvnr[0],tfhvnr[1],tfhvnr[2]); printf("File was created on %li/%02li/%02li %02li:%02li:%02li \n", tfhdtc[0],tfhdtc[1],tfhdtc[2],tfhdtc[3],tfhdtc[4],tfhdtc[5]); printf("File will expire on %li/%02li/%02li %02li:%02li:%02li \n", tfhdte[0],tfhdte[1],tfhdte[2],tfhdte[3],tfhdte[4],tfhdte[5]); printf("Licensee's user ID(s): %s\n", tfhid); printf("Licensee's name: %s\n", tfhusr); printf("Remarks : %s\n", tfhrem);

Output:
Version number of the transparent file header format: 1
Name of the program which wrote the data-file: FactSage
Version number of the writing program: 5.0.0
Programs which are permitted to read the data-file: CAFU,CALI
Min. version number of the reading program: -1.-1.-1
File was created on 2003/06/05 12:11:39 
File will expire on 2036/12/31 12:00:00 
Licensee's user ID(s): ????
Licensee's name: GTT - Technologies
Remarks : For use with ChemApp example programs
  }


printf("\nEnd of output from cademo1.\n");

Output:
End of output from cademo1.

return 0; }


ChemApp Programmer's Manual, Edition 3.6© GTT-Technologies, 2003