added README_changes.txt
[wrffire.git] / wrfv2_fire / chem / KPP / kpp / kpp-2.1 / src / scanner.c
blobbc8a5ab5c676866cd2aad742ea328ec5d190ce57
1 /******************************************************************************
3 KPP - The Kinetic PreProcessor
4 Builds simulation code for chemical kinetic systems
6 Copyright (C) 1995-1996 Valeriu Damian and Adrian Sandu
7 Copyright (C) 1997-2005 Adrian Sandu
9 KPP is free software; you can redistribute it and/or modify it under the
10 terms of the GNU General Public License as published by the Free Software
11 Foundation (http://www.gnu.org/copyleft/gpl.html); either version 2 of the
12 License, or (at your option) any later version.
14 KPP is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 details.
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, consult http://www.gnu.org/copyleft/gpl.html or
21 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
24 Adrian Sandu
25 Computer Science Department
26 Virginia Polytechnic Institute and State University
27 Blacksburg, VA 24060
28 E-mail: sandu@cs.vt.edu
30 ******************************************************************************/
33 #include "gdata.h"
34 #include "scan.h"
35 #include "y.tab.h"
36 #include <stdlib.h>
37 #include <string.h>
38 #include <math.h>
40 int AtomNr = 0;
41 int SpeciesNr = 0;
42 int EqnNr = 0;
43 int SpcNr = 0;
44 int VarNr = 0;
45 int VarActiveNr = 0;
46 int FixNr = 0;
47 int VarStartNr = 0;
48 int FixStartNr = 0;
51 int initNr = -1;
52 int xNr = 0;
53 int yNr = 0;
54 int zNr = 0;
56 int falseSpcNr = 0;
58 ATOM_DEF AtomTable[ MAX_ATNR ];
59 SPECIES_DEF SpeciesTable[ MAX_SPECIES ];
60 CODE ReverseCode[ MAX_SPECIES ];
61 CODE Code[ MAX_SPECIES ];
62 KREACT kr[ MAX_EQN ];
64 float** Stoich_Left;
65 float** Stoich;
66 float** Stoich_Right;
67 int Reactive[ MAX_SPECIES ];
69 INLINE_KEY InlineKeys[] = { { F77_GLOBAL, APPEND, "F77_GLOBAL" },
70 { F77_INIT, APPEND, "F77_INIT" },
71 { F77_DATA, APPEND, "F77_DATA" },
72 { F77_UTIL, APPEND, "F77_UTIL" },
73 { F77_RATES, APPEND, "F77_RATES" },
74 { F77_RCONST, APPEND, "F77_RCONST" },
75 { F90_GLOBAL, APPEND, "F90_GLOBAL" },
76 { F90_INIT, APPEND, "F90_INIT" },
77 { F90_DATA, APPEND, "F90_DATA" },
78 { F90_UTIL, APPEND, "F90_UTIL" },
79 { F90_RATES, APPEND, "F90_RATES" },
80 { F90_RCONST, APPEND, "F90_RCONST" },
81 { C_GLOBAL, APPEND, "C_GLOBAL" },
82 { C_INIT, APPEND, "C_INIT" },
83 { C_DATA, APPEND, "C_DATA" },
84 { C_UTIL, APPEND, "C_UTIL" },
85 { C_RATES, APPEND, "C_RATES" },
86 { C_RCONST, APPEND, "C_RCONST" },
87 { MATLAB_GLOBAL, APPEND, "MATLAB_GLOBAL" },
88 { MATLAB_INIT, APPEND, "MATLAB_INIT" },
89 { MATLAB_DATA, APPEND, "MATLAB_DATA" },
90 { MATLAB_UTIL, APPEND, "MATLAB_UTIL" },
91 { MATLAB_RATES, APPEND, "MATLAB_RATES" },
92 { MATLAB_RCONST, APPEND, "MATLAB_RCONST" }
95 int useAggregate = 1;
96 int useJacobian = JAC_LU_ROW;
97 int useJacSparse = 1;
98 int useHessian = 1;
99 int useStoicmat = 1;
100 int useDouble = 1;
101 int useReorder = 1;
102 int useMex = 1;
103 int useDummyindex = 0;
104 int useEqntags = 0;
105 int useLang = F77_LANG;
106 int useStochastic = 0;
107 int useWRFConform = 0;
110 char integrator[ MAX_PATH ] = "none";
111 char driver[ MAX_PATH ] = "none";
112 char runArgs[ MAX_PATH ] = "";
114 /* mz_rs_20050701+ */
115 /* char varDefault[ MAX_IVAL ] = "1.E-8"; */
116 /* char fixDefault[ MAX_IVAL ] = "1.E-8"; */
117 /* double cfactor = 1.09E+10; */
118 char varDefault[ MAX_IVAL ] = "0.";
119 char fixDefault[ MAX_IVAL ] = "0.";
120 double cfactor = 1.;
121 /* mz_rs_20050701- */
123 ATOM crtAtoms[ MAX_ATOMS ];
124 int crtAtomNr = 0;
126 char *fileList[ MAX_FILES ];
127 int fileNr = 0;
129 double Abs( double x )
131 return x > 0 ? x : -x;
134 void DefineInitializeNbr( char *cmd )
136 int n;
138 n = sscanf( cmd, "%d", &initNr);
139 if( n != 1 )
140 ScanError("Bad number of species to initialize <%s>", cmd);
143 void DefineXGrid( char *cmd )
145 int n;
147 xNr = 1;
148 n = sscanf( cmd, "%d", &xNr);
149 if( n != 1 )
150 ScanError("Bad X grid number <%s>", cmd);
153 void DefineYGrid( char *cmd )
155 int n;
157 yNr = 1;
158 n = sscanf( cmd, "%d", &yNr);
159 if( n != 1 )
160 ScanError("Bad Y grid number <%s>", cmd);
163 void DefineZGrid( char *cmd )
165 int n;
167 zNr = 1;
168 n = sscanf( cmd, "%d", &zNr);
169 if( n != 1 )
170 ScanError("Bad Z grid number <%s>", cmd);
173 void CmdFunction( char *cmd )
175 if( EqNoCase( cmd, "AGGREGATE" ) ) {
176 useAggregate = 1;
177 return;
179 if( EqNoCase( cmd, "SPLIT" ) ) {
180 useAggregate = 0;
181 return;
183 ScanError("'%s': Unknown parameter for #FUNCTION [AGGREGATE|SPLIT]", cmd );
186 void CmdJacobian( char *cmd )
188 if( EqNoCase( cmd, "OFF" ) ) {
189 useJacobian = JAC_OFF;
190 useJacSparse = 0;
191 return;
193 if( EqNoCase( cmd, "FULL" ) ) {
194 useJacobian = JAC_FULL;
195 useJacSparse = 0;
196 return;
198 if( EqNoCase( cmd, "SPARSE_LU_ROW" ) ) {
199 useJacobian = JAC_LU_ROW;
200 useJacSparse = 1;
201 return;
203 if( EqNoCase( cmd, "SPARSE_ROW" ) ) {
204 useJacobian = JAC_ROW;
205 useJacSparse = 1;
206 return;
208 ScanError("'%s': Unknown parameter for #JACOBIAN [OFF|FULL|SPARSE_LU_ROW|SPARSE_ROW]", cmd );
211 void SparseData( char *cmd ) {
212 ScanError("Deprecated use of #SPARSEDATA %s: see #JACOBIAN for equivalent functionality", cmd );
215 void CmdHessian( char *cmd )
217 if( EqNoCase( cmd, "OFF" ) ) {
218 useHessian = 0;
219 return;
221 if( EqNoCase( cmd, "ON" ) ) {
222 useHessian = 1;
223 return;
225 ScanError("'%s': Unknown parameter for #HESSIAN [ON|OFF]", cmd );
228 void CmdStoicmat( char *cmd )
230 if( EqNoCase( cmd, "OFF" ) ) {
231 useStoicmat = 0;
232 return;
234 if( EqNoCase( cmd, "ON" ) ) {
235 useStoicmat = 1;
236 return;
238 ScanError("'%s': Unknown parameter for #STOICMAT [ON|OFF]", cmd );
241 void CmdDouble( char *cmd )
243 if( EqNoCase( cmd, "OFF" ) ) {
244 useDouble = 0;
245 return;
247 if( EqNoCase( cmd, "ON" ) ) {
248 useDouble = 1;
249 return;
251 ScanError("'%s': Unknown parameter for #DOUBLE [ON|OFF]", cmd );
254 void CmdReorder( char *cmd )
256 if( EqNoCase( cmd, "OFF" ) ) {
257 useReorder = 0;
258 return;
260 if( EqNoCase( cmd, "ON" ) ) {
261 useReorder = 1;
262 return;
264 ScanError("'%s': Unknown parameter for #REORDER [ON|OFF]", cmd );
267 void CmdMex( char *cmd )
269 if( EqNoCase( cmd, "OFF" ) ) {
270 useMex = 0;
271 return;
273 if( EqNoCase( cmd, "ON" ) ) {
274 useMex = 1;
275 return;
277 ScanError("'%s': Unknown parameter for #MEX [ON|OFF]", cmd );
280 void CmdDummyindex( char *cmd )
282 if( EqNoCase( cmd, "OFF" ) ) {
283 useDummyindex = 0;
284 return;
286 if( EqNoCase( cmd, "ON" ) ) {
287 useDummyindex = 1;
288 return;
290 ScanError("'%s': Unknown parameter for #DUMMYINDEX [ON|OFF]", cmd );
293 void CmdEqntags( char *cmd )
295 if( EqNoCase( cmd, "OFF" ) ) {
296 useEqntags = 0;
297 return;
299 if( EqNoCase( cmd, "ON" ) ) {
300 useEqntags = 1;
301 return;
303 ScanError("'%s': Unknown parameter for #EQNTAGS [ON|OFF]", cmd );
306 void CmdUse( char *cmd )
308 ScanError("Deprecated command '#USE %s';\nReplace with '#LANGUAGE %s'.",cmd,cmd );
312 void CmdLanguage( char *cmd )
314 if( EqNoCase( cmd, "FORTRAN77" ) ) {
315 useLang = F77_LANG;
316 return;
318 if( EqNoCase( cmd, "FORTRAN" ) ) {
319 ScanWarning("Fortran version not specified in '#LANGUAGE %s'. Will use Fortran 77.", cmd);
320 useLang = F77_LANG;
321 return;
323 if( EqNoCase( cmd, "FORTRAN90" ) ) {
324 useLang = F90_LANG;
325 return;
327 if( EqNoCase( cmd, "MATLAB" ) ) {
328 useLang = MATLAB_LANG;
329 return;
331 if( EqNoCase( cmd, "C" ) ) {
332 useLang = C_LANG;
333 return;
335 ScanError("'%s': Unknown parameter for #LANGUAGE [Fortran77|Fortran90|C|Matlab]", cmd );
338 void CmdStochastic( char *cmd )
340 if( EqNoCase( cmd, "ON" ) ) {
341 useStochastic = 1;
342 return;
344 if( EqNoCase( cmd, "OFF" ) ) {
345 useStochastic = 0;
346 return;
348 ScanError("'%s': Unknown parameter for #STOCHASTIC [OFF|ON]", cmd );
351 void CmdIntegrator( char *cmd )
353 strcpy( integrator, cmd );
356 void CmdDriver( char *cmd )
358 strcpy( driver, cmd );
361 void CmdRun( char *cmd )
363 strcpy( runArgs, cmd );
366 int FindAtom( char *atname )
368 int i;
370 for( i=0; i<AtomNr; i++ )
371 if( EqNoCase( AtomTable[ i ].name, atname ) ) {
372 return i;
374 return -1;
377 void DeclareAtom( char *atname )
379 int code;
381 code = FindAtom( atname );
382 if ( code >= 0 ) {
383 ScanError("Multiple declaration for atom %s.", atname );
384 return;
386 if( AtomNr >= MAX_ATNR ) {
387 Error("Too many atoms");
388 return;
391 strcpy( AtomTable[ AtomNr ].name, atname );
392 AtomTable[ AtomNr ].check = NO_CHECK;
393 AtomTable[ AtomNr ].masscheck = 0;
394 AtomNr++;
397 void SetAtomType( char *atname, int type )
399 int code;
401 code = FindAtom( atname );
402 if ( code < 0 ) {
403 ScanError("Undefined atom %s.", atname );
404 return;
406 AtomTable[ code ].check = type;
409 void CheckAll()
411 int i;
413 for( i=0; i<AtomNr; i++ ) {
414 if( AtomTable[ i ].check != CANCEL_CHECK )
415 AtomTable[ i ].check = DO_CHECK;
417 SetAtomType( "IGNORE", NO_CHECK );
420 void AddAtom( char *atname, char *nr )
422 int code;
424 code = FindAtom( atname );
425 if ( code < 0 ) {
426 ScanError("Undefined atom %s.", atname );
427 return;
429 crtAtoms[ crtAtomNr ].code = (unsigned char)code;
430 crtAtoms[ crtAtomNr ].nr = (unsigned char)atoi(nr);
431 crtAtomNr++;
434 int FindSpecies( char *spname )
436 int i;
438 for( i=0; i<SpeciesNr; i++ )
439 if( EqNoCase( SpeciesTable[ i ].name, spname ) ) {
440 return i;
442 for( i=0; i<2; i++ )
443 if( EqNoCase( SpeciesTable[ MAX_SPECIES -1 - i ].name, spname ) ) {
444 return MAX_SPECIES -1 - i;
446 return -1;
449 void StoreSpecies( int index, int type, char *spname )
451 int i;
453 strcpy( SpeciesTable[ index ].name, spname );
454 SpeciesTable[ index ].type = type;
455 *SpeciesTable[ index ].ival = '\0';
456 SpeciesTable[ index ].lookat = 0;
457 SpeciesTable[ index ].moni = 0;
458 SpeciesTable[ index ].trans = 0;
459 if( (SpeciesTable[ index ].nratoms == 0) || ( crtAtomNr > 0 ) ) {
460 SpeciesTable[ index ].nratoms = crtAtomNr;
461 for( i = 0; i < crtAtomNr; i++ )
462 SpeciesTable[ index ].atoms[i] = crtAtoms[i];
464 crtAtomNr = 0;
467 void DeclareSpecies( int type, char *spname )
469 int code;
471 code = FindSpecies( spname );
472 if ( code >= 0 ) {
473 ScanError("Multiple declaration for species %s.", spname );
474 return;
476 if( SpeciesNr >= MAX_SPECIES ) {
477 Error("Too many species");
478 return;
480 StoreSpecies( SpeciesNr, type, spname );
481 SpeciesNr++;
484 void SetSpcType( int type, char *spname )
486 int code;
487 int i;
489 if( EqNoCase( spname, "VAR_SPEC" ) ) {
490 for( i = 0; i < SpeciesNr; i++ )
491 if( SpeciesTable[i].type == VAR_SPC )
492 SpeciesTable[i].type = type;
493 return;
495 if( EqNoCase( spname, "FIX_SPEC" ) ) {
496 for( i = 0; i < SpeciesNr; i++ )
497 if( SpeciesTable[i].type == FIX_SPC )
498 SpeciesTable[i].type = type;
499 return;
501 if( EqNoCase( spname, "ALL_SPEC" ) ) {
502 for( i = 0; i < SpeciesNr; i++ )
503 SpeciesTable[i].type = type;
504 return;
507 code = FindSpecies( spname );
508 if ( code < 0 ) {
509 ScanError("Undefined species %s.", spname );
510 return;
512 SpeciesTable[ code ].type = type;
515 void AssignInitialValue( char *spname , char *spval )
517 int code;
518 double cf;
520 if( EqNoCase( spname, "CFACTOR" ) ) {
521 code = sscanf( spval, "%lg", &cf );
522 if( code != 1 ) {
523 ScanWarning("Invalid CFACTOR value: %s", spval);
524 return;
526 cfactor = cf;
527 return;
530 if( EqNoCase( spname, "VAR_SPEC" ) ) {
531 strcpy( varDefault, spval );
532 return;
536 if( EqNoCase( spname, "FIX_SPEC" ) ) {
537 strcpy( fixDefault, spval );
538 return;
541 if( EqNoCase( spname, "ALL_SPEC" ) ) {
542 strcpy( varDefault, spval );
543 strcpy( fixDefault, spval );
544 return;
547 code = FindSpecies( spname );
548 if ( code < 0 ) {
549 ScanError("Undefined species %s.", spname );
550 return;
552 strcpy( SpeciesTable[ code ].ival, spval );
555 void StoreEquationRate( char *rate, char *label )
557 double f;
558 char buf[ MAX_K ];
559 int n;
560 KREACT *kreact;
562 kreact = &kr[ EqnNr ];
563 strcpy( kreact->label, label );
564 if( isPhoto ) {
565 kreact->type = PHOTO;
566 strcpy( kreact->val.st, rate );
567 isPhoto = 0;
568 return;
570 n = sscanf( rate, "%lf%s", &f, buf );
571 if ( n == 1 ) {
572 kreact->type = NUMBER;
573 kreact->val.f = f;
574 return;
576 kreact->type = EXPRESION;
577 strcpy( kreact->val.st, rate );
578 return;
581 void CheckEquation()
583 int i,j;
584 int equal, index;
585 double r1, r2;
586 float atcnt[ MAX_ATNR ];
587 int spc;
588 SPECIES_DEF *sp;
589 char errmsg[80];
590 int err;
592 if( EqnNr >= MAX_EQN ) {
593 Error("Too many equations");
594 return;
597 for( i = 0; i < AtomNr; i++ )
598 atcnt[i] = 0;
600 for( spc = 0; spc < SpcNr; spc++ ) {
601 sp = &SpeciesTable[ Code[spc] ];
602 if( Stoich_Left[spc][EqnNr] != 0 ) {
603 for( i = 0; i < sp->nratoms; i++ )
604 atcnt[ sp->atoms[i].code ] += Stoich_Left[spc][EqnNr] * sp->atoms[i].nr;
606 if( Stoich_Right[spc][EqnNr] != 0 ) {
607 for( i = 0; i < sp->nratoms; i++ )
608 atcnt[ sp->atoms[i].code ] -= Stoich_Right[spc][EqnNr] * sp->atoms[i].nr;
612 *errmsg = 0;
613 err = 0;
615 for( i = 0; i < AtomNr; i++ ) {
616 if ( Abs( atcnt[i] ) > 1e-5 ) {
617 if ( AtomTable[i].check == CANCEL_CHECK ) {
618 err = 0;
619 break;
621 if ( AtomTable[i].check == NO_CHECK ) {
622 continue;
624 if ( AtomTable[i].check == DO_CHECK ) {
625 err = 1;
626 sprintf(errmsg, "%s %s", errmsg, AtomTable[i].name );
627 continue;
632 if ( err )
633 ScanWarning( "(eqn %d) Atom balance mismatch for:%s.", EqnNr+1, errmsg );
635 for( j = 0; j < SpcNr; j++ )
636 if( Stoich_Left[j][EqnNr] != 0 )
637 { index = j; break; }
638 for( i = 0; i < EqnNr; i++ ) {
639 equal = 1;
640 r1 = Stoich_Left[index][EqnNr];
641 r2 = Stoich_Left[index][i];
642 for( j = 0; j < SpcNr; j++ ) {
643 if( r1 * Stoich_Left[j][i] != r2 * Stoich_Left[j][EqnNr] )
644 { equal = 0; break; }
645 if( r1 * Stoich_Right[j][i] != r2 * Stoich_Right[j][EqnNr] )
646 { equal = 0; break; }
648 if ( equal ) {
649 if( r1 == r2 )
650 ScanError( "Duplicate equation: "
651 " (eqn<%d> = eqn<%d> )", i+1, EqnNr+1 );
652 else
653 ScanError( "Linearly dependent equations: "
654 "( %.0f eqn<%d> = %.0f eqn<%d> )",
655 r1, i+1, r2, EqnNr+1 );
656 break;
659 EqnNr++;
662 void ProcessTerm( int side, char *sign, char *coef, char *spname )
664 int code;
665 CODE crtSpec;
666 double val;
667 char buf[40];
670 code = FindSpecies( spname );
671 if ( code < 0 ) {
672 ScanError("Undefined species %s.", spname );
673 return;
676 crtSpec = ReverseCode[ code ];
678 if(EqNoCase(spname,"HV")) isPhoto = 1;
680 if ( crtSpec == NO_CODE ) {
681 if( MAX_SPECIES - code <= 2 ) falseSpcNr++;
682 crtSpec = SpcNr++;
683 Code[ crtSpec ] = code;
684 ReverseCode[ code ] = crtSpec;
687 strcpy( buf, sign );
688 strcat( buf, coef );
689 sscanf( buf, "%lf", &val );
691 switch( side ) {
692 case LHS: Stoich_Left[ crtSpec ][ EqnNr ] += val;
693 Stoich[ crtSpec ][ EqnNr ] -= val;
694 Reactive[ crtSpec ] = 1;
695 break;
696 case RHS: Stoich_Right[ crtSpec ][ EqnNr ] += val;
697 Stoich[ crtSpec ][ EqnNr ] += val;
698 break;
702 void AddLumpSpecies( char *spname )
704 int code;
706 code = FindSpecies( spname );
707 if ( code < 0 ) {
708 ScanError("Undefined species %s.", spname );
709 return;
712 /* ... */
716 void CheckLump( char *spname )
718 int code;
720 code = FindSpecies( spname );
721 if ( code < 0 ) {
722 ScanError("Undefined species %s.", spname );
723 return;
726 /* ... */
730 void AddLookAt( char *spname )
732 int code;
734 code = FindSpecies( spname );
735 if ( code < 0 ) {
736 ScanError("Undefined species %s.", spname );
737 return;
740 SpeciesTable[ code ].lookat = 1;
743 void LookAtAll()
745 int i;
747 for( i=0; i<SpeciesNr; i++ )
748 SpeciesTable[ i ].lookat = 1;
751 void AddMonitor( char *spname )
753 int code;
755 code = FindSpecies( spname );
756 if ( code >= 0 ) {
757 SpeciesTable[ code ].moni = 1;
758 return;
761 code = FindAtom( spname );
762 if ( code >= 0 ) {
763 AtomTable[ code ].masscheck = 1;
764 return;
767 ScanError("Undefined species or atom %s.", spname );
770 void AddTransport( char *spname )
772 int code;
774 code = FindSpecies( spname );
775 if ( code < 0 ) {
776 ScanError("Undefined species %s.", spname );
777 return;
780 SpeciesTable[ code ].trans = 1;
783 void TransportAll()
785 int i;
787 for( i=0; i<SpeciesNr; i++ )
788 SpeciesTable[ i ].trans = 1;
791 void AddUseFile( char *fname )
793 fileList[fileNr] = (char*)malloc(strlen(fname)+1);
794 strcpy(fileList[fileNr], fname);
795 fileNr++;
798 char * AppendString( char * s1, char * s2, int * maxlen, int addlen )
800 char * tmp;
802 *maxlen += addlen;
804 if( !s1 ) {
805 s1 = (char*)malloc( *maxlen );
806 *s1 = 0;
809 if( strlen( s1 ) + strlen( s2 ) >= *maxlen ) {
810 s1 = (char*)realloc( (void*)s1, *maxlen );
812 strcat( s1, s2 );
813 return s1;
816 char * ReplaceString( char * s1, char * s2, int * maxlen, int addlen )
818 char * tmp;
820 if( s1 ) free(s1);
822 *maxlen = strlen( s2 );
823 s1 = (char*)malloc( 1+*maxlen );
824 strcpy( s1, s2 );
826 return s1;
829 void AddInlineCode( char * ctx, char * s )
831 ICODE * c;
832 int i, key, type;
833 int totallength; /* mz_rs_20050607 */
835 c = NULL;
837 for( i = 0; i < INLINE_OPT; i++ )
838 if( EqNoCase( ctx, InlineKeys[i].kname ) ) {
839 key = InlineKeys[i].key;
840 c = &InlineCode[key];
841 type = InlineKeys[i].type;
842 break;
844 if( !c ) {
845 printf( "\n'%s': Unknown inline option (ignored)", ctx );
846 return;
849 /* mz_rs_20050607+ */
850 if (c->code)
851 totallength = strlen( c->code )+strlen( s );
852 else
853 totallength = strlen( s );
854 if (totallength>MAX_INLINE)
855 ScanError("\nInline code for %s is too long (%d>%d).\nIncrease MAX_INLINE in scan.h and recompile kpp!",
856 ctx, totallength, MAX_INLINE);
857 /* mz_rs_20050607- */
859 switch( type ) {
860 case APPEND: c->code = AppendString( c->code, s, &c->maxlen, MAX_INLINE );
861 break;
862 case REPLACE: c->code = ReplaceString( c->code, s, &c->maxlen, MAX_INLINE );
863 break;
867 int ParseEquationFile( char * filename )
869 int i,j;
870 int code;
872 for( i = 0; i < MAX_SPECIES; i++ ) {
873 ReverseCode[i] = NO_CODE;
874 Reactive[i] = 0;
876 for( i = 0; i < MAX_SPECIES; i++ ) {
877 for( j = 0; j < MAX_EQN; j++ ) {
878 Stoich_Left[i][j] = 0;
879 Stoich[i][j] = 0;
880 Stoich_Right[i][j] = 0;
883 for( i = 0; i < MAX_SPECIES; i++ ) {
884 SpeciesTable[ i ].nratoms = 0;
887 for( i = 0; i < INLINE_OPT; i++ ) {
888 InlineCode[i].code = NULL;
889 InlineCode[i].maxlen = 0;
892 EqnNr = 0;
893 SpcNr = 0;
895 DeclareAtom( "CANCEL" );
896 SetAtomType( "CANCEL", CANCEL_CHECK );
897 DeclareAtom( "IGNORE" );
898 SetAtomType( "IGNORE", NO_CHECK );
899 DeclareSpecies( DUMMY_SPC, "???" );
900 StoreSpecies( MAX_SPECIES-1, DUMMY_SPC, "HV" );
901 AddAtom( "CANCEL", "1" );
902 StoreSpecies( MAX_SPECIES-2, DUMMY_SPC, "PROD" );
904 code = Parser( filename );
906 return code;
909 void WRFConform()
911 useWRFConform = 1;
912 printf("\nKPP was told to generate WRF conform code");