1 /* #include <math.h> */
10 "To get this help message use: KPP_ROOT ? \n"
12 "To initialize default values use: KPP_ROOT \n"
13 " (type who to see the variables created) \n"
15 "To integrate the model use: \n"
16 " [ c, m, f ] = KPP_ROOT( t, c0, k, p, fn, tfn ); \n"
19 " t - Time vector, contains the time at which results \n"
20 " should be reported; \n"
21 " c0 - Vector with the initial concentrations for all \n"
23 " k - Vector with all rate constants; \n"
24 " p - Vector of parameters for the integration; \n"
25 " p(1) holds the relative tolerance \n"
26 " p(2) holds the absolute tolerance \n"
27 " p(3) holds the minimum step size allowed \n"
28 " p(4) holds the maximum step size allowed \n"
29 " If any of the above is zero the default value is \n"
31 " fn - (optional) Name of a matlab function to be called \n"
32 " to update the values of k's and concentrations \n"
33 " If not present no update is performed. \n"
35 " tfn - (optional) Time at which the fn function should \n"
36 " be called. If missing <t> is assumed. \n"
39 " c - Matrix of concentrations of all species vs. time; \n"
40 " m - (optional) Mass conservation of all atoms vs. time; \n"
41 " f - (optional) Matrix of fluxes of all species vs. time; \n"
48 void F9Error( char *fmt
, ... )
52 char errmsg
[ MAX_BUF
];
54 va_start( args
, fmt
);
55 vsprintf( buf
, fmt
, args
);
58 if( giveusage
) Usage();
60 mexPrintf("Error: %s\n", buf
);
66 int CreateVar(char *name
, KPP_REAL val
)
71 sprintf(allvars
, "%s %s",allvars
, name
);
72 GA
= mxCreateDoubleMatrix(1,1,mxREAL
);
76 return mexPutArray(GA
,"global");
79 int CreateVec(char *name
, int len
, KPP_REAL
*val
)
85 sprintf(allvars
, "%s %s",allvars
, name
);
86 GA
= mxCreateDoubleMatrix(1,len
,mxREAL
);
88 if( sizeof(KPP_REAL
) == sizeof(double) ) {
89 memmove( pga
, val
, len
*sizeof(double) );
91 for( i
= 0; i
< len
; i
++ ) pga
[i
] = (double)val
[i
];
94 return mexPutArray(GA
,"global");
97 int CreateStrVec(char *name
, int len
, char **val
)
101 sprintf(allvars
, "%s %s",allvars
, name
);
102 GA
= mxCreateCharMatrixFromStrings( len
, (const char **)val
);
104 return mexPutArray(GA
,"global");
107 int CreateStr(char *name
, char *val
)
111 sprintf(allvars
, "%s %s",allvars
, name
);
112 GA
= mxCreateString( val
);
114 return mexPutArray(GA
,"global");
117 #define T_PRM prhs[0]
118 #define C0_PRM prhs[1]
119 #define K_PRM prhs[2]
120 #define P_PRM prhs[3]
121 #define FN_PRM prhs[4]
122 #define TFN_PRM prhs[5]
124 #define C_PRM plhs[0]
125 #define M_PRM plhs[1]
126 #define F_PRM plhs[2]
128 #define HAS_FN (nrhs >= 5)
129 #define HAS_TFN (nrhs >= 6)
131 #define HAS_M (nlhs >= 2)
132 #define HAS_F (nlhs >= 3)
134 #define DBL (sizeof(KPP_REAL) == sizeof(double))
137 int nlhs
, mxArray
*plhs
[],
138 int nrhs
, const mxArray
*prhs
[]
152 double dval
[ NMASS
+NSPEC
];
154 mxArray
*Carr
, *Karr
, *Tarr
;
160 int nsteps
, nspc
, nreact
, ncb
;
176 sprintf(allvars
,"global ");
178 CreateVec("PRM",4, prm
);
180 CreateVar("NSPEC",NSPEC
);
181 CreateVar("NREACT",NREACT
);
182 CreateVar("NMASS",NMASS
);
184 CreateVec("C0", NSPEC
, C
);
185 CreateVec("K0", NREACT
, RCONST
);
187 for( i
= 0; i
< NLOOKAT
; i
++ )
188 CreateVar( SLOOKAT
[i
], (double)(i
+1) );
190 for( i
= 0; i
< NMASS
; i
++ )
191 CreateVar( SMASS
[i
], (double)(i
+1) );
193 CreateStrVec("SSPEC", NSPEC
, SLOOKAT
);
194 CreateStrVec("SMASS", NMASS
, SMASS
);
195 CreateStrVec("SEQN", NREACT
, SEQN
);
197 CreateStr("GLOBALCMD", allvars
);
199 mexEvalString(allvars
);
201 mexPrintf("The KPP_ROOT model parameters were sucessfully initialized.\n");
207 F9Error("First 4 parameters are REQUIRED only %d received.", nrhs
);
209 F9Error("At least one output parameter REQUIRED.");
211 if(! mxIsDouble(T_PRM
)) F9Error("<t> must be of type double.");
212 if(! mxIsDouble(C0_PRM
)) F9Error("<c0> must be of type double.");
213 if(! mxIsDouble(K_PRM
)) F9Error("<k> must be of type double.");
214 if(! mxIsDouble(P_PRM
)) F9Error("<p> must be of type double.");
215 if((nrhs
> 4) && (! mxIsChar(FN_PRM
))) F9Error("<fn> must be of type char.");
216 if((nrhs
> 5) && (! mxIsDouble(TFN_PRM
))) F9Error("<tfn> must be of type double.");
218 nd
= mxGetNumberOfDimensions( T_PRM
);
221 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) ) ) F9Error("<t> must be a column vector.");
222 nsteps
= (m
== 1) ? n
: m
;
223 tp
= mxGetPr( T_PRM
);
225 nd
= mxGetNumberOfDimensions( C0_PRM
);
226 m
= mxGetM( C0_PRM
);
227 n
= mxGetN( C0_PRM
);
228 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) ) ) F9Error("<c0> must be a column vector.");
229 nspc
= (m
== 1) ? n
: m
;
230 c0p
= mxGetPr( C0_PRM
);
232 nd
= mxGetNumberOfDimensions( K_PRM
);
235 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) ) ) F9Error("<k> must be a column vector.");
236 nreact
= (m
== 1) ? n
: m
;
237 kp
= mxGetPr( K_PRM
);
239 nd
= mxGetNumberOfDimensions( P_PRM
);
242 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) && (n
*m
== 4) ) )
243 F9Error("<p> must be a column vectorof length 4.");
244 pp
= mxGetPr( P_PRM
);
248 nd
= mxGetNumberOfDimensions( FN_PRM
);
249 m
= mxGetM( FN_PRM
);
250 n
= mxGetN( FN_PRM
);
251 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) ) ) F9Error("<fn> must be a character string.");
252 if( mxGetString( FN_PRM
, fnp
, MAX_BUF
) )
253 F9Error("Can not read function mane (too long?)");
255 Carr
= mxCreateDoubleMatrix(1,NSPEC
,mxREAL
);
258 mexPutArray(Carr
,"base");
260 Karr
= mxCreateDoubleMatrix(1,NREACT
,mxREAL
);
263 mexPutArray(Karr
,"base");
265 Tarr
= mxCreateDoubleMatrix(1,1,mxREAL
);
268 mexPutArray(Tarr
,"base");
273 nd
= mxGetNumberOfDimensions( TFN_PRM
);
274 m
= mxGetM( TFN_PRM
);
275 n
= mxGetN( TFN_PRM
);
276 if( !( (nd
== 2) && ((m
== 1) || (n
== 1)) ) ) F9Error("<tfn> must be a column vector.");
277 ncb
= (m
== 1) ? n
: m
;
278 tfnp
= mxGetPr( TFN_PRM
);
283 if( !((nspc
== NSPEC
) && (nreact
== NREACT
)) ) {
284 F9Error("Size of parameters do not match the model:\n\n"
285 " Number of species was %d and should be %d;\n"
286 " Number of rections (rate constants) was %d and should be %d;\n",
287 nspc
, NSPEC
, nreact
, NREACT
);
290 if( DBL
) { memmove( C
, c0p
, sizeof(double)*NSPEC
);
291 memmove( RCONST
, kp
, sizeof(double)*NREACT
); }
292 else { for( i
= 0; i
< NSPEC
; i
++ ) C
[i
] = (KPP_REAL
)c0p
[i
];
293 for( i
= 0; i
< NREACT
; i
++ ) RCONST
[i
] = (KPP_REAL
)kp
[i
]; }
300 if( pp
[0] ) RTOLS
= pp
[0];
301 if( pp
[1] ) ATOLS
= pp
[1];
302 if( pp
[2] ) STEPMIN
= pp
[2];
303 if( pp
[3] ) STEPMAX
= pp
[3];
305 for( i
= 0; i
< NVAR
; i
++ ) {
310 C_PRM
= mxCreateDoubleMatrix(NSPEC
,nsteps
,mxREAL
);
314 M_PRM
= mxCreateDoubleMatrix(NMASS
,nsteps
,mxREAL
);
319 F_PRM
= mxCreateDoubleMatrix(NSPEC
,nsteps
,mxREAL
);
325 for( t
= 0; t
< nsteps
; t
++ ) {
332 if( tfnp
[tcb
] <= TIME
) { CallBack
= 1; tcb
++; }
338 if( DBL
) { memmove( fcp
, C
, sizeof(double)*NSPEC
);
339 memmove( fkp
, RCONST
, sizeof(double)*NREACT
); }
340 else { for( i
= 0; i
< NSPEC
; i
++ ) fcp
[i
] = (double)C
[i
];
341 for( i
= 0; i
< NREACT
; i
++ ) fkp
[i
] = (double)RCONST
[i
]; }
344 mexPutArray(Carr
,"base");
345 mexPutArray(Karr
,"base");
346 mexPutArray(Tarr
,"base");
348 mexCallMATLAB( 0, 0, 0, 0, fnp
);
350 mxDestroyArray(Carr
); Carr
= mexGetArray("C","base"); fcp
= mxGetPr(Carr
);
351 mxDestroyArray(Karr
); Karr
= mexGetArray("K","base"); fkp
= mxGetPr(Karr
);
352 mxDestroyArray(Tarr
); Tarr
= mexGetArray("T","base"); ftp
= mxGetPr(Tarr
);
354 if( DBL
) { memmove( C
, fcp
, sizeof(double)*NSPEC
);
355 memmove( RCONST
, fkp
, sizeof(double)*NREACT
); }
356 else { for( i
= 0; i
< NSPEC
; i
++ ) C
[i
] = (KPP_REAL
)fcp
[i
];
357 for( i
= 0; i
< NREACT
; i
++ ) RCONST
[i
] = (KPP_REAL
)fkp
[i
]; }
361 INTEGRATE( tp
[t
-1], tp
[t
] );
363 if( DBL
) { memmove( cp
, C
, sizeof(double)*NSPEC
); cp
+= NSPEC
; }
364 else { for( i
= 0; i
< NSPEC
; i
++ ) *cp
++ = (double)C
[i
]; }
366 if( DBL
) { GetMass( mp
); mp
+= NMASS
; }
367 else { GetMass( dval
);
368 for( i
= 0; i
< NMASS
; i
++ ) *mp
++ = (double)dval
[i
]; }
371 if( DBL
) { FLUX( fp
); fp
+= NSPEC
; }
373 for( i
= 0; i
< NSPEC
; i
++ ) *fp
++ = (double)dval
[i
]; }