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
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.
25 Computer Science Department
26 Virginia Polytechnic Institute and State University
28 E-mail: sandu@cs.vt.edu
30 ******************************************************************************/
39 /* NONE, ADD, SUB, MUL, DIV, POW, CONST, ELM, VELM, MELM, EELM */
40 int PRI
[] = { 10, 1, 1, 2, 2, 3, 10, 10, 10, 10, 10 };
42 void (*WriteElm
)( NODE
*n
);
43 void (*WriteSymbol
)( int op
);
44 void (*WriteAssign
)( char* lval
, char* rval
);
45 void (*WriteComment
)( char *fmt
, ... );
46 void (*Declare
)( int v
);
47 void (*ExternDeclare
)( int v
);
48 void (*GlobalDeclare
)( int v
);
49 void (*InitDeclare
)( int var
, int nv
, void * values
);
50 void (*DeclareConstant
)( int v
, char *val
);
51 void (*FunctionStart
)( int f
, int *vars
);
52 void (*FunctionPrototipe
)( int f
, ... );
53 void (*FunctionBegin
)( int f
, ... );
54 void (*FunctionEnd
)( int f
);
62 VARIABLE cnst
= { "", CONST
, REAL
, 0, 0 };
63 VARIABLE expr
= { "", EELM
, 0, 0, 0 };
64 VARIABLE
*varTable
[ MAX_VAR
] = { &cnst
, &expr
};
66 int IsConst( NODE
*n
, float val
);
67 NODE
* BinaryOp( int op
, NODE
*n1
, NODE
*n2
);
68 int NodeCmp( NODE
*n1
, NODE
*n2
);
69 NODE
* NodeCopy( NODE
*n1
);
70 void WriteNode( NODE
*n
);
71 void WriteOp( int op
);
72 void ExpandElm( NODE
* n
);
73 int ExpandNode( NODE
*n
, int lastop
);
74 NODE
* LookUpSubst( NODE
*n
);
76 FILE * param_headerFile
= 0;
77 FILE * initFile
= 0; /* mz_rs_20050117 */
78 FILE * driverFile
= 0;
79 FILE * integratorFile
= 0;
80 FILE * linalgFile
= 0;
81 FILE * functionFile
= 0;
82 FILE * jacobianFile
= 0;
84 FILE * stoichiomFile
= 0;
86 FILE * sparse_dataFile
= 0;
87 FILE * sparse_jacFile
= 0;
88 FILE * sparse_hessFile
= 0;
89 FILE * sparse_stoicmFile
= 0;
90 FILE * stochasticFile
= 0;
91 FILE * global_dataFile
= 0;
92 FILE * hessianFile
= 0;
95 FILE * monitorFile
= 0;
96 FILE * mex_funFile
= 0;
97 FILE * mex_jacFile
= 0;
98 FILE * mex_hessFile
= 0;
99 FILE * wrf_UpdateRconstFile
= 0;
106 FILE * UseFile( FILE * file
)
110 printf("\n\nKPP Warning (internal): trying to UseFile NULL file pointer!\n");
117 void OpenFile( FILE **fpp
, char *name
, char * ext
, char * identity
)
125 sprintf( bufname
, "%s%s", name
, ext
);
126 if( *fpp
) fclose( *fpp
);
127 *fpp
= fopen( bufname
, "w" );
129 FatalError(3,"%s: Can't create file", bufname
);
135 WriteComment("%s",identity
);
137 WriteComment("Generated by KPP-%s symbolic chemistry Kinetics PreProcessor",
139 WriteComment(" (http://www.cs.vt.edu/~asandu/Software/KPP)");
140 WriteComment("KPP is distributed under GPL, the general public licence");
141 WriteComment(" (http://www.gnu.org/copyleft/gpl.html)");
142 WriteComment("(C) 1995-1997, V. Damian & A. Sandu, CGRER, Univ. Iowa" );
143 WriteComment("(C) 1997-2005, A. Sandu, Michigan Tech, Virginia Tech" );
144 WriteComment(" With important contributions from:" );
145 WriteComment(" M. Damian, Villanova University, USA");
146 WriteComment(" R. Sander, Max-Planck Institute for Chemistry, Mainz, Germany");
148 WriteComment("%-20s : %s", "File", bufname
);
149 strcpy( buf
, ctime( &t
) );
150 buf
[ (int)strlen(buf
) - 1 ] = 0;
151 WriteComment("%-20s : %s", "Time", buf
);
152 WriteComment("%-20s : %s", "Working directory", getcwd(buf
, 200) );
153 WriteComment("%-20s : %s", "Equation file", eqFileName
);
154 WriteComment("%-20s : %s", "Output root filename", rootFileName
);
158 /* Include Headers in .c Files, except Makefile */
159 blength
= strlen(bufname
);
160 if ( (bufname
[blength
-2]=='.')&&(bufname
[blength
-1]=='c') ) {
161 C_Inline("#include <stdio.h>");
162 C_Inline("#include <stdlib.h>");
163 C_Inline("#include <math.h>");
164 C_Inline("#include <string.h>");
165 C_Inline("#include \"%s_Parameters.h\"", rootFileName
);
166 C_Inline("#include \"%s_Global.h\"", rootFileName
);
168 C_Inline("#include \"%s_Sparse.h\"", rootFileName
);
175 *(outBuffer
-1) |= 0x80;
178 void bprintf( char *fmt
, ... )
183 Va_start( args
, fmt
);
184 vsprintf( outBuffer
, fmt
, args
);
186 outBuffer
+= strlen( outBuffer
);
196 fprintf( currentFile
, outBuf
);
201 void FlushThisBuf( char * buf
)
208 fprintf( currentFile
, buf
);
214 WriteComment("****************************************************************");
216 WriteComment("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
219 void NewLines( int n
)
227 void IncludeFile( char * fname
)
231 char line
[ MAX_LINE
];
234 fp
= fopen( fname
, "r" );
236 FatalError(3,"%s: Can't read file", fname
);
242 fgets( line
, MAX_LINE
, fp
);
243 fputs( line
, currentFile
);
249 void IncludeCode( char* fmt
, ... )
254 static char tmpfile
[] = "kppfile.tmp";
257 Va_start( args
, fmt
);
258 vsprintf( buf
, fmt
, args
);
262 case F77_LANG
: sprintf( buf
, "%s.f", buf
);
264 case F90_LANG
: sprintf( buf
, "%s.f90", buf
);
266 case C_LANG
: sprintf( buf
, "%s.c", buf
);
268 case MATLAB_LANG
: sprintf( buf
, "%s.m", buf
);
270 default: printf("\n Language '%d' not implemented!\n",useLang
);
273 fp
= fopen( buf
, "r" );
275 FatalError(3,"%s: Can't read file", buf
);
278 strcpy( cmd
, "sed " );
280 sprintf( cmd
, "%s -e 's/KPP_ROOT/%s/g'", cmd
, rootFileName
);
281 sprintf( cmd
, "%s -e 's/KPP_NVAR/%d/g'", cmd
, VarNr
);
282 sprintf( cmd
, "%s -e 's/KPP_NFIX/%d/g'", cmd
, FixNr
);
283 sprintf( cmd
, "%s -e 's/KPP_NSPEC/%d/g'", cmd
,SpcNr
);
284 sprintf( cmd
, "%s -e 's/KPP_NREACT/%d/g'", cmd
, EqnNr
);
285 sprintf( cmd
, "%s -e 's/KPP_NONZERO/%d/g'", cmd
, Jac_NZ
);
286 sprintf( cmd
, "%s -e 's/KPP_LU_NONZERO/%d/g'", cmd
, LU_Jac_NZ
);
287 sprintf( cmd
, "%s -e 's/KPP_NHESS/%d/g'", cmd
, Hess_NZ
);
291 sprintf( cmd
, "%s -e 's/KPP_REAL/%s/g'", cmd
, F77_types
[real
] );
294 sprintf( cmd
, "%s -e 's/KPP_REAL/%s/g'", cmd
, F90_types
[real
] );
297 sprintf( cmd
, "%s -e 's/KPP_REAL/%s/g'", cmd
, C_types
[real
] );
301 default: printf("\n Language '%d' not implemented!\n",useLang
);
305 sprintf( cmd
, "%s %s > %s", cmd
, buf
, tmpfile
);
308 IncludeFile( tmpfile
);
309 sprintf( cmd
, "rm %s", tmpfile
);
313 void MapFunctionComment( int f
, int *vars
)
317 oldf
= UseFile( mapFile
);
318 FunctionStart( f
, vars
);
320 CommentFncBegin( f, vars );*/
325 int DefineVariable( char * name
, int t
, int bt
, int maxi
, int maxj
, char * comment
)
330 for( i
= 0; i
< MAX_VAR
; i
++ )
331 if( varTable
[ i
] == 0 ) break;
333 if( varTable
[ i
] != 0 ) {
334 printf("\nVariable Table overflow");
338 var
= (VARIABLE
*) malloc( sizeof( VARIABLE
) );
345 var
->comment
= comment
;
351 void FreeVariable( int n
)
353 if( varTable
[ n
] ) {
354 free( varTable
[ n
] );
359 NODE
* Elm( int v
, ... )
370 n
= (NODE
*) malloc( sizeof(NODE
) );
371 elm
= (ELEMENT
*) malloc( sizeof(ELEMENT
) );
380 switch( var
->type
) {
381 case CONST
: switch( var
->baseType
) {
382 case REAL
: elm
->val
.cnst
= (float)va_arg( args
, double );
384 case INT
: elm
->val
.cnst
= (float)va_arg( args
, int );
386 if( elm
->val
.cnst
< 0 ) {
387 elm
->val
.cnst
= -elm
->val
.cnst
;
393 case VELM
: elm
->val
.idx
.i
= va_arg( args
, int );
395 case MELM
: elm
->val
.idx
.i
= va_arg( args
, int );
396 elm
->val
.idx
.j
= va_arg( args
, int );
398 case EELM
: elm
->val
.expr
= va_arg( args
, char* );
406 int IsConst( NODE
*n
, float val
)
409 ( n
->type
== CONST
) &&
410 ( n
->elm
->val
.cnst
== val
)
414 NODE
* BinaryOp( int op
, NODE
*n1
, NODE
*n2
)
418 n
= (NODE
*) malloc( sizeof(NODE
) );
427 NODE
* Add( NODE
*n1
, NODE
*n2
)
429 if( n1
== 0 ) return n2
;
430 if( n2
== 0 ) return n1
;
432 if( IsConst( n1
, 0 ) ) {
436 if( IsConst( n2
, 0 ) ) {
440 return BinaryOp( ADD
, n1
, n2
);
443 NODE
* Sub( NODE
*n1
, NODE
*n2
)
445 if( n1
== 0 ) return BinaryOp( SUB
, 0, n2
);
446 if( n2
== 0 ) return n1
;
448 if( IsConst( n1
, 0 ) ) {
450 return BinaryOp( SUB
, 0, n2
);
452 if( IsConst( n2
, 0 ) ) {
456 return BinaryOp( SUB
, n1
, n2
);
459 NODE
* Mul( NODE
*n1
, NODE
*n2
)
461 if( n1
== 0 ) return n2
;
462 if( n2
== 0 ) return n1
;
464 if( IsConst( n1
, 1 ) ) {
465 n2
->sign
*= n1
->sign
;
469 if( IsConst( n2
, 1 ) ) {
470 n2
->sign
*= n1
->sign
;
474 if( IsConst( n1
, 0 ) ) {
478 if( IsConst( n2
, 0 ) ) {
483 return BinaryOp( MUL
, n1
, n2
);
486 NODE
* Div( NODE
*n1
, NODE
*n2
)
488 if( n1
== 0 ) return BinaryOp( DIV
, Const(1), n2
);
489 if( n2
== 0 ) return n1
;
491 if( IsConst( n2
, 1 ) ) {
492 n2
->sign
*= n1
->sign
;
497 return BinaryOp( DIV
, n1
, n2
);
500 NODE
* Pow( NODE
*n1
, NODE
*n2
)
502 if( n1
== 0 ) return n2
;
503 if( n2
== 0 ) return n1
;
504 return BinaryOp( POW
, n1
, n2
);
507 void FreeNode( NODE
* n
)
511 FreeNode( n
->right
);
512 if( n
->elm
) free( n
->elm
);
516 int NodeCmp( NODE
*n1
, NODE
*n2
)
521 if( n1
== n2
) return 1;
522 if( n1
== 0 ) return 0;
523 if( n2
== 0 ) return 0;
525 if( (n1
->type
% SUBST
) != (n2
->type
% SUBST
) ) return 0;
530 if( elm1
== elm2
) return 1;
531 if( elm1
== 0 ) return 0;
532 if( elm2
== 0 ) return 0;
534 if( elm1
->var
!= elm2
->var
)return 0;
536 case CONST
: if( elm1
->val
.cnst
!= elm2
->val
.cnst
) return 0;
539 case VELM
: if( elm1
->val
.idx
.i
!= elm2
->val
.idx
.i
) return 0;
541 case MELM
: if( elm1
->val
.idx
.i
!= elm2
->val
.idx
.i
) return 0;
542 if( elm1
->val
.idx
.j
!= elm2
->val
.idx
.j
) return 0;
544 case EELM
: if( strcmp( elm1
->val
.expr
, elm2
->val
.expr
) != 0 ) return 0;
551 NODE
* NodeCopy( NODE
*n1
)
556 n
= (NODE
*) malloc( sizeof(NODE
) );
557 elm
= (ELEMENT
*) malloc( sizeof(ELEMENT
) );
564 void WriteNode( NODE
*n
)
567 ExpandNode( n
, NONE
);
570 void WriteOp( int op
)
576 void ExpandElm( NODE
* n
)
580 if( substENABLED
== 0 ) {
584 cn
= LookUpSubst( n
);
588 if( cn
->type
> SUBST
) {
592 WriteSymbol( O_PAREN
);
593 WriteNode( cn
->right
);
594 WriteSymbol( C_PAREN
);
600 int ExpandNode( NODE
*n
, int lastop
)
604 if( n
== 0 ) return lastop
;
607 ( PRI
[ n
->left
->type
] < PRI
[ n
->type
] ) )
612 WriteSymbol( O_PAREN
);
614 lastop
= ExpandNode( n
->left
, lastop
);
615 if( needParen
) WriteSymbol( C_PAREN
);
622 case POW
: crtop
= n
->type
;
624 case NONE
: printf("ERROR - null element");
632 case MUL
: case DIV
: case POW
:
634 if ( n
->sign
== -1 ) {
635 WriteSymbol( O_PAREN
);
638 WriteSymbol( C_PAREN
);
643 case ADD
: if( n
->sign
== -1 )
648 case SUB
: if( n
->sign
== -1 )
653 case NONE
: if( n
->sign
== -1 )
662 ( PRI
[ n
->right
->type
] <= PRI
[ n
->type
] ) )
667 WriteSymbol( O_PAREN
);
669 lastop
= ExpandNode( n
->right
, n
->type
);
670 if( needParen
) WriteSymbol( C_PAREN
);
674 void Assign( NODE
*lval
, NODE
*rval
)
680 ls
= (char*)malloc( MAX_OUTBUF
);
681 rs
= (char*)malloc( MAX_OUTBUF
);
690 WriteAssign( ls
, rs
);
698 NODE
* LookUpSubst( NODE
*n
)
704 if( NodeCmp( n
, cn
) )
711 void MkSubst( NODE
*n1
, NODE
*n2
)
715 n
= LookUpSubst( n1
);
721 FreeNode( n
->right
);
727 void RmSubst( NODE
*n
)
735 if( NodeCmp( n
, cn
) )
740 if( cn
== 0 ) return;
742 FreeNode( cn
->right
);
746 substList
= cn
->left
;
763 WriteNode( n
->right
);
770 void CommentFncBegin( int f
, int *vars
)
777 name
= varTable
[ f
]->name
;
778 narg
= varTable
[ f
]->maxi
;
783 WriteComment("%s - %s", var
->name
, var
->comment
);
784 WriteComment(" Arguments :");
785 for( i
= 0; i
< narg
; i
++ ) {
786 var
= varTable
[vars
[i
]];
787 WriteComment(" %-10s- %s", var
->name
, var
->comment
);
794 void CommentFunctionBegin( int f
, ... )
802 name
= varTable
[ f
]->name
;
803 narg
= varTable
[ f
]->maxi
;
806 for( i
= 0; i
< narg
; i
++ )
807 vars
[i
] = va_arg( args
, int );
810 CommentFncBegin( f
, vars
);
811 /* MapFunctionComment( f, vars ); */
814 void CommentFunctionEnd( int f
)
816 WriteComment("End of %s function", varTable
[ f
]->name
);