added README_changes.txt
[wrffire.git] / wrfv2_fire / chem / KPP / kpp / kpp-2.1 / src.org / scanner.c
blob73278a295b706f801cf9c40a446dd0dd55b75e65
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;
108 char integrator[ MAX_PATH ] = "none";
109 char driver[ MAX_PATH ] = "none";
110 char runArgs[ MAX_PATH ] = "";
112 /* mz_rs_20050701+ */
113 /* char varDefault[ MAX_IVAL ] = "1.E-8"; */
114 /* char fixDefault[ MAX_IVAL ] = "1.E-8"; */
115 /* double cfactor = 1.09E+10; */
116 char varDefault[ MAX_IVAL ] = "0.";
117 char fixDefault[ MAX_IVAL ] = "0.";
118 double cfactor = 1.;
119 /* mz_rs_20050701- */
121 ATOM crtAtoms[ MAX_ATOMS ];
122 int crtAtomNr = 0;
124 char *fileList[ MAX_FILES ];
125 int fileNr = 0;
127 double Abs( double x )
129 return x > 0 ? x : -x;
132 void DefineInitializeNbr( char *cmd )
134 int n;
136 n = sscanf( cmd, "%d", &initNr);
137 if( n != 1 )
138 ScanError("Bad number of species to initialize <%s>", cmd);
141 void DefineXGrid( char *cmd )
143 int n;
145 xNr = 1;
146 n = sscanf( cmd, "%d", &xNr);
147 if( n != 1 )
148 ScanError("Bad X grid number <%s>", cmd);
151 void DefineYGrid( char *cmd )
153 int n;
155 yNr = 1;
156 n = sscanf( cmd, "%d", &yNr);
157 if( n != 1 )
158 ScanError("Bad Y grid number <%s>", cmd);
161 void DefineZGrid( char *cmd )
163 int n;
165 zNr = 1;
166 n = sscanf( cmd, "%d", &zNr);
167 if( n != 1 )
168 ScanError("Bad Z grid number <%s>", cmd);
171 void CmdFunction( char *cmd )
173 if( EqNoCase( cmd, "AGGREGATE" ) ) {
174 useAggregate = 1;
175 return;
177 if( EqNoCase( cmd, "SPLIT" ) ) {
178 useAggregate = 0;
179 return;
181 ScanError("'%s': Unknown parameter for #FUNCTION [AGGREGATE|SPLIT]", cmd );
184 void CmdJacobian( char *cmd )
186 if( EqNoCase( cmd, "OFF" ) ) {
187 useJacobian = JAC_OFF;
188 useJacSparse = 0;
189 return;
191 if( EqNoCase( cmd, "FULL" ) ) {
192 useJacobian = JAC_FULL;
193 useJacSparse = 0;
194 return;
196 if( EqNoCase( cmd, "SPARSE_LU_ROW" ) ) {
197 useJacobian = JAC_LU_ROW;
198 useJacSparse = 1;
199 return;
201 if( EqNoCase( cmd, "SPARSE_ROW" ) ) {
202 useJacobian = JAC_ROW;
203 useJacSparse = 1;
204 return;
206 ScanError("'%s': Unknown parameter for #JACOBIAN [OFF|FULL|SPARSE_LU_ROW|SPARSE_ROW]", cmd );
209 void SparseData( char *cmd ) {
210 ScanError("Deprecated use of #SPARSEDATA %s: see #JACOBIAN for equivalent functionality", cmd );
213 void CmdHessian( char *cmd )
215 if( EqNoCase( cmd, "OFF" ) ) {
216 useHessian = 0;
217 return;
219 if( EqNoCase( cmd, "ON" ) ) {
220 useHessian = 1;
221 return;
223 ScanError("'%s': Unknown parameter for #HESSIAN [ON|OFF]", cmd );
226 void CmdStoicmat( char *cmd )
228 if( EqNoCase( cmd, "OFF" ) ) {
229 useStoicmat = 0;
230 return;
232 if( EqNoCase( cmd, "ON" ) ) {
233 useStoicmat = 1;
234 return;
236 ScanError("'%s': Unknown parameter for #STOICMAT [ON|OFF]", cmd );
239 void CmdDouble( char *cmd )
241 if( EqNoCase( cmd, "OFF" ) ) {
242 useDouble = 0;
243 return;
245 if( EqNoCase( cmd, "ON" ) ) {
246 useDouble = 1;
247 return;
249 ScanError("'%s': Unknown parameter for #DOUBLE [ON|OFF]", cmd );
252 void CmdReorder( char *cmd )
254 if( EqNoCase( cmd, "OFF" ) ) {
255 useReorder = 0;
256 return;
258 if( EqNoCase( cmd, "ON" ) ) {
259 useReorder = 1;
260 return;
262 ScanError("'%s': Unknown parameter for #REORDER [ON|OFF]", cmd );
265 void CmdMex( char *cmd )
267 if( EqNoCase( cmd, "OFF" ) ) {
268 useMex = 0;
269 return;
271 if( EqNoCase( cmd, "ON" ) ) {
272 useMex = 1;
273 return;
275 ScanError("'%s': Unknown parameter for #MEX [ON|OFF]", cmd );
278 void CmdDummyindex( char *cmd )
280 if( EqNoCase( cmd, "OFF" ) ) {
281 useDummyindex = 0;
282 return;
284 if( EqNoCase( cmd, "ON" ) ) {
285 useDummyindex = 1;
286 return;
288 ScanError("'%s': Unknown parameter for #DUMMYINDEX [ON|OFF]", cmd );
291 void CmdEqntags( char *cmd )
293 if( EqNoCase( cmd, "OFF" ) ) {
294 useEqntags = 0;
295 return;
297 if( EqNoCase( cmd, "ON" ) ) {
298 useEqntags = 1;
299 return;
301 ScanError("'%s': Unknown parameter for #EQNTAGS [ON|OFF]", cmd );
304 void CmdUse( char *cmd )
306 ScanError("Deprecated command '#USE %s';\nReplace with '#LANGUAGE %s'.",cmd,cmd );
310 void CmdLanguage( char *cmd )
312 if( EqNoCase( cmd, "FORTRAN77" ) ) {
313 useLang = F77_LANG;
314 return;
316 if( EqNoCase( cmd, "FORTRAN" ) ) {
317 ScanWarning("Fortran version not specified in '#LANGUAGE %s'. Will use Fortran 77.", cmd);
318 useLang = F77_LANG;
319 return;
321 if( EqNoCase( cmd, "FORTRAN90" ) ) {
322 useLang = F90_LANG;
323 return;
325 if( EqNoCase( cmd, "MATLAB" ) ) {
326 useLang = MATLAB_LANG;
327 return;
329 if( EqNoCase( cmd, "C" ) ) {
330 useLang = C_LANG;
331 return;
333 ScanError("'%s': Unknown parameter for #LANGUAGE [Fortran77|Fortran90|C|Matlab]", cmd );
336 void CmdStochastic( char *cmd )
338 if( EqNoCase( cmd, "ON" ) ) {
339 useStochastic = 1;
340 return;
342 if( EqNoCase( cmd, "OFF" ) ) {
343 useStochastic = 0;
344 return;
346 ScanError("'%s': Unknown parameter for #STOCHASTIC [OFF|ON]", cmd );
349 void CmdIntegrator( char *cmd )
351 strcpy( integrator, cmd );
354 void CmdDriver( char *cmd )
356 strcpy( driver, cmd );
359 void CmdRun( char *cmd )
361 strcpy( runArgs, cmd );
364 int FindAtom( char *atname )
366 int i;
368 for( i=0; i<AtomNr; i++ )
369 if( EqNoCase( AtomTable[ i ].name, atname ) ) {
370 return i;
372 return -1;
375 void DeclareAtom( char *atname )
377 int code;
379 code = FindAtom( atname );
380 if ( code >= 0 ) {
381 ScanError("Multiple declaration for atom %s.", atname );
382 return;
384 if( AtomNr >= MAX_ATNR ) {
385 Error("Too many atoms");
386 return;
389 strcpy( AtomTable[ AtomNr ].name, atname );
390 AtomTable[ AtomNr ].check = NO_CHECK;
391 AtomTable[ AtomNr ].masscheck = 0;
392 AtomNr++;
395 void SetAtomType( char *atname, int type )
397 int code;
399 code = FindAtom( atname );
400 if ( code < 0 ) {
401 ScanError("Undefined atom %s.", atname );
402 return;
404 AtomTable[ code ].check = type;
407 void CheckAll()
409 int i;
411 for( i=0; i<AtomNr; i++ ) {
412 if( AtomTable[ i ].check != CANCEL_CHECK )
413 AtomTable[ i ].check = DO_CHECK;
415 SetAtomType( "IGNORE", NO_CHECK );
418 void AddAtom( char *atname, char *nr )
420 int code;
422 code = FindAtom( atname );
423 if ( code < 0 ) {
424 ScanError("Undefined atom %s.", atname );
425 return;
427 crtAtoms[ crtAtomNr ].code = (unsigned char)code;
428 crtAtoms[ crtAtomNr ].nr = (unsigned char)atoi(nr);
429 crtAtomNr++;
432 int FindSpecies( char *spname )
434 int i;
436 for( i=0; i<SpeciesNr; i++ )
437 if( EqNoCase( SpeciesTable[ i ].name, spname ) ) {
438 return i;
440 for( i=0; i<2; i++ )
441 if( EqNoCase( SpeciesTable[ MAX_SPECIES -1 - i ].name, spname ) ) {
442 return MAX_SPECIES -1 - i;
444 return -1;
447 void StoreSpecies( int index, int type, char *spname )
449 int i;
451 strcpy( SpeciesTable[ index ].name, spname );
452 SpeciesTable[ index ].type = type;
453 *SpeciesTable[ index ].ival = '\0';
454 SpeciesTable[ index ].lookat = 0;
455 SpeciesTable[ index ].moni = 0;
456 SpeciesTable[ index ].trans = 0;
457 if( (SpeciesTable[ index ].nratoms == 0) || ( crtAtomNr > 0 ) ) {
458 SpeciesTable[ index ].nratoms = crtAtomNr;
459 for( i = 0; i < crtAtomNr; i++ )
460 SpeciesTable[ index ].atoms[i] = crtAtoms[i];
462 crtAtomNr = 0;
465 void DeclareSpecies( int type, char *spname )
467 int code;
469 code = FindSpecies( spname );
470 if ( code >= 0 ) {
471 ScanError("Multiple declaration for species %s.", spname );
472 return;
474 if( SpeciesNr >= MAX_SPECIES ) {
475 Error("Too many species");
476 return;
478 StoreSpecies( SpeciesNr, type, spname );
479 SpeciesNr++;
482 void SetSpcType( int type, char *spname )
484 int code;
485 int i;
487 if( EqNoCase( spname, "VAR_SPEC" ) ) {
488 for( i = 0; i < SpeciesNr; i++ )
489 if( SpeciesTable[i].type == VAR_SPC )
490 SpeciesTable[i].type = type;
491 return;
493 if( EqNoCase( spname, "FIX_SPEC" ) ) {
494 for( i = 0; i < SpeciesNr; i++ )
495 if( SpeciesTable[i].type == FIX_SPC )
496 SpeciesTable[i].type = type;
497 return;
499 if( EqNoCase( spname, "ALL_SPEC" ) ) {
500 for( i = 0; i < SpeciesNr; i++ )
501 SpeciesTable[i].type = type;
502 return;
505 code = FindSpecies( spname );
506 if ( code < 0 ) {
507 ScanError("Undefined species %s.", spname );
508 return;
510 SpeciesTable[ code ].type = type;
513 void AssignInitialValue( char *spname , char *spval )
515 int code;
516 double cf;
518 if( EqNoCase( spname, "CFACTOR" ) ) {
519 code = sscanf( spval, "%lg", &cf );
520 if( code != 1 ) {
521 ScanWarning("Invalid CFACTOR value: %s", spval);
522 return;
524 cfactor = cf;
525 return;
528 if( EqNoCase( spname, "VAR_SPEC" ) ) {
529 strcpy( varDefault, spval );
530 return;
534 if( EqNoCase( spname, "FIX_SPEC" ) ) {
535 strcpy( fixDefault, spval );
536 return;
539 if( EqNoCase( spname, "ALL_SPEC" ) ) {
540 strcpy( varDefault, spval );
541 strcpy( fixDefault, spval );
542 return;
545 code = FindSpecies( spname );
546 if ( code < 0 ) {
547 ScanError("Undefined species %s.", spname );
548 return;
550 strcpy( SpeciesTable[ code ].ival, spval );
553 void StoreEquationRate( char *rate, char *label )
555 double f;
556 char buf[ MAX_K ];
557 int n;
558 KREACT *kreact;
560 kreact = &kr[ EqnNr ];
561 strcpy( kreact->label, label );
562 if( isPhoto ) {
563 kreact->type = PHOTO;
564 strcpy( kreact->val.st, rate );
565 isPhoto = 0;
566 return;
568 n = sscanf( rate, "%lf%s", &f, buf );
569 if ( n == 1 ) {
570 kreact->type = NUMBER;
571 kreact->val.f = f;
572 return;
574 kreact->type = EXPRESION;
575 strcpy( kreact->val.st, rate );
576 return;
579 void CheckEquation()
581 int i,j;
582 int equal, index;
583 double r1, r2;
584 float atcnt[ MAX_ATNR ];
585 int spc;
586 SPECIES_DEF *sp;
587 char errmsg[80];
588 int err;
590 if( EqnNr >= MAX_EQN ) {
591 Error("Too many equations");
592 return;
595 for( i = 0; i < AtomNr; i++ )
596 atcnt[i] = 0;
598 for( spc = 0; spc < SpcNr; spc++ ) {
599 sp = &SpeciesTable[ Code[spc] ];
600 if( Stoich_Left[spc][EqnNr] != 0 ) {
601 for( i = 0; i < sp->nratoms; i++ )
602 atcnt[ sp->atoms[i].code ] += Stoich_Left[spc][EqnNr] * sp->atoms[i].nr;
604 if( Stoich_Right[spc][EqnNr] != 0 ) {
605 for( i = 0; i < sp->nratoms; i++ )
606 atcnt[ sp->atoms[i].code ] -= Stoich_Right[spc][EqnNr] * sp->atoms[i].nr;
610 *errmsg = 0;
611 err = 0;
613 for( i = 0; i < AtomNr; i++ ) {
614 if ( Abs( atcnt[i] ) > 1e-5 ) {
615 if ( AtomTable[i].check == CANCEL_CHECK ) {
616 err = 0;
617 break;
619 if ( AtomTable[i].check == NO_CHECK ) {
620 continue;
622 if ( AtomTable[i].check == DO_CHECK ) {
623 err = 1;
624 sprintf(errmsg, "%s %s", errmsg, AtomTable[i].name );
625 continue;
630 if ( err )
631 ScanWarning( "(eqn %d) Atom balance mismatch for:%s.", EqnNr+1, errmsg );
633 for( j = 0; j < SpcNr; j++ )
634 if( Stoich_Left[j][EqnNr] != 0 )
635 { index = j; break; }
636 for( i = 0; i < EqnNr; i++ ) {
637 equal = 1;
638 r1 = Stoich_Left[index][EqnNr];
639 r2 = Stoich_Left[index][i];
640 for( j = 0; j < SpcNr; j++ ) {
641 if( r1 * Stoich_Left[j][i] != r2 * Stoich_Left[j][EqnNr] )
642 { equal = 0; break; }
643 if( r1 * Stoich_Right[j][i] != r2 * Stoich_Right[j][EqnNr] )
644 { equal = 0; break; }
646 if ( equal ) {
647 if( r1 == r2 )
648 ScanError( "Duplicate equation: "
649 " (eqn<%d> = eqn<%d> )", i+1, EqnNr+1 );
650 else
651 ScanError( "Linearly dependent equations: "
652 "( %.0f eqn<%d> = %.0f eqn<%d> )",
653 r1, i+1, r2, EqnNr+1 );
654 break;
657 EqnNr++;
660 void ProcessTerm( int side, char *sign, char *coef, char *spname )
662 int code;
663 CODE crtSpec;
664 double val;
665 char buf[40];
668 code = FindSpecies( spname );
669 if ( code < 0 ) {
670 ScanError("Undefined species %s.", spname );
671 return;
674 crtSpec = ReverseCode[ code ];
676 if(EqNoCase(spname,"HV")) isPhoto = 1;
678 if ( crtSpec == NO_CODE ) {
679 if( MAX_SPECIES - code <= 2 ) falseSpcNr++;
680 crtSpec = SpcNr++;
681 Code[ crtSpec ] = code;
682 ReverseCode[ code ] = crtSpec;
685 strcpy( buf, sign );
686 strcat( buf, coef );
687 sscanf( buf, "%lf", &val );
689 switch( side ) {
690 case LHS: Stoich_Left[ crtSpec ][ EqnNr ] += val;
691 Stoich[ crtSpec ][ EqnNr ] -= val;
692 Reactive[ crtSpec ] = 1;
693 break;
694 case RHS: Stoich_Right[ crtSpec ][ EqnNr ] += val;
695 Stoich[ crtSpec ][ EqnNr ] += val;
696 break;
700 void AddLumpSpecies( char *spname )
702 int code;
704 code = FindSpecies( spname );
705 if ( code < 0 ) {
706 ScanError("Undefined species %s.", spname );
707 return;
710 /* ... */
714 void CheckLump( char *spname )
716 int code;
718 code = FindSpecies( spname );
719 if ( code < 0 ) {
720 ScanError("Undefined species %s.", spname );
721 return;
724 /* ... */
728 void AddLookAt( char *spname )
730 int code;
732 code = FindSpecies( spname );
733 if ( code < 0 ) {
734 ScanError("Undefined species %s.", spname );
735 return;
738 SpeciesTable[ code ].lookat = 1;
741 void LookAtAll()
743 int i;
745 for( i=0; i<SpeciesNr; i++ )
746 SpeciesTable[ i ].lookat = 1;
749 void AddMonitor( char *spname )
751 int code;
753 code = FindSpecies( spname );
754 if ( code >= 0 ) {
755 SpeciesTable[ code ].moni = 1;
756 return;
759 code = FindAtom( spname );
760 if ( code >= 0 ) {
761 AtomTable[ code ].masscheck = 1;
762 return;
765 ScanError("Undefined species or atom %s.", spname );
768 void AddTransport( char *spname )
770 int code;
772 code = FindSpecies( spname );
773 if ( code < 0 ) {
774 ScanError("Undefined species %s.", spname );
775 return;
778 SpeciesTable[ code ].trans = 1;
781 void TransportAll()
783 int i;
785 for( i=0; i<SpeciesNr; i++ )
786 SpeciesTable[ i ].trans = 1;
789 void AddUseFile( char *fname )
791 fileList[fileNr] = (char*)malloc(strlen(fname)+1);
792 strcpy(fileList[fileNr], fname);
793 fileNr++;
796 char * AppendString( char * s1, char * s2, int * maxlen, int addlen )
798 char * tmp;
800 *maxlen += addlen;
802 if( !s1 ) {
803 s1 = (char*)malloc( *maxlen );
804 *s1 = 0;
807 if( strlen( s1 ) + strlen( s2 ) >= *maxlen ) {
808 s1 = (char*)realloc( (void*)s1, *maxlen );
810 strcat( s1, s2 );
811 return s1;
814 char * ReplaceString( char * s1, char * s2, int * maxlen, int addlen )
816 char * tmp;
818 if( s1 ) free(s1);
820 *maxlen = strlen( s2 );
821 s1 = (char*)malloc( 1+*maxlen );
822 strcpy( s1, s2 );
824 return s1;
827 void AddInlineCode( char * ctx, char * s )
829 ICODE * c;
830 int i, key, type;
831 int totallength; /* mz_rs_20050607 */
833 c = NULL;
835 for( i = 0; i < INLINE_OPT; i++ )
836 if( EqNoCase( ctx, InlineKeys[i].kname ) ) {
837 key = InlineKeys[i].key;
838 c = &InlineCode[key];
839 type = InlineKeys[i].type;
840 break;
842 if( !c ) {
843 printf( "\n'%s': Unknown inline option (ignored)", ctx );
844 return;
847 /* mz_rs_20050607+ */
848 if (c->code)
849 totallength = strlen( c->code )+strlen( s );
850 else
851 totallength = strlen( s );
852 if (totallength>MAX_INLINE)
853 ScanError("\nInline code for %s is too long (%d>%d).\nIncrease MAX_INLINE in scan.h and recompile kpp!",
854 ctx, totallength, MAX_INLINE);
855 /* mz_rs_20050607- */
857 switch( type ) {
858 case APPEND: c->code = AppendString( c->code, s, &c->maxlen, MAX_INLINE );
859 break;
860 case REPLACE: c->code = ReplaceString( c->code, s, &c->maxlen, MAX_INLINE );
861 break;
865 int ParseEquationFile( char * filename )
867 int i,j;
868 int code;
870 for( i = 0; i < MAX_SPECIES; i++ ) {
871 ReverseCode[i] = NO_CODE;
872 Reactive[i] = 0;
874 for( i = 0; i < MAX_SPECIES; i++ ) {
875 for( j = 0; j < MAX_EQN; j++ ) {
876 Stoich_Left[i][j] = 0;
877 Stoich[i][j] = 0;
878 Stoich_Right[i][j] = 0;
881 for( i = 0; i < MAX_SPECIES; i++ ) {
882 SpeciesTable[ i ].nratoms = 0;
885 for( i = 0; i < INLINE_OPT; i++ ) {
886 InlineCode[i].code = NULL;
887 InlineCode[i].maxlen = 0;
890 EqnNr = 0;
891 SpcNr = 0;
893 DeclareAtom( "CANCEL" );
894 SetAtomType( "CANCEL", CANCEL_CHECK );
895 DeclareAtom( "IGNORE" );
896 SetAtomType( "IGNORE", NO_CHECK );
897 DeclareSpecies( DUMMY_SPC, "???" );
898 StoreSpecies( MAX_SPECIES-1, DUMMY_SPC, "HV" );
899 AddAtom( "CANCEL", "1" );
900 StoreSpecies( MAX_SPECIES-2, DUMMY_SPC, "PROD" );
902 code = Parser( filename );
904 return code;