source: palm/trunk/UTIL/chemistry/gasphase_preproc/kpp/src/scanner.c @ 4843

Last change on this file since 4843 was 4843, checked in by raasch, 16 months ago

local namelist parameter added to switch off the module although the respective module namelist appears in the namelist file, further copyright updates

File size: 19.7 KB
Line 
1/******************************************************************************
2
3  KPP - The Kinetic PreProcessor
4        Builds simulation code for chemical kinetic systems
5
6  Copyright (C) -2021 996 Valeriu Damian and Adrian Sandu
7  Copyright (C) -2021 005 Adrian Sandu
8
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.
13
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.
18
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.
23
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
29
30******************************************************************************/
31
32
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>
39
40int AtomNr    = 0;
41int SpeciesNr = 0;
42int EqnNr     = 0;
43int SpcNr     = 0;
44int VarNr     = 0;
45int VarActiveNr  = 0;
46int FixNr     = 0;
47int VarStartNr   = 0;
48int FixStartNr   = 0;
49
50
51int initNr = -1;
52int xNr = 0;
53int yNr = 0;
54int zNr = 0;
55
56int falseSpcNr = 0;
57
58ATOM_DEF AtomTable[ MAX_ATNR ];
59SPECIES_DEF SpeciesTable[ MAX_SPECIES ];
60CODE ReverseCode[ MAX_SPECIES ];
61CODE Code[ MAX_SPECIES ];
62KREACT kr[ MAX_EQN ];
63
64float** Stoich_Left;
65float** Stoich;
66float** Stoich_Right;
67int Reactive[ MAX_SPECIES ];
68
69INLINE_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" } 
93                          };
94
95int useAggregate   = 1;
96int useJacobian    = JAC_LU_ROW;
97int useJacSparse   = 1;
98int useHessian     = 1;
99int useStoicmat    = 1;
100int useDouble      = 1;
101int useReorder     = 1;
102int useMex         = 1;
103int useDummyindex  = 0;
104int useEqntags     = 0;
105int useLang        = F77_LANG;
106int useStochastic  = 0;
107/* if useValues=1 KPP replaces parameters like NVAR etc.
108       by their values in vector/matrix declarations */
109int useDeclareValues = 0; 
110
111char integrator[ MAX_PATH ] = "none";
112char driver[ MAX_PATH ] = "none";
113char runArgs[  MAX_PATH ] = "";
114
115/*  mz_rs_20050701+ */
116/* char varDefault[ MAX_IVAL ] = "1.E-8"; */
117/* char fixDefault[ MAX_IVAL ] = "1.E-8"; */
118/* double cfactor = 1.09E+10; */
119char varDefault[ MAX_IVAL ] = "0.";
120char fixDefault[ MAX_IVAL ] = "0.";
121double cfactor = 1.;
122/*  mz_rs_20050701- */
123
124ATOM crtAtoms[ MAX_ATOMS ];
125int crtAtomNr = 0;
126
127char *fileList[ MAX_FILES ];
128int fileNr = 0;
129
130double Abs( double x ) 
131{
132  return x > 0 ? x : -x;
133}
134
135void DefineInitializeNbr( char *cmd )
136{
137int n;
138
139  n = sscanf( cmd, "%d", &initNr);
140  if( n != 1 )
141    ScanError("Bad number of species to initialize <%s>", cmd);
142}
143
144void DefineXGrid( char *cmd )
145{
146int n;
147
148  xNr = 1;
149  n = sscanf( cmd, "%d", &xNr);
150  if( n != 1 )
151    ScanError("Bad X grid number <%s>", cmd);
152}
153
154void DefineYGrid( char *cmd )
155{
156int n;
157
158  yNr = 1;
159  n = sscanf( cmd, "%d", &yNr);
160  if( n != 1 )
161    ScanError("Bad Y grid number <%s>", cmd);
162}
163
164void DefineZGrid( char *cmd )
165{
166int n;
167
168  zNr = 1;
169  n = sscanf( cmd, "%d", &zNr);
170  if( n != 1 )
171    ScanError("Bad Z grid number <%s>", cmd);
172}
173
174void CmdFunction( char *cmd )
175{
176  if( EqNoCase( cmd, "AGGREGATE" ) ) {
177    useAggregate = 1;
178    return;
179  }
180  if( EqNoCase( cmd, "SPLIT" ) ) {
181    useAggregate = 0;
182    return;
183  }
184  ScanError("'%s': Unknown parameter for #FUNCTION [AGGREGATE|SPLIT]", cmd );
185}
186
187void CmdDeclareValues( char *cmd )
188{
189  if( EqNoCase( cmd, "SYMBOL" ) ) {
190    useDeclareValues = 0;
191    return;
192  }
193  if( EqNoCase( cmd, "VALUE" ) ) {
194    useDeclareValues = 1;
195    return;
196  }
197  ScanError("'%s': Unknown parameter for #DECLARE [SYMBOL|VALUE]", cmd );
198}
199
200void CmdJacobian( char *cmd )
201{
202  if( EqNoCase( cmd, "OFF" ) ) {
203    useJacobian = JAC_OFF;
204    useJacSparse = 0;
205    return;
206  }
207  if( EqNoCase( cmd, "FULL" ) ) {
208    useJacobian = JAC_FULL;
209    useJacSparse = 0;
210    return;
211  }
212  if( EqNoCase( cmd, "SPARSE_LU_ROW" ) ) {
213    useJacobian = JAC_LU_ROW;
214    useJacSparse = 1;
215    return;
216  }
217  if( EqNoCase( cmd, "SPARSE_ROW" ) ) {
218    useJacobian = JAC_ROW;
219    useJacSparse = 1;
220    return;
221  }
222  ScanError("'%s': Unknown parameter for #JACOBIAN [OFF|FULL|SPARSE_LU_ROW|SPARSE_ROW]", cmd );
223}
224
225void SparseData( char *cmd ) {
226  ScanError("Deprecated use of #SPARSEDATA %s: see #JACOBIAN for equivalent functionality", cmd );
227}
228
229void CmdHessian( char *cmd )
230{
231  if( EqNoCase( cmd, "OFF" ) ) {
232    useHessian = 0;
233    return;
234  }
235  if( EqNoCase( cmd, "ON" ) ) {
236    useHessian = 1;
237    return;
238  }
239  ScanError("'%s': Unknown parameter for #HESSIAN [ON|OFF]", cmd );
240}
241
242void CmdStoicmat( char *cmd )
243{
244  if( EqNoCase( cmd, "OFF" ) ) {
245    useStoicmat = 0;
246    return;
247  }
248  if( EqNoCase( cmd, "ON" ) ) {
249    useStoicmat = 1;
250    return;
251  }
252  ScanError("'%s': Unknown parameter for #STOICMAT [ON|OFF]", cmd );
253}
254
255void CmdDouble( char *cmd )
256{
257  if( EqNoCase( cmd, "OFF" ) ) {
258    useDouble = 0;
259    return;
260  }
261  if( EqNoCase( cmd, "ON" ) ) {
262    useDouble = 1;
263    return;
264  }
265  ScanError("'%s': Unknown parameter for #DOUBLE [ON|OFF]", cmd );
266}
267
268void CmdReorder( char *cmd )
269{
270  if( EqNoCase( cmd, "OFF" ) ) {
271    useReorder = 0;
272    return;
273  }
274  if( EqNoCase( cmd, "ON" ) ) {
275    useReorder = 1;
276    return;
277  }
278  ScanError("'%s': Unknown parameter for #REORDER [ON|OFF]", cmd );
279}
280
281void CmdMex( char *cmd )
282{
283  if( EqNoCase( cmd, "OFF" ) ) {
284    useMex = 0;
285    return;
286  }
287  if( EqNoCase( cmd, "ON" ) ) {
288    useMex = 1;
289    return;
290  }
291  ScanError("'%s': Unknown parameter for #MEX [ON|OFF]", cmd );
292}
293
294void CmdDummyindex( char *cmd )
295{
296  if( EqNoCase( cmd, "OFF" ) ) {
297    useDummyindex = 0;
298    return;
299  }
300  if( EqNoCase( cmd, "ON" ) ) {
301    useDummyindex = 1;
302    return;
303  }
304  ScanError("'%s': Unknown parameter for #DUMMYINDEX [ON|OFF]", cmd );
305}
306
307void CmdEqntags( char *cmd )
308{
309  if( EqNoCase( cmd, "OFF" ) ) {
310    useEqntags = 0;
311    return;
312  }
313  if( EqNoCase( cmd, "ON" ) ) {
314    useEqntags = 1;
315    return;
316  }
317  ScanError("'%s': Unknown parameter for #EQNTAGS [ON|OFF]", cmd );
318}
319
320void CmdUse( char *cmd )
321{
322  ScanError("Deprecated command '#USE %s';\nReplace with '#LANGUAGE %s'.",cmd,cmd );
323}
324
325
326void CmdLanguage( char *cmd )
327{
328  if( EqNoCase( cmd, "FORTRAN77" ) ) {
329    useLang = F77_LANG;
330    return;
331  }
332  if( EqNoCase( cmd, "FORTRAN" ) ) {
333    ScanWarning("Fortran version not specified in '#LANGUAGE %s'. Will use Fortran 77.", cmd);
334    useLang = F77_LANG;
335    return;
336  }
337  if( EqNoCase( cmd, "FORTRAN90" ) ) {
338    useLang = F90_LANG;
339    return;
340  }
341  if( EqNoCase( cmd, "MATLAB" ) ) {
342    useLang = MATLAB_LANG;
343    return;
344  }
345  if( EqNoCase( cmd, "C" ) ) {
346    useLang = C_LANG;
347    return;
348  }
349  ScanError("'%s': Unknown parameter for #LANGUAGE [Fortran77|Fortran90|C|Matlab]", cmd );
350}
351
352void CmdStochastic( char *cmd )
353{
354  if( EqNoCase( cmd, "ON" ) ) {
355    useStochastic = 1;
356    return;
357  }
358  if( EqNoCase( cmd, "OFF" ) ) {
359    useStochastic = 0;
360    return;
361  }
362  ScanError("'%s': Unknown parameter for #STOCHASTIC [OFF|ON]", cmd );
363}
364
365void CmdIntegrator( char *cmd )
366{
367  strcpy( integrator, cmd );
368}
369
370void CmdDriver( char *cmd )
371{
372  strcpy( driver, cmd );
373}
374
375void CmdRun( char *cmd )
376{
377  strcpy( runArgs, cmd );
378}
379
380int FindAtom( char *atname )
381{
382int i;
383 
384  for( i=0; i<AtomNr; i++ )
385    if( EqNoCase( AtomTable[ i ].name, atname ) ) {
386      return i;   
387    }
388  return -1;     
389}
390
391void DeclareAtom( char *atname )
392{
393int code;
394
395  code = FindAtom( atname );
396  if ( code >= 0 ) {
397    ScanError("Multiple declaration for atom %s.", atname );
398    return;
399  }
400  if( AtomNr >= MAX_ATNR ) {
401    Error("Too many atoms");
402    return;
403  }
404 
405  strcpy( AtomTable[ AtomNr ].name, atname );
406  AtomTable[ AtomNr ].check = NO_CHECK;
407  AtomTable[ AtomNr ].masscheck = 0;
408  AtomNr++;
409}
410
411void SetAtomType( char *atname, int type )
412{
413int code;
414
415  code = FindAtom( atname );
416  if ( code < 0 ) {
417    ScanError("Undefined atom %s.", atname );
418    return;
419  }
420  AtomTable[ code ].check = type;
421}
422
423void CheckAll()
424{
425int i;
426 
427  for( i=0; i<AtomNr; i++ ) {
428    if( AtomTable[ i ].check != CANCEL_CHECK )
429      AtomTable[ i ].check = DO_CHECK;
430  }   
431  SetAtomType( "IGNORE", NO_CHECK );
432}
433
434void AddAtom( char *atname, char *nr )
435{
436int code;
437
438  code = FindAtom( atname );
439  if ( code < 0 ) {
440    ScanError("Undefined atom %s.", atname );
441    return;
442  }
443  crtAtoms[ crtAtomNr ].code = (unsigned char)code;
444  crtAtoms[ crtAtomNr ].nr = (unsigned char)atoi(nr);
445  crtAtomNr++;
446}
447
448int FindSpecies( char *spname )
449{
450int i;
451 
452  for( i=0; i<SpeciesNr; i++ )
453    if( EqNoCase( SpeciesTable[ i ].name, spname ) ) {
454      return i;   
455    }
456  for( i=0; i<2; i++ )
457    if( EqNoCase( SpeciesTable[ MAX_SPECIES -1 - i ].name, spname ) ) {
458      return MAX_SPECIES -1 - i;   
459    }
460  return -1;     
461}
462
463void StoreSpecies( int index, int type, char *spname )
464{
465int i;
466
467  strcpy( SpeciesTable[ index ].name, spname );
468  SpeciesTable[ index ].type = type; 
469  *SpeciesTable[ index ].ival = '\0'; 
470  SpeciesTable[ index ].lookat = 0;
471  SpeciesTable[ index ].moni = 0;
472  SpeciesTable[ index ].trans = 0;
473  if( (SpeciesTable[ index ].nratoms == 0) || ( crtAtomNr > 0 ) ) {
474    SpeciesTable[ index ].nratoms = crtAtomNr;
475    for( i = 0; i < crtAtomNr; i++ )
476      SpeciesTable[ index ].atoms[i] = crtAtoms[i];
477  }
478  crtAtomNr = 0;
479}
480
481void DeclareSpecies( int type, char *spname )
482{
483int code;
484
485  code = FindSpecies( spname );
486  if ( code >= 0 ) {
487    ScanError("Multiple declaration for species %s.", spname );
488    return;
489  }
490  if( SpeciesNr >= MAX_SPECIES ) {
491    Error("Too many species");
492    return;
493  }
494  StoreSpecies( SpeciesNr, type, spname );
495  SpeciesNr++;
496}
497
498void SetSpcType( int type, char *spname )
499{
500int code;
501int i;
502
503  if( EqNoCase( spname, "VAR_SPEC" ) ) {
504    for( i = 0; i < SpeciesNr; i++ ) 
505      if( SpeciesTable[i].type == VAR_SPC ) 
506        SpeciesTable[i].type = type;
507    return;
508  }
509  if( EqNoCase( spname, "FIX_SPEC" ) ) {
510    for( i = 0; i < SpeciesNr; i++ ) 
511      if( SpeciesTable[i].type == FIX_SPC ) 
512        SpeciesTable[i].type = type;
513    return;
514  }
515  if( EqNoCase( spname, "ALL_SPEC" ) ) {
516    for( i = 0; i < SpeciesNr; i++ )
517        SpeciesTable[i].type = type;
518    return;
519  }
520
521  code = FindSpecies( spname );
522  if ( code < 0 ) {
523    ScanError("Undefined species %s.", spname );
524    return;
525  }
526  SpeciesTable[ code ].type = type; 
527}
528
529void AssignInitialValue( char *spname , char *spval )
530{
531int code; 
532double cf;
533 
534  if( EqNoCase( spname, "CFACTOR" ) ) {
535    code = sscanf( spval, "%lg", &cf );
536    if( code != 1 ) {
537      ScanWarning("Invalid CFACTOR value: %s", spval);
538      return;
539    }
540    cfactor = cf;
541    return;
542  }
543 
544  if( EqNoCase( spname, "VAR_SPEC" ) ) {
545    strcpy( varDefault, spval );
546    return;
547  }
548 
549 
550  if( EqNoCase( spname, "FIX_SPEC" ) ) {
551    strcpy( fixDefault, spval );
552    return;
553  }
554 
555  if( EqNoCase( spname, "ALL_SPEC" ) ) {
556    strcpy( varDefault, spval );
557    strcpy( fixDefault, spval );
558    return;
559  }
560 
561  code = FindSpecies( spname );
562  if ( code < 0 ) {
563    ScanError("Undefined species %s.", spname );
564    return; 
565  }     
566  strcpy( SpeciesTable[ code ].ival, spval ); 
567}
568
569void StoreEquationRate( char *rate, char *label )
570{
571double f;
572char buf[ MAX_K ];
573int n;
574KREACT *kreact;
575
576  kreact = &kr[ EqnNr ]; 
577  strcpy( kreact->label, label );
578  if( isPhoto ) {
579    kreact->type = PHOTO;
580    strcpy( kreact->val.st, rate );
581    isPhoto = 0;
582    return;
583  }
584  n = sscanf( rate, "%lf%s", &f, buf );
585  if ( n == 1 ) {
586    kreact->type = NUMBER;
587    kreact->val.f = f;
588    return;
589  }
590  kreact->type = EXPRESION;
591  strcpy( kreact->val.st, rate );
592  return;
593}
594
595void CheckEquation()
596{
597int i,j;
598int equal, index;
599double r1, r2;
600float atcnt[ MAX_ATNR ];
601int spc;
602SPECIES_DEF *sp;
603char errmsg[80];
604int err;
605
606  if( EqnNr >= MAX_EQN ) {
607    Error("Too many equations");
608    return;
609  }
610 
611  for( i = 0; i < AtomNr; i++ )
612    atcnt[i] = 0;
613   
614  for( spc = 0; spc < SpcNr; spc++ ) {
615    sp = &SpeciesTable[ Code[spc] ];
616    if( Stoich_Left[spc][EqnNr] != 0 ) {
617      for( i = 0; i < sp->nratoms; i++ ) 
618        atcnt[ sp->atoms[i].code ] += Stoich_Left[spc][EqnNr] * sp->atoms[i].nr;
619    }
620    if( Stoich_Right[spc][EqnNr] != 0 ) {
621      for( i = 0; i < sp->nratoms; i++ ) 
622        atcnt[ sp->atoms[i].code ] -= Stoich_Right[spc][EqnNr] * sp->atoms[i].nr; 
623    }
624  } 
625 
626  *errmsg = 0;
627  err = 0;
628 
629  for( i = 0; i < AtomNr; i++ ) {
630    if ( Abs( atcnt[i] ) > 1e-5 ) {
631      if ( AtomTable[i].check == CANCEL_CHECK ) {
632        err = 0;
633        break;
634      }
635      if ( AtomTable[i].check == NO_CHECK ) {
636        continue;
637      }
638      if ( AtomTable[i].check == DO_CHECK ) {
639        err = 1;
640        sprintf(errmsg, "%s %s", errmsg, AtomTable[i].name );
641        continue;
642      }
643    }
644  } 
645   
646  if ( err ) 
647    ScanWarning( "(eqn %d) Atom balance mismatch for:%s.", EqnNr+1, errmsg );   
648       
649  for( j = 0; j < SpcNr; j++ )
650    if( Stoich_Left[j][EqnNr] != 0 )
651      { index = j; break; }
652  for( i = 0; i < EqnNr; i++ ) {
653    equal = 1;
654    r1 = Stoich_Left[index][EqnNr];
655    r2 = Stoich_Left[index][i];
656    for( j = 0; j < SpcNr; j++ ) {
657      if( r1 * Stoich_Left[j][i] != r2 * Stoich_Left[j][EqnNr] )
658        { equal = 0; break; }
659      if( r1 * Stoich_Right[j][i] != r2 * Stoich_Right[j][EqnNr] )
660        { equal = 0; break; }
661    }
662    if ( equal ) {
663      if( r1 == r2 )
664        ScanError( "Duplicate equation: "
665                   " (eqn<%d> = eqn<%d> )", i+1, EqnNr+1 );
666      else
667        ScanError( "Linearly dependent equations: "
668                   "( %.0f eqn<%d> = %.0f eqn<%d> )",
669                   r1, i+1, r2, EqnNr+1 );
670      break;
671    }
672  }
673  EqnNr++;
674}
675
676void ProcessTerm( int side, char *sign, char *coef, char *spname  )
677{
678int code; 
679CODE crtSpec;
680double val;
681char buf[40];
682
683
684  code = FindSpecies( spname );
685  if ( code < 0 ) {
686    ScanError("Undefined species %s.", spname );
687    return;
688  }
689 
690  crtSpec = ReverseCode[ code ];
691
692  if(EqNoCase(spname,"HV")) isPhoto = 1;
693
694  if ( crtSpec == NO_CODE ) {
695    if( MAX_SPECIES - code <= 2 ) falseSpcNr++;
696    crtSpec = SpcNr++;
697    Code[ crtSpec ] = code;
698    ReverseCode[ code ] = crtSpec;
699  }
700 
701  strcpy( buf, sign ); 
702  strcat( buf, coef ); 
703  sscanf( buf, "%lf", &val );
704
705  switch( side ) {
706    case LHS: Stoich_Left[ crtSpec ][ EqnNr ] += val;
707              Stoich[ crtSpec ][ EqnNr ] -= val;
708              Reactive[ crtSpec ] = 1;
709              break;
710    case RHS: Stoich_Right[ crtSpec ][ EqnNr ] += val;
711              Stoich[ crtSpec ][ EqnNr ] += val;
712              break;
713  }
714}
715           
716void AddLumpSpecies( char *spname )
717{
718int code; 
719 
720  code = FindSpecies( spname );
721  if ( code < 0 ) {
722    ScanError("Undefined species %s.", spname );
723    return;
724  }
725
726  /* ... */               
727
728}
729
730void CheckLump( char *spname )
731{
732int code; 
733 
734  code = FindSpecies( spname );
735  if ( code < 0 ) {
736    ScanError("Undefined species %s.", spname );
737    return;
738  }
739
740  /* ... */               
741
742}
743
744void AddLookAt( char *spname )
745{
746int code; 
747 
748  code = FindSpecies( spname );
749  if ( code < 0 ) {
750    ScanError("Undefined species %s.", spname );
751    return;
752  }
753
754  SpeciesTable[ code ].lookat = 1;   
755}
756
757void LookAtAll()
758{
759int i;
760
761  for( i=0; i<SpeciesNr; i++ )
762    SpeciesTable[ i ].lookat = 1; 
763}
764
765void AddMonitor( char *spname )
766{
767int code; 
768 
769  code = FindSpecies( spname );
770  if ( code >= 0 ) {
771    SpeciesTable[ code ].moni = 1;
772    return;
773  } 
774 
775  code = FindAtom( spname );
776  if ( code >= 0 ) {
777    AtomTable[ code ].masscheck = 1;
778    return;
779  }
780   
781  ScanError("Undefined species or atom %s.", spname );
782}
783
784void AddTransport( char *spname )
785{
786int code; 
787 
788  code = FindSpecies( spname );
789  if ( code < 0 ) {
790    ScanError("Undefined species %s.", spname );
791    return;
792  }
793
794  SpeciesTable[ code ].trans = 1;   
795}
796
797void TransportAll()
798{
799int i;
800
801  for( i=0; i<SpeciesNr; i++ )
802    SpeciesTable[ i ].trans = 1; 
803}
804
805void AddUseFile( char *fname )
806{
807  fileList[fileNr] = (char*)malloc(strlen(fname)+1);
808  strcpy(fileList[fileNr], fname);
809  fileNr++;
810}
811
812char * AppendString( char * s1, char * s2, int * maxlen, int addlen ) 
813{
814char * tmp;
815
816  *maxlen += addlen;
817
818  if( !s1 ) {
819    s1 = (char*)malloc( *maxlen );
820    *s1 = 0;
821  }   
822 
823  if( strlen( s1 ) + strlen( s2 ) >= *maxlen ) {
824    s1 = (char*)realloc( (void*)s1, *maxlen );
825  }
826  strcat( s1, s2 ); 
827  return s1;
828}
829
830char * ReplaceString( char * s1, char * s2, int * maxlen, int addlen ) 
831{
832char * tmp;
833
834  if( s1 ) free(s1);
835
836  *maxlen = strlen( s2 );
837  s1 = (char*)malloc( 1+*maxlen );
838  strcpy( s1, s2 );
839
840  return s1;
841}
842
843void AddInlineCode( char * ctx, char * s )
844{
845ICODE * c;
846int i, key, type;
847int totallength; /* mz_rs_20050607 */
848 
849  c = NULL;
850 
851  for( i = 0; i < INLINE_OPT; i++ ) 
852    if( EqNoCase( ctx, InlineKeys[i].kname ) ) {
853      key = InlineKeys[i].key;
854      c = &InlineCode[key];
855      type = InlineKeys[i].type;
856      break;
857    }
858  if( !c ) {
859    printf( "\n'%s': Unknown inline option (ignored)", ctx );
860    return;
861  }
862
863  /*  mz_rs_20050607+ */
864  if (c->code) 
865    totallength = strlen( c->code )+strlen( s );
866  else
867    totallength = strlen( s );
868  if (totallength>MAX_INLINE)
869    ScanError("\nInline code for %s is too long (%d>%d).\nIncrease MAX_INLINE in scan.h and recompile kpp!", 
870              ctx, totallength, MAX_INLINE);   
871  /*  mz_rs_20050607- */
872
873  switch( type ) {
874    case APPEND:  c->code = AppendString( c->code, s, &c->maxlen, MAX_INLINE );
875                  break;
876    case REPLACE: c->code = ReplaceString( c->code, s, &c->maxlen, MAX_INLINE );
877                  break;
878  }
879}
880
881int ParseEquationFile( char * filename )
882{
883int i,j;
884int code;
885
886  for( i = 0; i < MAX_SPECIES; i++ ) {
887    ReverseCode[i] = NO_CODE;
888    Reactive[i] = 0;
889  }
890  for( i = 0; i < MAX_SPECIES; i++ ) {
891    for( j = 0; j < MAX_EQN; j++ ) {
892      Stoich_Left[i][j] = 0;
893      Stoich[i][j] = 0;
894      Stoich_Right[i][j] = 0;
895    }
896  }
897  for( i = 0; i < MAX_SPECIES; i++ ) {
898    SpeciesTable[ i ].nratoms = 0;
899  }
900 
901  for( i = 0; i < INLINE_OPT; i++ ) {
902    InlineCode[i].code = NULL;
903    InlineCode[i].maxlen = 0;
904  } 
905 
906  EqnNr = 0;
907  SpcNr = 0;
908 
909  DeclareAtom( "CANCEL" );   
910  SetAtomType( "CANCEL", CANCEL_CHECK );
911  DeclareAtom( "IGNORE" );   
912  SetAtomType( "IGNORE", NO_CHECK );
913  DeclareSpecies( DUMMY_SPC, "???" );
914  StoreSpecies( MAX_SPECIES-1, DUMMY_SPC, "HV" );
915  AddAtom( "CANCEL", "1" );
916  StoreSpecies( MAX_SPECIES-2, DUMMY_SPC, "PROD" );
917
918  code = Parser( filename );
919
920  return code;
921}
922
Note: See TracBrowser for help on using the repository browser.