1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2011 Carnegie Mellon University |
3 |
|
4 |
This program is free software; you can redistribute it and/or modify |
5 |
|
6 |
it under the terms of the GNU General Public License as published by |
7 |
the Free Software Foundation; either version 2, or (at your option) |
8 |
any later version. |
9 |
|
10 |
This program is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
14 |
GNU General Public License for more details. |
15 |
|
16 |
You should have received a copy of the GNU General Public License |
17 |
along with this program; if not, write to the Free Software |
18 |
Foundation, Inc., 59 Temple Place - Suite 330, |
19 |
Boston, MA 02111-1307, USA. |
20 |
|
21 |
*//* |
22 |
by Harry, 4th June 2015 |
23 |
|
24 |
This file contains an implmentation of the prepare_integrator function |
25 |
that sets up the integration engine to perform event guided integration. |
26 |
The various tasks it performs include: allocate memory (ida_mem), obtain |
27 |
integrator configuration, analyse equations and configure IDA to setup |
28 |
sufficient memory for the derivative and non-derivative variables. |
29 |
|
30 |
*/ |
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
#define _GNU_SOURCE |
37 |
|
38 |
#include "ida.h" |
39 |
#include "idalinear.h" |
40 |
#include "idaanalyse.h" |
41 |
#include "idatypes.h" /* The list of includes needs cleaning up! Once basic files are written, |
42 |
#include "idaprec.h" all commonly called functions can be added in just one header file. |
43 |
#include "idacalc.h" Once that's done, these includes must be revisited*/ |
44 |
#include "idaio.h" |
45 |
#include "idaboundary.h" |
46 |
|
47 |
#include <signal.h> /*Check if these includes are necessary*/ |
48 |
#include <setjmp.h> |
49 |
#include <fenv.h> |
50 |
#include <math.h> |
51 |
|
52 |
#ifdef ASC_WITH_MMIO |
53 |
# include <mmio.h> |
54 |
#endif |
55 |
|
56 |
#include <ascend/general/platform.h> |
57 |
#include <ascend/utilities/error.h> |
58 |
#include <ascend/utilities/ascSignal.h> |
59 |
#include <ascend/general/panic.h> |
60 |
#include <ascend/compiler/instance_enum.h> |
61 |
|
62 |
|
63 |
#include <ascend/system/slv_client.h> |
64 |
#include <ascend/system/relman.h> |
65 |
#include <ascend/system/block.h> |
66 |
#include <ascend/system/slv_stdcalls.h> |
67 |
#include <ascend/system/jacobian.h> |
68 |
#include <ascend/system/bndman.h> |
69 |
|
70 |
#include <ascend/utilities/config.h> |
71 |
#include <ascend/integrator/integrator.h> |
72 |
|
73 |
|
74 |
int ida_prepare_integrator(IntegratorSystem *integ){ |
75 |
flag = IDAInit(ida_mem, &integrator_ida_fex, t0, y0 ,yp0); |
76 |
|
77 |
/*------------------- RECORDING INTEGRATOR PREFERENCES --------------------* |
78 |
The following block sets several preferences based on user choices. |
79 |
The code implemented in this block was initially obtained from |
80 |
ida.c in the Ksenija2 directory. |
81 |
*-----------------------------------------------------------------------------------------------------------*/ |
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
/*Takes in a host of parameters for specifying integrator preferences*/ |
94 |
static int integrator_ida_params_default(IntegratorSystem *integ) { |
95 |
asc_assert(integ!=NULL); |
96 |
asc_assert(integ->engine==INTEG_IDA); |
97 |
slv_parameters_t *p; |
98 |
p = &(integ->params); |
99 |
slv_destroy_parms(p); |
100 |
if (p->parms == NULL) { |
101 |
//CONSOLE_DEBUG("params NULL"); |
102 |
p->parms = ASC_NEW_ARRAY(struct slv_parameter, IDA_PARAMS_SIZE); |
103 |
return -1; |
104 |
p->dynamic_parms = 1; |
105 |
}else{ |
106 |
//CONSOLE_DEBUG("params not NULL"); |
107 |
} |
108 |
/* reset the number of parameters to zero so that we can check it at the end */ |
109 |
p->num_parms = 0; |
110 |
/*The following calls to slv_param_* specify several preferences. See integrator manual for choice of available preferences in IDA*/ |
111 |
slv_param_bool(p, IDA_PARAM_AUTODIFF, |
112 |
(SlvParameterInitBool){{"autodiff" |
113 |
,"Use auto-diff?",1 |
114 |
,"Use automatic differentiation of expressions (1) or use numerical derivatives (0)" |
115 |
}, TRUE}); |
116 |
|
117 |
slv_param_char(p,IDA_PARAM_CALCIC |
118 |
,(SlvParameterInitChar){{"calcic" |
119 |
,"Initial conditions calcuation",1 |
120 |
,"Use specified values of ydot to solve for inital y (Y)," |
121 |
" or use the the values of the differential variables (yd) to solve" |
122 |
" for the pure algebraic variables (ya) along with the derivatives" |
123 |
" of the differential variables (yddot) (YA_YDP), or else don't solve" |
124 |
" the intial conditions at all (NONE). See IDA manual p 41 (IDASetId)" |
125 |
}, "YA_YDP"}, (char *[]) {"Y", "YA_YDP", "NONE",NULL}); |
126 |
|
127 |
|
128 |
slv_param_bool(p,IDA_PARAM_SAFEEVAL |
129 |
,(SlvParameterInitBool){{"safeeval" |
130 |
,"Use safe evaluation?",1 |
131 |
,"Use 'safe' function evaluation routines (TRUE) or allow ASCEND to " |
132 |
"throw SIGFPE errors which will then halt integration." |
133 |
}, FALSE}); |
134 |
|
135 |
slv_param_bool(p,IDA_PARAM_ATOLVECT |
136 |
,(SlvParameterInitBool){{"atolvect" |
137 |
,"Use 'ode_atol' values as specified?",1 |
138 |
,"If TRUE, values of 'ode_atol' are taken from your model and used " |
139 |
" in the integration. If FALSE, a scalar absolute tolerance value" |
140 |
" is shared by all variables. See IDA manual, section 5.5.1" |
141 |
}, TRUE}); |
142 |
|
143 |
slv_param_real(p,IDA_PARAM_ATOL |
144 |
,(SlvParameterInitReal){{"atol" |
145 |
,"Scalar absolute error tolerance",1 |
146 |
,"Value of the scalar absolute error tolerance. See also 'atolvect'." |
147 |
" See IDA manual, sections 5.5.1 and 5.5.2 'Advice on choice and use of tolerances'" |
148 |
}, 1e-5, 0, 1e10}); |
149 |
|
150 |
slv_param_real(p,IDA_PARAM_RTOL |
151 |
,(SlvParameterInitReal){{"rtol" |
152 |
,"Scalar relative error tolerance",1 |
153 |
,"Value of the scalar relative error tolerance. (Note that for IDA," |
154 |
" it's not possible to set per-variable relative tolerances as it is" |
155 |
" with LSODE)." |
156 |
" See IDA manual, section 5.5.2 'Advice on choice and use of tolerances'" |
157 |
}, 1e-4, 0, 1}); |
158 |
|
159 |
slv_param_char(p,IDA_PARAM_LINSOLVER |
160 |
,(SlvParameterInitChar){{"linsolver" |
161 |
,"Linear solver",1 |
162 |
,"See IDA manual, section 5.5.3. Choose 'ASCEND' to use the linsolqr" |
163 |
" direct linear solver bundled with ASCEND, 'DENSE' to use the dense" |
164 |
" solver bundled with IDA, or one of the Krylov solvers SPGMR, SPBCG" |
165 |
" or SPTFQMR (which still need preconditioners to be implemented" |
166 |
" before they can be very useful."},"DENSE"},(char *[]){"ASCEND","DENSE","BAND","SPGMR","SPBCG","SPTFQMR",NULL}); |
167 |
|
168 |
slv_param_int(p,IDA_PARAM_MAXL |
169 |
,(SlvParameterInitInt){{"maxl" |
170 |
,"Maximum Krylov dimension",0 |
171 |
,"The maximum dimension of Krylov space used by the linear solver" |
172 |
" (for SPGMR, SPBCG, SPTFQMR) with IDA. See IDA manual section 5.5." |
173 |
" The default of 0 results in IDA using its internal default, which" |
174 |
" is currently a value of 5." |
175 |
}, 0, 0, 20}); |
176 |
|
177 |
slv_param_int(p,IDA_PARAM_MAXORD |
178 |
,(SlvParameterInitInt){{"maxord" |
179 |
,"Maximum order of linear multistep method",0 |
180 |
,"The maximum order of the linear multistep method with IDA. See" |
181 |
" IDA manual p 38." |
182 |
}, 5, 1, 5}); |
183 |
|
184 |
slv_param_bool(p,IDA_PARAM_GSMODIFIED |
185 |
,(SlvParameterInitBool){{"gsmodified" |
186 |
,"Gram-Schmidt Orthogonalisation Scheme", 2 |
187 |
,"TRUE = GS_MODIFIED, FALSE = GS_CLASSICAL. See IDA manual section" |
188 |
" 5.5.6.6. Only applies when linsolve=SPGMR is selected." |
189 |
}, TRUE}); |
190 |
|
191 |
slv_param_int(p,IDA_PARAM_MAXNCF |
192 |
,(SlvParameterInitInt){{"maxncf" |
193 |
,"Max nonlinear solver convergence failures per step", 2 |
194 |
,"Maximum number of allowable nonlinear solver convergence failures" |
195 |
" on one step. See IDA manual section 5.5.6.1." |
196 |
}, 10,0,1000}); |
197 |
|
198 |
slv_param_char(p,IDA_PARAM_PREC |
199 |
,(SlvParameterInitChar){{"prec" |
200 |
,"Preconditioner",1 |
201 |
,"See IDA manual, section section 5.6.8." |
202 |
},"NONE"}, (char *[]) {"NONE","DIAG",NULL}); |
203 |
|
204 |
/*Check to verify the number of parameters are correct*/ |
205 |
asc_assert(p->num_parms == IDA_PARAMS_SIZE); |
206 |
//CONSOLE_DEBUG("Created %d params", p->num_parms); |
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
/*------------------- PASSING ON USER PREFERENCES TO INTEGRATOR --------------------* |
218 |
In the following block, the user preferences for several integrator |
219 |
settings are passed on to the integrator engine. |
220 |
|
221 |
*-----------------------------------------------------------------------------------------------------------*/ |
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
/*Passing initial calculation details*/ |
235 |
/*Passing initial calculation details*/ |
236 |
icopt = 0; |
237 |
if (strcmp(SLV_PARAM_CHAR(&integ->params,IDA_PARAM_CALCIC), "Y") == 0) { |
238 |
CONSOLE_DEBUG("Solving initial conditions using values of yddot"); |
239 |
icopt = IDA_Y_INIT; |
240 |
asc_assert(icopt!=0); |
241 |
}else if (strcmp(SLV_PARAM_CHAR(&integ->params,IDA_PARAM_CALCIC), "YA_YDP") == 0){ |
242 |
CONSOLE_DEBUG("Solving initial conditions using values of yd"); |
243 |
icopt = IDA_YA_YDP_INIT; |
244 |
asc_assert(icopt!=0); |
245 |
flag = IDACalcIC(ida_mem, icopt, tout1); |
246 |
|
247 |
/*Passing safe-evaluation option*/ /*Passing safe-evaluation option*/ |
248 |
|
249 |
#ifdef ASC_SIGNAL_TRAPS /*Fix Dependencies here? Re-visit!*/ |
250 |
if(enginedata->safeeval) { |
251 |
CONSOLE_DEBUG("SETTING TO IGNORE SIGFPE..."); |
252 |
Asc_SignalHandlerPush(SIGFPE, SIG_DFL); |
253 |
}else{ |
254 |
#ifdef FEX_DEBUG |
255 |
CONSOLE_DEBUG("SETTING TO CATCH SIGFPE..."); |
256 |
#endif |
257 |
Asc_SignalHandlerPushDefault(SIGFPE); |
258 |
} |
259 |
|
260 |
/*Passing tolerance preferences*/ /*Passing tolerance preferences*/ |
261 |
|
262 |
int ida_malloc(IntegratorSystem *integ, void *ida_mem, realtype t0, |
263 |
N_Vector y0, N_Vector yp0) { |
264 |
int flag; |
265 |
N_Vector abstolvect; |
266 |
realtype reltol, abstol; |
267 |
/* relative error tolerance */ |
268 |
reltol = SLV_PARAM_REAL(&(integ->params),IDA_PARAM_RTOL); |
269 |
//CONSOLE_DEBUG("rtol = %8.2e",reltol); |
270 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
271 |
flag = IDAInit(ida_mem, &integrator_ida_fex, t0, y0 ,yp0); |
272 |
#else |
273 |
if(SLV_PARAM_BOOL(&(integ->params),IDA_PARAM_ATOLVECT)) { |
274 |
/* vector of absolute tolerances */ |
275 |
CONSOLE_DEBUG("USING VECTOR OF ATOL VALUES"); |
276 |
abstolvect = N_VNew_Serial(integ->n_y); |
277 |
integrator_get_atol(integ, NV_DATA_S(abstolvect)); |
278 |
flag = IDAMalloc(ida_mem, &integrator_ida_fex, t0, y0, yp0, IDA_SV, |
279 |
reltol, abstolvect); |
280 |
N_VDestroy_Serial(abstolvect); |
281 |
}else{ |
282 |
/* scalar absolute tolerance (one value for all) */ |
283 |
abstol = SLV_PARAM_REAL(&(integ->params),IDA_PARAM_ATOL); |
284 |
CONSOLE_DEBUG("USING SCALAR ATOL VALUE = %8.2e",abstol); |
285 |
flag = IDAMalloc(ida_mem, &integrator_ida_fex, t0, y0, yp0, IDA_SS, |
286 |
reltol, &abstol); |
287 |
} |
288 |
#endif |
289 |
|
290 |
/*Passing solver-type preferences*/ /*Passing solver-type preferences*/ |
291 |
linsolver = SLV_PARAM_CHAR(&(integ->params),IDA_PARAM_LINSOLVER); |
292 |
//CONSOLE_DEBUG("ASSIGNING LINEAR SOLVER '%s'",linsolver); |
293 |
if(strcmp(linsolver, "ASCEND") == 0) { |
294 |
CONSOLE_DEBUG("ASCEND DIRECT SOLVER, size = %d",integ->n_y); |
295 |
IDAASCEND(ida_mem, integ->n_y); |
296 |
IDAASCENDSetJacFn(ida_mem, &integrator_ida_sjex, (void *) integ); |
297 |
enginedata->flagfntype = "IDAASCEND"; |
298 |
enginedata->flagfn = &IDAASCENDGetLastFlag; |
299 |
enginedata->flagnamefn = &IDAASCENDGetReturnFlagName; |
300 |
}else if (strcmp(linsolver, "DENSE") == 0){ |
301 |
//CONSOLE_DEBUG("DENSE DIRECT SOLVER, size = %d",integ->n_y); |
302 |
flag = IDADense(ida_mem, integ->n_y); |
303 |
switch(flag){ |
304 |
case IDADENSE_SUCCESS: |
305 |
break; |
306 |
case IDADENSE_MEM_NULL: |
307 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"ida_mem is NULL"); |
308 |
return 5; |
309 |
case IDADENSE_ILL_INPUT: |
310 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"IDADENSE is not compatible with current nvector module"); |
311 |
return 5; |
312 |
case IDADENSE_MEM_FAIL: |
313 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Memory allocation failed for IDADENSE"); |
314 |
return 5; |
315 |
default: |
316 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"bad return"); |
317 |
return 5; |
318 |
} |
319 |
|
320 |
if(SLV_PARAM_BOOL(&(integ->params),IDA_PARAM_AUTODIFF)) { |
321 |
//CONSOLE_DEBUG("USING AUTODIFF"); |
322 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
323 |
flag = IDADlsSetDenseJacFn(ida_mem, &integrator_ida_djex); |
324 |
#else |
325 |
flag = IDADenseSetJacFn(ida_mem, &integrator_ida_djex, |
326 |
(void *) integ); |
327 |
#endif |
328 |
switch (flag) { |
329 |
case IDADENSE_SUCCESS: |
330 |
break; |
331 |
default: |
332 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed IDADenseSetJacFn"); |
333 |
return 6; |
334 |
} |
335 |
}else{ |
336 |
CONSOLE_DEBUG("USING NUMERICAL DIFF"); |
337 |
} |
338 |
|
339 |
enginedata->flagfntype = "IDADENSE"; |
340 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
341 |
enginedata->flagfn = &IDADlsGetLastFlag; |
342 |
enginedata->flagnamefn = &IDADlsGetReturnFlagName; |
343 |
#else |
344 |
enginedata->flagfn = &IDADenseGetLastFlag; |
345 |
enginedata->flagnamefn = &IDADenseGetReturnFlagName; |
346 |
#endif |
347 |
}else{ |
348 |
/* remaining methods are all SPILS */ |
349 |
CONSOLE_DEBUG("IDA SPILS"); |
350 |
maxl = SLV_PARAM_INT(&(integ->params),IDA_PARAM_MAXL); |
351 |
CONSOLE_DEBUG("maxl = %d",maxl); |
352 |
|
353 |
/* what preconditioner for SPILS solver? */ |
354 |
|
355 |
pname = SLV_PARAM_CHAR(&(integ->params),IDA_PARAM_PREC); |
356 |
if(strcmp(pname, "NONE") == 0){ |
357 |
prec = NULL; |
358 |
}else if(strcmp(pname, "JACOBI") == 0){ |
359 |
prec = &prec_jacobi; |
360 |
}else{ |
361 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Invalid preconditioner choice '%s'",pname); |
362 |
return 7; |
363 |
} |
364 |
|
365 |
/* which SPILS linear solver? */ |
366 |
if(strcmp(linsolver, "SPGMR") == 0){ |
367 |
CONSOLE_DEBUG("IDA SPGMR"); |
368 |
flag = IDASpgmr(ida_mem, maxl); /* 0 means use the default max Krylov dimension of 5 */ |
369 |
}else if(strcmp(linsolver, "SPBCG") == 0){ |
370 |
CONSOLE_DEBUG("IDA SPBCG"); |
371 |
flag = IDASpbcg(ida_mem, maxl); |
372 |
}else if(strcmp(linsolver, "SPTFQMR") == 0){ |
373 |
CONSOLE_DEBUG("IDA SPTFQMR"); |
374 |
flag = IDASptfqmr(ida_mem, maxl); |
375 |
}else{ |
376 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unknown IDA linear solver choice '%s'",linsolver); |
377 |
return 8; |
378 |
} |
379 |
|
380 |
if(prec){ |
381 |
/* assign the preconditioner to the linear solver */ |
382 |
(prec->pcreate)(integ); |
383 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
384 |
IDASpilsSetPreconditioner(ida_mem,prec->psetup,prec->psolve); |
385 |
#else |
386 |
IDASpilsSetPreconditioner(ida_mem, prec->psetup, prec->psolve, |
387 |
(void *) integ); |
388 |
#endif |
389 |
CONSOLE_DEBUG("PRECONDITIONER = %s",pname); |
390 |
}else{ |
391 |
CONSOLE_DEBUG("No preconditioner"); |
392 |
} |
393 |
|
394 |
enginedata->flagfntype = "IDASPILS"; |
395 |
enginedata->flagfn = &IDASpilsGetLastFlag; |
396 |
enginedata->flagnamefn = &IDASpilsGetReturnFlagName; |
397 |
if(flag == IDASPILS_MEM_NULL){ |
398 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"ida_mem is NULL"); |
399 |
return 9; |
400 |
}else if (flag == IDASPILS_MEM_FAIL) { |
401 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to allocate memory (IDASpgmr)"); |
402 |
return 9; |
403 |
}/* else success */ |
404 |
/* assign the J*v function */ |
405 |
if(SLV_PARAM_BOOL(&(integ->params),IDA_PARAM_AUTODIFF)) { |
406 |
CONSOLE_DEBUG("USING AUTODIFF"); |
407 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
408 |
flag = IDASpilsSetJacTimesVecFn(ida_mem, &integrator_ida_jvex); |
409 |
#else |
410 |
flag = IDASpilsSetJacTimesVecFn(ida_mem, &integrator_ida_jvex, |
411 |
(void *) integ); |
412 |
#endif |
413 |
if(flag == IDASPILS_MEM_NULL) { |
414 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"ida_mem is NULL"); |
415 |
return 10; |
416 |
}else if (flag == IDASPILS_LMEM_NULL) { |
417 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"IDASPILS linear solver has not been initialized"); |
418 |
return 10; |
419 |
}/* else success */ |
420 |
}else{ |
421 |
CONSOLE_DEBUG("USING NUMERICAL DIFF"); |
422 |
} |
423 |
if(strcmp(linsolver, "SPGMR") == 0) { |
424 |
/* select Gram-Schmidt orthogonalisation */ |
425 |
if(SLV_PARAM_BOOL(&(integ->params),IDA_PARAM_GSMODIFIED)) { |
426 |
CONSOLE_DEBUG("USING MODIFIED GS"); |
427 |
flag = IDASpilsSetGSType(ida_mem, MODIFIED_GS); |
428 |
if(flag != IDASPILS_SUCCESS) { |
429 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to set GS_MODIFIED"); |
430 |
return 11; |
431 |
} |
432 |
}else{ |
433 |
CONSOLE_DEBUG("USING CLASSICAL GS"); |
434 |
flag = IDASpilsSetGSType(ida_mem, CLASSICAL_GS); |
435 |
if(flag != IDASPILS_SUCCESS) { |
436 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to set GS_MODIFIED"); |
437 |
return 11; |
438 |
} |
439 |
} |
440 |
} |
441 |
} |
442 |
|
443 |
/*Passing Maxord and Maxncf values*/ /*Passing Maxord and Maxncf values*/ |
444 |
|
445 |
#if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR>=4 |
446 |
IDASetUserData(ida_mem, (void *)integ); |
447 |
#else |
448 |
IDASetRdata(ida_mem, (void *) integ); |
449 |
#endif |
450 |
IDASetMaxStep(ida_mem, integrator_get_maxstep(integ)); |
451 |
IDASetInitStep(ida_mem, integrator_get_stepzero(integ)); |
452 |
IDASetMaxNumSteps(ida_mem, integrator_get_maxsubsteps(integ)); |
453 |
if (integrator_get_minstep(integ) > 0) { |
454 |
ERROR_REPORTER_HERE(ASC_PROG_NOTE,"IDA does not support minstep (ignored)\n"); |
455 |
} |
456 |
//CONSOLE_DEBUG("MAXNCF = %d",SLV_PARAM_INT(&integ->params,IDA_PARAM_MAXNCF)); |
457 |
IDASetMaxConvFails(ida_mem, SLV_PARAM_INT(&integ->params,IDA_PARAM_MAXNCF)); |
458 |
//CONSOLE_DEBUG("MAXORD = %d",SLV_PARAM_INT(&integ->params,IDA_PARAM_MAXORD)); |
459 |
IDASetMaxOrd(ida_mem, SLV_PARAM_INT(&integ->params,IDA_PARAM_MAXORD)); |
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
|
468 |
/*------------------- ANALYSE EQUATIONS --------------------* |
469 |
The following block analyses the equations passed on from the |
470 |
GUI to aid integration. This block runs a series of checks, the |
471 |
process is stopped when flag takes a non-zero value. |
472 |
*-----------------------------------------------------------------------------------------------------------*/ |
473 |
|
474 |
flag = integrator_ida_check_vars(integ) + integrator_ida_flag_rels(integ) |
475 |
+ integrator_ida_sort_rels_and_vars(integ) + integrator_ida_create_lists(integ) + |
476 |
integrator_ida_analyse(integ) + integrator_ida_check_partitioning(integ)+ |
477 |
integrator_ida_check_diffindex(integ); |
478 |
|
479 |
if(flag!=0){ |
480 |
return -2; /*Failed analysis*/ |
481 |
} |
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
/*------------------- ALLOCATE MEMORY FOR YDOT, Y ETC --------------------* |
490 |
The following block analyses the equations passed on from the |
491 |
GUI to aid integration. This block runs a series of checks, the |
492 |
process is stopped when flag takes a non-zero value. |
493 |
*-----------------------------------------------------------------------------------------------------------*/ |
494 |
|
495 |
|
496 |
|
497 |
/*This block has to be discussed with Ksenija before implamentation. Is this block necessary? |
498 |
The IDA Manual says that most memory allocation procedures are taken care of. Also there's the |
499 |
implementation of IDAMalloc, which needs to be cleared up. Also ida_malloc has already been called above |
500 |
this does the same job of allocating ydot and ypdot. Anything else needs to be done here? */ |
501 |
|
502 |
|
503 |
|
504 |
|
505 |
|
506 |
|
507 |
return 0; /*prepare_integrator successful!*/ |
508 |
} |