Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / chem / KPP / kpp / kpp-2.1 / src.org / code_c.c
blob64deef20a32c5a379a03abb1d5e962543a233778
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 "code.h"
35 #include <string.h>
37 #define MAX_LINE 120
38 #define LINE_LENGTH 70
40 int fncPrototipe = 0;
42 char *C_types[] = { "void", /* VOID */
43 "int", /* INT */
44 "float", /* FLOAT */
45 "double", /* DOUBLE */
46 "char *", /* STRING */
47 "char *" /* DOUBLESTRING */
48 };
50 void C_WriteElm( NODE * n )
52 ELEMENT *elm;
53 char * name;
54 char maxi[20];
55 char maxj[20];
57 elm = n->elm;
58 name = varTable[ elm->var ]->name;
60 switch( n->type ) {
61 case CONST: bprintf("%g", elm->val.cnst);
62 break;
63 case ELM: bprintf("%s", name);
64 break;
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 );
68 break;
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 );
74 break;
75 case EELM: bprintf("(%s)", elm->val.expr );
76 break;
80 void C_WriteSymbol( int op )
82 switch( op ) {
83 case ADD: bprintf("+");
84 AllowBreak();
85 break;
86 case SUB: bprintf("-");
87 AllowBreak();
88 break;
89 case MUL: bprintf("*");
90 AllowBreak();
91 break;
92 case DIV: bprintf("/");
93 AllowBreak();
94 break;
95 case POW: bprintf("power");
96 break;
97 case O_PAREN: bprintf("(");
98 AllowBreak();
99 break;
100 case C_PAREN: bprintf(")");
101 break;
102 case NONE:
103 break;
107 void C_WriteAssign( char *ls, char *rs )
109 int start;
110 int crtident;
111 int linelg;
112 int i,j;
113 char c;
114 int first;
115 int number_of_lines = 1, MAX_NO_OF_LINES = 99;
116 int ifound, jfound;
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;
127 first = 1;
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]==',' ) ) {
139 ifound = 1; break;
141 if( i <= 10 ) {
142 printf("\n Warning: possible error in continuation lines for %s = ...",ls);
143 i = linelg;
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] == ',' ) )
151 break;
152 if( i < 10 ) {
153 printf("\nPossible error when cutting lines");
154 i = linelg;
157 c = rs[i];
158 rs[i] = 0;
159 if ( first ) {
160 bprintf("%s", rs );
161 linelg++;
162 first = 0;
163 } else {
164 bprintf("\n%*s%s", start, "", rs );
165 if ( jfound ) {
166 bprintf(";\n%*s%s = %s", crtident, "", ls, ls);
167 number_of_lines = 1;
170 rs[i] = c;
171 rs += i;
172 number_of_lines++;
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 );
181 FlushBuf();
184 void C_WriteComment( char *fmt, ... )
186 Va_list args;
187 char buf[ MAX_LINE ];
189 Va_start( args, fmt );
190 vsprintf( buf, fmt, args );
191 va_end( args );
193 bprintf( "/* %-*s */\n", LINE_LENGTH - 6, buf );
195 FlushBuf();
199 char * C_Decl( int v )
201 static char buf[120];
202 VARIABLE *var;
203 char *baseType;
204 char maxi[20];
205 char maxj[20];
207 var = varTable[ v ];
208 baseType = C_types[ var->baseType ];
210 *buf = 0;
212 switch( var->type ) {
213 case ELM:
214 sprintf( buf, "%s %s", baseType, var->name );
215 break;
216 case VELM:
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 );
223 else
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 );*/
230 if( fncPrototipe )
231 sprintf( buf, "%s %s[]", baseType, var->name );
232 else
233 sprintf( buf, "%s %s[%s]", baseType, var->name, maxi );
234 break;
235 case MELM:
236 if( var->maxi > 0 ) sprintf( maxi, "%d", var->maxi );
237 else {
238 if (varTable[ -var->maxi ]->value < 0)
239 sprintf( maxi, "%s", varTable[ -var->maxi ]->name );
240 else
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 );
248 else {
249 if (varTable[ -var->maxj ]->value < 0)
250 sprintf( maxj, "%s", varTable[ -var->maxj ]->name );
251 else
252 sprintf( maxj, "%d", (varTable[-var->maxj]->value)==0?
253 1:varTable[-var->maxj]->value );
255 if( fncPrototipe )
256 sprintf( buf, "%s %s[][]", baseType, var->name );
257 else
258 sprintf( buf, "%s %s[%s][%s]",
259 baseType, var->name, maxi, maxj );
260 break;
261 default:
262 Message( "Can not declare type %d", var->type );
263 Message( "v = %d", v );
264 break;
266 return buf;
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 );
274 else
275 bprintf("\n");
277 FlushBuf();
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 );
285 else
286 bprintf("\n");
288 FlushBuf();
291 void C_GlobalDeclare( int v )
293 C_Declare( v );
296 void C_InitDeclare( int v, int n, void * values )
298 int i;
299 VARIABLE *var;
300 int * ival;
301 double * dval;
302 char ** cval;
303 int maxCols = MAX_COLS;
305 var = varTable[ v ];
306 ival = (int*) values;
307 dval = (double*) values;
308 cval = (char**) values;
310 if( var->comment )
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;
318 case DOUBLE:
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" );
328 break;
330 case ELM: bprintf( " %s %s = ", C_types[var->baseType], var->name );
331 switch( var->baseType ) {
332 case INT: bprintf( "%d", *ival ); break;
333 case DOUBLE:
334 case REAL:bprintf( "%lg", *dval ); break;
335 case STRING:bprintf( "\"%s\"", *cval ); break;
336 case DOUBLESTRING:bprintf( "\"%s\"", *cval ); break;
338 bprintf( ";\n\n" );
339 break;
341 default: printf( "\n Function not defined !\n" );
342 break;
345 FlushBuf();
348 void C_DeclareConstant( int v, char *val )
350 VARIABLE *var;
351 int ival;
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;
357 var = varTable[ v ];
359 if( sscanf(val, "%d", &ival) == 1 )
360 if( ival == 0 ) var->maxi = 0;
361 else var->maxi = 1;
362 else
363 var->maxi = -1;
365 switch( var->type ) {
366 case CONST: bprintf("#define %-20s %-10s ", var->name, val );
367 break;
368 default:
369 printf( "Invalid constant", var->type );
370 break;
372 if( varTable[ v ]->comment )
373 bprintf(" /* %s */\n", varTable[ v ]->comment );
374 else
375 bprintf("\n");
377 FlushBuf();
380 void C_FunctionStart( int f, int *vars )
382 int i;
383 int v;
384 char * name;
385 int narg;
387 name = varTable[ f ]->name;
388 narg = varTable[ f ]->maxi;
390 fncPrototipe = 1;
392 bprintf("void %s( \n", name );
393 for( i = 0; i < narg-1; i++ ) {
394 v = vars[ i ];
395 bprintf(" %-38s", strcat( C_Decl(v), "," ) );
396 if( varTable[ v ]->comment )
397 bprintf(" /* %s */\n", varTable[ v ]->comment );
398 else
399 bprintf("\n");
401 if( narg >= 1 ) {
402 v = vars[ i ];
403 bprintf(" %-38s", C_Decl(v) );
404 if( varTable[ v ]->comment )
405 bprintf(" /* %s */\n", varTable[ v ]->comment );
406 else
407 bprintf("\n");
409 bprintf(")");
411 fncPrototipe = 0;
413 FlushBuf();
416 void C_FunctionPrototipe( int f, ... )
418 Va_list args;
419 int i;
420 int vars[20];
421 char * name;
422 int narg;
424 name = varTable[ f ]->name;
425 narg = varTable[ f ]->maxi;
427 Va_start( args, f );
428 for( i = 0; i < narg; i++ )
429 vars[i] = va_arg( args, int );
430 va_end( args );
431 C_FunctionStart( f, vars );
432 bprintf(";\n");
434 FlushBuf();
437 void C_FunctionBegin( int f, ... )
439 Va_list args;
440 int i;
441 int vars[20];
442 char * name;
443 int narg;
445 name = varTable[ f ]->name;
446 narg = varTable[ f ]->maxi;
448 Va_start( args, f );
449 for( i = 0; i < narg; i++ )
450 vars[i] = va_arg( args, int );
451 va_end( args );
453 CommentFncBegin( f, vars );
454 C_FunctionStart( f, vars );
455 bprintf("\n");
456 bprintf("{\n");
458 FlushBuf();
460 MapFunctionComment( f, vars );
463 void C_FunctionEnd( int f )
465 bprintf("}\n\n");
467 FlushBuf();
469 CommentFunctionEnd( f );
472 void C_Inline( char *fmt, ... )
474 Va_list args;
475 char buf[ 1000 ];
477 if( useLang != C_LANG ) return;
479 Va_start( args, fmt );
480 vsprintf( buf, fmt, args );
481 va_end( args );
482 bprintf( "%s\n",buf );
484 FlushBuf();
487 void Use_C()
489 WriteElm = C_WriteElm;
490 WriteSymbol = C_WriteSymbol;
491 WriteAssign = C_WriteAssign;
492 WriteComment = C_WriteComment;
493 DeclareConstant = C_DeclareConstant;
494 Declare = C_Declare;
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( &param_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" );
517 if ( useStochastic )
518 OpenFile( &stochasticFile, rootFileName, "_Stochastic.c",
519 "The Stochastic Chemical Model File" );
520 if ( useStoicmat ) {
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" );
534 if ( useHessian ) {
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" );