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 ******************************************************************************/
40 enum strutypes
{ PLAIN
, LU
};
46 ICODE InlineCode
[ INLINE_OPT
];
48 int NSPEC
, NVAR
, NVARACT
, NFIX
, NREACT
;
49 int NVARST
, NFIXST
, PI
;
52 int ARP
, JVRP
, NJVRP
, CROW_JVRP
, IROW_JVRP
, ICOL_JVRP
;
55 int Vdot
, P_VAR
, D_VAR
;
56 int KR
, A
, BV
, BR
, IV
;
57 int JV
, UV
, JUV
, JTUV
, JVS
;
61 int D2A
, NTMPD2A
, NHESS
, HESS
, IHESS_I
, IHESS_J
, IHESS_K
;
63 int STOICM
, NSTOICM
, IROW_STOICM
, ICOL_STOICM
, CCOL_STOICM
, CNEQN
;
64 int IROW
, ICOL
, CROW
, DIAG
;
65 int LU_IROW
, LU_ICOL
, LU_CROW
, LU_DIAG
, CNVAR
;
66 int LOOKAT
, NLOOKAT
, MONITOR
, NMONITOR
;
68 int SPC_NAMES
, EQN_NAMES
;
70 int NONZERO
, LU_NONZERO
;
72 int RTOLS
, TSTART
, TEND
, DT
;
73 int ATOL
, RTOL
, STEPMIN
, STEPMAX
, CFACTOR
;
75 int NMLCV
, NMLCF
, SCT
, PROPENSITY
, VOLUME
, IRCT
;
77 int Jac_NZ
, LU_Jac_NZ
, nzr
;
87 int Hess_NZ
, *iHess_i
, *iHess_j
, *iHess_k
;
90 /* if ValueDimension=1 KPP replaces parameters like NVAR etc. by their values in vector/matrix declarations */
91 char ValueDimension
= 0;
93 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
102 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
103 char * ascid(double x
)
107 sprintf(s
, "%12.6e", x
);
108 /* if (useDouble && ( (useLang==F77_LANG)||(useLang==F90_LANG) ) ) { */
109 if (useDouble
&& (useLang
==F77_LANG
))
110 s
[strlen(s
)-4] = 'd';
111 if (useDouble
&& (useLang
==F90_LANG
))
112 sprintf(s
, "%s_dp",s
);
116 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
117 NODE
* RConst( int n
)
119 switch( kr
[n
].type
) {
120 case NUMBER
: return Const( kr
[n
].val
.f
);
122 case EXPRESION
: return Elm( RCT
, n
);
129 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
134 NSPEC
= DefConst( "NSPEC", INT
, "Number of chemical species" );
135 NVAR
= DefConst( "NVAR", INT
, "Number of Variable species" );
136 NVARACT
= DefConst( "NVARACT", INT
, "Number of Active species" );
137 NFIX
= DefConst( "NFIX", INT
, "Number of Fixed species" );
138 NREACT
= DefConst( "NREACT", INT
, "Number of reactions" );
139 NVARST
= DefConst( "NVARST", INT
, "Starting of variables in conc. vect." );
140 NFIXST
= DefConst( "NFIXST", INT
, "Starting of fixed in conc. vect." );
141 NONZERO
= DefConst( "NONZERO", INT
, "Number of nonzero entries in Jacobian" );
142 LU_NONZERO
= DefConst( "LU_NONZERO", INT
, "Number of nonzero entries in LU factoriz. of Jacobian" );
143 CNVAR
= DefConst( "CNVAR", INT
, "(NVAR+1) Number of elements in compressed row format" );
144 CNEQN
= DefConst( "CNEQN", INT
, "(NREACT+1) Number stoicm elements in compressed col format" );
146 PI
= DefConst( "PI", real
, "Value of pi" );
148 VAR
= DefvElm( "VAR", real
, -NVAR
, "Concentrations of variable species (global)" );
149 FIX
= DefvElm( "FIX", real
, -NFIX
, "Concentrations of fixed species (global)" );
151 V
= DefvElm( "V", real
, -NVAR
, "Concentrations of variable species (local)" );
152 F
= DefvElm( "F", real
, -NFIX
, "Concentrations of fixed species (local)" );
154 V_USER
= DefvElm( "V_USER", real
, -NVAR
, "Concentration of variable species in USER's order" );
156 RCONST
= DefvElm( "RCONST", real
, -NREACT
, "Rate constants (global)" );
157 RCT
= DefvElm( "RCT", real
, -NREACT
, "Rate constants (local)" );
159 Vdot
= DefvElm( "Vdot", real
, -NVAR
, "Time derivative of variable species concentrations" );
160 P_VAR
= DefvElm( "P_VAR", real
, -NVAR
, "Production term" );
161 D_VAR
= DefvElm( "D_VAR", real
, -NVAR
, "Destruction term" );
164 JVS
= DefvElm( "JVS", real
, -LU_NONZERO
, "sparse Jacobian of variables" );
166 JV
= DefmElm( "JV", real
, -NVAR
, -NVAR
, "full Jacobian of variables" );
168 UV
= DefvElm( "UV", real
, -NVAR
, "User vector for variables" );
169 JUV
= DefvElm( "JUV", real
, -NVAR
, "Jacobian times user vector" );
170 JTUV
= DefvElm( "JTUV",real
, -NVAR
, "Jacobian transposed times user vector" );
172 X
= DefvElm( "X", real
, -NVAR
, "Vector for variables" );
173 XX
= DefvElm( "XX", real
, -NVAR
, "Vector for output variables" );
175 TIME
= DefElm( "TIME", real
, "Current integration time");
176 SUN
= DefElm( "SUN", real
, "Sunlight intensity between [0,1]");
177 TEMP
= DefElm( "TEMP", real
, "Temperature");
179 RTOLS
= DefElm( "RTOLS", real
, "(scalar) Relative tolerance");
180 TSTART
= DefElm( "TSTART", real
, "Integration start time");
181 TEND
= DefElm( "TEND", real
, "Integration end time");
182 DT
= DefElm( "DT", real
, "Integration step");
184 A
= DefvElm( "A", real
, -NREACT
, "Rate for each equation" );
186 ARP
= DefvElm( "ARP", real
, -NREACT
, "Reactant product in each equation" );
187 NJVRP
= DefConst( "NJVRP", INT
, "Length of sparse Jacobian JVRP" );
188 JVRP
= DefvElm( "JVRP", real
, -NJVRP
, "d ARP(1:NREACT)/d VAR (1:NVAR)" );
189 CROW_JVRP
= DefvElm( "CROW_JVRP", INT
, -CNEQN
, "Beginning of rows in JVRP" );
190 ICOL_JVRP
= DefvElm( "ICOL_JVRP", INT
, -NJVRP
, "Column indices in JVRP" );
191 IROW_JVRP
= DefvElm( "IROW_JVRP", INT
, -NJVRP
, "Row indices in JVRP" );
193 NTMPB
= DefConst( "NTMPB", INT
, "Length of Temporary Array B" );
194 BV
= DefvElm( "B", real
, -NTMPB
, "Temporary array" );
196 NSTOICM
= DefConst("NSTOICM", INT
, "Length of Sparse Stoichiometric Matrix" );
197 STOICM
= DefvElm( "STOICM", real
, -NSTOICM
, "Stoichiometric Matrix in compressed column format" );
198 IROW_STOICM
= DefvElm( "IROW_STOICM", INT
, -NSTOICM
, "Row indices in STOICM" );
199 ICOL_STOICM
= DefvElm( "ICOL_STOICM", INT
, -NSTOICM
, "Column indices in STOICM" );
200 CCOL_STOICM
= DefvElm( "CCOL_STOICM", INT
, -CNEQN
, "Beginning of columns in STOICM" );
202 DDMTYPE
= DefElm( "DDMTYPE", INT
, "DDM sensitivity w.r.t.: 0=init.val., 1=params" );
204 NTMPD2A
= DefConst( "NTMPD2A", INT
, "Length of Temporary Array D2A" );
205 D2A
= DefvElm( "D2A", real
, -NTMPD2A
, "Second derivatives of equation rates" );
206 NHESS
= DefConst( "NHESS", INT
, "Length of Sparse Hessian" );
207 HESS
= DefvElm( "HESS", real
, -NHESS
, "Hessian of Var (i.e. the 3-tensor d Jac / d Var)" );
208 IHESS_I
= DefvElm( "IHESS_I", INT
, -NHESS
, "Index i of Hessian element d^2 f_i/dv_j.dv_k" );
209 IHESS_J
= DefvElm( "IHESS_J", INT
, -NHESS
, "Index j of Hessian element d^2 f_i/dv_j.dv_k" );
210 IHESS_K
= DefvElm( "IHESS_K", INT
, -NHESS
, "Index k of Hessian element d^2 f_i/dv_j.dv_k" );
211 U1
= DefvElm( "U1", real
, -NVAR
, "User vector" );
212 U2
= DefvElm( "U2", real
, -NVAR
, "User vector" );
213 HU
= DefvElm( "HU", real
, -NVAR
, "Hessian times user vectors: (Hess x U2) * U1 = [d (Jac*U1)/d Var] * U2" );
214 HTU
= DefvElm( "HTU", real
, -NVAR
, "Transposed Hessian times user vectors: (Hess x U2)^T * U1 = [d (Jac^T*U1)/d Var] * U2 " );
216 KR
= DefeElm( "KR", 0 );
218 IROW
= DefvElm( "IROW", INT
, -NONZERO
, "Row indexes of the Jacobian of variables" );
219 ICOL
= DefvElm( "ICOL", INT
, -NONZERO
, "Column indexes of the Jacobian of variables" );
220 CROW
= DefvElm( "CROW", INT
, -CNVAR
, "Compressed row indexes of the Jacobian of variables" );
221 DIAG
= DefvElm( "DIAG", INT
, -CNVAR
, "Diagonal indexes of the Jacobian of variables" );
222 LU_IROW
= DefvElm( "LU_IROW", INT
, -LU_NONZERO
, "Row indexes of the LU Jacobian of variables" );
223 LU_ICOL
= DefvElm( "LU_ICOL", INT
, -LU_NONZERO
, "Column indexes of the LU Jacobian of variables" );
224 LU_CROW
= DefvElm( "LU_CROW", INT
, -CNVAR
, "Compressed row indexes of the LU Jacobian of variables" );
225 LU_DIAG
= DefvElm( "LU_DIAG", INT
, -CNVAR
, "Diagonal indexes of the LU Jacobian of variables" );
227 IV
= DefeElm( "IV", 0 );
229 C_DEFAULT
= DefvElm( "C_DEFAULT", real
, -NSPEC
, "Default concentration for all species" );
230 C
= DefvElm( "C", real
, -NSPEC
, "Concentration of all species" );
231 CL
= DefvElm( "CL", real
, -NSPEC
, "Concentration of all species (local)" );
232 DC
= DefvElm( "DC", real
, -NSPEC
, "Fluxes of all species" );
233 ATOL
= DefvElm( "ATOL", real
, -NSPEC
, "Absolute tolerance" );
234 RTOL
= DefvElm( "RTOL", real
, -NSPEC
, "Relative tolerance" );
236 STEPMIN
= DefElm( "STEPMIN", real
, "Lower bound for integration step");
237 STEPMAX
= DefElm( "STEPMAX", real
, "Upper bound for integration step");
239 NLOOKAT
= DefConst( "NLOOKAT", INT
, "Number of species to look at" );
240 LOOKAT
= DefvElm( "LOOKAT", INT
, -NLOOKAT
, "Indexes of species to look at" );
242 NMONITOR
= DefConst( "NMONITOR", INT
, "Number of species to monitor" );
243 MONITOR
= DefvElm( "MONITOR", INT
, -NMONITOR
, "Indexes of species to monitor" );
245 NMASS
= DefConst( "NMASS", INT
, "Number of atoms to check mass balance" );
246 SMASS
= DefvElm( "SMASS", STRING
, -NMASS
, "Names of atoms for mass balance" );
248 EQN_TAGS
= DefvElm( "EQN_TAGS", STRING
, -NREACT
, "Equation tags" );
249 EQN_NAMES
= DefvElm( "EQN_NAMES", DOUBLESTRING
, -NREACT
, "Equation names" );
250 SPC_NAMES
= DefvElm( "SPC_NAMES", STRING
, -NSPEC
, "Names of chemical species" );
252 CFACTOR
= DefElm( "CFACTOR", real
, "Conversion factor for concentration units");
254 /* Elements of Stochastic simulation*/
255 NMLCV
= DefvElm( "NmlcV", INT
, -NVAR
, "No. molecules of variable species" );
256 NMLCF
= DefvElm( "NmlcF", INT
, -NFIX
, "No. molecules of fixed species" );
257 SCT
= DefvElm( "SCT", real
, -NREACT
, "Stochastic rate constants" );
258 PROPENSITY
= DefvElm( "Prop", real
, -NREACT
, "Propensity vector" );
259 VOLUME
= DefElm( "Volume", real
, "Volume of the reaction container" );
260 IRCT
= DefElm( "IRCT", INT
, "Index of chemical reaction" );
262 for ( i
=0; i
<EqnNr
; i
++ )
263 for ( j
=0; j
<SpcNr
; j
++ )
264 structB
[i
][j
] = ( Stoich_Left
[j
][i
] != 0 ) ? 1 : 0;
266 /* Constant values are useful to declare vectors of this size */
267 if (ValueDimension
) {
268 varTable
[ NSPEC
] -> value
= max(SpcNr
,1);
269 varTable
[ NVAR
] -> value
= max(VarNr
,1);
270 varTable
[ NVARACT
] -> value
= max(VarActiveNr
,1);
271 varTable
[ NFIX
] -> value
= max(FixNr
,1);
272 varTable
[ NREACT
] -> value
= max(EqnNr
,1);
273 varTable
[ NVARST
] -> value
= Index(0);
274 varTable
[ NFIXST
] -> value
= Index(VarNr
);
278 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
279 int NonZero( int stru
, int start
, int end
,
280 int *row
, int *col
, int *crow
, int *diag
)
286 for (i
= 0; i
< end
-start
; i
++) {
287 crow
[i
] = Index(nElm
);
288 for (j
= 0; j
< end
-start
; j
++) {
289 if( (i
== j
) || ( (stru
) ? LUstructJ
[i
+start
][j
+start
]
290 : structJ
[i
+start
][j
+start
] ) ) {
291 row
[nElm
] = Index(i
);
292 col
[nElm
] = Index(j
);
296 diag
[i
] = Index(nElm
-1);
300 crow
[i
] = Index(nElm
);
301 diag
[i
] = Index(nElm
);
306 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
315 char *snames
[MAX_SPECIES
];
317 char *strans
[MAX_SPECIES
];
318 char *smass
[MAX_ATOMS
];
319 char *EQN_NAMES
[MAX_EQN
];
320 char *EQN_TAGS
[MAX_EQN
];
324 if ( (useLang
!= C_LANG
)&&(useLang
!= MATLAB_LANG
) ) return;
326 UseFile( driverFile
);
331 C_Inline("%s * %s = & %s[%d];", C_types
[real
],
332 varTable
[VAR
]->name
, varTable
[C
]->name
, 0 );
333 C_Inline("%s * %s = & %s[%d];", C_types
[real
],
334 varTable
[FIX
]->name
, varTable
[C
]->name
, VarNr
);
337 GlobalDeclare( RCONST
);
338 GlobalDeclare( TIME
);
339 GlobalDeclare( SUN
);
340 GlobalDeclare( TEMP
);
341 GlobalDeclare( RTOLS
);
342 GlobalDeclare( TSTART
);
343 GlobalDeclare( TEND
);
345 GlobalDeclare( ATOL
);
346 GlobalDeclare( RTOL
);
347 GlobalDeclare( STEPMIN
);
348 GlobalDeclare( STEPMAX
);
349 GlobalDeclare( CFACTOR
);
351 GlobalDeclare( VOLUME
);
353 MATLAB_Inline(" %s_Parameters;",rootFileName
);
354 MATLAB_Inline(" %s_Global_defs;",rootFileName
);
355 MATLAB_Inline(" %s_Sparse;",rootFileName
);
356 MATLAB_Inline(" %s_Monitor;",rootFileName
);
358 MATLAB_Inline(" %s_JacobianSP;",rootFileName
);
360 MATLAB_Inline(" %s_HessianSP;",rootFileName
);
362 MATLAB_Inline(" %s_StoichiomSP;",rootFileName
);
368 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
369 void GenerateMonitorData()
377 char *snames
[MAX_SPECIES
];
379 char *strans
[MAX_SPECIES
];
380 char *smass
[MAX_ATOMS
];
386 /* Allocate local data structures */
388 crow
= AllocIntegerVector( dim
, "crow in GenerateMonitorData");
389 diag
= AllocIntegerVector( dim
, "diag in GenerateMonitorData");
390 lookat
= AllocIntegerVector( dim
, "lookat in GenerateMonitorData");
391 moni
= AllocIntegerVector( dim
, "moni in GenerateMonitorData");
392 trans
= AllocIntegerVector( dim
, "trans in GenerateMonitorData");
394 UseFile( monitorFile
);
396 F77_Inline("%6sBLOCK DATA MONITOR_DATA\n", " " );
397 F77_Inline("%6sINCLUDE '%s_Parameters.h'", " ",rootFileName
);
398 F77_Inline("%6sINCLUDE '%s_Global.h'", " ",rootFileName
);
399 F77_Inline("%6sINTEGER i", " " );
401 /* InitDeclare( CFACTOR, 0, (void*)&cfactor ); */
405 for (i
= 0; i
< SpcNr
; i
++) {
406 snames
[i
] = SpeciesTable
[Code
[i
]].name
;
408 InitDeclare( SPC_NAMES
, SpcNr
, (void*)snames
);
411 for (i
= 0; i
< SpcNr
; i
++)
412 if ( SpeciesTable
[Code
[i
]].lookat
) {
413 lookat
[nlookat
] = Index(i
);
418 varTable
[ NLOOKAT
] -> value
= max(nlookat
,1);
419 InitDeclare( LOOKAT
, nlookat
, (void*)lookat
);
422 for (i
= 0; i
< SpcNr
; i
++)
423 if ( SpeciesTable
[Code
[i
]].moni
) {
424 moni
[nmoni
] = Index(i
);
428 if( nmoni
> MAX_MONITOR
) {
429 Warning( "%d species to monitorize. Too many, keeping %d.",
430 nmoni
, MAX_MONITOR
);
435 varTable
[ NMONITOR
] -> value
= max(nmoni
,1);
436 InitDeclare( MONITOR
, nmoni
, (void*)moni
);
439 for (i
= 0; i
< SpcNr
; i
++)
440 if ( SpeciesTable
[Code
[i
]].trans
) {
441 trans
[ntrans
] = Index(i
);
442 strans
[ntrans
] = SpeciesTable
[Code
[i
]].name
;
447 for (i
= 0; i
< AtomNr
; i
++)
448 if ( AtomTable
[i
].masscheck
) {
449 smass
[nmass
] = AtomTable
[i
].name
;
453 varTable
[ NMASS
] -> value
= max(nmass
,1);
454 InitDeclare( SMASS
, nmass
, (void*)smass
);
456 if ( (bufeqn
= (char*)malloc(MAX_EQNLEN
*EqnNr
+2))==NULL
) {
457 FatalError(-30,"GenerateMonitorData: Cannot allocate bufeqn (%d chars)",
462 for (i
= 0; i
< EqnNr
; i
++) {
467 InitDeclare( EQN_NAMES
, EqnNr
, (void*)seqn
);
472 for (i
= 0; i
< EqnNr
; i
++) {
473 seqn
[i
] = kr
[i
].label
;
475 InitDeclare( EQN_TAGS
, EqnNr
, (void*)seqn
);
479 WriteComment("INLINED global variables");
482 case C_LANG
: bprintf( InlineCode
[ C_DATA
].code
);
484 case F77_LANG
: bprintf( InlineCode
[ F77_DATA
].code
);
486 case F90_LANG
: bprintf( InlineCode
[ F90_DATA
].code
);
488 case MATLAB_LANG
: bprintf( InlineCode
[ MATLAB_DATA
].code
);
494 WriteComment("End INLINED global variables");
497 F77_Inline( "%6sEND\n\n", " " );
499 /* Free local data structures */
500 free(crow
); free(diag
); free(lookat
); free(moni
); free(trans
);
505 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
506 void GenerateJacobianSparseData()
515 if( !useJacSparse
) return;
517 /* Allocate local arrays */
519 irow
= AllocIntegerVector( dim
*dim
, "irow in GenerateJacobianSparseData" );
520 icol
= AllocIntegerVector( dim
*dim
, "icol in GenerateJacobianSparseData" );
521 crow
= AllocIntegerVector( dim
, "crow in GenerateJacobianSparseData" );
522 diag
= AllocIntegerVector( dim
, "diag in GenerateJacobianSparseData" );
524 UseFile( sparse_jacFile
);
527 WriteComment("Sparse Jacobian Data");
530 F77_Inline("%6sBLOCK DATA JACOBIAN_SPARSE_DATA\n", " " );
531 F77_Inline("%6sINCLUDE '%s_Sparse.h'", " ",rootFileName
);
532 F77_Inline("%6sINTEGER i"," ");
533 /* F90_Inline(" USE %s_Sparse", rootFileName); */
536 Jac_NZ
= NonZero( PLAIN
, 0, VarNr
, irow
, icol
, crow
, diag
);
537 LU_Jac_NZ
= NonZero( LU
, 0, VarNr
, irow
, icol
, crow
, diag
);
538 if (ValueDimension
) {
539 varTable
[NONZERO
] -> value
= Jac_NZ
;
540 varTable
[LU_NONZERO
] -> value
= LU_Jac_NZ
;
543 switch (useJacobian
) {
545 Jac_NZ
= NonZero( PLAIN
, 0, VarNr
, irow
, icol
, crow
, diag
);
546 InitDeclare( IROW
, Jac_NZ
, (void*)irow
);
547 InitDeclare( ICOL
, Jac_NZ
, (void*)icol
);
548 InitDeclare( CROW
, VarNr
+1, (void*)crow
);
549 InitDeclare( DIAG
, VarNr
+1, (void*)diag
);
552 LU_Jac_NZ
= NonZero( LU
, 0, VarNr
, irow
, icol
, crow
, diag
);
553 InitDeclare( LU_IROW
, LU_Jac_NZ
, (void*)irow
);
554 InitDeclare( LU_ICOL
, LU_Jac_NZ
, (void*)icol
);
555 InitDeclare( LU_CROW
, VarNr
+1, (void*)crow
);
556 InitDeclare( LU_DIAG
, VarNr
+1, (void*)diag
);
559 F77_Inline( "%6sEND\n\n", " " );
561 /* Free local arrays */
562 free(irow
); free(icol
); free(crow
); free(diag
);
567 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
568 void GenerateJacobianSparseHeader()
570 UseFile( sparse_dataFile
);
572 CommonName
= "SDATA";
575 WriteComment(" ----------> Sparse Jacobian Data");
578 switch (useJacobian
) {
580 ExternDeclare( IROW
);
581 ExternDeclare( ICOL
);
582 ExternDeclare( CROW
);
583 ExternDeclare( DIAG
);
586 ExternDeclare( LU_IROW
);
587 ExternDeclare( LU_ICOL
);
588 ExternDeclare( LU_CROW
);
589 ExternDeclare( LU_DIAG
);
598 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
604 int F_VAR
, FSPLIT_VAR
;
606 if( VarNr
== 0 ) return;
608 if (useLang
!= MATLAB_LANG
) /* Matlab generates an additional file per function */
609 UseFile( functionFile
);
611 F_VAR
= DefFnc( "Fun", 4, "time derivatives of variables - Agregate form");
612 FSPLIT_VAR
= DefFnc( "Fun_SPLIT", 5, "time derivatives of variables - Split form");
615 FunctionBegin( F_VAR
, V
, F
, RCT
, Vdot
);
617 FunctionBegin( FSPLIT_VAR
, V
, F
, RCT
, P_VAR
, D_VAR
);
619 if ( (useLang
==MATLAB_LANG
)&&(!useAggregate
) )
620 printf("\nWarning: in the function definition move P_VAR to output vars\n");
623 if ( useLang
!=F90_LANG
) { /* A is a module variable in F90 */
625 WriteComment("Local variables");
629 WriteComment("Computation of equation rates");
631 for(j
=0; j
<EqnNr
; j
++) {
634 for (i
= 0; i
< VarNr
; i
++)
635 if ( Stoich
[i
][j
] != 0 ) {
640 for (i
= 0; i
< VarNr
; i
++)
641 if ( Stoich_Right
[i
][j
] != 0 ) {
649 for (i
= 0; i
< VarNr
; i
++)
650 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
651 prod
= Mul( prod
, Elm( V
, i
) );
652 for ( ; i
< SpcNr
; i
++)
653 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
654 prod
= Mul( prod
, Elm( F
, i
- VarNr
) );
655 Assign( Elm( A
, j
), prod
);
662 WriteComment("Aggregate function");
664 for (i
= 0; i
< VarNr
; i
++) {
666 for (j
= 0; j
< EqnNr
; j
++)
667 sum
= Add( sum
, Mul( Const( Stoich
[i
][j
] ), Elm( A
, j
) ) );
668 Assign( Elm( Vdot
, i
), sum
);
674 WriteComment("Production function");
676 for (i
= 0; i
< VarNr
; i
++) {
678 for (j
= 0; j
< EqnNr
; j
++)
679 sum
= Add( sum
, Mul( Const( Stoich_Right
[i
][j
] ), Elm( A
, j
) ) );
680 Assign( Elm( P_VAR
, i
), sum
);
684 WriteComment("Destruction function");
686 for (i
= 0; i
< VarNr
; i
++) {
688 for(j
=0; j
<EqnNr
; j
++) {
689 if ( Stoich_Left
[i
][j
] == 0 ) continue;
690 prod
= Mul( RConst( j
), Const( Stoich_Left
[i
][j
] ) );
691 for (l
= 0; l
< VarNr
; l
++) {
692 m
=(int)Stoich_Left
[l
][j
] - (l
==i
);
693 for (k
= 1; k
<= m
; k
++ )
694 prod
= Mul( prod
, Elm( V
, l
) );
696 for ( ; l
< SpcNr
; l
++)
697 for (k
= 1; k
<= (int)Stoich_Left
[l
][j
]; k
++ )
698 prod
= Mul( prod
, Elm( F
, l
- VarNr
) );
699 sum
= Add( sum
, prod
);
701 Assign( Elm( D_VAR
, i
), sum
);
706 MATLAB_Inline("\n Vdot = Vdot(:);\n");
708 MATLAB_Inline("\n P_VAR = P_VAR(:);\n D_VAR = D_VAR(:);\n");
711 FunctionEnd( F_VAR
);
713 FunctionEnd( FSPLIT_VAR
);
715 FreeVariable( F_VAR
);
716 FreeVariable( FSPLIT_VAR
);
723 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
724 void GenerateStochastic()
726 int i
, j
, k
, l
, m
, n
, jnr
;
730 if( VarNr
== 0 ) return;
732 if (useLang
!= MATLAB_LANG
) /* Matlab generates an additional file per function */
733 UseFile( stochasticFile
);
735 /* ~~~~~~~> 1. PROPENSITY FUNCTION ~~~~~~~~~~~~ */
736 F_VAR
= DefFnc( "Propensity", 4, "Propensity function");
737 FunctionBegin( F_VAR
, NMLCV
, NMLCF
, SCT
, PROPENSITY
);
739 if ( (useLang
==MATLAB_LANG
)&&(!useAggregate
) )
740 printf("\nWarning: in the function definition move P_VAR to output vars\n");
744 for(j
=0; j
<EqnNr
; j
++) {
746 for (i
= 0; i
< VarNr
; i
++)
747 if ( Stoich
[i
][j
] != 0 ) {
752 prod
= Elm( SCT
, j
);
753 for (i
= 0; i
< VarNr
; i
++)
754 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
756 prod
= Mul( prod
, Elm( NMLCV
, i
) );
758 prod
= Mul( prod
, Add( Elm( NMLCV
, i
), Const(-k
+1) ) );
760 for ( ; i
< SpcNr
; i
++)
761 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
763 prod
= Mul( prod
, Elm( NMLCF
, i
- VarNr
) );
765 prod
= Mul( prod
, Add( Elm( NMLCF
, i
- VarNr
), Const(-k
+1) ) );
766 Assign( Elm( PROPENSITY
, j
), prod
);
770 MATLAB_Inline("\n Prop = Prop(:);\n");
771 FunctionEnd( F_VAR
);
772 FreeVariable( F_VAR
);
774 /* ~~~~~~~> 2. RATE CONVERSION ~~~~~~~~~~~~ */
775 F_VAR
= DefFnc( "StochasticRates", 3, "Convert deterministic rates to stochastic");
776 FunctionBegin( F_VAR
, RCT
, VOLUME
, SCT
);
777 WriteComment("No. of molecules = Concentration x Volume");
778 WriteComment("For a reaction with k reactants:");
779 WriteComment(" RCT [ (molec/Volume)^(1-k) * sec^(-1) ]");
780 WriteComment(" SCT [ (molec)^(1-k) * sec^(-1) ] = RCT*Volume^(k-1)");
781 WriteComment("For p molecules of the same type: SCT = SCT/(p!)");
785 for(j
=0; j
<EqnNr
; j
++) {
786 prod
= Elm( RCT
, j
);
788 for (i
= 0; i
< SpcNr
; i
++)
789 m
+= (int)Stoich_Left
[i
][j
];
790 for ( i
=2 ; i
<= m
; i
++)
791 prod
= Mul( prod
, Elm(VOLUME
, 1) );
793 for (i
= 0; i
< SpcNr
; i
++)
794 for (k
= 2; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
796 prod
= Div( prod
, Const( n
) );
797 Assign( Elm( SCT
, j
), prod
);
800 MATLAB_Inline("\n SCT = SCT(:);\n");
801 FunctionEnd( F_VAR
);
802 FreeVariable( F_VAR
);
804 /* ~~~~~~~> 3. THE CHANGE IN NUMBER OF MOLECULES */
805 if (useLang
== MATLAB_LANG
) {
806 F_VAR
= DefFnc( "MoleculeChange", 3, "Change in the number of molecules");
807 FunctionBegin( F_VAR
, IRCT
, NMLCV
, NMLCV
);
809 F_VAR
= DefFnc( "MoleculeChange", 2, "Change in the number of molecules");
810 FunctionBegin( F_VAR
, IRCT
, NMLCV
);
815 F90_Inline("\n SELECT CASE (IRCT)\n");
816 C_Inline ("\n switch (IRCT) { \n");
817 MATLAB_Inline("\n switch (IRCT) \n");
818 for(j
=0; j
<EqnNr
; j
++) {
821 F77_Inline("\n%6sIF (IRCT.EQ.%d) THEN"," ",jnr
);
823 F77_Inline("\n%6sELSEIF (IRCT.EQ.%d) THEN "," ",jnr
);
824 F90_Inline("\n CASE (%d) ",jnr
);
825 C_Inline("\n case %d: ",jnr
);
826 MATLAB_Inline("\n case %d, ",jnr
);
827 for (i
= 0; i
< VarNr
; i
++) {
828 if ( Stoich_Left
[i
][j
] || Stoich_Right
[i
][j
] )
829 Assign( Elm( NMLCV
, i
), Add(Elm( NMLCV
, i
),
830 Const(Stoich_Right
[i
][j
]-Stoich_Left
[i
][j
])) );
832 C_Inline(" break;",j
);
834 F77_Inline("\n%6sEND IF ! n\n"," ");
835 F90_Inline("\n END SELECT\n");
836 C_Inline("\n } /* switch (IRCT) */ \n");
837 MATLAB_Inline("\n end\n");
839 FunctionEnd( F_VAR
);
840 FreeVariable( F_VAR
);
847 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
848 void GenerateReactantProd()
855 if( VarNr
== 0 ) return;
857 UseFile( stoichiomFile
);
859 F_STOIC
= DefFnc( "ReactantProd",3, "Reactant Products in each equation");
861 FunctionBegin( F_STOIC
, V
, F
, ARP
);
864 WriteComment("Reactant Products in each equation are useful in the");
865 WriteComment(" stoichiometric formulation of mass action law");
867 for(j
=0; j
<EqnNr
; j
++) {
870 for (i
= 0; i
< VarNr
; i
++)
871 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
872 prod
= Mul( prod
, Elm( V
, i
) );
873 for ( ; i
< SpcNr
; i
++)
874 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
875 prod
= Mul( prod
, Elm( F
, i
- VarNr
) );
876 Assign( Elm( ARP
, j
), prod
);
880 FunctionEnd( F_STOIC
);
881 FreeVariable( F_STOIC
);
887 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
888 void GenerateJacReactantProd()
890 int i
, j
, k
, l
, m
, JVRP_NZ
, newrow
;
893 int crow_JVRP
[MAX_EQN
], icol_JVRP
[MAX_EQN
*MAX_SPECIES
];
894 int irow_JVRP
[MAX_EQN
*MAX_SPECIES
];
896 if( VarNr
== 0 ) return;
898 UseFile( stoichiomFile
);
900 F_STOIC
= DefFnc( "JacReactantProd",3, "Jacobian of Reactant Products vector");
902 FunctionBegin( F_STOIC
, V
, F
, JVRP
);
906 WriteComment("Reactant Products in each equation are useful in the");
907 WriteComment(" stoichiometric formulation of mass action law");
908 WriteComment("Below we compute the Jacobian of the Reactant Products vector");
909 WriteComment(" w.r.t. variable species: d ARP(1:NREACT) / d Var(1:NVAR)");
914 for ( i
=0; i
<EqnNr
; i
++ ) {
916 crow_JVRP
[i
] = JVRP_NZ
+1;
917 for ( j
=0; j
<VarNr
; j
++ ) {
918 if ( Stoich_Left
[j
][i
] != 0 ) {
920 icol_JVRP
[JVRP_NZ
] = j
;
921 irow_JVRP
[JVRP_NZ
] = i
;
922 if ( newrow
== 0 ) { /* a new row begins here */
923 crow_JVRP
[i
] = JVRP_NZ
;
926 prod
= Const( Stoich_Left
[j
][i
] ) ;
927 for (l
= 0; l
< VarNr
; l
++) {
928 m
= (int)Stoich_Left
[l
][i
] - (l
==j
);
929 for (k
= 1; k
<= m
; k
++ )
930 prod
= Mul( prod
, Elm( V
, l
) );
932 for ( ; l
< SpcNr
; l
++)
933 for (k
= 1; k
<= (int)Stoich_Left
[l
][i
]; k
++ )
934 prod
= Mul( prod
, Elm( F
, l
- VarNr
) );
936 WriteComment("JVRP(%d) = dARP(%d)/dV(%d)",Index(JVRP_NZ
),Index(i
),Index(j
));
937 Assign( Elm( JVRP
, JVRP_NZ
), prod
);
941 crow_JVRP
[EqnNr
] = JVRP_NZ
+ 1;
943 varTable
[ NJVRP
] -> value
= JVRP_NZ
+ 1;
945 FunctionEnd( F_STOIC
);
946 FreeVariable( F_STOIC
);
949 UseFile( sparse_stoicmFile
);
951 WriteComment("Row-compressed sparse data for the Jacobian of reaction products JVRP");
952 F77_Inline("%6sBLOCK DATA JVRP_SPARSE_DATA\n", " " );
953 F77_Inline("%6sINCLUDE '%s_Sparse.h'", " ", rootFileName
);
954 F77_Inline("%6sINTEGER i", " ");
955 /* F90_Inline(" USE %s_Sparse", rootFileName); */
956 if( (useLang
==F77_LANG
)||(useLang
==F90_LANG
) ) {
957 for (k
=0; k
<JVRP_NZ
; k
++) {
961 for (k
=0; k
<EqnNr
+1; k
++)
964 InitDeclare( CROW_JVRP
, EqnNr
+1, (void*)crow_JVRP
);
965 InitDeclare( ICOL_JVRP
, JVRP_NZ
+ 1, (void*)icol_JVRP
);
966 InitDeclare( IROW_JVRP
, JVRP_NZ
+ 1, (void*)irow_JVRP
);
968 F77_Inline( "%6sEND\n\n", " " );
972 UseFile( param_headerFile
);
973 CommonName
= "GDATA";
975 DeclareConstant( NJVRP
, ascii( JVRP_NZ
+ 1 ) );
981 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
985 int nElm
, nonzeros_B
;
988 if( VarNr
== 0 ) return;
989 if (useJacobian
== JAC_OFF
) return;
991 if (useLang
!= MATLAB_LANG
) /* Matlab generates an additional file per function */
992 UseFile( jacobianFile
);
994 Jac_SP
= DefFnc( "Jac_SP", 4,
995 "the Jacobian of Variables in sparse matrix representation");
996 Jac
= DefFnc( "Jac", 4, "the Jacobian of Variables");
999 FunctionBegin( Jac_SP
, V
, F
, RCT
, JVS
);
1001 FunctionBegin( Jac
, V
, F
, RCT
, JV
);
1003 if (useLang
== MATLAB_LANG
) {
1004 switch (useJacobian
) {
1006 ExternDeclare(IROW
); ExternDeclare(ICOL
);
1009 ExternDeclare(LU_IROW
); ExternDeclare(LU_ICOL
);
1014 /* Each nonzero entry of B now counts its rank */
1016 for ( i
=0; i
<EqnNr
; i
++ )
1017 for ( j
=0; j
<SpcNr
; j
++ )
1018 if ( structB
[i
][j
] != 0 ) {
1020 structB
[i
][j
] = nonzeros_B
;
1023 if ( (useLang
==C_LANG
)||(useLang
==F77_LANG
)||(useLang
==F90_LANG
) ) {
1025 WriteComment("Local variables");
1026 /* DeclareConstant( NTMPB, ascii( nonzeros_B ) ); */
1027 varTable
[ NTMPB
] -> value
= nonzeros_B
;
1033 for ( i
=0; i
<EqnNr
; i
++ ) {
1034 for ( j
=0; j
<VarNr
; j
++ ) {
1035 if ( Stoich_Left
[j
][i
] != 0 ) {
1036 prod
= Mul( RConst( i
), Const( Stoich_Left
[j
][i
] ) );
1037 for (l
= 0; l
< VarNr
; l
++) {
1038 m
= (int)Stoich_Left
[l
][i
] - (l
==j
);
1039 for (k
= 1; k
<= m
; k
++ )
1040 prod
= Mul( prod
, Elm( V
, l
) );
1042 for ( ; l
< SpcNr
; l
++)
1043 for (k
= 1; k
<= (int)Stoich_Left
[l
][i
]; k
++ )
1044 prod
= Mul( prod
, Elm( F
, l
- VarNr
) );
1046 WriteComment("B(%d) = dA(%d)/dV(%d)",Index(structB
[i
][j
]-1),Index(i
),Index(j
));
1047 Assign( Elm( BV
, structB
[i
][j
]-1 ), prod
);
1054 WriteComment("Construct the Jacobian terms from B's");
1056 if ( useJacSparse
) {
1057 for (i
= 0; i
< VarNr
; i
++) {
1058 for (j
= 0; j
< VarNr
; j
++) {
1059 if( LUstructJ
[i
][j
] ) {
1061 for (k
= 0; k
< EqnNr
; k
++) {
1062 if( Stoich
[i
][k
]*structB
[k
][j
] != 0 )
1063 sum
= Add( sum
, Mul( Const( Stoich
[i
][k
] ), Elm( BV
, structB
[k
][j
]-1 ) ) );
1066 WriteComment("JVS(%d) = Jac_FULL(%d,%d)",
1067 Index(nElm
),Index(i
),Index(j
));
1068 Assign( Elm( JVS
, nElm
), sum
);
1072 Assign( Elm( JVS
, nElm
), Const(0) );
1078 } else { /* full Jacobian */
1079 for (i
= 0; i
< VarNr
; i
++) {
1080 for (j
= 0; j
< VarNr
; j
++) {
1081 if( structJ
[i
][j
] ) {
1083 for (k
= 0; k
< EqnNr
; k
++) {
1084 if( Stoich
[i
][k
]*structB
[k
][j
] != 0 )
1085 sum
= Add( sum
, Mul( Const( Stoich
[i
][k
] ), Elm( BV
, structB
[k
][j
]-1 ) ) );
1087 Assign( Elm( JV
, i
, j
), sum
);
1093 if (useLang
== MATLAB_LANG
) {
1094 switch (useJacobian
) {
1096 MATLAB_Inline("\n JVS = sparse(IROW,ICOL,JVS,%d,%d);\n",VarNr
,VarNr
);
1099 MATLAB_Inline("\n JVS = sparse(LU_IROW,LU_ICOL,JVS,%d,%d);\n",VarNr
,VarNr
);
1105 FunctionEnd( Jac_SP
);
1109 FreeVariable( Jac_SP
);
1110 FreeVariable( Jac
);
1119 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1120 void GenerateHessian()
1121 /* Unlike Hess, this function deffers the sparse Data structure generation */
1125 int l
, m
, i1
, i2
, nElm
;
1126 int F_Hess
, F_Hess_VEC
, F_HessTR_VEC
;
1127 int *coeff_j
, *coeff_i1
, *coeff_i2
;
1130 if ( VarNr
== 0 ) return;
1132 if (useLang
!= MATLAB_LANG
) /* Matlab generates an additional file per function */
1133 UseFile( hessianFile
);
1135 /* Calculate the number of nonzero terms of the form d^2 A(j)/ ( d v(i1) d v(i2) )*/
1137 for(j
=0; j
<EqnNr
; j
++)
1138 for (i1
= 0; i1
< VarNr
; i1
++)
1139 for (i2
= i1
; i2
< VarNr
; i2
++)
1141 if (Stoich_Left
[i1
][j
]>=2)
1143 } else { /* i1 != i2 */
1144 if ( (Stoich_Left
[i1
][j
]>=1)&&(Stoich_Left
[i2
][j
]>=1) )
1148 /* Allocate temporary index arrays */
1149 coeff_j
= AllocIntegerVector(nElm
, "coeff_j in GenerateHess");
1150 coeff_i1
= AllocIntegerVector(nElm
, "coeff_i1 in GenerateHess");
1151 coeff_i2
= AllocIntegerVector(nElm
, "coeff_i2 in GenerateHess");
1153 /* Fill in temporary index arrays */
1155 for(j
=0; j
<EqnNr
; j
++)
1156 for (i1
= 0; i1
< VarNr
; i1
++)
1157 for (i2
= i1
; i2
< VarNr
; i2
++)
1159 if (Stoich_Left
[i1
][j
]>=2) {
1160 coeff_j
[nElm
] = j
; coeff_i1
[nElm
] = i1
; coeff_i2
[nElm
] = i2
;
1163 } else { /* i1 != i2 */
1164 if ( (Stoich_Left
[i1
][j
]>=1)&&(Stoich_Left
[i2
][j
]>=1) ) {
1165 coeff_j
[nElm
] = j
; coeff_i1
[nElm
] = i1
; coeff_i2
[nElm
] = i2
;
1169 /* Number of nonzero terms of the form d^2 f(i)/ ( d v(i1) d v(i2) ) */
1171 for (i
= 0; i
< VarNr
; i
++)
1172 for (i1
= 0; i1
< VarNr
; i1
++)
1173 for (i2
= i1
; i2
< VarNr
; i2
++) {
1175 for (j
= 0; j
< EqnNr
; j
++)
1176 if ( Stoich
[i
][j
] != 0 )
1177 for (k
= 0; k
< nElm
; k
++)
1178 if ( (coeff_j
[k
]==j
) && (coeff_i1
[k
]==i1
)
1179 && (coeff_i2
[k
]==i2
) ) {
1182 if (Djv_isElm
== 1) Hess_NZ
++ ;
1183 } /* for i, i1, i2 */
1185 varTable
[ NHESS
] -> value
= max( Hess_NZ
, 1 );
1187 /* Allocate temporary index arrays */
1188 iHess_i
= AllocIntegerVector(Hess_NZ
, "iHess_i in GenerateHess");
1189 iHess_j
= AllocIntegerVector(Hess_NZ
, "iHess_j in GenerateHess");
1190 iHess_k
= AllocIntegerVector(Hess_NZ
, "iHess_k in GenerateHess");
1192 F_Hess
= DefFnc( "Hessian", 4, "function for Hessian (Jac derivative w.r.t. variables)");
1193 FunctionBegin( F_Hess
, V
, F
, RCT
, HESS
);
1195 WriteComment("--------------------------------------------------------");
1196 WriteComment("Note: HESS is represented in coordinate sparse format: ");
1197 WriteComment(" HESS(m) = d^2 f_i / dv_j dv_k = d Jac_{i,j} / dv_k");
1198 WriteComment(" where i = IHESS_I(m), j = IHESS_J(m), k = IHESS_K(m).");
1199 WriteComment("--------------------------------------------------------");
1200 WriteComment("Note: d^2 f_i / dv_j dv_k = d^2 f_i / dv_k dv_j, ");
1201 WriteComment(" therefore only the terms d^2 f_i / dv_j dv_k");
1202 WriteComment(" with j <= k are computed and stored in HESS.");
1203 WriteComment("--------------------------------------------------------");
1205 if ( (useLang
==C_LANG
)||(useLang
==F77_LANG
)||(useLang
==F90_LANG
) ) {
1207 WriteComment("Local variables");
1208 /* DeclareConstant( NTMPD2A, ascii( max( nElm, 1 ) ) ); */
1209 varTable
[ NTMPD2A
] -> value
= max( nElm
, 1 );
1214 WriteComment("Computation of the second derivatives of equation rates");
1216 /* Generate d^2 A(j)/ ( d v(i1) d v(i2) )*/
1218 for(j
=0; j
<EqnNr
; j
++)
1219 for (i1
= 0; i1
< VarNr
; i1
++)
1220 for (i2
= i1
; i2
< VarNr
; i2
++) {
1224 if (Stoich_Left
[i1
][j
]>=2) {
1226 for (i
= 0; i
< i1
; i
++)
1227 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1228 prod
= Mul( prod
, Elm( V
, i
) );
1229 prod
= Mul( prod
, Const( Stoich_Left
[i1
][j
] ) );
1230 prod
= Mul( prod
, Const( Stoich_Left
[i1
][j
]-1 ) );
1231 for (k
= 1; k
<= (int)Stoich_Left
[i1
][j
]-2; k
++ )
1232 prod
= Mul( prod
, Elm( V
, i1
) );
1233 for (i
= i1
+1; i
< VarNr
; i
++)
1234 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1235 prod
= Mul( prod
, Elm( V
, i
) );
1236 for ( ; i
< SpcNr
; i
++)
1237 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1238 prod
= Mul( prod
, Elm( F
, i
- VarNr
) );
1239 /* Comment the D2A */
1240 WriteComment("D2A(%d) = d^2 A(%d)/{dV(%d)dV(%d)}",Index(nElm
),Index(j
),Index(i1
),Index(i2
));
1241 Assign( Elm( D2A
, nElm
), prod
);
1243 } /* if (Stoich_Left[i1][j]>=2) */
1245 } else { /* i1 != i2 */
1246 if ( (Stoich_Left
[i1
][j
]>=1)&&(Stoich_Left
[i2
][j
]>=1) ) {
1248 for (i
= 0; i
< i1
; i
++)
1249 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1250 prod
= Mul( prod
, Elm( V
, i
) );
1251 prod
= Mul( prod
, Const( Stoich_Left
[i1
][j
] ) );
1252 for (k
= 1; k
<= (int)Stoich_Left
[i1
][j
]-1; k
++ )
1253 prod
= Mul( prod
, Elm( V
, i1
) );
1254 for (i
= i1
+1; i
< i2
; i
++)
1255 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1256 prod
= Mul( prod
, Elm( V
, i
) );
1257 prod
= Mul( prod
, Const( Stoich_Left
[i2
][j
] ) );
1258 for (k
= 1; k
<= (int)Stoich_Left
[i2
][j
]-1; k
++ )
1259 prod
= Mul( prod
, Elm( V
, i2
) );
1260 for (i
= i2
+1; i
< VarNr
; i
++)
1261 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1262 prod
= Mul( prod
, Elm( V
, i
) );
1263 for ( ; i
< SpcNr
; i
++)
1264 for (k
= 1; k
<= (int)Stoich_Left
[i
][j
]; k
++ )
1265 prod
= Mul( prod
, Elm( F
, i
- VarNr
) );
1266 /* Comment the D2A */
1267 WriteComment("D2A(%d) = d^2 A(%d) / dV(%d)dV(%d)",
1268 Index(nElm
),Index(j
),Index(i1
),Index(i2
));
1269 Assign( Elm( D2A
, nElm
), prod
);
1271 } /* if ( (Stoich_Left[i1][j]>=1)&&(Stoich_Left[i2][j]>=1) ) */
1274 } /* for j, i1, i2 */
1277 WriteComment("Computation of the Jacobian derivative");
1279 /* Generate d^2 f(i)/ ( d v(i1) d v(i2) ) */
1281 for (i
= 0; i
< VarNr
; i
++)
1282 for (i1
= 0; i1
< VarNr
; i1
++)
1283 for (i2
= i1
; i2
< VarNr
; i2
++) {
1286 for (j
= 0; j
< EqnNr
; j
++)
1287 if ( Stoich
[i
][j
] != 0 )
1288 for (k
= 0; k
< nElm
; k
++)
1289 if ( (coeff_j
[k
]==j
) && (coeff_i1
[k
]==i1
)
1290 && (coeff_i2
[k
]==i2
) ) {
1292 Mul( Const( Stoich
[i
][j
] ), Elm( D2A
, k
) ) );
1295 if (Djv_isElm
== 1) {
1296 WriteComment("HESS(%d) = d^2 Vdot(%d)/{dV(%d)dV(%d)} = d^2 Vdot(%d)/{dV(%d)dV(%d)}",
1297 Index(Hess_NZ
),Index(i
),Index(i1
),Index(i2
),Index(i
),Index(i2
),Index(i1
));
1298 Assign( Elm( HESS
, Hess_NZ
), sum
);
1299 iHess_i
[ Hess_NZ
] = i
;
1300 iHess_j
[ Hess_NZ
] = i1
;
1301 iHess_k
[ Hess_NZ
] = i2
;
1305 } /* for i, i1, i2 */
1308 /* free temporary index arrays */
1309 free(coeff_j
); free(coeff_i1
); free(coeff_i2
);
1311 MATLAB_Inline("\n HESS = HESS(:);");
1313 FunctionEnd( F_Hess
);
1315 FreeVariable( F_Hess
);
1318 F_HessTR_VEC
= DefFnc( "HessTR_Vec", 4, "Hessian transposed times user vectors");
1319 FunctionBegin( F_HessTR_VEC
, HESS
, U1
, U2
, HTU
);
1320 WriteComment("Compute the vector HTU =(Hess x U2)^T * U1 = d (Jac^T*U1)/d Var * U2 ");
1322 for (i
=0; i
<VarNr
; i
++) {
1324 for (k
=0; k
<Hess_NZ
; k
++) {
1327 Mul( Elm( HESS
, k
),
1328 Mul( Elm( U1
, iHess_i
[k
] ), Elm( U2
, iHess_k
[k
] ) ) ) );
1329 else if (iHess_k
[k
]==i
)
1331 Mul( Elm( HESS
, k
),
1332 Mul( Elm( U1
, iHess_i
[k
] ), Elm( U2
, iHess_j
[k
] ) ) ) );
1334 Assign( Elm( HTU
, i
), sum
);
1337 MATLAB_Inline("\n HTU = HTU(:);");
1339 FunctionEnd( F_HessTR_VEC
);
1340 FreeVariable( F_HessTR_VEC
);
1343 F_Hess_VEC
= DefFnc( "Hess_Vec", 4, "Hessian times user vectors");
1344 FunctionBegin( F_HessTR_VEC
, HESS
, U1
, U2
, HU
);
1345 WriteComment("Compute the vector HU =(Hess x U2) * U1 = d (Jac*U1)/d Var * U2 ");
1347 for (i
=0; i
<VarNr
; i
++) {
1349 for (m
=0; m
<Hess_NZ
; m
++) {
1350 if (iHess_i
[m
]==i
) {
1355 Mul( Elm( HESS
, m
),
1356 Mul( Elm( U1
, k
), Elm( U2
, k
) ) ) );
1359 /* This is the optimized code. It can lead to problems when
1360 splitting for continuation lines. Therefore we
1361 use the non-optimized code below the comment.
1363 Mul( Elm( HESS, m ),
1364 Add( Mul( Elm( U1, j ), Elm( U2, k ) ),
1365 Mul( Elm( U1, k ), Elm( U2, j ) ) ) ) ); */
1367 Mul( Elm( HESS
, m
),
1368 Mul( Elm( U1
, j
), Elm( U2
, k
) ) ) );
1370 Mul( Elm( HESS
, m
),
1371 Mul( Elm( U1
, k
), Elm( U2
, j
) ) ) );
1375 Assign( Elm( HU
, i
), sum
);
1378 MATLAB_Inline("\n HU = HU(:);");
1380 FunctionEnd( F_Hess_VEC
);
1381 FreeVariable( F_Hess_VEC
);
1387 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1388 void GenerateHessianSparseData()
1393 UseFile( sparse_hessFile
);
1398 WriteComment("Hessian Sparse Data");
1401 F77_Inline("%6sBLOCK DATA HESSIAN_SPARSE_DATA\n", " " );
1402 F77_Inline("%6sINCLUDE '%s_Sparse.h'", " ", rootFileName
);
1403 F77_Inline("%6sINTEGER i", " ");
1404 /* F90_Inline(" USE %s_Sparse", rootFileName); */
1406 if( (useLang
==F77_LANG
)||(useLang
==F90_LANG
)||(useLang
==MATLAB_LANG
) ) {
1407 for (k
=0; k
<Hess_NZ
; k
++) {
1408 iHess_i
[k
]++; iHess_j
[k
]++; iHess_k
[k
]++;
1412 InitDeclare( IHESS_I
, Hess_NZ
, (void*)iHess_i
);
1413 InitDeclare( IHESS_J
, Hess_NZ
, (void*)iHess_j
);
1414 InitDeclare( IHESS_K
, Hess_NZ
, (void*)iHess_k
);
1416 if( (useLang
==F77_LANG
)||(useLang
==F90_LANG
) ) {
1417 for (k
=0; k
<Hess_NZ
; k
++) {
1418 iHess_i
[k
]--; iHess_j
[k
]--; iHess_k
[k
]--;
1423 F77_Inline( "%6sEND\n\n", " " );
1429 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1430 void GenerateHessianSparseHeader()
1432 UseFile( sparse_dataFile
);
1434 CommonName
= "HESSDATA";
1437 WriteComment(" ----------> Sparse Hessian Data");
1440 ExternDeclare( IHESS_I
);
1441 ExternDeclare( IHESS_J
);
1442 ExternDeclare( IHESS_K
);
1451 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1452 void GenerateStoicmSparseData()
1454 int i
,j
,k
, nnz_stoicm
;
1456 int irow_stoicm[MAX_SPECIES*MAX_EQN];
1457 int ccol_stoicm[MAX_EQN+2];
1458 int icol_stoicm[MAX_SPECIES*MAX_EQN];
1459 double stoicm[MAX_SPECIES*MAX_EQN];
1467 /* Compute the sparsity structure and allocate data structure vectors */
1469 for (j
=0; j
<EqnNr
; j
++)
1470 for (i
=0; i
<VarNr
; i
++)
1471 if ( Stoich
[i
][j
] != 0.0 )
1473 if ( (irow_stoicm
=(int*)calloc(nnz_stoicm
+2,sizeof(int)) ) == NULL
)
1474 FatalError(-30,"GenerateStoicmSparseData: Cannot allocate irow_stoicm");
1475 if ( (ccol_stoicm
=(int*)calloc(EqnNr
+2,sizeof(int)) ) == NULL
)
1476 FatalError(-30,"GenerateStoicmSparseData: Cannot allocate ccol_stoicm");
1477 if ( (icol_stoicm
=(int*)calloc(nnz_stoicm
+2,sizeof(int)) ) == NULL
)
1478 FatalError(-30,"GenerateStoicmSparseData: Cannot allocate icol_stoicm");
1479 if ( (stoicm
=(double*)calloc(nnz_stoicm
+2,sizeof(double)) ) == NULL
)
1480 FatalError(-30,"GenerateStoicmSparseData: Cannot allocate stoicm");
1482 UseFile( sparse_stoicmFile
);
1485 for (j
=0; j
<EqnNr
; j
++) {
1486 ccol_stoicm
[ j
] = nnz_stoicm
;
1487 for (i
=0; i
<VarNr
; i
++) {
1488 if ( Stoich
[i
][j
] != 0 ) {
1489 irow_stoicm
[ nnz_stoicm
] = i
;
1490 icol_stoicm
[ nnz_stoicm
] = j
;
1491 stoicm
[ nnz_stoicm
] = Stoich
[i
][j
];
1496 ccol_stoicm
[ EqnNr
] = nnz_stoicm
;
1498 if( (useLang
==F77_LANG
)||(useLang
==F90_LANG
) ) {
1499 for (k
=0; k
<nnz_stoicm
; k
++) {
1500 irow_stoicm
[k
]++; icol_stoicm
[k
]++;
1502 for (k
=0; k
<=EqnNr
; k
++) {
1509 WriteComment(" Stoichiometric Matrix in Compressed Column Sparse Format");
1511 F77_Inline("%6sBLOCK DATA STOICM_MATRIX\n", " " );
1512 F77_Inline("%6sINCLUDE '%s_Sparse.h'", " ", rootFileName
);
1513 F77_Inline("%6sINTEGER i", " ");
1514 /* F90_Inline(" USE %s_Sparse", rootFileName); */
1515 InitDeclare( CCOL_STOICM
, EqnNr
+1, (void*)ccol_stoicm
);
1516 InitDeclare( IROW_STOICM
, nnz_stoicm
, (void*)irow_stoicm
);
1517 InitDeclare( ICOL_STOICM
, nnz_stoicm
, (void*)icol_stoicm
);
1518 InitDeclare( STOICM
, nnz_stoicm
, (void*)stoicm
);
1520 F77_Inline( "%6sEND\n\n", " " );
1523 UseFile( param_headerFile
);
1524 CommonName
= "GDATA";
1526 DeclareConstant( NSTOICM
, ascii( max( nnz_stoicm
, 1 ) ) );
1528 /* Free data structure vectors */
1529 free(irow_stoicm
); free(ccol_stoicm
); free(icol_stoicm
); free(stoicm
);
1532 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1533 void GenerateStoicmSparseHeader()
1535 UseFile( sparse_dataFile
);
1538 WriteComment(" ----------> Sparse Stoichiometric Matrix");
1540 CommonName
= "STOICM_VALUES";
1541 ExternDeclare( STOICM
);
1542 CommonName
= "STOICM_DATA";
1543 ExternDeclare( IROW_STOICM
);
1544 ExternDeclare( CCOL_STOICM
);
1545 ExternDeclare( ICOL_STOICM
);
1549 WriteComment(" ----------> Sparse Data for Jacobian of Reactant Products");
1551 CommonName
= "JVRP";
1552 ExternDeclare( ICOL_JVRP
);
1553 ExternDeclare( IROW_JVRP
);
1554 ExternDeclare( CROW_JVRP
);
1562 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1563 void GenerateJacVect()
1569 if( useLang
== MATLAB_LANG
) return;
1571 if( VarNr
== 0 ) return;
1573 UseFile( jacobianFile
);
1574 Jac_VEC
= DefFnc( "Jac_Vec", 3,
1575 "function for sparse multiplication: square Jacobian times vector");
1576 Jac_SP_VEC
= DefFnc( "Jac_SP_Vec", 3,
1577 "function for sparse multiplication: sparse Jacobian times vector");
1579 if ( useJacSparse
) {
1580 FunctionBegin( Jac_SP_VEC
, JVS
, UV
, JUV
);
1582 for( i
= 0; i
< VarNr
; i
++) {
1584 for( j
= 0; j
< VarNr
; j
++ )
1585 if( LUstructJ
[i
][j
] ) {
1586 if( structJ
[i
][j
] != 0 )
1587 sum
= Add( sum
, Mul( Elm( JVS
, nElm
), Elm( UV
, j
) ) );
1590 Assign( Elm( JUV
, i
), sum
);
1592 FunctionEnd( Jac_SP_VEC
);
1596 FunctionBegin( Jac_VEC
, JV
, UV
, JUV
);
1597 for( i
= 0; i
< VarNr
; i
++) {
1599 for( j
= 0; j
< VarNr
; j
++ )
1600 if( structJ
[i
][j
] != 0 )
1601 sum
= Add( sum
, Mul( Elm( JV
, i
, j
), Elm( UV
, j
) ) );
1602 Assign( Elm( JUV
, i
), sum
);
1604 FunctionEnd( Jac_VEC
);
1607 FreeVariable( Jac_VEC
);
1608 FreeVariable( Jac_SP_VEC
);
1613 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1614 void GenerateJacTRVect()
1621 if( useLang
== MATLAB_LANG
) return;
1623 if ( VarNr
== 0 ) return;
1625 UseFile( jacobianFile
);
1627 JacTR_VEC
= DefFnc( "JacTR_Vec", 3,
1628 "sparse multiplication: square Jacobian transposed times vector");
1629 JacTR_SP_VEC
= DefFnc( "JacTR_SP_Vec", 3,
1630 "sparse multiplication: sparse Jacobian transposed times vector");
1632 if ( useJacSparse
) {
1634 /* The temporary array of structure */
1635 TmpStruct
= AllocIntegerMatrix( VarNr
, VarNr
, "TmpStruct in GenerateJacTRVect" );
1638 for( i
= 0; i
< VarNr
; i
++)
1639 for( j
= 0; j
< VarNr
; j
++ )
1640 if( LUstructJ
[i
][j
] ) {
1641 TmpStruct
[i
][j
] = nElm
;
1645 FunctionBegin( JacTR_SP_VEC
, JVS
, UV
, JTUV
);
1647 for( i
= 0; i
< VarNr
; i
++) {
1649 for( j
= 0; j
< VarNr
; j
++ )
1650 if( structJ
[j
][i
] != 0 )
1651 sum
= Add( sum
, Mul( Elm( JVS
, TmpStruct
[j
][i
] ), Elm( UV
, j
) ) );
1652 Assign( Elm( JTUV
, i
), sum
);
1654 FunctionEnd( JacTR_SP_VEC
);
1656 /* Free the temporary array of structure */
1657 FreeIntegerMatrix( TmpStruct
, VarNr
, VarNr
);
1662 FunctionBegin( JacTR_VEC
, JV
, UV
, JTUV
);
1663 for( i
= 0; i
< VarNr
; i
++) {
1665 for( j
= 0; j
< VarNr
; j
++ )
1666 if( structJ
[j
][i
] != 0 )
1667 sum
= Add( sum
, Mul( Elm( JV
, j
, i
), Elm( UV
, j
) ) );
1668 Assign( Elm( JTUV
, i
), sum
);
1670 FunctionEnd( JacTR_VEC
);
1673 FreeVariable( JacTR_VEC
);
1674 FreeVariable( JacTR_SP_VEC
);
1680 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1681 void GenerateSparseUtil()
1685 if ( useLang
== MATLAB_LANG
) return;
1687 UseFile( linalgFile
);
1689 SUTIL
= DefFnc( "SPARSE_UTIL", 0, "SPARSE utility functions");
1690 CommentFunctionBegin( SUTIL
);
1692 IncludeCode( "%s/util/sutil", Home
);
1694 CommentFunctionEnd( SUTIL
);
1695 FreeVariable( SUTIL
);
1700 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1705 if ( useLang
== MATLAB_LANG
) return;
1707 UseFile( linalgFile
);
1709 BLAS
= DefFnc( "BLAS_UTIL", 0, "BLAS-LIKE utility functions");
1710 CommentFunctionBegin( BLAS
);
1712 IncludeCode( "%s/util/blas", Home
);
1714 CommentFunctionEnd( BLAS
);
1715 FreeVariable( BLAS
);
1719 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1720 void GenerateDFunDRcoeff()
1723 UseFile( stoichiomFile
);
1726 WriteComment("Begin Derivative w.r.t. Rate Coefficients");
1729 IncludeCode( "%s/util/dFun_dRcoeff", Home
);
1732 WriteComment("End Derivative w.r.t. Rate Coefficients");
1739 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1740 void GenerateDJacDRcoeff()
1743 UseFile( stoichiomFile
);
1746 WriteComment("Begin Jacobian Derivative w.r.t. Rate Coefficients");
1749 IncludeCode( "%s/util/dJac_dRcoeff", Home
);
1752 WriteComment("End Jacobian Derivative w.r.t. Rate Coefficients");
1759 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1760 void GenerateSolve()
1773 if( useLang
== MATLAB_LANG
) return;
1775 /* Allocate local arrays for dimension dim */
1777 irow
= AllocIntegerVector( dim
*dim
, "irow in GenerateSolve" );
1778 icol
= AllocIntegerVector( dim
*dim
, "icol in GenerateSolve" );
1779 crow
= AllocIntegerVector( dim
, "crow in GenerateSolve" );
1780 diag
= AllocIntegerVector( dim
, "diag in GenerateSolve" );
1782 useLangOld
= useLang
;
1784 nElm
= NonZero( LU
, 0, VarNr
, irow
, icol
, crow
, diag
);
1785 useLang
= useLangOld
;
1787 UseFile( linalgFile
);
1789 SOLVE
= DefFnc( "KppSolve", 2, "sparse back substitution");
1790 FunctionBegin( SOLVE
, JVS
, X
);
1792 for( i
= 0; i
< VarNr
; i
++) {
1795 if( ibgn
<= iend
) {
1797 if ( ibgn
< iend
) {
1798 for( j
= ibgn
; j
< iend
; j
++ )
1799 sum
= Sub( sum
, Mul( Elm( JVS
, j
), Elm( X
, icol
[j
] ) ) );
1800 Assign( Elm( X
, i
), sum
);
1805 for( i
= VarNr
-1; i
>=0; i
--) {
1809 for( j
= ibgn
; j
< iend
; j
++ )
1810 sum
= Sub( sum
, Mul( Elm( JVS
, j
), Elm( X
, icol
[j
] ) ) );
1811 sum
= Div( sum
, Elm( JVS
, diag
[i
] ) );
1812 Assign( Elm( X
, i
), sum
);
1815 FunctionEnd( SOLVE
);
1816 FreeVariable( SOLVE
);
1818 /* Free Local Arrays */
1828 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1829 void GenerateTRSolve()
1843 if( useLang
== MATLAB_LANG
) return;
1845 /* Allocate local arrays for dimension dim */
1847 irow
= AllocIntegerVector( dim
*dim
, "irow in GenerateTRSolve" );
1848 icol
= AllocIntegerVector( dim
*dim
, "icol in GenerateTRSolve" );
1849 crow
= AllocIntegerVector( dim
, "crow in GenerateTRSolve" );
1850 diag
= AllocIntegerVector( dim
, "diag in GenerateTRSolve" );
1851 pos
= AllocIntegerMatrix( dim
+1, dim
+1, "pos in GenerateTRSolve");
1853 useLangOld
= useLang
;
1855 nElm
= NonZero( LU
, 0, VarNr
, irow
, icol
, crow
, diag
);
1856 useLang
= useLangOld
;
1858 UseFile( linalgFile
);
1860 SOLVETR
= DefFnc( "KppSolveTR", 3, "sparse, transposed back substitution");
1861 FunctionBegin( SOLVETR
, JVS
, X
, XX
);
1862 for( i
= 0; i
< VarNr
; i
++) {
1863 for( j
= 0; j
< VarNr
; j
++)
1866 for( i
= 0; i
< VarNr
; i
++) {
1869 if( ibgn
<= iend
) {
1870 if ( ibgn
< iend
) {
1871 for( j
= ibgn
; j
< iend
; j
++ )
1877 for( i
= VarNr
-1; i
>=0; i
--) {
1880 for( j
= ibgn
; j
< iend
; j
++ )
1885 for( i
= 0; i
<VarNr
; i
++) {
1887 for (j
=0; j
<i
; j
++ ){
1888 if(pos
[i
][j
] >= 0) {
1889 sum
=Sub( sum
, Mul ( Elm(JVS
,pos
[i
][j
] ), Elm( XX
, j
) ) );
1892 sum
=Div( sum
, Elm(JVS
, diag
[i
] ) );
1893 Assign( Elm( XX
, i
), sum
);
1895 for( i
= VarNr
-1; i
>=0; i
--) {
1897 for (j
=i
+1; j
<VarNr
; j
++) {
1898 if(pos
[i
][j
] >= 0) {
1899 sum
=Sub( sum
, Mul ( Elm(JVS
,pos
[i
][j
] ), Elm( XX
, j
) ) );
1902 Assign( Elm( XX
, i
), sum
);
1905 FunctionEnd( SOLVETR
);
1906 FreeVariable( SOLVETR
);
1907 /* Free Local Arrays */
1908 free(irow
); free(icol
); free(crow
); free(diag
);
1909 FreeIntegerMatrix(pos
, dim
+1, dim
+1);
1913 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1914 void GenerateRateLaws()
1917 UseFile( rateFile
);
1920 WriteComment("Begin Rate Law Functions from KPP_HOME/util/UserRateLaws");
1922 IncludeCode( "%s/util/UserRateLaws", Home
);
1924 WriteComment("End Rate Law Functions from KPP_HOME/util/UserRateLaws");
1928 WriteComment("Begin INLINED Rate Law Functions");
1932 case C_LANG
: bprintf( InlineCode
[ C_RATES
].code
);
1934 case F77_LANG
: bprintf( InlineCode
[ F77_RATES
].code
);
1936 case F90_LANG
: bprintf( InlineCode
[ F90_RATES
].code
);
1938 case MATLAB_LANG
: bprintf( InlineCode
[ MATLAB_RATES
].code
);
1944 WriteComment("End INLINED Rate Law Functions");
1952 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1953 void GenerateUpdateSun()
1957 UseFile( rateFile
);
1959 UPDATE_SUN
= DefFnc( "Update_SUN", 0, "update SUN light using TIME");
1960 CommentFunctionBegin( UPDATE_SUN
);
1962 IncludeCode( "%s/util/UpdateSun", Home
);
1964 CommentFunctionEnd( UPDATE_SUN
);
1965 FreeVariable( UPDATE_SUN
);
1968 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1969 void GenerateUpdateRconst()
1974 UseFile( rateFile
);
1976 UPDATE_RCONST
= DefFnc( "Update_RCONST", 0, "function to update rate constants");
1978 FunctionBegin( UPDATE_RCONST
);
1979 F77_Inline(" INCLUDE '%s_Global.h'", rootFileName
);
1980 MATLAB_Inline("global SUN TEMP RCONST");
1982 if ( (useLang
==F77_LANG
) )
1983 IncludeCode( "%s/util/UserRateLaws_FcnHeader", Home
);
1988 WriteComment("Begin INLINED RCONST");
1992 case C_LANG
: bprintf( InlineCode
[ C_RCONST
].code
);
1994 case F77_LANG
: bprintf( InlineCode
[ F77_RCONST
].code
);
1996 case F90_LANG
: bprintf( InlineCode
[ F90_RCONST
].code
);
1998 case MATLAB_LANG
: bprintf( InlineCode
[ MATLAB_RCONST
].code
);
2004 WriteComment("End INLINED RCONST");
2007 for( i
= 0; i
< EqnNr
; i
++) {
2008 if( kr
[i
].type
== EXPRESION
)
2009 Assign( Elm( RCONST
, i
), Elm( KR
, kr
[i
].val
.st
) );
2010 if( kr
[i
].type
== PHOTO
)
2011 Assign( Elm( RCONST
, i
), Elm( KR
, kr
[i
].val
.st
) );
2012 /* mz_rs_20050117+ */
2013 if ( kr
[i
].type
== NUMBER
) {
2014 F90_Inline("! RCONST(%d) = constant rate coefficient", i
+1);
2015 /* WriteComment("Constant rate coefficient (value inlined in the code):"); */
2016 /* Assign( Elm( RCONST, i ), Const( kr[i].val.f ) ); */
2018 /* mz_rs_20050117- */
2021 MATLAB_Inline(" RCONST = RCONST(:);");
2023 FunctionEnd( UPDATE_RCONST
);
2024 FreeVariable( UPDATE_RCONST
);
2029 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2030 void GenerateUpdatePhoto()
2035 UseFile( rateFile
);
2037 UPDATE_PHOTO
= DefFnc( "Update_PHOTO", 0, "function to update photolytical rate constants");
2039 FunctionBegin( UPDATE_PHOTO
);
2040 F77_Inline(" INCLUDE '%s_Global.h'", rootFileName
);
2041 F90_Inline(" USE %s_Global", rootFileName
);
2042 MATLAB_Inline("global SUN TEMP RCONST");
2046 for( i
= 0; i
< EqnNr
; i
++) {
2047 if( kr
[i
].type
== PHOTO
)
2048 Assign( Elm( RCONST
, i
), Elm( KR
, kr
[i
].val
.st
) );
2051 FunctionEnd( UPDATE_PHOTO
);
2052 FreeVariable( UPDATE_PHOTO
);
2057 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2058 void GenerateIntegrator()
2060 int TIN
, TOUT
, INTEGRATE
;
2062 UseFile( integratorFile
);
2064 TIN
= DefElm( "TIN", real
, "Start Time for Integration");
2065 TOUT
= DefElm( "TOUT", real
, "End Time for Integration");
2066 INTEGRATE
= DefFnc( "INTEGRATE", 2, "Integrator routine");
2067 CommentFunctionBegin( INTEGRATE
, TIN
, TOUT
);
2069 if( strchr( integrator
, '/' ) )
2070 IncludeCode( integrator
);
2072 IncludeCode( "%s/int/%s", Home
, integrator
);
2074 CommentFunctionEnd( INTEGRATE
);
2075 FreeVariable( INTEGRATE
);
2080 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2081 void GenerateDriver()
2085 UseFile( driverFile
);
2087 MAIN
= DefFnc( "MAIN", 0, "Main program - driver routine");
2088 CommentFunctionBegin( MAIN
);
2090 if( strchr( driver
, '/' ) )
2091 IncludeCode( driver
);
2093 IncludeCode( "%s/drv/%s", Home
, driver
);
2095 CommentFunctionEnd( MAIN
);
2096 FreeVariable( MAIN
);
2101 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2106 /* if (useLang == MATLAB_LANG) return; */
2108 UseFile( utilFile
);
2110 WriteComment("User INLINED Utility Functions");
2113 case C_LANG
: bprintf( InlineCode
[ C_UTIL
].code
);
2115 case F77_LANG
: bprintf( InlineCode
[ F77_UTIL
].code
);
2117 case F90_LANG
: bprintf( InlineCode
[ F90_UTIL
].code
);
2119 case MATLAB_LANG
:bprintf( InlineCode
[ MATLAB_UTIL
].code
);
2125 WriteComment("End INLINED Utility Functions");
2128 WriteComment("Utility Functions from KPP_HOME/util/util");
2129 UTIL
= DefFnc( "UTIL", 0, "Utility functions");
2130 CommentFunctionBegin( UTIL
);
2132 IncludeCode( "%s/util/util", Home
);
2134 if ((useLang
== F90_LANG
) && (useEqntags
==1)) {
2135 IncludeCode( "%s/util/tag2num", Home
);
2138 WriteComment("End Utility Functions from KPP_HOME/util/util");
2139 CommentFunctionEnd( UTIL
);
2140 FreeVariable( UTIL
);
2145 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2146 void GenerateParamHeader()
2154 int j
,dummy_species
;
2156 /* ----------> First declaration of constants */
2157 UseFile( param_headerFile
);
2160 DeclareConstant( NSPEC
, ascii( max(SpcNr
, 1) ) );
2161 DeclareConstant( NVAR
, ascii( max(VarNr
, 1) ) );
2162 DeclareConstant( NVARACT
, ascii( max(VarActiveNr
, 1) ) );
2163 DeclareConstant( NFIX
, ascii( max(FixNr
, 1) ) );
2164 DeclareConstant( NREACT
, ascii( max(EqnNr
, 1) ) );
2165 DeclareConstant( NVARST
, ascii( VarStartNr
) );
2166 DeclareConstant( NFIXST
, ascii( FixStartNr
) );
2167 DeclareConstant( NONZERO
, ascii( max(Jac_NZ
, 1) ) );
2168 DeclareConstant( LU_NONZERO
, ascii( max(LU_Jac_NZ
, 1) ) );
2169 DeclareConstant( CNVAR
, ascii( VarNr
+1 ) );
2170 if ( useStoicmat
) {
2171 DeclareConstant( CNEQN
, ascii( EqnNr
+1 ) );
2174 DeclareConstant( NHESS
, ascii( max(Hess_NZ
, 1) ) );
2177 DeclareConstant( NLOOKAT
, ascii( nlookat
) );
2178 DeclareConstant( NMONITOR
, ascii( nmoni
) );
2179 DeclareConstant( NMASS
, ascii( nmass
) );
2181 DeclareConstant( PI
, "3.14159265358979" );
2184 WriteComment("Index declaration for variable species in C and VAR");
2185 WriteComment(" VAR(ind_spc) = C(ind_spc)");
2187 for( i
= 0; i
< VarNr
; i
++) {
2188 sprintf( name
, "ind_%s", SpeciesTable
[ Code
[i
] ].name
);
2189 spc
= DefConst( name
, INT
, 0 );
2190 DeclareConstant( spc
, ascii( Index(i
) ) );
2191 FreeVariable( spc
);
2195 WriteComment("Index declaration for fixed species in C");
2196 WriteComment(" C(ind_spc)");
2198 for( i
= 0; i
< FixNr
; i
++) {
2199 sprintf( name
, "ind_%s", SpeciesTable
[ Code
[i
+ VarNr
] ].name
);
2200 spc
= DefConst( name
, INT
, 0 );
2201 DeclareConstant( spc
, ascii( Index(i
+VarNr
) ) );
2202 FreeVariable( spc
);
2205 if (useDummyindex
==1) {
2207 WriteComment("Index declaration for dummy species");
2209 for( i
= 0; i
< MAX_SPECIES
; i
++) {
2210 if (SpeciesTable
[i
].type
== 0) continue;
2212 for( j
= 0; j
< MAX_SPECIES
; j
++)
2213 if (Code
[j
] == i
) dummy_species
= 0;
2214 if (dummy_species
) {
2215 sprintf( name
, "ind_%s", SpeciesTable
[i
].name
);
2216 spc
= DefConst( name
, INT
, 0 );
2217 DeclareConstant( spc
, ascii( 0 ) );
2218 FreeVariable( spc
);
2224 WriteComment("Index declaration for fixed species in FIX");
2225 WriteComment(" FIX(indf_spc) = C(ind_spc) = C(NVAR+indf_spc)");
2227 for( i
= 0; i
< FixNr
; i
++) {
2228 sprintf( name
, "indf_%s", SpeciesTable
[ Code
[i
+ VarNr
] ].name
);
2229 spc
= DefConst( name
, INT
, 0 );
2230 DeclareConstant( spc
, ascii( Index(i
) ) );
2231 FreeVariable( spc
);
2237 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2238 void GenerateGlobalHeader()
2246 UseFile( global_dataFile
);
2248 CommonName
= "GDATA";
2251 WriteComment("Declaration of global variables");
2254 /* ExternDeclare( C_DEFAULT ); */
2258 if( useLang
== F77_LANG
) {
2262 WriteComment("VAR, FIX are chunks of array C");
2263 F77_Inline(" EQUIVALENCE( %s(%d),%s(1) )",
2264 varTable
[C
]->name
, 1, varTable
[VAR
]->name
);
2265 if ( FixNr
> 0 ) { /* mz_rs_20050121 */
2266 F77_Inline(" EQUIVALENCE( %s(%d),%s(1) )",
2267 varTable
[C
]->name
, VarNr
+1, varTable
[FIX
]->name
);
2271 if( useLang
== F90_LANG
) {
2272 ExternDeclare( VAR
);
2273 ExternDeclare( FIX
);
2274 WriteComment("VAR, FIX are chunks of array C");
2275 F90_Inline(" EQUIVALENCE( %s(%d),%s(1) )",
2276 varTable
[C
]->name
, 1, varTable
[VAR
]->name
);
2277 if ( FixNr
> 0 ) { /* mz_rs_20050121 */
2278 F90_Inline(" EQUIVALENCE( %s(%d),%s(1) )",
2279 varTable
[C
]->name
, VarNr
+1, varTable
[FIX
]->name
);
2283 if( useLang
== MATLAB_LANG
) {
2284 ExternDeclare( VAR
);
2285 ExternDeclare( FIX
);
2288 C_Inline(" extern %s * %s;", C_types
[real
], varTable
[VAR
]->name
);
2289 C_Inline(" extern %s * %s;", C_types
[real
], varTable
[FIX
]->name
);
2292 ExternDeclare( RCONST
);
2293 ExternDeclare( TIME
);
2294 ExternDeclare( SUN
);
2295 ExternDeclare( TEMP
);
2296 ExternDeclare( RTOLS
);
2297 ExternDeclare( TSTART
);
2298 ExternDeclare( TEND
);
2299 ExternDeclare( DT
);
2300 ExternDeclare( ATOL
);
2301 ExternDeclare( RTOL
);
2302 ExternDeclare( STEPMIN
);
2303 ExternDeclare( STEPMAX
);
2304 ExternDeclare( CFACTOR
);
2306 ExternDeclare( VOLUME
);
2308 CommonName
= "INTGDATA";
2310 ExternDeclare( DDMTYPE
);
2314 if ( (useLang
== C_LANG
) || (useLang
== F77_LANG
) ) {
2315 CommonName
= "INTGDATA";
2316 ExternDeclare( LOOKAT
);
2317 ExternDeclare( MONITOR
);
2318 CommonName
= "CHARGDATA";
2319 ExternDeclare( SPC_NAMES
);
2320 ExternDeclare( SMASS
);
2321 ExternDeclare( EQN_NAMES
);
2322 ExternDeclare( EQN_TAGS
);
2326 WriteComment("INLINED global variable declarations");
2329 case C_LANG
: bprintf( InlineCode
[ C_GLOBAL
].code
);
2331 case F77_LANG
: bprintf( InlineCode
[ F77_GLOBAL
].code
);
2333 case F90_LANG
: bprintf( InlineCode
[ F90_GLOBAL
].code
);
2335 case MATLAB_LANG
: bprintf( InlineCode
[ MATLAB_GLOBAL
].code
);
2341 WriteComment("INLINED global variable declarations");
2345 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2346 void WriteSpec( int i
, int j
)
2351 sprintf( buf
, "%s (r)", SpeciesTable
[ Code
[j
] ].name
);
2353 sprintf( buf
, "%s (n)", SpeciesTable
[ Code
[j
] ].name
);
2354 WriteAll("%3d = %-10s", 1 + i
, buf
);
2358 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2359 int EqnStr( int eq
, char * buf
, float** mat
)
2363 /* bugfix if stoichiometric factor is not an integer */
2369 for( spc
= 0; spc
< SpcNr
; spc
++ )
2370 if( mat
[spc
][eq
] != 0 ) {
2371 if( ((mat
[spc
][eq
] == 1)||(mat
[spc
][eq
] == -1)) ) {
2375 /* mz_rs_20050130+ */
2376 /* sprintf(s, "%g", mat[spc][eq]); */
2377 /* remove the minus sign with fabs(), it will be re-inserted later */
2378 sprintf(s
, "%g", fabs(mat
[spc
][eq
]));
2379 /* mz_rs_20050130- */
2380 /* remove trailing zeroes */
2381 for (n
= strlen(s
) - 1; n
>= 0; n
--)
2382 if (s
[n
] != '0') break;
2384 sprintf(s
, "%s ", s
);
2388 if( mat
[spc
][eq
] > 0 ) sprintf(buf
, "%s%s", buf
, s
);
2389 else sprintf(buf
, "%s- %s", buf
, s
);
2392 if( mat
[spc
][eq
] > 0 ) sprintf(buf
, "%s + %s", buf
, s
);
2393 else sprintf(buf
, "%s - %s", buf
, s
);
2395 sprintf(buf
, "%s%s", buf
, SpeciesTable
[ Code
[spc
] ].name
);
2396 if (strlen(buf
)>MAX_EQNLEN
/2) { /* truncate if eqn string too long */
2397 sprintf(buf
, "%s ... etc.",buf
);
2405 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2406 int EqnString( int eq
, char * buf
)
2412 char lhsbuf
[MAX_EQNLEN
], rhsbuf
[MAX_EQNLEN
];
2414 if(lhs
== 0) for( i
= 0; i
< EqnNr
; i
++ ) {
2415 l
= EqnStr( i
, lhsbuf
, Stoich_Left
);
2416 lhs
= (lhs
> l
) ? lhs
: l
;
2419 if(rhs
== 0) for( i
= 0; i
< EqnNr
; i
++ ) {
2420 l
= EqnStr( i
, rhsbuf
, Stoich_Right
);
2421 rhs
= (rhs
> l
) ? lhs
: l
;
2425 EqnStr( eq
, lhsbuf
, Stoich_Left
);
2426 EqnStr( eq
, rhsbuf
, Stoich_Right
);
2428 sprintf(buf
, "%*s --> %-*s", lhs
, lhsbuf
, rhs
, rhsbuf
);
2433 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2441 WriteAll("### Options -------------------------------------------\n");
2443 if( useAggregate
) WriteAll("FUNCTION - AGGREGATE\n");
2444 else WriteAll("FUNCTION - SPLIT\n");
2445 switch ( useJacobian
) {
2446 case JAC_OFF
: WriteAll("JACOBIAN - OFF\n"); break;
2447 case JAC_FULL
: WriteAll("JACOBIAN - FULL\n"); break;
2448 case JAC_LU_ROW
: WriteAll("JACOBIAN - SPARSE W/ ACCOUNT FOR LU DECOMPOSITION FILL-IN\n"); break;
2449 case JAC_ROW
: WriteAll("JACOBIAN - SPARSE\n"); break;
2451 if( useDouble
) WriteAll("DOUBLE - ON\n");
2452 else WriteAll("DOUBLE - OFF\n");
2453 if( useReorder
) WriteAll("REORDER - ON\n");
2454 else WriteAll("REORDER - OFF\n");
2457 WriteAll("### Parameters ----------------------------------------\n");
2460 VarStartNr
= Index(0);
2461 FixStartNr
= Index(VarNr
);
2463 DeclareConstant( NSPEC
, ascii( SpcNr
) );
2464 DeclareConstant( NVAR
, ascii( max( VarNr
, 1 ) ) );
2465 DeclareConstant( NVARACT
, ascii( max( VarActiveNr
, 1 ) ) );
2466 DeclareConstant( NFIX
, ascii( max( FixNr
, 1 ) ) );
2467 DeclareConstant( NREACT
, ascii( EqnNr
) );
2468 DeclareConstant( NVARST
, ascii( VarStartNr
) );
2469 DeclareConstant( NFIXST
, ascii( FixStartNr
) );
2472 WriteAll("### Species -------------------------------------------\n");
2475 WriteAll("Variable species\n");
2478 for( i
= 0; i
< dn
; i
++ ) {
2479 if( i
< VarNr
) WriteSpec( i
, i
);
2480 i
+= dn
; if( i
< VarNr
) WriteSpec( i
, i
);
2481 i
+= dn
; if( i
< VarNr
) WriteSpec( i
, i
);
2482 i
-= 2*dn
; WriteAll("\n");
2487 WriteAll("Fixed species\n");
2490 for( i
= 0; i
< dn
; i
++ ) {
2491 if( i
< FixNr
) WriteSpec( i
, i
+ VarNr
);
2492 i
+= dn
; if( i
< FixNr
) WriteSpec( i
, i
+ VarNr
);
2493 i
+= dn
; if( i
< FixNr
) WriteSpec( i
, i
+ VarNr
);
2494 i
-= 2*dn
; WriteAll("\n");
2498 WriteAll("### Subroutines ---------------------------------------\n");
2505 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2506 void GenerateInitialize()
2512 if ( (useLang
==C_LANG
)||(useLang
==F77_LANG
)||(useLang
==F90_LANG
) )
2513 UseFile( initFile
);
2515 INITVAL
= DefFnc( "Initialize", 0, "function to initialize concentrations");
2516 FunctionBegin( INITVAL
);
2517 F77_Inline(" INCLUDE '%s_Global.h'", rootFileName
);
2518 F90_Inline(" USE %s_Global\n", rootFileName
);
2519 MATLAB_Inline("global CFACTOR VAR FIX NVAR NFIX", rootFileName
);
2521 I
= DefElm( "i", INT
, 0);
2522 X
= DefElm( "x", real
, 0);
2527 WriteAssign( varTable
[CFACTOR
]->name
, ascid( (double)cfactor
) );
2530 Assign( Elm( X
), Mul( Elm( IV
, varDefault
), Elm( CFACTOR
) ) );
2531 C_Inline(" for( i = 0; i < NVAR; i++ )" );
2532 F77_Inline(" DO i = 1, NVAR" );
2533 F90_Inline(" DO i = 1, NVAR" );
2534 MATLAB_Inline(" for i = 1:NVAR" );
2536 Assign( Elm( VAR
, -I
), Elm( X
) );
2538 F77_Inline(" END DO" );
2539 F90_Inline(" END DO" );
2540 MATLAB_Inline(" end" );
2544 Assign( Elm( X
), Mul( Elm( IV
, fixDefault
), Elm( CFACTOR
) ) );
2545 C_Inline(" for( i = 0; i < NFIX; i++ )" );
2546 F77_Inline(" DO i = 1, NFIX" );
2547 F90_Inline(" DO i = 1, NFIX" );
2548 MATLAB_Inline(" for i = 1:NFIX" );
2550 Assign( Elm( FIX
, -I
), Elm( X
) );
2552 F77_Inline(" END DO" );
2553 F90_Inline(" END DO" );
2554 MATLAB_Inline(" end" );
2559 for( i
= 0; i
< VarNr
; i
++) {
2560 if( *SpeciesTable
[ Code
[i
] ].ival
== 0 ) continue;
2561 Assign( Elm( VAR
, i
), Mul(
2562 Elm( IV
, SpeciesTable
[ Code
[i
] ].ival
),
2567 for( i
= 0; i
< FixNr
; i
++) {
2568 if( *SpeciesTable
[ Code
[i
+ VarNr
] ].ival
== 0 ) continue;
2569 Assign( Elm( FIX
, i
), Mul(
2570 Elm( IV
, SpeciesTable
[ Code
[i
+ VarNr
] ].ival
),
2575 C_Inline(" for( i = 0; i < NSPEC; i++ )" );
2576 F77_Inline(" do i = 1, NSPEC" );
2578 Assign( Elm( C_DEFAULT, -I ), Elm( C, -I ) );
2580 F77_Inline(" end do" );
2583 /* mz_rs_20050117+ */
2584 WriteComment("constant rate coefficients");
2585 for( i
= 0; i
< EqnNr
; i
++) {
2586 if ( kr
[i
].type
== NUMBER
)
2587 Assign( Elm( RCONST
, i
), Const( kr
[i
].val
.f
) );
2589 WriteComment("END constant rate coefficients");
2590 /* mz_rs_20050117- */
2593 WriteComment("INLINED initializations");
2596 case C_LANG
: bprintf( InlineCode
[ C_INIT
].code
);
2598 case F77_LANG
: bprintf( InlineCode
[ F77_INIT
].code
);
2600 case F90_LANG
: bprintf( InlineCode
[ F90_INIT
].code
);
2602 case MATLAB_LANG
: bprintf( InlineCode
[ MATLAB_INIT
].code
);
2608 WriteComment("End INLINED initializations");
2611 MATLAB_Inline(" VAR = VAR(:);\n FIX = FIX(:);\n" );
2615 FunctionEnd( INITVAL
);
2616 FreeVariable( INITVAL
);
2621 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2622 void GenerateShuffle_user2kpp()
2625 int Shuffle_user2kpp
;
2627 UseFile( utilFile
);
2629 Shuffle_user2kpp
= DefFnc( "Shuffle_user2kpp", 2, "function to copy concentrations from USER to KPP");
2630 FunctionBegin( Shuffle_user2kpp
, V_USER
, V
);
2633 for( i
= 1; i
< SpcNr
; i
++) {
2634 if( ReverseCode
[i
] < 0 ) {
2635 if( SpeciesTable
[i
].type
== VAR_SPC
) k
++;
2638 switch( SpeciesTable
[i
].type
) {
2641 Assign( Elm( V
, ReverseCode
[i
] ), Elm( V_USER
, k
++ ) );
2650 FunctionEnd( Shuffle_user2kpp
);
2651 FreeVariable( Shuffle_user2kpp
);
2656 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2657 void GenerateShuffle_kpp2user()
2660 int Shuffle_kpp2user
;
2662 UseFile( utilFile
);
2664 Shuffle_kpp2user
= DefFnc( "Shuffle_kpp2user", 2, "function to restore concentrations from KPP to USER");
2665 FunctionBegin( Shuffle_kpp2user
, V
, V_USER
);
2668 for( i
= 0; i
< SpcNr
; i
++) {
2669 if( ReverseCode
[i
] < 0 ) {
2670 if( SpeciesTable
[i
].type
== VAR_SPC
) k
++;
2673 switch( SpeciesTable
[i
].type
) {
2676 Assign( Elm( V_USER
, k
++ ), Elm( V
, ReverseCode
[i
] ) );
2684 FunctionEnd( Shuffle_kpp2user
);
2685 FreeVariable( Shuffle_kpp2user
);
2690 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2691 void GenerateGetMass()
2699 UseFile( utilFile
);
2702 for( atm
= 0; atm
< AtomNr
; atm
++ )
2703 if( AtomTable
[atm
].masscheck
) nmass
++;
2704 if( nmass
== 0 ) nmass
= 1;
2706 MASS
= DefvElm( "Mass", real
, nmass
, "value of mass balance" );
2707 GETMASS
= DefFnc( "GetMass", 2, "compute total mass of selected atoms");
2708 FunctionBegin( GETMASS
, CL
, MASS
);
2711 for( atm
= 0; atm
< AtomNr
; atm
++ ) {
2712 if( AtomTable
[atm
].masscheck
) {
2714 for( spc
= 0; spc
< SpcNr
; spc
++ ) {
2715 sp
= &SpeciesTable
[ Code
[spc
] ];
2716 for( i
= 0; i
< sp
->nratoms
; i
++ ) {
2717 if( sp
->atoms
[i
].code
== atm
) {
2718 sum
= Add( sum
, Mul( Const( sp
->atoms
[i
].nr
),
2723 Assign( Elm( MASS
, numass
), sum
);
2728 FunctionEnd( GETMASS
);
2729 FreeVariable( GETMASS
);
2732 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2733 void GenerateMakefile()
2737 if ( useLang
== MATLAB_LANG
) return;
2739 sprintf( buf
, "Makefile_%s", rootFileName
);
2740 makeFile
= fopen(buf
, "w");
2741 if( makeFile
== 0 ) {
2742 FatalError(3,"%s: Can't create file", buf
);
2745 UseFile( makeFile
);
2747 IncludeCode( "%s/util/Makefile", Home
);
2751 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2754 char buf
[100], suffix
[5];
2756 if (useLang
== MATLAB_LANG
) return;
2757 if (useMex
== 0) return;
2760 case F77_LANG
: sprintf( suffix
, "f");
2762 case F90_LANG
: sprintf( suffix
, "f90");
2764 case C_LANG
: sprintf( suffix
, "c");
2766 default: printf("\nCannot create mex files for language %d\n", useLang
);
2771 sprintf( buf
, "%s_mex_Fun.%s", rootFileName
, suffix
);
2772 mex_funFile
= fopen(buf
, "w");
2773 if( mex_funFile
== 0 ) {
2774 FatalError(3,"%s: Can't create file", buf
);
2776 UseFile( mex_funFile
);
2777 IncludeCode( "%s/util/Mex_Fun", Home
);
2780 sprintf( buf
, "%s_mex_Jac_SP.%s", rootFileName
, suffix
);
2781 mex_jacFile
= fopen(buf
, "w");
2782 if( mex_jacFile
== 0 ) {
2783 FatalError(3,"%s: Can't create file", buf
);
2785 UseFile( mex_jacFile
);
2786 IncludeCode( "%s/util/Mex_Jac_SP", Home
);
2790 sprintf( buf
, "%s_mex_Hessian.%s", rootFileName
, suffix
);
2791 mex_hessFile
= fopen(buf
, "w");
2792 if( mex_hessFile
== 0 ) {
2793 FatalError(3,"%s: Can't create file", buf
);
2795 UseFile( mex_hessFile
);
2796 IncludeCode( "%s/util/Mex_Hessian", Home
);
2802 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2803 void GenerateMatlabTemplates()
2805 char buf
[200], suffix
[5];
2807 if (useLang
!= MATLAB_LANG
) return;
2810 sprintf( buf
, "%s_Fun_Chem.m", rootFileName
);
2811 mex_funFile
= fopen(buf
, "w");
2812 if( mex_funFile
== 0 ) {
2813 FatalError(3,"%s: Can't create file", buf
);
2815 UseFile( mex_funFile
);
2816 IncludeCode( "%s/util/Template_Fun_Chem", Home
);
2818 sprintf( buf
, "%s_Update_SUN.m", rootFileName
);
2819 mex_funFile
= fopen(buf
, "w");
2820 if( mex_funFile
== 0 ) {
2821 FatalError(3,"%s: Can't create file", buf
);
2823 UseFile( mex_funFile
);
2824 IncludeCode( "%s/util/UpdateSun", Home
);
2827 sprintf( buf
, "%s_Jac_Chem.m", rootFileName
);
2828 mex_jacFile
= fopen(buf
, "w");
2829 if( mex_jacFile
== 0 ) {
2830 FatalError(3,"%s: Can't create file", buf
);
2832 UseFile( mex_jacFile
);
2833 IncludeCode( "%s/util/Template_Jac_Chem", Home
);
2841 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2842 void GenerateF90Modules(char where
)
2846 if (useLang
!= F90_LANG
) return;
2851 sprintf( buf
, "%s_Precision.f90", rootFileName
);
2852 sparse_dataFile
= fopen(buf
, "w");
2853 if( sparse_dataFile
== 0 ) {
2854 FatalError(3,"%s: Can't create file", buf
);
2856 UseFile( sparse_dataFile
);
2857 F90_Inline("\nMODULE %s_Precision\n", rootFileName
);
2859 F90_Inline("! Definition of different levels of accuracy");
2860 F90_Inline("! for REAL variables using KIND parameterization");
2862 F90_Inline("! KPP SP - Single precision kind");
2863 F90_Inline(" INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,30)");
2864 F90_Inline("! KPP DP - Double precision kind");
2865 F90_Inline(" INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(14,300)");
2866 F90_Inline("! KPP QP - Quadruple precision kind");
2867 F90_Inline(" INTEGER, PARAMETER :: qp = SELECTED_REAL_KIND(18,400)");
2868 F90_Inline("\nEND MODULE %s_Precision\n\n", rootFileName
);
2870 UseFile( initFile
);
2871 F90_Inline("MODULE %s_Initialize\n", rootFileName
);
2872 F90_Inline(" IMPLICIT NONE\n", rootFileName
);
2873 F90_Inline("CONTAINS\n\n");
2875 UseFile( param_headerFile
);
2876 F90_Inline("MODULE %s_Parameters\n", rootFileName
);
2877 F90_Inline(" USE %s_Precision", rootFileName
);
2878 F90_Inline(" PUBLIC\n SAVE\n");
2880 UseFile( global_dataFile
);
2881 F90_Inline("MODULE %s_Global\n", rootFileName
);
2882 F90_Inline(" USE %s_Parameters, ONLY: dp, NSPEC, NVAR, NFIX, NREACT", rootFileName
);
2883 F90_Inline(" PUBLIC\n SAVE\n");
2885 UseFile( functionFile
);
2886 F90_Inline("MODULE %s_Function\n", rootFileName
);
2887 F90_Inline(" USE %s_Parameters", rootFileName
);
2888 F90_Inline(" IMPLICIT NONE\n", rootFileName
);
2889 Declare( A
); /* mz_rs_20050117 */
2890 F90_Inline("\nCONTAINS\n\n");
2892 UseFile( rateFile
);
2893 F90_Inline("MODULE %s_Rates\n", rootFileName
);
2894 F90_Inline(" USE %s_Parameters", rootFileName
);
2895 F90_Inline(" USE %s_Global", rootFileName
);
2896 F90_Inline(" IMPLICIT NONE", rootFileName
);
2897 F90_Inline("\nCONTAINS\n\n");
2899 if ( useStochastic
) {
2900 UseFile(stochasticFile
);
2901 F90_Inline("MODULE %s_Stochastic\n", rootFileName
);
2902 F90_Inline(" USE %s_Precision", rootFileName
);
2903 F90_Inline(" USE %s_Parameters, ONLY: NVAR, NFIX, NREACT", rootFileName
);
2904 F90_Inline(" PUBLIC\n SAVE\n");
2905 F90_Inline("\nCONTAINS\n\n");
2908 if ( useJacSparse
) {
2909 UseFile(sparse_jacFile
);
2910 F90_Inline("MODULE %s_JacobianSP\n", rootFileName
);
2911 F90_Inline(" PUBLIC\n SAVE\n");
2914 UseFile( jacobianFile
);
2915 F90_Inline("MODULE %s_Jacobian\n", rootFileName
);
2916 F90_Inline(" USE %s_Parameters", rootFileName
);
2918 F90_Inline(" USE %s_JacobianSP\n", rootFileName
);
2919 F90_Inline(" IMPLICIT NONE", rootFileName
);
2920 F90_Inline("\nCONTAINS\n\n");
2922 if ( useStoicmat
) {
2923 UseFile(sparse_stoicmFile
);
2924 F90_Inline("MODULE %s_StoichiomSP\n", rootFileName
);
2925 F90_Inline(" USE %s_Precision", rootFileName
);
2926 F90_Inline(" PUBLIC\n SAVE\n");
2928 UseFile( stoichiomFile
);
2929 F90_Inline("MODULE %s_Stoichiom\n", rootFileName
);
2930 F90_Inline(" USE %s_Parameters", rootFileName
);
2931 F90_Inline(" USE %s_StoichiomSP\n", rootFileName
);
2932 F90_Inline(" IMPLICIT NONE", rootFileName
);
2933 F90_Inline("\nCONTAINS\n\n");
2937 UseFile(sparse_hessFile
);
2938 F90_Inline("MODULE %s_HessianSP\n", rootFileName
);
2939 /* F90_Inline(" USE %s_Precision", rootFileName ); */ /* mz_rs_20050321 */
2940 F90_Inline(" PUBLIC\n SAVE\n");
2942 UseFile( hessianFile
);
2943 F90_Inline("MODULE %s_Hessian\n", rootFileName
);
2944 F90_Inline(" USE %s_Parameters", rootFileName
);
2945 F90_Inline(" USE %s_HessianSP\n", rootFileName
);
2946 F90_Inline(" IMPLICIT NONE", rootFileName
);
2947 F90_Inline("\nCONTAINS\n\n");
2950 UseFile( monitorFile
);
2951 F90_Inline("MODULE %s_Monitor", rootFileName
);
2953 UseFile( linalgFile
);
2954 F90_Inline("MODULE %s_LinearAlgebra\n", rootFileName
);
2955 F90_Inline(" USE %s_Parameters", rootFileName
);
2956 /* mz_rs_20050511+ if( useJacSparse ) added */
2958 F90_Inline(" USE %s_JacobianSP\n", rootFileName
);
2959 /* mz_rs_20050511- */
2960 /* mz_rs_20050321+ */
2961 /* if (useHessian) */
2962 /* F90_Inline(" USE %s_HessianSP\n", rootFileName); */
2963 /* mz_rs_20050321- */
2964 F90_Inline(" IMPLICIT NONE", rootFileName
);
2965 F90_Inline("\nCONTAINS\n\n");
2967 UseFile( utilFile
);
2968 F90_Inline("MODULE %s_Util\n", rootFileName
);
2969 F90_Inline(" USE %s_Parameters", rootFileName
);
2970 F90_Inline(" IMPLICIT NONE", rootFileName
);
2971 F90_Inline("\nCONTAINS\n\n");
2973 /* Here we define the model module which aggregates everything */
2974 /* put module rootFileName_Model into separate file */
2975 /* (reusing "sparse_dataFile" as done above for _Precision file) */
2976 sprintf( buf
, "%s_Model.f90", rootFileName
);
2977 sparse_dataFile
= fopen(buf
, "w");
2978 if( sparse_dataFile
== 0 ) {
2979 FatalError(3,"%s: Can't create file", buf
);
2981 UseFile( sparse_dataFile
);
2982 F90_Inline("MODULE %s_Model\n", rootFileName
);
2983 F90_Inline("!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
2984 F90_Inline("! Completely defines the model %s", rootFileName
);
2985 F90_Inline("! by using all the associated modules");
2986 F90_Inline("!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
2987 F90_Inline("\n USE %s_Precision", rootFileName
);
2988 F90_Inline(" USE %s_Parameters", rootFileName
);
2989 F90_Inline(" USE %s_Global", rootFileName
);
2990 F90_Inline(" USE %s_Function", rootFileName
);
2991 F90_Inline(" USE %s_Integrator", rootFileName
);
2992 F90_Inline(" USE %s_Rates", rootFileName
);
2993 if ( useStochastic
)
2994 F90_Inline(" USE %s_Stochastic", rootFileName
);
2996 F90_Inline(" USE %s_Jacobian", rootFileName
);
2998 F90_Inline(" USE %s_Hessian", rootFileName
);
3000 F90_Inline(" USE %s_Stoichiom", rootFileName
);
3001 F90_Inline(" USE %s_LinearAlgebra", rootFileName
);
3002 F90_Inline(" USE %s_Monitor", rootFileName
);
3003 F90_Inline(" USE %s_Util", rootFileName
);
3004 F90_Inline("\nEND MODULE %s_Model\n", rootFileName
);
3006 /* mz_rs_20050518+ */
3007 /* UseFile( driverFile ); */
3009 /* mz_rs_20050518- */
3015 /* mz_rs_20050117+ */
3016 UseFile( initFile
);
3017 F90_Inline("\nEND MODULE %s_Initialize\n", rootFileName
);
3018 /* mz_rs_20050117- */
3020 UseFile( param_headerFile
);
3021 F90_Inline("\nEND MODULE %s_Parameters\n", rootFileName
);
3023 UseFile( global_dataFile
);
3024 F90_Inline("\nEND MODULE %s_Global\n", rootFileName
);
3026 UseFile( functionFile
);
3027 F90_Inline("\nEND MODULE %s_Function\n", rootFileName
);
3029 UseFile( rateFile
);
3030 F90_Inline("\nEND MODULE %s_Rates\n", rootFileName
);
3032 if ( useStochastic
) {
3033 UseFile(stochasticFile
);
3034 F90_Inline("\nEND MODULE %s_Stochastic\n", rootFileName
);
3037 if ( useJacSparse
) {
3038 UseFile(sparse_jacFile
);
3039 F90_Inline("\nEND MODULE %s_JacobianSP\n", rootFileName
);
3042 UseFile( jacobianFile
);
3043 F90_Inline("\nEND MODULE %s_Jacobian\n", rootFileName
);
3045 if ( useStoicmat
) {
3046 UseFile(sparse_stoicmFile
);
3047 F90_Inline("\nEND MODULE %s_StoichiomSP\n", rootFileName
);
3049 UseFile( stoichiomFile
);
3050 F90_Inline("\nEND MODULE %s_Stoichiom\n", rootFileName
);
3054 UseFile(sparse_hessFile
);
3055 F90_Inline("\nEND MODULE %s_HessianSP\n", rootFileName
);
3057 UseFile( hessianFile
);
3058 F90_Inline("\nEND MODULE %s_Hessian\n", rootFileName
);
3061 UseFile(monitorFile
);
3062 F90_Inline("\nEND MODULE %s_Monitor", rootFileName
);
3064 UseFile( linalgFile
);
3065 F90_Inline("\nEND MODULE %s_LinearAlgebra\n", rootFileName
);
3067 UseFile( utilFile
);
3068 F90_Inline("\nEND MODULE %s_Util\n", rootFileName
);
3073 printf("\n Unrecognized option '%s' in GenerateF90Modules\n", where
);
3079 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3088 real
= useDouble
? DOUBLE
: REAL
;
3091 for( i
= 1; i
< INLINE_OPT
; i
++ )
3092 if( InlineCode
[i
].maxlen
> n
)
3093 n
= InlineCode
[i
].maxlen
;
3095 outBuf
= (char*)malloc( n
);
3099 case F77_LANG
: Use_F( rootFileName
);
3101 case F90_LANG
: Use_F90( rootFileName
);
3103 case C_LANG
: Use_C( rootFileName
);
3105 case MATLAB_LANG
: Use_MATLAB( rootFileName
);
3107 default: printf("\n Language no '%s' unknown\n",useLang
);
3109 printf("\nKPP is initializing the code generation.");
3112 if ( useLang
== F90_LANG
)
3113 GenerateF90Modules('h');
3117 /* if( (useLang == F77_LANG)||(useLang == F90_LANG)||(useLang == C_LANG) )
3119 printf("\nKPP is generating the monitor data:");
3120 printf("\n - %s_Monitor",rootFileName
);
3121 GenerateMonitorData();
3124 printf("\nKPP is generating the utility data:");
3125 printf("\n - %s_Util",rootFileName
);
3128 printf("\nKPP is generating the global declarations:");
3129 printf("\n - %s_Main",rootFileName
);
3133 printf("\nKPP is generating the ODE function:");
3134 printf("\n - %s_Function",rootFileName
);
3137 if ( useStochastic
) {
3138 printf("\nKPP is generating the Stochastic description:");
3139 printf("\n - %s_Function",rootFileName
);
3140 GenerateStochastic();
3143 if ( useJacobian
) {
3144 printf("\nKPP is generating the ODE Jacobian:");
3145 printf("\n - %s_Jacobian\n - %s_JacobianSP",rootFileName
,rootFileName
);
3147 GenerateJacobianSparseData();
3148 if ( (useLang
== F77_LANG
)||(useLang
== F90_LANG
)||(useLang
== C_LANG
) ) {
3150 GenerateJacTRVect();
3151 if( useJacSparse
) {
3152 printf("\nKPP is generating the linear algebra routines:");
3153 printf("\n - %s_LinearAlgebra",rootFileName
);
3154 GenerateSparseUtil();
3164 printf("\nKPP is generating the Hessian:");
3165 printf("\n - %s_Hessian\n - %s_HessianSP",rootFileName
,rootFileName
);
3167 GenerateHessianSparseData();
3170 printf("\nKPP is generating the utility functions:");
3171 printf("\n - %s_Util",rootFileName
);
3173 GenerateInitialize();
3175 GenerateShuffle_user2kpp();
3176 GenerateShuffle_kpp2user();
3178 printf("\nKPP is generating the rate laws:");
3179 printf("\n - %s_Rates",rootFileName
);
3182 GenerateUpdateSun();
3183 GenerateUpdateRconst();
3184 GenerateUpdatePhoto();
3188 printf("\nKPP is generating the parameters:");
3189 printf("\n - %s_Parameters",rootFileName
);
3191 GenerateParamHeader();
3193 printf("\nKPP is generating the global data:");
3194 printf("\n - %s_Global",rootFileName
);
3196 GenerateGlobalHeader();
3198 if ( (useLang
== F77_LANG
)||(useLang
== C_LANG
)||(useLang
== MATLAB_LANG
) ) {
3199 printf("\nKPP is generating the sparsity data:");
3200 if( useJacSparse
) {
3201 GenerateJacobianSparseHeader();
3202 printf("\n - %s_JacobianSP",rootFileName
);
3205 GenerateHessianSparseHeader();
3206 printf("\n - %s_HessianSP",rootFileName
);
3210 if ( useStoicmat
) {
3211 printf("\nKPP is generating the stoichiometric description files:");
3212 printf("\n - %s_Stoichiom\n - %s_StoichiomSP",rootFileName
,rootFileName
);
3213 GenerateReactantProd();
3214 GenerateJacReactantProd();
3215 GenerateStoicmSparseData();
3216 if ( (useLang
== F77_LANG
)||(useLang
== C_LANG
)||(useLang
== MATLAB_LANG
) )
3217 GenerateStoicmSparseHeader();
3218 GenerateDFunDRcoeff();
3219 GenerateDJacDRcoeff();
3222 printf("\nKPP is generating the driver from %s.f90:", driver
);
3223 printf("\n - %s_Main",rootFileName
);
3225 if ( (useLang
== F77_LANG
)||(useLang
== F90_LANG
)||(useLang
== C_LANG
) )
3226 GenerateIntegrator();
3228 /* mz_rs_20050518+ no driver file if driver = none */
3229 if( strcmp( driver
, "none" ) != 0 )
3231 /* mz_rs_20050518- */
3233 if ( (useLang
== F77_LANG
)||(useLang
== F90_LANG
)||(useLang
== C_LANG
) )
3236 if ( useLang
== F90_LANG
)
3237 GenerateF90Modules('t');
3239 if ( useLang
== MATLAB_LANG
)
3240 GenerateMatlabTemplates();
3242 if ( (useLang
== F77_LANG
)||(useLang
== F90_LANG
)||(useLang
== C_LANG
) )
3245 /* mz_rs_20050117+ */
3246 if( initFile
) fclose( initFile
);
3247 /* mz_rs_20050117- */
3248 if( driverFile
) fclose( driverFile
);
3249 if( functionFile
) fclose( functionFile
);
3250 if( global_dataFile
) fclose( global_dataFile
);
3251 if( hessianFile
) fclose( hessianFile
);
3252 if( integratorFile
) fclose( integratorFile
);
3253 if( jacobianFile
) fclose( jacobianFile
);
3254 if( linalgFile
) fclose( linalgFile
);
3255 if( mapFile
) fclose( mapFile
);
3256 if( makeFile
) fclose( makeFile
);
3257 if( monitorFile
) fclose( monitorFile
);
3258 if( mex_funFile
) fclose( mex_funFile
);
3259 if( mex_jacFile
) fclose( mex_jacFile
);
3260 if( mex_hessFile
) fclose( mex_hessFile
);
3261 if( param_headerFile
) fclose( param_headerFile
);
3262 if( rateFile
) fclose( rateFile
);
3263 if( sparse_dataFile
) fclose( sparse_dataFile
);
3264 if( sparse_jacFile
) fclose( sparse_jacFile
);
3265 if( sparse_hessFile
) fclose( sparse_hessFile
);
3266 if( sparse_stoicmFile
) fclose( sparse_stoicmFile
);
3267 if( stoichiomFile
) fclose( stoichiomFile
);
3268 if( utilFile
) fclose( utilFile
);
3269 if( stochasticFile
) fclose( stochasticFile
);
3273 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3274 int* AllocIntegerVector(int n
, char* message
)
3277 if ( ( vec
=(int*)calloc(n
,sizeof(int)) ) == NULL
)
3278 FatalError(-30,"%s: Cannot allocate vector.",message
);
3282 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3283 /* Allocates a matrix of integers */
3284 int** AllocIntegerMatrix(int m
, int n
, char* message
)
3288 if ( (mat
= (int**)calloc(m
,sizeof(int*)))==NULL
) {
3289 FatalError(-30,"%s: Cannot allocate matrix.", message
);
3292 if ( (mat
[i
] = (int*)calloc(n
,sizeof(int)))==NULL
) {
3293 FatalError(-30,"%s: Cannot allocate matrix[%d].", message
, i
);
3298 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3299 /* Frees the memory allocated by AllocIntegerMatrix */
3300 void FreeIntegerMatrix(int** mat
, int m
, int n
)
3308 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
3309 /* i = C-type index; returns language-appropriate index */
3321 default: printf("\n Unknown language no %d\n",useLang
);