Original WRF subgrid support version from John Michalakes without fire
[wrffire.git] / wrfv2_fire / chem / KPP / kpp / kpp-2.1 / src.org / code_matlab.c
blob746486b91b969b742bd0b238b0a82a4c53b6e7b6
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
39 char *MATLAB_types[] = { "", /* VOID */
40 "INTEGER", /* INT */
41 "REAL", /* FLOAT */
42 /*"REAL(dp)", */ /* DOUBLE */
43 "DOUBLE PRECISION", /* DOUBLE */
44 "CHARACTER(LEN=12)", /* STRING */
45 "CHARACTER(LEN=100)" /* DOUBLESTRING */
48 /*************************************************************************************************/
49 void MATLAB_WriteElm( NODE * n )
51 ELEMENT *elm;
52 char * name;
53 char maxi[20];
54 char maxj[20];
56 elm = n->elm;
57 name = varTable[ elm->var ]->name;
59 switch( n->type ) {
60 case CONST: bprintf("%g", elm->val.cnst);
61 break;
62 case ELM: bprintf("%s", name);
63 break;
64 case VELM: if( elm->val.idx.i >= 0 ) sprintf( maxi, "%d", elm->val.idx.i+1 );
65 else sprintf( maxi, "%s", varTable[ -elm->val.idx.i ]->name );
66 bprintf("%s(%s)", name, maxi );
67 break;
68 case MELM: if( elm->val.idx.i >= 0 ) sprintf( maxi, "%d", elm->val.idx.i+1 );
69 else sprintf( maxi, "%s", varTable[ -elm->val.idx.i ]->name );
70 if( elm->val.idx.j >= 0 ) sprintf( maxj, "%d", elm->val.idx.j+1 );
71 else sprintf( maxj, "%s", varTable[ -elm->val.idx.j ]->name );
72 bprintf("%s(%s,%s)", name, maxi, maxj );
73 break;
74 case EELM: bprintf("(%s)", elm->val.expr );
75 break;
79 /*************************************************************************************************/
80 void MATLAB_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("^");
96 break;
97 case O_PAREN: bprintf("(");
98 AllowBreak();
99 break;
100 case C_PAREN: bprintf(")");
101 break;
102 case NONE:
103 break;
107 /*************************************************************************************************/
108 void MATLAB_WriteAssign( char *ls, char *rs )
110 int start;
111 int linelg;
112 int i, j;
113 int ifound, jfound;
114 char c;
115 int first;
116 int crtident;
118 /* Max no of continuation lines in F95 standard is 39 */
119 int number_of_lines = 1, MAX_NO_OF_LINES = 36;
121 /* Operator Mapping: 0xaa = '*' | 0xab = '+' | 0xac = ','
122 0xad = '-' | 0xae ='.' | 0xaf = '/' */
123 char op_mult=0xaa, op_plus=0xab, op_minus=0xad, op_dot=0xae, op_div=0xaf;
125 crtident = 3 + ident * 2;
126 bprintf("%*s%s = ", crtident, "", ls);
127 start = strlen( ls ) + 2;
128 linelg = 70 - crtident - start - 1;
130 first = 1;
131 while( strlen(rs) > linelg ) {
132 ifound = 0; jfound = 0;
133 if ( number_of_lines >= MAX_NO_OF_LINES ) {
134 /* If a new line needs to be started.
135 Note: the approach below will create erroneous code if the +/- is within a subexpression, e.g. for
136 A*(B+C) one cannot start a new continuation line by splitting at the + sign */
137 for( j=linelg; j>5; j-- ) /* split row here if +, -, or comma */
138 if ( ( rs[j] == op_plus )||( rs[j] == op_minus )||( rs[j]==',' ) ) {
139 jfound = 1; i=j; break;
142 if ( ( number_of_lines < MAX_NO_OF_LINES )||( !jfound ) ) {
143 for( i=linelg; i>10; i-- ) /* split row here if operator or comma */
144 if ( ( rs[i] & 0x80 )||( rs[i]==',' ) ) {
145 ifound = 1; break;
147 if( i <= 10 ) {
148 printf("\n Warning: possible error in continuation lines for %s = ...",ls);
149 i = linelg;
152 while ( rs[i-1] & 0x80 ) i--; /* put all operators on the next row */
153 while ( rs[i] == ',' ) i++; /* put commas on the current row */
155 c = rs[i];
156 rs[i] = 0;
158 if ( first ) { /* first line in a split row */
159 bprintf("%s", rs );
160 linelg++;
161 first = 0;
162 } else {/* continuation line in a split row - but not last line*/
163 bprintf(" ...\n %*s%s", start, "", rs );
164 if ( jfound ) {
165 bprintf(" ;\n%*s%s = %s", crtident, "", ls, ls);
166 number_of_lines = 1;
169 rs[i] = c;
170 rs += i; /* jump to the first not-yet-written character */
171 number_of_lines++;
174 if ( number_of_lines > MAX_NO_OF_LINES ) {
175 printf("\n Warning: %d continuation lines for %s = ...",number_of_lines,ls);
178 if ( first ) bprintf("%s ;\n", rs ); /* non-split row */
179 else bprintf(" ...\n %*s%s;\n", start, "", rs ); /* last line in a split row */
182 FlushBuf();
186 /*************************************************************************************************/
187 void MATLAB_WriteComment( char *fmt, ... )
189 Va_list args;
190 char buf[ MAX_LINE ];
192 va_start( args, fmt );
193 vsprintf( buf, fmt, args );
194 va_end( args );
196 fprintf( currentFile, "%c ", '%' );
197 bprintf( "%-65s\n", buf );
199 FlushBuf();
202 /*************************************************************************************************/
203 char * MATLAB_Decl( int v )
205 static char buf[120];
206 VARIABLE *var;
207 char *baseType;
208 char maxi[20];
209 char maxj[20];
211 buf[0] = 0; return buf; /* Nothing to declare in matlab */
212 var = varTable[ v ];
213 baseType = MATLAB_types[ var->baseType ];
215 *buf = 0;
217 switch( var->type ) {
218 case ELM: sprintf( buf, "%s :: %s",
219 baseType, var->name );
220 break;
221 case VELM:
222 if( var->maxi > 0 ) sprintf( maxi, "%d", var->maxi );
223 else sprintf( maxi, "%s", varTable[ -var->maxi ]->name );
224 if( (var->maxi == 0) ||
225 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
226 strcat( maxi, "+1");
227 sprintf( buf, "%s, DIMENSION(%s) :: %s",
228 baseType, maxi, var->name );
229 break;
230 case MELM: if( var->maxi > 0 ) sprintf( maxi, "%d", var->maxi );
231 else sprintf( maxi, "%s", varTable[ -var->maxi ]->name );
232 if( (var->maxi == 0) ||
233 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
234 strcat( maxi, "+1");
235 if( var->maxj > 0 ) sprintf( maxj, "%d", var->maxj );
236 else sprintf( maxj, "%s", varTable[ -var->maxj ]->name );
237 if( (var->maxj == 0) ||
238 ((var->maxj < 0 ) && (varTable[ -var->maxj ]->maxi == 0)) )
239 strcat( maxj, "+1");
240 sprintf( buf, "%s, DIMENSION(%s,%s) :: %s",
241 baseType, maxi, maxj,var->name );
242 break;
243 default:
244 printf( "Can not declare type %d\n", var->type );
245 break;
247 return buf;
250 /*************************************************************************************************/
251 char * MATLAB_DeclareData( int v, void * values, int n)
253 int i, j;
254 int nlines, nmax;
255 int split;
256 static char buf[120];
257 VARIABLE *var;
258 int * ival;
259 double * dval;
260 char ** cval;
261 char *baseType;
262 char maxi[20];
263 char maxj[20];
264 int maxCols = MAX_COLS;
265 char dsbuf[55];
267 int i_from, i_to;
268 int isplit;
269 int splitsize;
270 int maxi_mod;
271 int maxi_div;
273 char mynumber[30];
275 var = varTable[ v ];
276 ival = (int*) values;
277 dval = (double *) values;
278 cval = (char **) values;
280 nlines = 1;
281 nmax = 1;
282 split = 0;
283 var -> maxi = max( n, 1 );
285 baseType = MATLAB_types[ var->baseType ];
287 *buf = 0;
289 switch( var->type ) { /* changed here */
290 case ELM:
291 /* bprintf( " %s :: %s = ", baseType, var->name );
292 switch ( var->baseType ) {
293 case INT: bprintf( "%d", *ival ); break;
294 case DOUBLE: bprintf( "%f", *dval); break;
295 case REAL: bprintf( "%lg", *dval ); break;
296 case STRING: bprintf( "'%3s'", *cval ); break;
297 } */
298 break;
299 case VELM:
300 splitsize = 36; /*elements*/
301 maxi_mod = var->maxi % splitsize;
302 maxi_div = var->maxi / splitsize;
304 if( var->maxi > 0 ) sprintf( maxi, "%d", var->maxi );
305 else sprintf( maxi, "%s", varTable[ -var->maxi ]->name );
306 if( (var->maxi == 0) ||
307 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
308 strcat( maxi, "+1");
309 if( var->maxj > 0 ) sprintf( maxj, "%d", var->maxj );
310 else sprintf( maxj, "%s", varTable[ -var->maxj ]->name );
311 if( (var->maxj == 0) ||
312 ((var->maxj < 0 ) && (varTable[ -var->maxj ]->maxi == 0)) )
313 strcat( maxj, "+1");
314 /* now list values */
315 /* if ( (var->baseType==STRING)||(var->baseType==DOUBLESTRING) ) {
316 bprintf( "%s(1:%s,:) = [ ... \n", var->name, maxi) ;
317 } else {
318 bprintf( "%s(1:%s) = [ ... \n", var->name, maxi) ;
320 if ( (var->baseType==STRING)||(var->baseType==DOUBLESTRING) ) {
321 bprintf( "%s = [ ... \n", var->name, maxi) ;
322 } else {
323 bprintf( "%s = [ ... \n", var->name, maxi) ;
326 /* if the array is defined in one piece, then the for loop will
327 go from 0 to n. Otherwise, there will be partial arrays from
328 i_from to i_to which are of size splitsize except for the
329 last one which is usually smaller and contains the rest */
330 for ( i=0; i < n; i++ ) {
331 switch( var -> baseType ) {
332 case INT:
333 bprintf( "%4d", ival[i] ); maxCols =12; break;
334 case DOUBLE:
335 sprintf(mynumber, "%12.6e",dval[i]);
336 bprintf( " %s", mynumber ); maxCols = 5; break;
337 case REAL:
338 bprintf( "%12.6e", dval[i] ); maxCols = 5; break;
339 case STRING:
340 bprintf( "'%12s'", cval[i] ); maxCols = 3; break;
341 case DOUBLESTRING:
342 strncpy( dsbuf, cval[i], 54 ); dsbuf[54]='\0';
343 bprintf( "'%48s'", dsbuf ); maxCols=1; break;
345 if( i < n-1 ) {
346 bprintf( ";" );
347 if( (i+1) % maxCols == 0 ) {
348 bprintf( " ... \n" );
349 nlines++;
353 bprintf( " ];\n" );
354 break;
356 case MELM: if( var->maxi > 0 ) sprintf( maxi, "%d", var->maxi );
357 else sprintf( maxi, "%s", varTable[ -var->maxi ]->name );
358 if( (var->maxi == 0) ||
359 ((var->maxi < 0) && (varTable[ -var->maxi ]->maxi == 0)) )
360 strcat( maxi, "+1");
361 if( var->maxj > 0 ) sprintf( maxj, "%d", var->maxj );
362 else sprintf( maxj, "%s", varTable[ -var->maxj ]->name );
363 if( (var->maxj == 0) ||
364 ((var->maxj < 0 ) && (varTable[ -var->maxj ]->maxi == 0)) )
365 strcat( maxj, "+1");
366 sprintf( buf, "%s, DIMENSION(%s,%s) :: %s\n", /* changed here */
367 baseType, maxi, maxj,var->name );
368 break;
369 default:
370 printf( "Can not declare type %d", var->type );
371 break;
373 return buf;
376 /*************************************************************************************************/
377 void MATLAB_Declare( int v )
379 if( varTable[ v ]->comment ) {
380 MATLAB_WriteComment( "%s - %s",
381 varTable[ v ]->name, varTable[ v ]->comment );
383 FlushBuf();
384 bprintf(" %s\n", MATLAB_Decl(v) );
386 FlushBuf();
389 /*************************************************************************************************/
390 void MATLAB_ExternDeclare( int v )
392 if( varTable[ v ]->comment ) {
393 MATLAB_WriteComment( "%s - %s",
394 varTable[ v ]->name, varTable[ v ]->comment );
396 FlushBuf();
397 bprintf(" global %s;\n", varTable[ v ]->name );
398 FlushBuf();
402 /*************************************************************************************************/
403 void MATLAB_GlobalDeclare( int v )
408 /*************************************************************************************************/
409 void MATLAB_DeclareConstant( int v, char *val )
411 VARIABLE *var;
412 int ival;
413 char dummy_val[100]; /* used just to avoid strange behaviour of
414 sscanf when compiled with gcc */
416 strcpy(dummy_val,val);val = dummy_val;
418 var = varTable[ v ];
420 if( sscanf(val, "%d", &ival) == 1 )
421 if( ival == 0 ) var->maxi = 0;
422 else var->maxi = 1;
423 else
424 var->maxi = -1;
426 if( var->comment )
427 MATLAB_WriteComment( "%s - %s", var->name, var->comment );
429 switch( var->type ) {
430 case CONST: bprintf(" global %s;",var->name, val );
431 bprintf(" %s = %s; \n", var->name, val );
432 break;
433 default:
434 printf( "Invalid constant %d", var->type );
435 break;
438 FlushBuf();
442 /*************************************************************************************************/
443 void MATLAB_WriteVecData( VARIABLE * var, int min, int max, int split )
445 char buf[80];
446 char *p;
448 if( split )
449 sprintf( buf, "%6sdata( %s(i), i = %d, %d ) / &\n%5s",
450 " ", var->name, min, max, " " );
451 else
452 sprintf( buf, "%6sdata %s / &\n%5s",
453 " ", var->name, " " );
455 FlushThisBuf( buf );
456 bprintf( " / \n\n" );
457 FlushBuf();
460 /*************************************************************************************************/
461 void MATLAB_DeclareDataOld( int v, int * values, int n )
463 int i, j;
464 int nlines, min, max;
465 int split;
466 VARIABLE *var;
467 int * ival;
468 double * dval;
469 char **cval;
470 int maxCols = MAX_COLS;
471 char dsbuf[55];
473 var = varTable[ v ];
474 ival = (int*) values;
475 dval = (double*) values;
476 cval = (char**) values;
478 nlines = 1;
479 min = max = 1;
480 split = 0;
482 switch( var->type ) {
483 case VELM: if( n <= 0 ) break;
484 for( i = 0; i < n; i++ ) {
485 switch( var->baseType ) {
486 case INT: bprintf( "%3d", ival[i] ); maxCols=12; break;
487 case DOUBLE:
488 case REAL:bprintf( "%5lg", dval[i] ); maxCols=8; break;
489 case STRING:bprintf( "'%s'", cval[i] ); maxCols=5; break;
490 case DOUBLESTRING:
491 strncpy( dsbuf, cval[i], 54 ); dsbuf[54]='\0';
492 bprintf( "'%48s'", dsbuf ); maxCols=1; break;
494 if( ( (i+1) % 12 == 0 ) && ( nlines > MAX_LINES ) ) {
495 split = 1; nlines = 1;
496 MATLAB_WriteVecData( var, min, max, split );
497 min = max + 1;
499 else {
500 if( i < n-1 ) bprintf( "," );
501 if( (i+1) % maxCols == 0 ) {
502 bprintf( "\n%5s", " " );
503 nlines++;
506 max ++;
508 MATLAB_WriteVecData( var, min, max-1, split );
509 break;
511 case ELM: bprintf( "%6sdata %s / ", " ", var->name );
512 switch( var->baseType ) {
513 case INT: bprintf( "%d", *ival ); break;
514 case DOUBLE:
515 case REAL:bprintf( "%lg", *dval ); break;
516 case STRING:bprintf( "'%s'", *cval ); break;
517 case DOUBLESTRING:
518 strncpy( dsbuf, *cval, 54 ); dsbuf[54]='\0';
519 bprintf( "'%s'", dsbuf ); maxCols=1; break;
520 /* bprintf( "'%50s'", *cval ); break; */
522 bprintf( " / \n" );
523 FlushBuf();
524 break;
525 default:
526 printf( "\n Function not defined !\n" );
527 break;
531 /*************************************************************************************************/
532 void MATLAB_InitDeclare( int v, int n, void * values )
534 int i;
535 VARIABLE * var;
537 var = varTable[ v ];
538 var->maxi = max( n, 1 );
540 NewLines(1);
541 MATLAB_DeclareData( v, values, n );
544 /*************************************************************************************************/
545 void MATLAB_FunctionStart( int f, int *vars )
547 int i;
548 int v;
549 char * name;
550 int narg;
552 name = varTable[ f ]->name;
553 narg = varTable[ f ]->maxi;
555 bprintf("function " );
556 if( narg >= 1 ) {
557 v = vars[ narg-1 ];
558 bprintf("[ %s ] = ", varTable[ v ]->name );
560 bprintf(" %s_%s ( ", rootFileName, name );
561 for( i = 0; i < narg-1; i++ ) {
562 v = vars[ i ];
563 bprintf("%s ", varTable[ v ]->name );
564 if (i<narg-2) bprintf(", ");
566 bprintf(")\n");
568 FlushBuf();
571 /*************************************************************************************************/
572 void MATLAB_FunctionPrototipe( int f, ... )
574 char * name;
575 int narg;
577 name = varTable[ f ]->name;
578 narg = varTable[ f ]->maxi;
580 bprintf(" EXTERNAL %s\n", name );
582 FlushBuf();
585 /*************************************************************************************************/
586 void MATLAB_FunctionBegin( int f, ... )
588 Va_list args;
589 int i;
590 int v;
591 int vars[20];
592 char * name;
593 int narg;
594 FILE *oldf;
595 char buf[200], bufname[200];
596 time_t t;
598 name = varTable[ f ]->name;
599 narg = varTable[ f ]->maxi;
601 /*Adi - each Matlab functin requires a separate file*/
602 sprintf( buf, "%s_%s.m", rootFileName, varTable[ f ]->name );
603 mex_funFile = fopen(buf, "w");
604 if( mex_funFile == 0 ) {
605 FatalError(3,"%s: Can't create file", buf );
607 UseFile( mex_funFile );
608 /*Adi*/
611 Va_start( args, f );
612 for( i = 0; i < narg; i++ )
613 vars[ i ] = va_arg( args, int );
614 va_end( args );
616 CommentFncBegin( f, vars );
618 WriteDelim();
619 WriteComment("");
620 WriteComment("Generated by KPP - symbolic chemistry Kinetics PreProcessor" );
621 WriteComment(" KPP is developed at CGRER labs University of Iowa by" );
622 WriteComment(" Valeriu Damian & Adrian Sandu" );
623 WriteComment("");
624 WriteComment("%-20s : %s", "File", buf );
625 strcpy( buf, (char*)ctime( &t ) );
626 buf[ (int)strlen(buf) - 1 ] = 0;
627 WriteComment("%-20s : %s", "Time", buf );
628 WriteComment("%-20s : %s", "Working directory", getcwd(buf, 200) );
629 WriteComment("%-20s : %s", "Equation file", eqFileName );
630 WriteComment("%-20s : %s", "Output root filename", rootFileName );
631 WriteComment("");
632 WriteDelim();
633 NewLines(1);
635 MATLAB_FunctionStart( f, vars );
636 NewLines(1);
638 FlushBuf();
640 MapFunctionComment( f, vars );
643 /*************************************************************************************************/
644 void MATLAB_FunctionEnd( int f )
646 bprintf(" \nreturn\n\n");
648 FlushBuf();
650 CommentFunctionEnd( f );
652 /*Adi*/
653 fclose(mex_funFile);
658 /*************************************************************************************************/
659 void MATLAB_Inline( char *fmt, ... )
661 Va_list args;
662 char buf[ 1000 ];
664 if( useLang != MATLAB_LANG ) return;
666 Va_start( args, fmt );
667 vsprintf( buf, fmt, args );
668 va_end( args );
669 bprintf( "%s\n", buf );
671 FlushBuf();
674 /*************************************************************************************************/
675 void Use_MATLAB()
677 WriteElm = MATLAB_WriteElm;
678 WriteSymbol = MATLAB_WriteSymbol;
679 WriteAssign = MATLAB_WriteAssign;
680 WriteComment = MATLAB_WriteComment;
681 DeclareConstant = MATLAB_DeclareConstant;
682 Declare = MATLAB_Declare;
683 ExternDeclare = MATLAB_ExternDeclare;
684 GlobalDeclare = MATLAB_GlobalDeclare;
685 InitDeclare = MATLAB_InitDeclare;
687 FunctionStart = MATLAB_FunctionStart;
688 FunctionPrototipe = MATLAB_FunctionPrototipe;
689 FunctionBegin = MATLAB_FunctionBegin;
690 FunctionEnd = MATLAB_FunctionEnd;
692 OpenFile( &param_headerFile, rootFileName, "_Parameters.m","Parameter Definition File" );
693 OpenFile( &driverFile, rootFileName, "_Main.m", "Main Program File" );
694 OpenFile( &rateFile, rootFileName, "_Rates.m",
695 "The Reaction Rates File" );
696 if ( useStoicmat ) {
697 OpenFile( &stoichiomFile, rootFileName, "_Stoichiom.m",
698 "The Stoichiometric Chemical Model File" );
699 OpenFile( &sparse_stoicmFile, rootFileName, "_StoichiomSP.m",
700 "Sparse Stoichiometric Data Structures File" );
702 OpenFile( &utilFile, rootFileName, "_Util.m",
703 "Auxiliary Routines File" );
704 OpenFile( &sparse_dataFile, rootFileName, "_Sparse.m",
705 "Sparse Data Definition File" );
706 OpenFile( &global_dataFile, rootFileName, "_Global_defs.m", "Global Data Definition File" );
707 if ( useJacSparse ) {
708 OpenFile( &sparse_jacFile, rootFileName, "_JacobianSP.m",
709 "Sparse Jacobian Data Structures File" );
711 if ( useHessian ) {
712 OpenFile( &sparse_hessFile, rootFileName, "_HessianSP.m",
713 "Sparse Hessian Data Structures File" );
715 OpenFile( &mapFile, rootFileName, ".map",
716 "Map File with Human-Readable Information" );
717 OpenFile( &monitorFile, rootFileName, "_Monitor.m",
718 "Utility Data Definition File" );