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 ******************************************************************************/
38 #define LINE_LENGTH 70
42 char *C_types
[] = { "void", /* VOID */
45 "double", /* DOUBLE */
46 "char *", /* STRING */
47 "char *" /* DOUBLESTRING */
50 void C_WriteElm( NODE
* n
)
58 name
= varTable
[ elm
->var
]->name
;
61 case CONST
: bprintf("%g", elm
->val
.cnst
);
63 case ELM
: bprintf("%s", name
);
65 case VELM
: if( elm
->val
.idx
.i
>= 0 ) sprintf( maxi
, "%d", elm
->val
.idx
.i
);
66 else sprintf( maxi
, "%s", varTable
[ -elm
->val
.idx
.i
]->name
);
67 bprintf("%s[%s]", name
, maxi
);
69 case MELM
: if( elm
->val
.idx
.i
>= 0 ) sprintf( maxi
, "%d", elm
->val
.idx
.i
);
70 else sprintf( maxi
, "%s", varTable
[ -elm
->val
.idx
.i
]->name
);
71 if( elm
->val
.idx
.j
>= 0 ) sprintf( maxj
, "%d", elm
->val
.idx
.j
);
72 else sprintf( maxj
, "%s", varTable
[ -elm
->val
.idx
.j
]->name
);
73 bprintf("%s[%s][%s]", name
, maxi
, maxj
);
75 case EELM
: bprintf("(%s)", elm
->val
.expr
);
80 void C_WriteSymbol( int op
)
83 case ADD
: bprintf("+");
86 case SUB
: bprintf("-");
89 case MUL
: bprintf("*");
92 case DIV
: bprintf("/");
95 case POW
: bprintf("power");
97 case O_PAREN
: bprintf("(");
100 case C_PAREN
: bprintf(")");
107 void C_WriteAssign( char *ls
, char *rs
)
115 int number_of_lines
= 1, MAX_NO_OF_LINES
= 99;
118 /* Operator Mapping: 0xaa = '*' | 0xab = '+' | 0xac = ','
119 0xad = '-' | 0xae ='.' | 0xaf = '/' */
120 char op_mult
=0xaa, op_plus
=0xab, op_minus
=0xad, op_dot
=0xae, op_div
=0xaf;
122 crtident
= 2 + ident
* 2;
123 bprintf("%*s%s = ", crtident
, "", ls
);
124 start
= strlen( ls
) + crtident
+ 2;
125 linelg
= LINE_LENGTH
- start
;
128 while( strlen(rs
) > linelg
) {
129 ifound
= 0; jfound
= 0;
130 if ( number_of_lines
>= MAX_NO_OF_LINES
) {/* if a new line needs to be started */
131 for( j
=linelg
; j
>5; j
-- ) /* split row here if +, -, or comma */
132 if ( ( rs
[j
] == op_plus
)||( rs
[j
] == op_minus
)||( rs
[j
]==',' ) ) {
133 jfound
= 1; i
=j
; break;
136 if ( ( number_of_lines
< MAX_NO_OF_LINES
)||( !jfound
) ) {
137 for( i
=linelg
; i
>10; i
-- ) /* split row here if operator or comma */
138 if ( ( rs
[i
] & 0x80 )||( rs
[i
]==',' ) ) {
142 printf("\n Warning: possible error in continuation lines for %s = ...",ls
);
146 while ( rs
[i
-1] & 0x80 ) i
--; /* put all operators on the next row */
147 while ( rs
[i
] == ',' ) i
++; /* put commas on the current row */
149 /*for( i=linelg; i>10; i-- )
150 if( ( rs[i] & 0x80 ) || ( rs[i] == ',' ) )
153 printf("\nPossible error when cutting lines");
164 bprintf("\n%*s%s", start
, "", rs
);
166 bprintf(";\n%*s%s = %s", crtident
, "", ls
, ls
);
175 if ( number_of_lines
> MAX_NO_OF_LINES
)
176 printf("\n Warning: many continuation lines (%d) for %s = ...",number_of_lines
,ls
);
178 if ( first
) bprintf("%s;\n", rs
);
179 else bprintf("\n%*s%s;\n", start
, "", rs
);
184 void C_WriteComment( char *fmt
, ... )
187 char buf
[ MAX_LINE
];
189 Va_start( args
, fmt
);
190 vsprintf( buf
, fmt
, args
);
193 bprintf( "/* %-*s */\n", LINE_LENGTH
- 6, buf
);
199 char * C_Decl( int v
)
201 static char buf
[120];
208 baseType
= C_types
[ var
->baseType
];
212 switch( var
->type
) {
214 sprintf( buf
, "%s %s", baseType
, var
->name
);
217 if( var
->maxi
> 0 ) sprintf( maxi
, "%d", var
->maxi
);
218 if( var
->maxi
== 0 ) sprintf( maxi
, "%d", 1 );
219 /* else sprintf( maxi, "%s", varTable[ -var->maxi ]->name); */
220 if ( var
->maxi
< 0 ) {
221 if (varTable
[ -var
->maxi
]->value
< 0)
222 sprintf( maxi
, "%s", varTable
[ -var
->maxi
]->name
);
224 sprintf( maxi
, "%d", (varTable
[-var
->maxi
]->value
)==0?
225 1:varTable
[-var
->maxi
]->value
);
227 /*if( (var->maxi == 0) ||
228 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
229 sprintf( maxi, "%s+1", maxi );*/
231 sprintf( buf
, "%s %s[]", baseType
, var
->name
);
233 sprintf( buf
, "%s %s[%s]", baseType
, var
->name
, maxi
);
236 if( var
->maxi
> 0 ) sprintf( maxi
, "%d", var
->maxi
);
238 if (varTable
[ -var
->maxi
]->value
< 0)
239 sprintf( maxi
, "%s", varTable
[ -var
->maxi
]->name
);
241 sprintf( maxi
, "%d", (varTable
[-var
->maxi
]->value
)==0?
242 1:varTable
[-var
->maxi
]->value
);
244 /* if( (var->maxi == 0) ||
245 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
246 strcat( maxi, "+1"); */
247 if( var
->maxj
> 0 ) sprintf( maxj
, "%d", var
->maxj
);
249 if (varTable
[ -var
->maxj
]->value
< 0)
250 sprintf( maxj
, "%s", varTable
[ -var
->maxj
]->name
);
252 sprintf( maxj
, "%d", (varTable
[-var
->maxj
]->value
)==0?
253 1:varTable
[-var
->maxj
]->value
);
256 sprintf( buf
, "%s %s[][]", baseType
, var
->name
);
258 sprintf( buf
, "%s %s[%s][%s]",
259 baseType
, var
->name
, maxi
, maxj
);
262 Message( "Can not declare type %d", var
->type
);
263 Message( "v = %d", v
);
269 void C_Declare( int v
)
271 bprintf("%-40s", strcat( C_Decl(v
), ";" ) );
272 if( varTable
[ v
]->comment
)
273 bprintf(" /* %s */\n", varTable
[ v
]->comment
);
280 void C_ExternDeclare( int v
)
282 bprintf("extern %-40s", strcat( C_Decl(v
), ";" ) );
283 if( varTable
[ v
]->comment
)
284 bprintf(" /* %s */\n", varTable
[ v
]->comment
);
291 void C_GlobalDeclare( int v
)
296 void C_InitDeclare( int v
, int n
, void * values
)
303 int maxCols
= MAX_COLS
;
306 ival
= (int*) values
;
307 dval
= (double*) values
;
308 cval
= (char**) values
;
311 bprintf(" /* %s */\n\n", var
->comment
);
313 switch( var
->type
) {
314 case VELM
: bprintf( " %s %s[] = {\n%5s", C_types
[var
->baseType
], var
->name
, " " );
315 for( i
= 0; i
< n
; i
++ ) {
316 switch( var
->baseType
) {
317 case INT
: bprintf( "%3d", ival
[i
] ); maxCols
=12; break;
319 case REAL
:bprintf( "%5lg", dval
[i
] ); maxCols
=8; break;
320 case STRING
:bprintf( "\"%s\"", cval
[i
] ); maxCols
=8; break;
321 case DOUBLESTRING
:bprintf( "\"%s\"", cval
[i
] ); maxCols
=1; break;
323 if( i
< n
-1 ) bprintf( "," );
324 if( (i
+1) % maxCols
== 0 ) bprintf( "\n%5s", " " );
326 if( n
== 0 ) bprintf( "0" );
327 bprintf( " }; \n\n" );
330 case ELM
: bprintf( " %s %s = ", C_types
[var
->baseType
], var
->name
);
331 switch( var
->baseType
) {
332 case INT
: bprintf( "%d", *ival
); break;
334 case REAL
:bprintf( "%lg", *dval
); break;
335 case STRING
:bprintf( "\"%s\"", *cval
); break;
336 case DOUBLESTRING
:bprintf( "\"%s\"", *cval
); break;
341 default: printf( "\n Function not defined !\n" );
348 void C_DeclareConstant( int v
, char *val
)
352 char dummy_val
[100]; /* used just to avoid strange behaviour of
353 sscanf when compiled with gcc */
355 strcpy(dummy_val
,val
);val
= dummy_val
;
359 if( sscanf(val
, "%d", &ival
) == 1 )
360 if( ival
== 0 ) var
->maxi
= 0;
365 switch( var
->type
) {
366 case CONST
: bprintf("#define %-20s %-10s ", var
->name
, val
);
369 printf( "Invalid constant", var
->type
);
372 if( varTable
[ v
]->comment
)
373 bprintf(" /* %s */\n", varTable
[ v
]->comment
);
380 void C_FunctionStart( int f
, int *vars
)
387 name
= varTable
[ f
]->name
;
388 narg
= varTable
[ f
]->maxi
;
392 bprintf("void %s( \n", name
);
393 for( i
= 0; i
< narg
-1; i
++ ) {
395 bprintf(" %-38s", strcat( C_Decl(v
), "," ) );
396 if( varTable
[ v
]->comment
)
397 bprintf(" /* %s */\n", varTable
[ v
]->comment
);
403 bprintf(" %-38s", C_Decl(v
) );
404 if( varTable
[ v
]->comment
)
405 bprintf(" /* %s */\n", varTable
[ v
]->comment
);
416 void C_FunctionPrototipe( int f
, ... )
424 name
= varTable
[ f
]->name
;
425 narg
= varTable
[ f
]->maxi
;
428 for( i
= 0; i
< narg
; i
++ )
429 vars
[i
] = va_arg( args
, int );
431 C_FunctionStart( f
, vars
);
437 void C_FunctionBegin( int f
, ... )
445 name
= varTable
[ f
]->name
;
446 narg
= varTable
[ f
]->maxi
;
449 for( i
= 0; i
< narg
; i
++ )
450 vars
[i
] = va_arg( args
, int );
453 CommentFncBegin( f
, vars
);
454 C_FunctionStart( f
, vars
);
460 MapFunctionComment( f
, vars
);
463 void C_FunctionEnd( int f
)
469 CommentFunctionEnd( f
);
472 void C_Inline( char *fmt
, ... )
477 if( useLang
!= C_LANG
) return;
479 Va_start( args
, fmt
);
480 vsprintf( buf
, fmt
, args
);
482 bprintf( "%s\n",buf
);
489 WriteElm
= C_WriteElm
;
490 WriteSymbol
= C_WriteSymbol
;
491 WriteAssign
= C_WriteAssign
;
492 WriteComment
= C_WriteComment
;
493 DeclareConstant
= C_DeclareConstant
;
495 ExternDeclare
= C_ExternDeclare
;
496 GlobalDeclare
= C_GlobalDeclare
;
497 InitDeclare
= C_InitDeclare
;
499 FunctionStart
= C_FunctionStart
;
500 FunctionPrototipe
= C_FunctionPrototipe
;
501 FunctionBegin
= C_FunctionBegin
;
502 FunctionEnd
= C_FunctionEnd
;
504 OpenFile( ¶m_headerFile
, rootFileName
, "_Parameters.h", "Parameter Header File" );
505 OpenFile( &initFile
, rootFileName
, "_Initialize.c", "Initialization File" );
506 OpenFile( &driverFile
, rootFileName
, "_Main.c", "Main Program File" );
507 OpenFile( &integratorFile
, rootFileName
, "_Integrator.c",
508 "Numerical Integrator (Time-Stepping) File" );
509 OpenFile( &linalgFile
, rootFileName
, "_LinearAlgebra.c",
510 "Linear Algebra Data and Routines File" );
511 OpenFile( &functionFile
, rootFileName
, "_Function.c",
512 "The ODE Function of Chemical Model File" );
513 OpenFile( &jacobianFile
, rootFileName
, "_Jacobian.c",
514 "The ODE Jacobian of Chemical Model File" );
515 OpenFile( &rateFile
, rootFileName
, "_Rates.c",
516 "The Reaction Rates File" );
518 OpenFile( &stochasticFile
, rootFileName
, "_Stochastic.c",
519 "The Stochastic Chemical Model File" );
521 OpenFile( &stoichiomFile
, rootFileName
, "_Stoichiom.c",
522 "The Stoichiometric Chemical Model File" );
523 OpenFile( &sparse_stoicmFile
, rootFileName
, "_StoichiomSP.c",
524 "Sparse Stoichiometric Data Structures File" );
526 OpenFile( &utilFile
, rootFileName
, "_Util.c",
527 "Auxiliary Routines File" );
528 OpenFile( &sparse_dataFile
, rootFileName
, "_Sparse.h", "Sparse Data Header File" );
529 OpenFile( &global_dataFile
, rootFileName
, "_Global.h", "Global Data Header File" );
530 if ( useJacSparse
) {
531 OpenFile( &sparse_jacFile
, rootFileName
, "_JacobianSP.c",
532 "Sparse Jacobian Data Structures File" );
535 OpenFile( &hessianFile
, rootFileName
, "_Hessian.c", "Hessian File" );
536 OpenFile( &sparse_hessFile
, rootFileName
, "_HessianSP.c",
537 "Sparse Hessian Data Structures File" );
539 OpenFile( &mapFile
, rootFileName
, ".map",
540 "Map File with Human-Readable Information" );
541 OpenFile( &monitorFile
, rootFileName
, "_Monitor.c",
542 "Utility Data Initialization" );