3 * Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * See the file ./license.txt
27 * input/output regular ports
30 * added object paramaters/states
33 * CVODE (sundials) replaced LSODAR
34 * IDA (Sundials) replaced DASKR
36 /*--------------------------------------------------------------------------*/
41 /* Sundials includes */
42 #include <cvode/cvode.h> /* prototypes for CVODES fcts. and consts. */
43 #include <cvode/cvode_dense.h> /* prototype for CVDense */
45 #include <ida/ida_dense.h>
46 #include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., and macros */
47 #include <sundials/sundials_dense.h> /* definitions DenseMat and DENSE_ELEM */
48 #include <sundials/sundials_types.h> /* definition of type realtype */
49 #include <sundials/sundials_math.h>
50 #include <kinsol/kinsol.h>
51 #include <kinsol/kinsol_dense.h>
52 #include <sundials/sundials_extension.h> /* uses extension for scicos */
55 #include "machine.h" /* C2F */
56 #include "dynamic_link.h"
57 #include "scicos-def.h"
58 #include "stack-def.h"
63 #include "core_math.h"
64 #include "storeCommand.h"
67 #include "math_graphics.h"
75 #include "dynlib_scicos.h"
77 #include "lsodar.h" /* prototypes for lsodar fcts. and consts. */
79 #if defined(linux) && defined(__i386__)
80 #include "setPrecisionFPU.h"
83 #include "localization.h"
84 #include "charEncoding.h"
85 /*--------------------------------------------------------------------------*/
92 double *gwork; /* just added for a very special use: a
93 space passing to grblkdakr for zero crossing surfaces
94 when updating mode variables during initialization */
97 SCICOS_IMPEXP SCSPTR_struct C2F(scsptr);
98 /*--------------------------------------------------------------------------*/
101 if (*neq>0) if (C2F(cmsolver).solver) (CVodeFree(&cvode_mem)); else (LSodarFree(&cvode_mem)); \
102 if (*neq>0) N_VDestroy_Serial(y); \
103 if ( ng>0 ) FREE(jroot); \
104 if ( ng>0 ) FREE(zcros);
107 /* TJacque allocates by sundials */
109 if (*neq>0) free(TJacque); \
110 if (*neq>0) FREE(data->rwork); \
111 if (( ng>0 )&& (*neq>0)) FREE(data->gwork); \
112 if (*neq>0) N_VDestroy_Serial(data->ewt); \
113 if (*neq>0) FREE(data); \
114 if (*neq>0) IDAFree(&ida_mem); \
115 if (*neq>0) N_VDestroy_Serial(IDx); \
116 if (*neq>0) N_VDestroy_Serial(yp); \
117 if (*neq>0) N_VDestroy_Serial(yy); \
118 if ( ng>0 ) FREE(jroot); \
119 if ( ng>0 ) FREE(zcros); \
120 if (nmod>0) FREE(Mode_save);
122 #define freeouttbptr \
133 N_VDestroy_Serial(y); \
134 N_VDestroy_Serial(fscale); \
135 N_VDestroy_Serial(yscale); \
139 #define ONE RCONST(1.0)
140 #define ZERO RCONST(0.0)
141 #define T0 RCONST(0.0)
142 /*--------------------------------------------------------------------------*/
143 /* Table of constant values */
144 static int c__90 = 90;
145 static int c__91 = 91;
147 static double c_b14 = 0.;
150 int TCritWarning = 0;
152 static double *t0 = NULL, *tf = NULL;
153 static double *x = NULL, *tevts = NULL, *xd = NULL, *g = NULL;
154 static double Atol = 0., rtol = 0., ttol = 0., deltat = 0., hmax = 0.;
155 static int *ierr = NULL;
156 static int *pointi = NULL;
157 static int *xptr = NULL, *modptr = NULL, *evtspt = NULL;
158 static int *funtyp = NULL, *inpptr = NULL, *outptr = NULL, *inplnk = NULL, *outlnk = NULL;
159 static int *clkptr = NULL, *ordptr = NULL, *ordclk = NULL, *cord = NULL, *iord = NULL, *oord = NULL, *zord = NULL, *critev = NULL, *zcptr = NULL;
160 static int nblk = 0, nordptr = 0, nlnk = 0, nx = 0, ng = 0, ncord = 0, noord = 0, nzord = 0;
161 static int nordclk = 0, niord = 0, nmod = 0;
162 static int nelem = 0;
163 static int *mod = NULL;
164 static int *neq = NULL;
165 static int *xprop = NULL; /* xproperty */
166 static int debug_block = 0;
167 static int *iwa = NULL;
170 /* declaration of ptr for typed port */
171 static void **outtbptr = NULL; /*pointer array of object of outtb*/
172 static int *outtbsz = NULL; /*size of object of outtb*/
173 static int *outtbtyp = NULL; /*type of object of outtb*/
175 SCSREAL_COP *outtbdptr = NULL; /*to store double of outtb*/
176 SCSINT8_COP *outtbcptr = NULL; /*to store int8 of outtb*/
177 SCSINT16_COP *outtbsptr = NULL; /*to store int16 of outtb*/
178 SCSINT32_COP *outtblptr = NULL; /*to store int32 of outtb*/
179 SCSUINT8_COP *outtbucptr = NULL; /*to store unsigned int8 of outtb */
180 SCSUINT16_COP *outtbusptr = NULL; /*to store unsigned int16 of outtb */
181 SCSUINT32_COP *outtbulptr = NULL; /*to store unsigned int32 of outtb */
183 static outtb_el *outtb_elem = NULL;
185 static scicos_block *Blocks = NULL;
187 /* pass to external variable for code generation */
188 /* reserved variable name */
189 int *block_error = NULL;
190 double scicos_time = 0.;
192 int Jacobian_Flag = 0;
193 // double CI = 0., CJ = 0.; // doubles returned by Get_Jacobian_ci and Get_Jacobian_cj respectively
194 double CJJ = 0.; // returned by Get_Jacobian_parameter
195 double SQuround = 0.;
197 static int AJacobian_block = 0;
200 /* Variable declaration moved to scicos.c because it was in the scicos-def.h therefore
201 * multiple declaration of the variable and linkers were complaining about duplicate
204 SCICOS_IMPEXP COSDEBUGCOUNTER_struct C2F(cosdebugcounter);
205 SCICOS_IMPEXP RTFACTOR_struct C2F(rtfactor);
206 SCICOS_IMPEXP SOLVER_struct C2F(cmsolver);
207 SCICOS_IMPEXP CURBLK_struct C2F(curblk);
208 SCICOS_IMPEXP COSDEBUG_struct C2F(cosdebug);
209 SCICOS_IMPEXP COSHLT_struct C2F(coshlt);
210 SCICOS_IMPEXP DBCOS_struct C2F(dbcos);
211 SCICOS_IMPEXP COSTOL_struct C2F(costol);
212 SCICOS_IMPEXP COSERR_struct coserr;
213 /*--------------------------------------------------------------------------*/
214 static void FREE_blocks();
215 static void cosini(double *told);
216 static void cosend(double *told);
217 static void cossim(double *told);
218 static void cossimdaskr(double *told);
219 static void doit(double *told);
220 static void idoit(double *told);
221 static void zdoit(double *told, double *xt, double *xtd, double *g);
222 static void cdoit(double *told);
223 static void ozdoit(double *told, double *xt, double *xtd, int *kiwa);
224 static void odoit(double *told, double *xt, double *xtd, double *residual);
225 static void ddoit(double *told);
226 static void edoit(double *told, int *kiwa);
227 static void reinitdoit(double *told);
228 static int CallKinsol(double *told);
229 static int simblk(realtype t, N_Vector yy, N_Vector yp, void *f_data);
230 static int grblkdaskr(realtype t, N_Vector yy, N_Vector yp, realtype *gout, void *g_data);
231 static int grblk(realtype t, N_Vector yy, realtype *gout, void *g_data);
232 static int simblklsodar(int * nequations, realtype * tOld, realtype * actual, realtype * res);
233 static int grblklsodar(int * nequations, realtype * tOld, realtype * actual, int * ngroot, realtype * res);
234 static void addevs(double t, int *evtnb, int *ierr1);
235 static int synchro_g_nev(ScicosImport *scs_imp, double *g, int kf, int *ierr);
236 static void Multp(double *A, double *B, double *R, int ra, int rb, int ca, int cb);
237 static int read_id(ezxml_t *elements, char *id, double *value);
238 static int simblkdaskr(realtype tres, N_Vector yy, N_Vector yp, N_Vector resval, void *rdata);
239 static int Jacobians(long int Neq, realtype tt, N_Vector yy, N_Vector yp,
240 N_Vector resvec, realtype cj, void *jdata, DenseMat Jacque,
241 N_Vector tempv1, N_Vector tempv2, N_Vector tempv3);
242 static void call_debug_scicos(scicos_block *block, scicos_flag *flag, int flagi, int deb_blk);
243 static int synchro_nev(ScicosImport *scs_imp, int kf, int *ierr);
244 /*--------------------------------------------------------------------------*/
245 extern int C2F(dset)(int *n, double *dx, double *dy, int *incy);
246 extern int C2F(dcopy)(int *, double *, int *, double *, int *);
247 extern int C2F(msgs)();
248 extern int C2F(getscsmax)();
249 extern int C2F(makescicosimport)();
250 extern int C2F(clearscicosimport)();
251 /*--------------------------------------------------------------------------*/
252 void putevs(double *t, int *evtnb, int *ierr1);
253 void Jdoit(double *told, double *xt, double *xtd, double *residual, int *job);
254 int simblkKinsol(N_Vector yy, N_Vector resval, void *rdata);
255 /*--------------------------------------------------------------------------*/
256 int C2F(scicos)(double *x_in, int *xptr_in, double *z__,
257 void **work, int *zptr, int *modptr_in,
258 void **oz, int *ozsz, int *oztyp, int *ozptr,
259 int *iz, int *izptr, double *t0_in,
260 double *tf_in, double *tevts_in, int *evtspt_in,
261 int *nevts, int *pointi_in, void **outtbptr_in,
262 int *outtbsz_in, int *outtbtyp_in,
263 outtb_el *outtb_elem_in, int *nelem1, int *nlnk1,
264 int *funptr, int *funtyp_in, int *inpptr_in,
265 int *outptr_in, int *inplnk_in, int *outlnk_in,
266 double *rpar, int *rpptr, int *ipar, int *ipptr,
267 void **opar, int *oparsz, int *opartyp, int *opptr,
268 int *clkptr_in, int *ordptr_in, int *nordptr1,
269 int *ordclk_in, int *cord_in, int *ncord1,
270 int *iord_in, int *niord1, int *oord_in,
271 int *noord1, int *zord_in, int *nzord1,
272 int *critev_in, int *nblk1, int *ztyp,
273 int *zcptr_in, int *subscr, int *nsubs,
274 double *simpar, int *flag__, int *ierr_out)
276 int i1, kf, lprt, in, out, job = 1;
279 static int mxtb = 0, ierr0 = 0, kfun0 = 0, i = 0, j = 0, k = 0, jj = 0;
280 static int ni = 0, no = 0;
281 static int nz = 0, noz = 0, nopar = 0;
284 // Set FPU Flag to Extended for scicos simulation
285 // in order to override Java setting it to Double.
286 #if defined(linux) && defined(__i386__)
289 /* Copyright INRIA */
290 /* iz,izptr are used to pass block labels */
297 /* Parameter adjustments */
301 modptr = modptr_in - 1;
305 evtspt = evtspt_in - 1;
306 tevts = tevts_in - 1;
307 outtbptr = outtbptr_in;
308 outtbsz = outtbsz_in;
309 outtbtyp = outtbtyp_in;
310 outtb_elem = outtb_elem_in;
311 funtyp = funtyp_in - 1;
312 inpptr = inpptr_in - 1;
313 outptr = outptr_in - 1;
314 inplnk = inplnk_in - 1;
315 outlnk = outlnk_in - 1;
319 clkptr = clkptr_in - 1;
320 ordptr = ordptr_in - 1;
321 ordclk = ordclk_in - 1;
327 critev = critev_in - 1;
329 zcptr = zcptr_in - 1;
337 C2F(rtfactor).scale = simpar[5];
338 C2F(cmsolver).solver = (int) simpar[6];
351 nordclk = ordptr[nordptr] - 1; /* number of rows in ordclk is ordptr(nclkp1)-1 */
352 ng = zcptr[nblk + 1] - 1; /* computes number of zero crossing surfaces */
353 nmod = modptr[nblk + 1] - 1; /* computes number of modes */
354 nz = zptr[nblk + 1] - 1; /* number of discrete real states */
355 noz = ozptr[nblk + 1] - 1; /* number of discrete object states */
356 nopar = opptr[nblk + 1] - 1; /* number of object parameters */
357 nx = xptr[nblk + 1] - 1; /* number of object parameters */
360 xd = &x[xptr[nblk + 1] - 1];
362 /* check for hard coded maxsize */
363 for (i = 1; i <= nblk; ++i)
365 if (funtyp[i] < 10000)
371 funtyp[i] = funtyp[i] % 1000 + 10000;
373 ni = inpptr[i + 1] - inpptr[i];
374 no = outptr[i + 1] - outptr[i];
379 /* hard coded maxsize in callf.c */
380 C2F(msgs)(&c__90, &c__0);
381 C2F(curblk).kfun = i;
386 else if (funtyp[i] == 2 || funtyp[i] == 3)
388 /* hard coded maxsize in scicos.h */
389 if (ni + no > SZ_SIZE)
391 C2F(msgs)(&c__90, &c__0);
392 C2F(curblk).kfun = i;
402 for (j = 1; j <= ni; ++j)
404 k = inplnk[inpptr[i] - 1 + j];
405 mxtb = mxtb + (outtbsz[k - 1] * outtbsz[(k - 1) + nlnk]);
410 for (j = 1; j <= no; ++j)
412 k = outlnk[outptr[i] - 1 + j];
413 mxtb = mxtb + (outtbsz[k - 1] * outtbsz[(k - 1) + nlnk]);
418 C2F(msgs)(&c__91, &c__0);
419 C2F(curblk).kfun = i;
426 if (nx > 0) /* xprop */
428 if ((xprop = MALLOC(sizeof(int) * nx)) == NULL )
434 for (i = 0; i < nx; i++) /* initialize */
438 if (nmod > 0) /* mod */
440 if ((mod = MALLOC(sizeof(int) * nmod)) == NULL )
443 if (nx > 0) FREE(xprop);
447 if (ng > 0) /* g becomes global */
449 if ((g = MALLOC(sizeof(double) * ng)) == NULL )
452 if (nmod > 0) FREE(mod);
453 if (nx > 0) FREE(xprop);
458 debug_block = -1; /* no debug block for start */
459 C2F(cosdebugcounter).counter = 0;
461 /** Create Block's array **/
462 if ((Blocks = MALLOC(sizeof(scicos_block) * nblk)) == NULL )
465 if (nx > 0) FREE(xprop);
466 if (nmod > 0) FREE(mod);
471 /** Setting blocks properties for each entry in Block's array **/
473 /* 1 : type and pointer on simulation function */
474 for (kf = 0; kf < nblk; ++kf) /*for each block */
476 C2F(curblk).kfun = kf + 1;
478 Blocks[kf].type = funtyp[kf + 1];
481 switch (funtyp[kf + 1])
484 Blocks[kf].funpt = F2C(sciblk);
487 sciprint(_("type 1 function not allowed for scilab blocks\n"));
488 *ierr = 1000 + kf + 1;
492 sciprint(_("type 2 function not allowed for scilab blocks\n"));
493 *ierr = 1000 + kf + 1;
497 Blocks[kf].funpt = sciblk2;
501 Blocks[kf].funpt = sciblk4;
504 case 99: /* debugging block */
505 Blocks[kf].funpt = sciblk4;
506 /*Blocks[kf].type=4;*/
511 Blocks[kf].funpt = sciblk4;
512 Blocks[kf].type = 10004;
515 sciprint(_("Undefined Function type\n"));
516 *ierr = 1000 + kf + 1;
520 Blocks[kf].scsptr = -i; /* set scilab function adress for sciblk */
522 else if (i <= ntabsim)
524 Blocks[kf].funpt = *(tabsim[i - 1].fonc);
525 Blocks[kf].scsptr = 0; /* this is done for being able to test if a block
526 is a scilab block in the debugging phase when
532 //TODO: see in dynamic_lin how to get funcptr from index
533 //GetDynFunc(i, &Blocks[kf].funpt);
534 if ( Blocks[kf].funpt == (voidf) 0)
536 sciprint(_("Function not found\n"));
537 *ierr = 1000 + kf + 1;
541 Blocks[kf].scsptr = 0; /* this is done for being able to test if a block
542 is a scilab block in the debugging phase when
546 /* 2 : Dimension properties */
547 Blocks[kf].ztyp = ztyp[kf + 1];
548 Blocks[kf].nx = xptr[kf + 2] - xptr[kf + 1]; /* continuuous state dimension*/
549 Blocks[kf].ng = zcptr[kf + 2] - zcptr[kf + 1]; /* number of zero crossing surface*/
550 Blocks[kf].nz = zptr[kf + 2] - zptr[kf + 1]; /* number of double discrete state*/
551 Blocks[kf].noz = ozptr[kf + 2] - ozptr[kf + 1]; /* number of other discrete state*/
552 Blocks[kf].nrpar = rpptr[kf + 2] - rpptr[kf + 1]; /* size of double precision parameter vector*/
553 Blocks[kf].nipar = ipptr[kf + 2] - ipptr[kf + 1]; /* size of integer precision parameter vector*/
554 Blocks[kf].nopar = opptr[kf + 2] - opptr[kf + 1]; /* number of other parameters (matrix, data structure,..)*/
555 Blocks[kf].nin = inpptr[kf + 2] - inpptr[kf + 1]; /* number of input ports */
556 Blocks[kf].nout = outptr[kf + 2] - outptr[kf + 1]; /* number of output ports */
558 /* 3 : input port properties */
559 /* in insz, we store :
560 * - insz[0..nin-1] : first dimension of input ports
561 * - insz[nin..2*nin-1] : second dimension of input ports
562 * - insz[2*nin..3*nin-1] : type of data of input ports
564 /* allocate size and pointer arrays (number of input ports)*/
565 Blocks[kf].insz = NULL;
566 Blocks[kf].inptr = NULL;
567 if (Blocks[kf].nin != 0)
569 if ((Blocks[kf].insz = MALLOC(Blocks[kf].nin * 3 * sizeof(int))) == NULL )
575 if ((Blocks[kf].inptr = MALLOC(Blocks[kf].nin * sizeof(double*))) == NULL )
582 for (in = 0; in < Blocks[kf].nin; in++)
584 lprt = inplnk[inpptr[kf + 1] + in];
585 Blocks[kf].inptr[in] = outtbptr[lprt - 1]; /* pointer on the data*/
586 Blocks[kf].insz[in] = outtbsz[lprt - 1]; /* row dimension of the input port*/
587 Blocks[kf].insz[Blocks[kf].nin + in] = outtbsz[(lprt - 1) + nlnk]; /* column dimension of the input port*/
588 Blocks[kf].insz[2 * Blocks[kf].nin + in] = outtbtyp[lprt - 1]; /*type of data of the input port*/
590 /* 4 : output port properties */
591 /* in outsz, we store :
592 * - outsz[0..nout-1] : first dimension of output ports
593 * - outsz[nout..2*nout-1] : second dimension of output ports
594 * - outsz[2*nout..3*nout-1] : type of data of output ports
596 /* allocate size and pointer arrays (number of output ports)*/
597 Blocks[kf].outsz = NULL;
598 Blocks[kf].outptr = NULL;
599 if (Blocks[kf].nout != 0)
601 if ((Blocks[kf].outsz = MALLOC(Blocks[kf].nout * 3 * sizeof(int))) == NULL )
607 if ((Blocks[kf].outptr = MALLOC(Blocks[kf].nout * sizeof(double*))) == NULL )
615 for (out = 0; out < Blocks[kf].nout; out++) /*for each output port */
617 lprt = outlnk[outptr[kf + 1] + out];
618 Blocks[kf].outptr[out] = outtbptr[lprt - 1]; /*pointer on data */
619 Blocks[kf].outsz[out] = outtbsz[lprt - 1]; /*row dimension of output port*/
620 Blocks[kf].outsz[Blocks[kf].nout + out] = outtbsz[(lprt - 1) + nlnk]; /*column dimension of output ports*/
621 Blocks[kf].outsz[2 * Blocks[kf].nout + out] = outtbtyp[lprt - 1]; /*type of data of output port */
624 /* 5 : event output port properties */
625 Blocks[kf].evout = NULL;
626 Blocks[kf].nevout = clkptr[kf + 2] - clkptr[kf + 1];
627 if (Blocks[kf].nevout != 0)
629 if ((Blocks[kf].evout = CALLOC(Blocks[kf].nevout, sizeof(double))) == NULL )
637 /* 6 : pointer on the begining of the double discrete state array ( z) */
638 Blocks[kf].z = &(z__[zptr[kf + 1] - 1]);
640 /* 7 : type, size and pointer on the other discrete states data structures (oz) */
641 Blocks[kf].ozsz = NULL;
642 if (Blocks[kf].noz == 0)
644 Blocks[kf].ozptr = NULL;
645 Blocks[kf].oztyp = NULL;
649 Blocks[kf].ozptr = &(oz[ozptr[kf + 1] - 1]);
650 if ((Blocks[kf].ozsz = MALLOC(Blocks[kf].noz * 2 * sizeof(int))) == NULL )
656 for (i = 0; i < Blocks[kf].noz; i++)
658 Blocks[kf].ozsz[i] = ozsz[(ozptr[kf + 1] - 1) + i];
659 Blocks[kf].ozsz[i + Blocks[kf].noz] = ozsz[(ozptr[kf + 1] - 1 + noz) + i];
661 Blocks[kf].oztyp = &(oztyp[ozptr[kf + 1] - 1]);
664 /* 8 : pointer on the begining of the double parameter array ( rpar ) */
665 Blocks[kf].rpar = &(rpar[rpptr[kf + 1] - 1]);
667 /* 9 : pointer on the begining of the integer parameter array ( ipar ) */
668 Blocks[kf].ipar = &(ipar[ipptr[kf + 1] - 1]);
670 /* 10 : type, size and pointer on the other parameters data structures (opar) */
671 Blocks[kf].oparsz = NULL;
672 if (Blocks[kf].nopar == 0)
674 Blocks[kf].oparptr = NULL;
675 Blocks[kf].opartyp = NULL;
679 Blocks[kf].oparptr = &(opar[opptr[kf + 1] - 1]);
680 if ((Blocks[kf].oparsz = MALLOC(Blocks[kf].nopar * 2 * sizeof(int))) == NULL)
686 for (i = 0; i < Blocks[kf].nopar; i++)
688 Blocks[kf].oparsz[i] = oparsz[(opptr[kf + 1] - 1) + i];
689 Blocks[kf].oparsz[i + Blocks[kf].nopar] = oparsz[(opptr[kf + 1] - 1 + nopar) + i];
691 Blocks[kf].opartyp = &(opartyp[opptr[kf + 1] - 1]);
694 /* 10 : pointer on the beginning of the residual array (res) */
695 Blocks[kf].res = NULL;
696 if (Blocks[kf].nx != 0)
698 if ((Blocks[kf].res = MALLOC(Blocks[kf].nx * sizeof(double))) == NULL)
706 /* 11 : block label (label) */
707 i1 = izptr[kf + 2] - izptr[kf + 1];
708 if ((Blocks[kf].label = MALLOC(sizeof(char) * (i1 + 1))) == NULL)
714 Blocks[kf].label[i1] = '\0';
715 C2F(cvstr)(&i1, &(iz[izptr[kf + 1] - 1]), Blocks[kf].label, &job, i1);
717 /* 12 : block array of crossed surfaces (jroot) */
718 Blocks[kf].jroot = NULL;
719 if (Blocks[kf].ng != 0)
721 if ((Blocks[kf].jroot = CALLOC(Blocks[kf].ng, sizeof(int))) == NULL)
729 /* 13 : block work array (work) */
730 Blocks[kf].work = (void **)(((double *)work) + kf);
732 /* 14 : block modes array (mode) */
733 Blocks[kf].nmode = modptr[kf + 2] - modptr[kf + 1];
734 if (Blocks[kf].nmode != 0)
736 Blocks[kf].mode = &(mod[modptr[kf + 1] - 1]);
739 /* 15 : block xprop array (xprop) */
740 Blocks[kf].xprop = NULL;
741 if (Blocks[kf].nx != 0)
743 Blocks[kf].xprop = &(xprop[xptr[kf + 1] - 1]);
746 /* 16 : pointer on the zero crossing surface computation function of the block (g) */
748 if (Blocks[kf].ng != 0)
750 Blocks[kf].g = &(g[zcptr[kf + 1] - 1]);
753 /** all block properties are stored in the Blocks array **/
759 if ((iwa = MALLOC(sizeof(int) * (*nevts))) == NULL)
767 /* save ptr of scicos in import structure */
768 C2F(makescicosimport)(x, &nx, &xptr[1], &zcptr[1], z__, &nz, &zptr[1],
769 &noz, oz, ozsz, oztyp, &ozptr[1],
770 g, &ng, mod, &nmod, &modptr[1], iz, &izptr[1],
771 &inpptr[1], &inplnk[1], &outptr[1], &outlnk[1],
772 outtbptr, outtbsz, outtbtyp,
774 &nlnk, rpar, &rpptr[1], ipar, &ipptr[1],
775 opar, oparsz, opartyp, &opptr[1],
776 &nblk, subscr, nsubs,
777 &tevts[1], &evtspt[1], nevts, pointi,
778 &iord[1], &niord, &oord[1], &noord, &zord[1], &nzord,
779 funptr, &funtyp[1], &ztyp[1],
780 &cord[1], &ncord, &ordclk[1], &nordclk, &clkptr[1],
781 &ordptr[1], &nordptr, &critev[1], iwa, Blocks,
782 t0, tf, &Atol, &rtol, &ttol, &deltat, &hmax,
785 if (*flag__ == 1) /*start*/
787 /* initialisation des blocks */
788 for (kf = 0; kf < nblk; ++kf)
790 *(Blocks[kf].work) = NULL;
796 kfun0 = C2F(curblk).kfun;
799 C2F(curblk).kfun = kfun0;
803 else if (*flag__ == 2) /*run*/
807 if (C2F(cmsolver).solver == 0) /* LSODAR: Method: DYNAMIC, Nonlinear solver= DYNAMIC */
811 else if (C2F(cmsolver).solver == 1) /* CVODE: Method: BDF, Nonlinear solver= NEWTON */
815 else if (C2F(cmsolver).solver == 2) /* CVODE: Method: BDF, Nonlinear solver= FUNCTIONAL */
819 else if (C2F(cmsolver).solver == 3) /* CVODE: Method: ADAMS, Nonlinear solver= NEWTON */
823 else if (C2F(cmsolver).solver == 4) /* CVODE: Method: ADAMS, Nonlinear solver= FUNCTIONAL */
827 else if (C2F(cmsolver).solver == 5) /* DOPRI: Method: Dormand-Prince, Nonlinear solver= */
831 else if (C2F(cmsolver).solver == 6) /* RK45: Method: Runge-Kutta, Nonlinear solver= */
835 else if (C2F(cmsolver).solver == 7) /* ImpRK45: Method: Runge-Kutta, Nonlinear solver= FIXED-POINT */
839 else if (C2F(cmsolver).solver == 100) /* IDA : Method: , Nonlinear solver= */
845 /* add a warning message please */
850 kfun0 = C2F(curblk).kfun;
853 C2F(curblk).kfun = kfun0;
857 else if (*flag__ == 3) /*finish*/
859 /* fermeture des blocks */
862 else if (*flag__ == 4) /*linear*/
868 if ((W = MALLOC(sizeof(double) * (Max(nx, ng)))) == NULL )
876 /*---------à la place de old simblk--------*/
877 /* C2F(simblk)(&nx, t0, x, W); */
879 if (ng > 0 && nmod > 0)
881 zdoit(t0, x, x + nx, W); /* updating modes as a function of state values; this was necessary in iGUI*/
883 for (jj = 0; jj < nx; jj++) W[jj] = 0.0;
884 C2F(ierode).iero = 0;
886 if (C2F(cmsolver).solver < 100)
892 odoit(t0, x, x + nx, W);
894 C2F(ierode).iero = *ierr;
895 /*-----------------------------------------*/
896 for (i = 0; i < nx; ++i)
903 else if (*flag__ == 5) /* initial_KINSOL= "Kinsol" */
905 C2F(ierode).iero = 0;
909 *ierr = C2F(ierode).iero;
916 C2F(clearscicosimport)();
919 /*--------------------------------------------------------------------------*/
921 static int check_flag(void *flagvalue, char *funcname, int opt)
925 /* Check if SUNDIALS function returned NULL pointer - no memory allocated */
926 if (opt == 0 && flagvalue == NULL)
928 sciprint(_("\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n"), funcname);
931 /* Check if flag < 0 */
934 errflag = (int *) flagvalue;
937 sciprint(_("\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n"),
942 /* Check if function returned NULL pointer - no memory allocated */
943 else if (opt == 2 && flagvalue == NULL)
945 sciprint(_("\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n"), funcname);
952 /*--------------------------------------------------------------------------*/
953 static void cosini(double *told)
955 static scicos_flag flag__ = 0;
958 static int kfune = 0;
961 SCSREAL_COP *outtbd = NULL; /*to save double of outtb*/
962 SCSINT8_COP *outtbc = NULL; /*to save int8 of outtb*/
963 SCSINT16_COP *outtbs = NULL; /*to save int16 of outtb*/
964 SCSINT32_COP *outtbl = NULL; /*to save int32 of outtb*/
965 SCSUINT8_COP *outtbuc = NULL; /*to save unsigned int8 of outtb*/
966 SCSUINT16_COP *outtbus = NULL; /*to save unsigned int16 of outtb*/
967 SCSUINT32_COP *outtbul = NULL; /*to save unsigned int32 of outtb*/
968 int szouttbd = 0; /*size of arrays*/
969 int szouttbc = 0, szouttbs = 0, szouttbl = 0;
970 int szouttbuc = 0, szouttbus = 0, szouttbul = 0;
971 int curouttbd = 0; /*current position in arrays*/
972 int curouttbc = 0, curouttbs = 0, curouttbl = 0;
973 int curouttbuc = 0, curouttbus = 0, curouttbul = 0;
975 int ii = 0, kk = 0; /*local counters*/
976 int sszz = 0; /*local size of element of outtb*/
977 /*Allocation of arrays for outtb*/
978 for (ii = 0; ii < nlnk; ii++)
980 switch (outtbtyp[ii])
983 szouttbd += outtbsz[ii] * outtbsz[ii + nlnk]; /*double real matrix*/
984 outtbd = (SCSREAL_COP *) REALLOC (outtbd, szouttbd * sizeof(SCSREAL_COP));
988 szouttbd += 2 * outtbsz[ii] * outtbsz[ii + nlnk]; /*double complex matrix*/
989 outtbd = (SCSCOMPLEX_COP *) REALLOC (outtbd, szouttbd * sizeof(SCSCOMPLEX_COP));
993 szouttbc += outtbsz[ii] * outtbsz[ii + nlnk]; /*int8*/
994 outtbc = (SCSINT8_COP *) REALLOC (outtbc, szouttbc * sizeof(SCSINT8_COP));
998 szouttbs += outtbsz[ii] * outtbsz[ii + nlnk]; /*int16*/
999 outtbs = (SCSINT16_COP *) REALLOC (outtbs, szouttbs * sizeof(SCSINT16_COP));
1003 szouttbl += outtbsz[ii] * outtbsz[ii + nlnk]; /*int32*/
1004 outtbl = (SCSINT32_COP *) REALLOC (outtbl, szouttbl * sizeof(SCSINT32_COP));
1008 szouttbuc += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint8*/
1009 outtbuc = (SCSUINT8_COP *) REALLOC (outtbuc, szouttbuc * sizeof(SCSUINT8_COP));
1013 szouttbus += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint16*/
1014 outtbus = (SCSUINT16_COP *) REALLOC (outtbus, szouttbus * sizeof(SCSUINT16_COP));
1018 szouttbul += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint32*/
1019 outtbul = (SCSUINT32_COP *) REALLOC (outtbul, szouttbul * sizeof(SCSUINT32_COP));
1022 default : /* Add a message here */
1028 AJacobian_block = 0;
1033 /* initialization (flag 4) */
1034 /* loop on blocks */
1035 C2F(dset)(&ng, &c_b14, g, &c__1);
1037 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1040 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1042 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1043 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1045 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1046 if (funtyp[C2F(curblk).kfun] >= 0) /* debug_block is not called here */
1048 /*callf(told, xd, x, x,g,&flag__);*/
1050 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1051 if (flag__ < 0 && *ierr == 0)
1054 kfune = C2F(curblk).kfun;
1056 if ((Jacobian_Flag == 1) && (AJacobian_block == 0)) AJacobian_block = C2F(curblk).kfun;
1061 C2F(curblk).kfun = kfune;
1066 /* initialization (flag 6) */
1068 for (jj = 1; jj <= ncord; ++jj)
1070 C2F(curblk).kfun = cord[jj];
1071 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1072 if (funtyp[C2F(curblk).kfun] >= 0)
1074 /*callf(told, xd, x, x,g,&flag__);*/
1075 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1085 /* point-fix iterations */
1087 for (i = 1; i <= nblk + 1; ++i) /*for each block*/
1089 /* loop on blocks */
1090 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1092 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1093 if (funtyp[C2F(curblk).kfun] >= 0)
1095 /*callf(told, xd, x, x,g,&flag__);*/
1096 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1107 for (jj = 1; jj <= ncord; ++jj) /*for each continous block*/
1109 C2F(curblk).kfun = cord[jj];
1110 if (funtyp[C2F(curblk).kfun] >= 0)
1112 /*callf(told, xd, x, x,g,&flag__);*/
1113 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1123 /*comparison between outtb and arrays*/
1131 for (jj = 0; jj < nlnk; jj++)
1133 switch (outtbtyp[jj]) /*for each type of ports*/
1136 outtbdptr = (SCSREAL_COP *)outtbptr[jj]; /*double real matrix*/
1137 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1138 for (kk = 0; kk < sszz; kk++)
1140 if (outtbdptr[kk] != (SCSREAL_COP)outtbd[curouttbd + kk]) goto L30;
1146 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[jj]; /*double complex matrix*/
1147 sszz = 2 * outtbsz[jj] * outtbsz[jj + nlnk];
1148 for (kk = 0; kk < sszz; kk++)
1150 if (outtbdptr[kk] != (SCSCOMPLEX_COP)outtbd[curouttbd + kk]) goto L30;
1156 outtbcptr = (SCSINT8_COP *)outtbptr[jj]; /*int8*/
1157 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1158 for (kk = 0; kk < sszz; kk++)
1160 if (outtbcptr[kk] != (SCSINT8_COP)outtbc[curouttbc + kk]) goto L30;
1166 outtbsptr = (SCSINT16_COP *)outtbptr[jj]; /*int16*/
1167 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1168 for (kk = 0; kk < sszz; kk++)
1170 if (outtbsptr[kk] != (SCSINT16_COP)outtbs[curouttbs + kk]) goto L30;
1176 outtblptr = (SCSINT32_COP *)outtbptr[jj]; /*int32*/
1177 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1178 for (kk = 0; kk < sszz; kk++)
1180 if (outtblptr[kk] != (SCSINT32_COP)outtbl[curouttbl + kk]) goto L30;
1186 outtbucptr = (SCSUINT8_COP *)outtbptr[jj]; /*uint8*/
1187 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1188 for (kk = 0; kk < sszz; kk++)
1190 if (outtbucptr[kk] != (SCSUINT8_COP)outtbuc[curouttbuc + kk]) goto L30;
1196 outtbusptr = (SCSUINT16_COP *)outtbptr[jj]; /*uint16*/
1197 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1198 for (kk = 0; kk < sszz; kk++)
1200 if (outtbusptr[kk] != (SCSUINT16_COP)outtbus[curouttbus + kk]) goto L30;
1206 outtbulptr = (SCSUINT32_COP *)outtbptr[jj]; /*uint32*/
1207 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1208 for (kk = 0; kk < sszz; kk++)
1210 if (outtbulptr[kk] != (SCSUINT32_COP)outtbul[curouttbul + kk]) goto L30;
1215 default : /* Add a message here */
1223 /*Save data of outtb in arrays*/
1231 for (ii = 0; ii < nlnk; ii++) /*for each link*/
1233 switch (outtbtyp[ii]) /*switch to type of outtb object*/
1236 outtbdptr = (SCSREAL_COP *)outtbptr[ii]; /*double real matrix*/
1237 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1238 C2F(dcopy)(&sszz, outtbdptr, &c__1, &outtbd[curouttbd], &c__1);
1243 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[ii]; /*double complex matrix*/
1244 sszz = 2 * outtbsz[ii] * outtbsz[ii + nlnk];
1245 C2F(dcopy)(&sszz, outtbdptr, &c__1, &outtbd[curouttbd], &c__1);
1250 outtbcptr = (SCSINT8_COP *)outtbptr[ii]; /*int8*/
1251 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1252 for (kk = 0; kk < sszz; kk++) outtbc[curouttbc + kk] = (SCSINT8_COP)outtbcptr[kk];
1257 outtbsptr = (SCSINT16_COP *)outtbptr[ii]; /*int16*/
1258 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1259 for (kk = 0; kk < sszz; kk++) outtbs[curouttbs + kk] = (SCSINT16_COP)outtbsptr[kk];
1264 outtblptr = (SCSINT32_COP *)outtbptr[ii]; /*int32*/
1265 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1266 for (kk = 0; kk < sszz; kk++) outtbl[curouttbl + kk] = (SCSINT32_COP)outtblptr[kk];
1271 outtbucptr = (SCSUINT8_COP *)outtbptr[ii]; /*uint8*/
1272 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1273 for (kk = 0; kk < sszz; kk++) outtbuc[curouttbuc + kk] = (SCSUINT8_COP)outtbucptr[kk];
1278 outtbusptr = (SCSUINT16_COP *)outtbptr[ii]; /*uint16*/
1279 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1280 for (kk = 0; kk < sszz; kk++) outtbus[curouttbus + kk] = (SCSUINT16_COP)outtbusptr[kk];
1285 outtbulptr = (SCSUINT32_COP *)outtbptr[ii]; /*uint32*/
1286 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1287 for (kk = 0; kk < sszz; kk++) outtbul[curouttbul + kk] = (SCSUINT32_COP)outtbulptr[kk];
1291 default : /* Add a message here */
1300 /*--------------------------------------------------------------------------*/
1301 static void cossim(double *told)
1303 /* System generated locals */
1306 //** used for the [stop] button
1307 static char CommandToUnstack[1024];
1308 static int CommandLength = 0;
1309 static int SeqSync = 0;
1312 /* Local variables */
1313 static scicos_flag flag__ = 0;
1314 static int ierr1 = 0;
1315 static int j = 0, k = 0;
1316 static double t = 0.;
1318 static double rhotmp = 0., tstop = 0.;
1319 static int inxsci = 0;
1320 static int kpo = 0, kev = 0;
1321 int Discrete_Jump = 0;
1322 int *jroot = NULL, *zcros = NULL;
1323 realtype reltol = 0., abstol = 0.;
1325 void *cvode_mem = NULL;
1326 int flag = 0, flagr = 0;
1331 if ((jroot = MALLOC(sizeof(int) * ng)) == NULL )
1338 for ( jj = 0 ; jj < ng ; jj++ )
1344 if ((zcros = MALLOC(sizeof(int) * ng)) == NULL )
1347 if (ng > 0) FREE(jroot);
1352 reltol = (realtype) rtol;
1353 abstol = (realtype) Atol; /* Ith(abstol,1) = realtype) Atol;*/
1355 if (*neq > 0) /* Unfortunately CVODE does not work with NEQ==0 */
1357 y = N_VNewEmpty_Serial(*neq);
1358 if (check_flag((void *)y, "N_VNewEmpty_Serial", 0))
1361 if (ng > 0) FREE(jroot);
1362 if (ng > 0) FREE(zcros);
1370 /* Set extension of Sundials for scicos */
1371 set_sundials_with_extension(TRUE);
1373 switch (C2F(cmsolver).solver)
1376 cvode_mem = LSodarCreate(neq, ng); /* Create the lsodar problem */
1379 cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
1382 cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL);
1385 cvode_mem = CVodeCreate(CV_ADAMS, CV_NEWTON);
1388 cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
1391 cvode_mem = CVodeCreate(CV_DOPRI, CV_FUNCTIONAL);
1394 cvode_mem = CVodeCreate(CV_ExpRK, CV_FUNCTIONAL);
1397 cvode_mem = CVodeCreate(CV_ImpRK, CV_FUNCTIONAL);
1401 /* cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);*/
1403 if (check_flag((void *)cvode_mem, "CVodeCreate", 0))
1406 N_VDestroy_Serial(y);
1412 if (!C2F(cmsolver).solver)
1414 flag = LSodarMalloc(cvode_mem, simblklsodar, T0, y, CV_SS, reltol, &abstol);
1417 flag = CVodeMalloc(cvode_mem, simblk, T0, y, CV_SS, reltol, &abstol);
1418 if (check_flag(&flag, "CVodeMalloc", 1))
1420 *ierr = 300 + (-flag);
1425 if (!C2F(cmsolver).solver)
1427 flag = LSodarRootInit(cvode_mem, ng, grblklsodar, NULL);
1430 flag = CVodeRootInit(cvode_mem, ng, grblk, NULL);
1431 if (check_flag(&flag, "CVodeRootInit", 1))
1433 *ierr = 300 + (-flag);
1438 if (C2F(cmsolver).solver)
1439 /* Call CVDense to specify the CVDENSE dense linear solver */
1440 flag = CVDense(cvode_mem, *neq);
1441 if (check_flag(&flag, "CVDense", 1))
1443 *ierr = 300 + (-flag);
1450 if (!C2F(cmsolver).solver)
1452 flag = LSodarSetMaxStep(cvode_mem, (realtype) hmax);
1455 flag = CVodeSetMaxStep(cvode_mem, (realtype) hmax);
1456 if (check_flag(&flag, "CVodeSetMaxStep", 1))
1458 *ierr = 300 + (-flag);
1463 /* Set the Jacobian routine to Jac (user-supplied)
1464 flag = CVDenseSetJacFn(cvode_mem, Jac, NULL);
1465 if (check_flag(&flag, "CVDenseSetJacFn", 1)) return(1); */
1467 }/* testing if neq>0 */
1470 C2F(coshlt).halt = 0;
1473 C2F(xscion)(&inxsci);
1474 /* initialization */
1475 C2F(realtimeinit)(told, &C2F(rtfactor).scale);
1481 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1483 if (Blocks[C2F(curblk).kfun - 1].ng >= 1)
1485 zcros[jj] = C2F(curblk).kfun;
1489 /* . Il faut: ng >= jj */
1494 /* initialisation (propagation of constant blocks outputs) */
1501 /*--discrete zero crossings----dzero--------------------*/
1502 if (ng > 0) /* storing ZC signs just after a solver call*/
1504 /*zdoit(told, g, x, x);*/
1505 zdoit(told, x, x, g);
1511 for (jj = 0; jj < ng; ++jj)
1512 if (g[jj] >= 0) jroot[jj] = 5;
1513 else jroot[jj] = -5;
1515 /*--discrete zero crossings----dzero--------------------*/
1517 /* main loop on time */
1520 while (ismenu()) //** if the user has done something, do the actions
1523 SeqSync = GetCommand(CommandToUnstack); //** get at the action
1524 CommandLength = (int)strlen(CommandToUnstack);
1525 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
1527 if (C2F(coshlt).halt != 0)
1529 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
1530 C2F(coshlt).halt = 0;
1542 if (fabs(t - *told) < ttol)
1545 /* update output part */
1549 /* ! scheduling problem */
1556 if (xptr[nblk + 1] == 1)
1558 /* . no continuous state */
1559 if (*told + deltat + ttol > t)
1567 /* . update outputs of 'c' type blocks with no continuous state */
1570 /* . we are at the end, update continuous part before leaving */
1582 rhotmp = *tf + ttol;
1587 if (critev[kpo] == 1)
1589 rhotmp = tevts[kpo];
1604 t = Min(*told + deltat, Min(t, *tf + ttol));
1606 if (ng > 0 && hot == 0 && nmod > 0)
1608 zdoit(told, x, x, g);
1616 if (hot == 0) /* hot==0 : cold restart*/
1618 if (!C2F(cmsolver).solver)
1620 flag = LSodarSetStopTime(cvode_mem, (realtype)tstop);
1623 flag = CVodeSetStopTime(cvode_mem, (realtype)tstop); /* Setting the stop time*/
1624 if (check_flag(&flag, "CVodeSetStopTime", 1))
1626 *ierr = 300 + (-flag);
1631 if (!C2F(cmsolver).solver)
1633 flag = LSodarReInit(cvode_mem, simblklsodar, (realtype)(*told), y, CV_SS, reltol, &abstol);
1636 flag = CVodeReInit(cvode_mem, simblk, (realtype)(*told), y, CV_SS, reltol, &abstol);
1637 if (check_flag(&flag, "CVodeReInit", 1))
1639 *ierr = 300 + (-flag);
1645 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1647 sciprint(_("****SUNDIALS.Cvode from: %f to %f hot= %d \n"), *told, t, hot);
1650 /*--discrete zero crossings----dzero--------------------*/
1651 /*--check for Dzeros after Mode settings or ddoit()----*/
1654 if (ng > 0 && hot == 0)
1656 zdoit(told, x, x, g);
1662 for (jj = 0; jj < ng; ++jj)
1664 if ((g[jj] >= 0.0) && (jroot[jj] == -5))
1669 else if ((g[jj] < 0.0) && (jroot[jj] == 5))
1677 /*--discrete zero crossings----dzero--------------------*/
1679 if (Discrete_Jump == 0) /* if there was a dzero, its event should be activated*/
1682 if (!C2F(cmsolver).solver)
1684 flag = LSodar(cvode_mem, t, y, told, LS_NORMAL);
1687 flag = CVode(cvode_mem, t, y, told, CV_NORMAL_TSTOP);
1697 flag = CV_ROOT_RETURN; /* in order to handle discrete jumps */
1700 /* . update outputs of 'c' type blocks if we are at the end*/
1713 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1714 sciprint(_("****SUNDIALS.Cvode reached: %f\n"), *told);
1718 else if ( flag == CV_TOO_MUCH_WORK || flag == CV_CONV_FAILURE || flag == CV_ERR_FAILURE)
1720 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1721 sciprint(_("****SUNDIALS.Cvode: too much work at time=%g (stiff region, change RTOL and ATOL)\n"), *told);
1726 *ierr = 300 + (-flag);
1733 if (flag < 0) *ierr = 300 + (-flag); /* raising errors due to internal errors, other wise erros due to flagr*/
1738 if (flag == CV_ZERO_DETACH_RETURN)
1741 }; /* new feature of sundials, detects zero-detaching */
1743 if (flag == CV_ROOT_RETURN)
1745 /* . at a least one root has been found */
1747 if (Discrete_Jump == 0)
1749 if (!C2F(cmsolver).solver)
1751 flagr = LSodarGetRootInfo(cvode_mem, jroot);
1754 flagr = CVodeGetRootInfo(cvode_mem, jroot);
1755 if (check_flag(&flagr, "CVodeGetRootInfo", 1))
1757 *ierr = 300 + (-flagr);
1762 /* . at a least one root has been found */
1763 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1765 sciprint(_("root found at t=: %f\n"), *told);
1767 /* . update outputs affecting ztyp blocks ONLY FOR OLD BLOCKS */
1768 zdoit(told, x, xd, g);
1774 for (jj = 0; jj < ng; ++jj)
1776 C2F(curblk).kfun = zcros[ jj];
1777 if (C2F(curblk).kfun == -1)
1783 for (j = zcptr[C2F(curblk).kfun] - 1 ;
1784 j < zcptr[C2F(curblk).kfun + 1] - 1 ; ++j)
1795 Blocks[C2F(curblk).kfun - 1].jroot = &jroot[zcptr[C2F(curblk).kfun] - 1];
1796 if (funtyp[C2F(curblk).kfun] > 0)
1799 if (Blocks[C2F(curblk).kfun - 1].nevout > 0)
1802 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1804 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1805 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1807 /* call corresponding block to determine output event (kev) */
1808 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
1809 /*callf(told, xd, x, x,g,&flag__);*/
1810 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1817 /* . update event agenda */
1818 for (k = 0; k < Blocks[C2F(curblk).kfun - 1].nevout; ++k)
1820 if (Blocks[C2F(curblk).kfun - 1].evout[k] >= 0.)
1822 i3 = k + clkptr[C2F(curblk).kfun] ;
1823 addevs(Blocks[C2F(curblk).kfun - 1].evout[k] + (*told), &i3, &ierr1);
1826 /* . nevts too small */
1834 /* . update state */
1835 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1837 /* . call corresponding block to update state */
1839 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1840 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1841 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
1842 /*callf(told, xd, x, x,g,&flag__);*/
1843 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1857 /*--discrete zero crossings----dzero--------------------*/
1858 if (ng > 0) /* storing ZC signs just after a sundials call*/
1860 zdoit(told, x, x, g);
1866 for (jj = 0; jj < ng; ++jj)
1878 /*--discrete zero crossings----dzero--------------------*/
1880 C2F(realtime)(told);
1885 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1887 sciprint(_("Event: %d activated at t=%f\n"), *pointi, *told);
1888 for (kev = 0; kev < nblk; kev++)
1890 if (Blocks[kev].nmode > 0)
1892 sciprint(_("mode of block %d=%d, "), kev, Blocks[kev].mode[0]);
1895 sciprint(_("**mod**\n"));
1899 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1901 sciprint(_("End of activation\n"));
1910 /* end of main loop on time */
1915 /*--------------------------------------------------------------------------*/
1916 static void cossimdaskr(double *told)
1918 /* System generated locals */
1920 //** used for the [stop] button
1921 static char CommandToUnstack[1024];
1922 static int CommandLength = 0;
1923 static int SeqSync = 0;
1926 /* Local variables */
1927 static scicos_flag flag__ = 0;
1928 static int ierr1 = 0;
1929 static int j = 0, k = 0;
1930 static double t = 0.;
1931 static int jj = 0, jt = 0;
1932 static double rhotmp = 0., tstop = 0.;
1933 static int inxsci = 0;
1934 static int kpo = 0, kev = 0;
1936 int *jroot = NULL, *zcros = NULL;
1938 int *Mode_save = NULL;
1939 int Mode_change = 0;
1941 int flag = 0, flagr = 0;
1942 N_Vector yy = NULL, yp = NULL;
1943 realtype reltol = 0., abstol = 0.;
1944 int Discrete_Jump = 0;
1945 N_Vector IDx = NULL;
1946 realtype *scicos_xproperty = NULL;
1947 DenseMat TJacque = NULL;
1949 void *ida_mem = NULL;
1950 UserData data = NULL;
1951 IDAMem copy_IDA_mem = NULL;
1952 int maxnj = 0, maxnit = 0;
1953 /*-------------------- Analytical Jacobian memory allocation ----------*/
1954 int Jn = 0, Jnx = 0, Jno = 0, Jni = 0, Jactaille = 0;
1956 int cnt = 0, N_iters = 0;
1960 /* Set extension of Sundials for scicos */
1961 set_sundials_with_extension(TRUE);
1963 // CI=1.0; /* for function Get_Jacobian_ci */
1967 if ((jroot = MALLOC(sizeof(int) * ng)) == NULL )
1973 for ( jj = 0 ; jj < ng ; jj++ ) jroot[jj] = 0 ;
1978 if ((zcros = MALLOC(sizeof(int) * ng)) == NULL )
1981 if (ng != 0) FREE(jroot);
1989 if ((Mode_save = MALLOC(sizeof(int) * nmod)) == NULL )
1992 if (ng != 0) FREE(jroot);
1993 if (ng != 0) FREE(zcros);
1998 reltol = (realtype) rtol;
1999 abstol = (realtype) Atol; /* Ith(abstol,1) = realtype) Atol;*/
2004 yy = N_VNewEmpty_Serial(*neq);
2005 if (check_flag((void *)yy, "N_VNew_Serial", 0))
2007 if (ng != 0) FREE(jroot);
2008 if (ng != 0) FREE(zcros);
2009 if (nmod != 0) FREE(Mode_save);
2014 yp = N_VNewEmpty_Serial(*neq);
2015 if (check_flag((void *)yp, "N_VNew_Serial", 0))
2017 if (*neq > 0) N_VDestroy_Serial(yy);
2018 if (ng != 0) FREE(jroot);
2019 if (ng != 0) FREE(zcros);
2020 if (nmod != 0) FREE(Mode_save);
2026 IDx = N_VNew_Serial(*neq);
2027 if (check_flag((void *)IDx, "N_VNew_Serial", 0))
2030 if (*neq > 0) N_VDestroy_Serial(yp);
2031 if (*neq > 0) N_VDestroy_Serial(yy);
2032 if (ng != 0) FREE(jroot);
2033 if (ng != 0) FREE(zcros);
2034 if (nmod != 0) FREE(Mode_save);
2038 /* Call IDACreate and IDAMalloc to initialize IDA memory */
2040 ida_mem = IDACreate();
2041 if (check_flag((void *)ida_mem, "IDACreate", 0))
2043 if (*neq > 0) N_VDestroy_Serial(IDx);
2044 if (*neq > 0) N_VDestroy_Serial(yp);
2045 if (*neq > 0) N_VDestroy_Serial(yy);
2046 if (ng != 0) FREE(jroot);
2047 if (ng != 0) FREE(zcros);
2048 if (nmod != 0) FREE(Mode_save);
2051 copy_IDA_mem = (IDAMem) ida_mem;
2053 flag = IDAMalloc(ida_mem, simblkdaskr, T0, yy, yp, IDA_SS, reltol, &abstol);
2054 if (check_flag(&flag, "IDAMalloc", 1))
2056 *ierr = 200 + (-flag);
2057 if (*neq > 0)IDAFree(&ida_mem);
2058 if (*neq > 0)N_VDestroy_Serial(IDx);
2059 if (*neq > 0) N_VDestroy_Serial(yp);
2060 if (*neq > 0)N_VDestroy_Serial(yy);
2061 if (ng != 0) FREE(jroot);
2062 if (ng != 0) FREE(zcros);
2063 if (nmod != 0) FREE(Mode_save);
2068 flag = IDARootInit(ida_mem, ng, grblkdaskr, NULL);
2069 if (check_flag(&flag, "IDARootInit", 1))
2071 *ierr = 200 + (-flag);
2072 if (*neq > 0)IDAFree(&ida_mem);
2073 if (*neq > 0)N_VDestroy_Serial(IDx);
2074 if (*neq > 0)N_VDestroy_Serial(yp);
2075 if (*neq > 0)N_VDestroy_Serial(yy);
2076 if (ng != 0) FREE(jroot);
2077 if (ng != 0) FREE(zcros);
2078 if (nmod != 0) FREE(Mode_save);
2083 flag = IDADense(ida_mem, *neq);
2084 if (check_flag(&flag, "IDADense", 1))
2086 *ierr = 200 + (-flag);
2087 if (*neq > 0)IDAFree(&ida_mem);
2088 if (*neq > 0)N_VDestroy_Serial(IDx);
2089 if (*neq > 0)N_VDestroy_Serial(yp);
2090 if (*neq > 0)N_VDestroy_Serial(yy);
2091 if (ng != 0) FREE(jroot);
2092 if (ng != 0) FREE(zcros);
2093 if (nmod != 0) FREE(Mode_save);
2098 if ((data = (UserData) MALLOC(sizeof(*data))) == NULL)
2101 if (*neq > 0)IDAFree(&ida_mem);
2102 if (*neq > 0)N_VDestroy_Serial(IDx);
2103 if (*neq > 0)N_VDestroy_Serial(yp);
2104 if (*neq > 0)N_VDestroy_Serial(yy);
2105 if (ng != 0) FREE(jroot);
2106 if (ng != 0) FREE(zcros);
2107 if (nmod != 0) FREE(Mode_save);
2110 data->ida_mem = ida_mem;
2116 data->ewt = N_VNew_Serial(*neq);
2117 if (check_flag((void *)data->ewt, "N_VNew_Serial", 0))
2119 *ierr = 200 + (-flag);
2120 if (*neq > 0)FREE(data);
2121 if (*neq > 0)IDAFree(&ida_mem);
2122 if (*neq > 0) N_VDestroy_Serial(IDx);
2123 if (*neq > 0) N_VDestroy_Serial(yp);
2124 if (*neq > 0) N_VDestroy_Serial(yy);
2125 if (ng != 0) FREE(jroot);
2126 if (ng != 0) FREE(zcros);
2127 if (nmod != 0) FREE(Mode_save);
2132 if ((data->gwork = (double *) MALLOC(ng * sizeof(double))) == NULL)
2134 if (*neq > 0) N_VDestroy_Serial(data->ewt);
2135 if (*neq > 0)FREE(data);
2136 if (*neq > 0)IDAFree(&ida_mem);
2137 if (*neq > 0)N_VDestroy_Serial(IDx);
2138 if (*neq > 0)N_VDestroy_Serial(yp);
2139 if (*neq > 0)N_VDestroy_Serial(yy);
2140 if (ng != 0) FREE(jroot);
2141 if (ng != 0) FREE(zcros);
2142 if (nmod != 0) FREE(Mode_save);
2146 /*Jacobian_Flag=0; */
2147 if (AJacobian_block > 0) /* set by the block with A-Jac in flag-4 using Set_Jacobian_flag(1); */
2150 Jnx = Blocks[AJacobian_block - 1].nx;
2151 Jno = Blocks[AJacobian_block - 1].nout;
2152 Jni = Blocks[AJacobian_block - 1].nin;
2161 Jactaille = 3 * Jn + (Jn + Jni) * (Jn + Jno) + Jnx * (Jni + 2 * Jn + Jno) + (Jn - Jnx) * (2 * (Jn - Jnx) + Jno + Jni) + 2 * Jni * Jno;
2163 if ((data->rwork = (double *) MALLOC(Jactaille * sizeof(double))) == NULL)
2165 if ( ng > 0 ) FREE(data->gwork);
2166 if (*neq > 0)N_VDestroy_Serial(data->ewt);
2167 if (*neq > 0)FREE(data);
2168 if (*neq > 0)IDAFree(&ida_mem);
2169 if (*neq > 0)N_VDestroy_Serial(IDx);
2170 if (*neq > 0)N_VDestroy_Serial(yp);
2171 if (*neq > 0)N_VDestroy_Serial(yy);
2172 if (ng != 0) FREE(jroot);
2173 if (ng != 0) FREE(zcros);
2174 if (nmod != 0) FREE(Mode_save);
2179 flag = IDADenseSetJacFn(ida_mem, Jacobians, data);
2180 if (check_flag(&flag, "IDADenseSetJacFn", 1))
2182 *ierr = 200 + (-flag);
2187 TJacque = (DenseMat) DenseAllocMat(*neq, *neq);
2189 flag = IDASetRdata(ida_mem, data);
2190 if (check_flag(&flag, "IDASetRdata", 1))
2192 *ierr = 200 + (-flag);
2199 flag = IDASetMaxStep(ida_mem, (realtype) hmax);
2200 if (check_flag(&flag, "IDASetMaxStep", 1))
2202 *ierr = 200 + (-flag);
2208 maxnj = 100; /* setting the maximum number of Jacobian evaluation during a Newton step */
2209 flag = IDASetMaxNumJacsIC(ida_mem, maxnj);
2210 if (check_flag(&flag, "IDASetMaxNumJacsIC", 1))
2212 *ierr = 200 + (-flag);
2217 maxnit = 10; /* setting the maximum number of Newton iterations in any one attemp to solve CIC */
2218 flag = IDASetMaxNumItersIC(ida_mem, maxnit);
2219 if (check_flag(&flag, "IDASetMaxNumItersIC", 1))
2221 *ierr = 200 + (-flag);
2226 /* setting the maximum number of steps in an integration interval */
2227 flag = IDASetMaxNumSteps(ida_mem, 2000);
2228 if (check_flag(&flag, "IDASetMaxNumSteps", 1))
2230 *ierr = 200 + (-flag);
2235 } /* testing if neq>0 */
2240 uround = uround * 0.5;
2242 while ( 1.0 + uround != 1.0);
2243 uround = uround * 2.0;
2244 SQuround = sqrt(uround);
2247 C2F(coshlt).halt = 0;
2256 C2F(xscion)(&inxsci);
2257 /* initialization */
2258 C2F(realtimeinit)(told, &C2F(rtfactor).scale);
2259 /* ATOL and RTOL are scalars */
2262 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
2264 if (Blocks[C2F(curblk).kfun - 1].ng >= 1)
2266 zcros[jj] = C2F(curblk).kfun;
2270 /* . Il faut: ng >= jj */
2275 /* initialisation (propagation of constant blocks outputs) */
2283 /*--discrete zero crossings----dzero--------------------*/
2284 if (ng > 0) /* storing ZC signs just after a solver call*/
2286 zdoit(told, x, x, g);
2292 for (jj = 0; jj < ng; ++jj)
2293 if (g[jj] >= 0) jroot[jj] = 5;
2294 else jroot[jj] = -5;
2296 /* main loop on time */
2299 while (ismenu()) //** if the user has done something, do the actions
2302 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2303 CommandLength = (int)strlen(CommandToUnstack);
2304 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2306 if (C2F(coshlt).halt != 0)
2308 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2309 C2F(coshlt).halt = 0;
2321 if (fabs(t - *told) < ttol)
2324 /* update output part */
2328 /* ! scheduling problem */
2335 if (xptr[nblk + 1] == 1)
2337 /* . no continuous state */
2338 if (*told + deltat + ttol > t)
2346 /* . update outputs of 'c' type blocks with no continuous state */
2349 /* . we are at the end, update continuous part before leaving */
2357 rhotmp = *tf + ttol;
2362 if (critev[kpo] == 1)
2364 rhotmp = tevts[kpo];
2375 hot = 0;/* Do cold-restart the solver:if the new TSTOP isn't beyong the previous one*/
2379 t = Min(*told + deltat, Min(t, *tf + ttol));
2381 if (hot == 0) /* CIC calculation when hot==0 */
2384 /* Setting the stop time*/
2385 flag = IDASetStopTime(ida_mem, (realtype)tstop);
2386 if (check_flag(&flag, "IDASetStopTime", 1))
2388 *ierr = 200 + (-flag);
2393 if (ng > 0 && nmod > 0)
2396 zdoit(told, x, xd, g);
2404 /*----------ID setting/checking------------*/
2405 N_VConst(ONE, IDx); /* Initialize id to 1's. */
2406 scicos_xproperty = NV_DATA_S(IDx);
2413 for (jj = 0; jj < *neq; jj++)
2415 if (xprop[jj] == 1) scicos_xproperty[jj] = ONE;
2416 if (xprop[jj] == -1) scicos_xproperty[jj] = ZERO;
2418 /* CI=0.0;CJ=100.0; // for functions Get_Jacobian_ci and Get_Jacobian_cj
2419 Jacobians(*neq, (realtype) (*told), yy, yp, bidon, (realtype) CJ, data, TJacque, tempv1, tempv2, tempv3);
2420 for (jj=0;jj<*neq;jj++){
2421 Jacque_col=DENSE_COL(TJacque,jj);
2423 for (kk=0;kk<*neq;kk++){
2424 if ((Jacque_col[kk]-Jacque_col[kk]!=0)) {
2428 if (Jacque_col[kk]!=0){
2434 if (CI>=ZERO){ scicos_xproperty[jj]=CI;}else{fprintf(stderr,"\nWarinng! Xproperties are not match for i=%d!",jj);}
2436 /* printf("\n"); for(jj=0;jj<*neq;jj++) { printf("x%d=%g ",jj,scicos_xproperty[jj]); }*/
2438 flag = IDASetId(ida_mem, IDx);
2439 if (check_flag(&flag, "IDASetId", 1))
2441 *ierr = 200 + (-flag);
2445 // CI=1.0; // for function Get_Jacobian_ci
2446 /*--------------------------------------------*/
2447 // maxnj=100; /* setting the maximum number of Jacobian evaluation during a Newton step */
2448 // flag=IDASetMaxNumJacsIC(ida_mem, maxnj);
2449 // if (check_flag(&flag, "IDASetMaxNumItersIC", 1)) {
2450 // *ierr=200+(-flag);
2454 // flag=IDASetLineSearchOffIC(ida_mem,FALSE); /* (def=false) */
2455 // if (check_flag(&flag, "IDASetLineSearchOffIC", 1)) {
2456 // *ierr=200+(-flag);
2460 // flag=IDASetMaxNumItersIC(ida_mem, 10);/* (def=10) setting the maximum number of Newton iterations in any one attemp to solve CIC */
2461 // if (check_flag(&flag, "IDASetMaxNumItersIC", 1)) {
2462 // *ierr=200+(-flag);
2467 N_iters = 4 + nmod * 4;
2468 for (j = 0; j <= N_iters; j++)
2470 /* counter to reevaluate the
2471 modes in mode->CIC->mode->CIC-> loop
2472 do it once in the absence of mode (nmod=0) */
2473 /* updating the modes through Flag==9, Phase==1 */
2475 /* Serge Steer 29/06/2009 */
2476 while (ismenu()) //** if the user has done something, do the actions
2479 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2480 CommandLength = (int)strlen(CommandToUnstack);
2481 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2483 if (C2F(coshlt).halt != 0)
2485 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2486 C2F(coshlt).halt = 0;
2492 flag = IDAReInit(ida_mem, simblkdaskr, (realtype)(*told), yy, yp, IDA_SS, reltol, &abstol);
2493 if (check_flag(&flag, "CVodeReInit", 1))
2495 *ierr = 200 + (-flag);
2500 phase = 2; /* IDACalcIC: PHI-> yy0: if (ok) yy0_cic-> PHI*/
2501 copy_IDA_mem->ida_kk = 1;
2503 // the initial conditons y0 and yp0 do not satisfy the DAE
2504 flagr = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, (realtype)(t));
2507 flag = IDAGetConsistentIC(ida_mem, yy, yp); /* PHI->YY */
2509 if (*ierr > 5) /* *ierr>5 => singularity in block */
2515 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2519 sciprint(_("**** SUNDIALS.IDA successfully initialized *****\n") );
2523 sciprint(_("**** SUNDIALS.IDA failed to initialize ->try again *****\n") );
2526 /*-------------------------------------*/
2527 /* saving the previous modes*/
2528 for (jj = 0; jj < nmod; ++jj)
2530 Mode_save[jj] = mod[jj];
2532 if (ng > 0 && nmod > 0)
2535 zdoit(told, x, xd, g);
2542 /*------------------------------------*/
2544 for (jj = 0; jj < nmod; ++jj)
2546 if (Mode_save[jj] != mod[jj])
2552 if (Mode_change == 0)
2556 break; /* if (flagr>=0) break; else{ *ierr=200+(-flagr); freeallx; return; }*/
2558 else if (j >= (int)( N_iters / 2))
2560 /* IDASetMaxNumStepsIC(mem,10); */ /* maxnh (def=5) */
2561 IDASetMaxNumJacsIC(ida_mem, 10); /* maxnj 100 (def=4)*/
2562 /* IDASetMaxNumItersIC(mem,100000); */ /* maxnit in IDANewtonIC (def=10) */
2563 IDASetLineSearchOffIC(ida_mem, TRUE); /* (def=false) */
2564 /* IDASetNonlinConvCoefIC(mem,1.01);*/ /* (def=0.01-0.33*/
2565 flag = IDASetMaxNumItersIC(ida_mem, 1000);
2566 if (check_flag(&flag, "IDASetMaxNumItersIC", 1))
2568 *ierr = 200 + (-flag);
2574 }/* mode-CIC counter*/
2575 if (Mode_change == 1)
2577 /* In tghis case, we try again by relaxing all modes and calling IDA_calc again
2580 copy_IDA_mem->ida_kk = 1;
2581 flagr = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, (realtype)(t));
2583 flag = IDAGetConsistentIC(ida_mem, yy, yp); /* PHI->YY */
2584 if ((flagr < 0) || (*ierr > 5)) /* *ierr>5 => singularity in block */
2591 /*-----If flagr<0 the initialization solver has not converged-----*/
2599 } /* CIC calculation when hot==0 */
2601 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2603 sciprint(_("****daskr from: %f to %f hot= %d \n"), *told, t, hot);
2606 /*--discrete zero crossings----dzero--------------------*/
2607 /*--check for Dzeros after Mode settings or ddoit()----*/
2609 if (ng > 0 && hot == 0)
2611 zdoit(told, x, xd, g);
2617 for (jj = 0; jj < ng; ++jj)
2619 if ((g[jj] >= 0.0) && ( jroot[jj] == -5))
2624 else if ((g[jj] < 0.0) && ( jroot[jj] == 5))
2633 /*--discrete zero crossings----dzero--------------------*/
2634 if (Discrete_Jump == 0) /* if there was a dzero, its event should be activated*/
2637 flagr = IDASolve(ida_mem, t, told, yy, yp, IDA_NORMAL_TSTOP);
2647 flagr = IDA_ROOT_RETURN; /* in order to handle discrete jumps */
2651 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2652 sciprint(_("****SUNDIALS.Ida reached: %f\n"), *told);
2656 else if ( flagr == IDA_TOO_MUCH_WORK || flagr == IDA_CONV_FAIL || flagr == IDA_ERR_FAIL)
2658 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2659 sciprint(_("**** SUNDIALS.Ida: too much work at time=%g (stiff region, change RTOL and ATOL)\n"), *told);
2664 *ierr = 200 + (-flagr);
2671 if (flagr < 0) *ierr = 200 + (-flagr); /* raising errors due to internal errors, other wise erros due to flagr*/
2676 /* update outputs of 'c' type blocks if we are at the end*/
2684 if (flagr == IDA_ZERO_DETACH_RETURN)
2687 }; /* new feature of sundials, detects unmasking */
2688 if (flagr == IDA_ROOT_RETURN)
2690 /* . at a least one root has been found */
2692 if (Discrete_Jump == 0)
2694 flagr = IDAGetRootInfo(ida_mem, jroot);
2695 if (check_flag(&flagr, "IDAGetRootInfo", 1))
2697 *ierr = 200 + (-flagr);
2703 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2705 sciprint(_("root found at t=: %f\n"), *told);
2707 /* . update outputs affecting ztyp blocks ONLY FOR OLD BLOCKS*/
2708 zdoit(told, x, xd, g);
2714 for (jj = 0; jj < ng; ++jj)
2716 C2F(curblk).kfun = zcros[jj];
2717 if (C2F(curblk).kfun == -1)
2722 for (j = zcptr[C2F(curblk).kfun] - 1 ;
2723 j < zcptr[C2F(curblk).kfun + 1] - 1 ; ++j)
2733 Blocks[C2F(curblk).kfun - 1].jroot = &jroot[zcptr[C2F(curblk).kfun] - 1];
2734 if (funtyp[C2F(curblk).kfun] > 0)
2736 if (Blocks[C2F(curblk).kfun - 1].nevout > 0)
2739 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2741 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2742 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2744 /* call corresponding block to determine output event (kev) */
2745 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
2746 /*callf(told, xd, x, x,g,&flag__);*/
2747 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2754 /* update event agenda */
2755 for (k = 0; k < Blocks[C2F(curblk).kfun - 1].nevout; ++k)
2757 if (Blocks[C2F(curblk).kfun - 1].evout[k] >= 0)
2759 i3 = k + clkptr[C2F(curblk).kfun] ;
2760 addevs(Blocks[C2F(curblk).kfun - 1].evout[k] + (*told), &i3, &ierr1);
2763 /* . nevts too small */
2772 if ((Blocks[C2F(curblk).kfun - 1].nx > 0) || (*Blocks[C2F(curblk).kfun - 1].work != NULL) )
2774 /* call corresponding block to update state */
2776 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2778 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2779 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2781 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
2783 Blocks[C2F(curblk).kfun - 1].xprop = &xprop[-1 + xptr[C2F(curblk).kfun]];
2784 /*callf(told, xd, x, x,g,&flag__);*/
2785 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2793 for (j = 0; j < *neq; j++) /* Adjust xprop for IDx */
2795 if (xprop[j] == 1) scicos_xproperty[j] = ONE;
2796 if (xprop[j] == -1) scicos_xproperty[j] = ZERO;
2803 /* Serge Steer 29/06/2009 */
2804 while (ismenu()) //** if the user has done something, do the actions
2807 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2808 CommandLength = (int)strlen(CommandToUnstack);
2809 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2812 if (C2F(coshlt).halt != 0)
2814 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2815 C2F(coshlt).halt = 0;
2832 /*--discrete zero crossings----dzero--------------------*/
2833 if (ng > 0) /* storing ZC signs just after a ddaskr call*/
2835 zdoit(told, x, xd, g);
2841 for (jj = 0; jj < ng; ++jj)
2853 /*--discrete zero crossings----dzero--------------------*/
2855 C2F(realtime)(told);
2860 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2862 sciprint(_("Event: %d activated at t=%f\n"), *pointi, *told);
2866 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2868 sciprint(_("End of activation"));
2876 /* end of main loop on time */
2879 } /* cossimdaskr_ */
2880 /*--------------------------------------------------------------------------*/
2881 /* Subroutine cosend */
2882 static void cosend(double *told)
2884 /* Local variables */
2885 static scicos_flag flag__ = 0;
2887 static int kfune = 0;
2891 /* loop on blocks */
2892 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
2895 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
2896 if (funtyp[C2F(curblk).kfun] >= 0)
2898 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2900 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2901 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2903 /*callf(told, xd, x, x,x,&flag__);*/
2904 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2905 if (flag__ < 0 && *ierr == 0)
2908 kfune = C2F(curblk).kfun;
2914 C2F(curblk).kfun = kfune;
2918 /*--------------------------------------------------------------------------*/
2920 void callf(double *t, scicos_block *block, scicos_flag *flag)
2922 double* args[SZ_SIZE];
2924 double intabl[TB_SIZE];
2925 double outabl[TB_SIZE];
2927 int ii = 0, in = 0, out = 0, ki = 0, ko = 0, no = 0, ni = 0, k = 0, j = 0;
2928 int szi = 0, flagi = 0;
2929 double *ptr_d = NULL;
2931 /* function pointers type def */
2935 /* ScicosFm1 loc3;*/
2943 int solver = C2F(cmsolver).solver;
2944 int cosd = C2F(cosdebug).cosd;
2945 /*int kf = C2F(curblk).kfun;*/
2947 block_error = (int*) flag;
2949 /* debug block is never called */
2950 /*if (kf==(debug_block+1)) return;*/
2951 if (block->type == 99) return;
2953 /* flag 7 implicit initialization */
2954 flagi = (int) * flag;
2955 /* change flag to zero if flagi==7 for explicit block */
2956 if (flagi == 7 && block->type < 10000)
2961 /* display information for debugging mode */
2966 sciprint(_("block %d is called "), C2F(curblk).kfun);
2967 sciprint(_("with flag %d "), *flag);
2968 sciprint(_("at time %f \n"), *t);
2970 if (debug_block > -1)
2972 if (cosd != 3) sciprint(_("Entering the block \n"));
2973 call_debug_scicos(block, flag, flagi, debug_block);
2974 if (*flag < 0) return; /* error in debug block */
2978 C2F(scsptr).ptr = block->scsptr;
2980 /* get pointer of the function */
2983 /* continuous state */
2984 if (solver == 100 && block->type < 10000 && *flag == 0)
2987 block->xd = block->res;
2991 //sciprint("callf type=%d flag=%d\n",block->type,flagi);
2992 switch (block->type)
2994 /*******************/
2995 /* function type 0 */
2996 /*******************/
2999 /* This is for compatibility */
3000 /* jroot is returned in g for old type */
3001 if (block->nevprt < 0)
3003 for (j = 0; j < block->ng; ++j)
3005 block->g[j] = (double)block->jroot[j];
3009 /* concatenated entries and concatened outputs */
3010 /* catenate inputs if necessary */
3015 for (in = 0; in < block->nin; in++)
3017 szi = block->insz[in] * block->insz[in + block->nin];
3018 for (ii = 0; ii < szi; ii++)
3020 intabl[ki++] = *((double *)(block->inptr[in]) + ii);
3024 args[0] = &(intabl[0]);
3028 if (block->nin == 0)
3034 args[0] = (double *)(block->inptr[0]);
3035 ni = block->insz[0] * block->insz[1];
3039 /* catenate outputs if necessary */
3041 if (block->nout > 1)
3044 for (out = 0; out < block->nout; out++)
3046 szi = block->outsz[out] * block->outsz[out + block->nout];
3047 for (ii = 0; ii < szi; ii++)
3049 outabl[ko++] = *((double *)(block->outptr[out]) + ii);
3053 args[1] = &(outabl[0]);
3057 if (block->nout == 0)
3063 args[1] = (double *)(block->outptr[0]);
3064 no = block->outsz[0] * block->outsz[1];
3068 loc0 = (ScicosF0) loc;
3070 (*loc0)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3071 block->z, &block->nz,
3072 block->evout, &block->nevout, block->rpar, &block->nrpar,
3073 block->ipar, &block->nipar, (double *)args[0], &ni,
3074 (double *)args[1], &no);
3076 /* split output vector on each port if necessary */
3077 if (block->nout > 1)
3080 for (out = 0; out < block->nout; out++)
3082 szi = block->outsz[out] * block->outsz[out + block->nout];
3083 for (ii = 0; ii < szi; ii++)
3085 *((double *)(block->outptr[out]) + ii) = outabl[ko++];
3090 /* adjust values of output register */
3091 for (in = 0; in < block->nevout; ++in)
3093 block->evout[in] = block->evout[in] - *t;
3099 /*******************/
3100 /* function type 1 */
3101 /*******************/
3104 /* This is for compatibility */
3105 /* jroot is returned in g for old type */
3106 if (block->nevprt < 0)
3108 for (j = 0; j < block->ng; ++j)
3110 block->g[j] = (double)block->jroot[j];
3114 /* one entry for each input or output */
3115 for (in = 0 ; in < block->nin ; in++)
3117 args[in] = block->inptr[in];
3118 sz[in] = block->insz[in];
3120 for (out = 0; out < block->nout; out++)
3122 args[in + out] = block->outptr[out];
3123 sz[in + out] = block->outsz[out];
3125 /* with zero crossing */
3126 if (block->ztyp > 0)
3128 args[block->nin + block->nout] = block->g;
3129 sz[block->nin + block->nout] = block->ng;
3132 loc1 = (ScicosF) loc;
3134 (*loc1)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3135 block->z, &block->nz,
3136 block->evout, &block->nevout, block->rpar, &block->nrpar,
3137 block->ipar, &block->nipar,
3138 (double *)args[0], &sz[0],
3139 (double *)args[1], &sz[1], (double *)args[2], &sz[2],
3140 (double *)args[3], &sz[3], (double *)args[4], &sz[4],
3141 (double *)args[5], &sz[5], (double *)args[6], &sz[6],
3142 (double *)args[7], &sz[7], (double *)args[8], &sz[8],
3143 (double *)args[9], &sz[9], (double *)args[10], &sz[10],
3144 (double *)args[11], &sz[11], (double *)args[12], &sz[12],
3145 (double *)args[13], &sz[13], (double *)args[14], &sz[14],
3146 (double *)args[15], &sz[15], (double *)args[16], &sz[16],
3147 (double *)args[17], &sz[17]);
3149 /* adjust values of output register */
3150 for (in = 0; in < block->nevout; ++in)
3152 block->evout[in] = block->evout[in] - *t;
3158 /*******************/
3159 /* function type 2 */
3160 /*******************/
3163 /* This is for compatibility */
3164 /* jroot is returned in g for old type */
3165 if (block->nevprt < 0)
3167 for (j = 0; j < block->ng; ++j)
3169 block->g[j] = (double)block->jroot[j];
3173 /* no zero crossing */
3174 if (block->ztyp == 0)
3176 loc2 = (ScicosF2) loc;
3177 (*loc2)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3178 block->z, &block->nz,
3179 block->evout, &block->nevout, block->rpar, &block->nrpar,
3180 block->ipar, &block->nipar, (double **)block->inptr,
3181 block->insz, &block->nin,
3182 (double **)block->outptr, block->outsz, &block->nout);
3184 /* with zero crossing */
3187 loc2z = (ScicosF2z) loc;
3188 (*loc2z)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3189 block->z, &block->nz,
3190 block->evout, &block->nevout, block->rpar, &block->nrpar,
3191 block->ipar, &block->nipar, (double **)block->inptr,
3192 block->insz, &block->nin,
3193 (double **)block->outptr, block->outsz, &block->nout,
3194 block->g, &block->ng);
3197 /* adjust values of output register */
3198 for (in = 0; in < block->nevout; ++in)
3200 block->evout[in] = block->evout[in] - *t;
3206 /*******************/
3207 /* function type 4 */
3208 /*******************/
3211 /* get pointer of the function type 4*/
3212 loc4 = (ScicosF4) loc;
3214 (*loc4)(block, *flag);
3219 /***********************/
3220 /* function type 10001 */
3221 /***********************/
3224 /* This is for compatibility */
3225 /* jroot is returned in g for old type */
3226 if (block->nevprt < 0)
3228 for (j = 0; j < block->ng; ++j)
3230 block->g[j] = (double)block->jroot[j];
3234 /* implicit block one entry for each input or output */
3235 for (in = 0 ; in < block->nin ; in++)
3237 args[in] = block->inptr[in];
3238 sz[in] = block->insz[in];
3240 for (out = 0; out < block->nout; out++)
3242 args[in + out] = block->outptr[out];
3243 sz[in + out] = block->outsz[out];
3245 /* with zero crossing */
3246 if (block->ztyp > 0)
3248 args[block->nin + block->nout] = block->g;
3249 sz[block->nin + block->nout] = block->ng;
3252 loci1 = (ScicosFi) loc;
3253 (*loci1)(flag, &block->nevprt, t, block->res, block->xd, block->x,
3254 &block->nx, block->z, &block->nz,
3255 block->evout, &block->nevout, block->rpar, &block->nrpar,
3256 block->ipar, &block->nipar,
3257 (double *)args[0], &sz[0],
3258 (double *)args[1], &sz[1], (double *)args[2], &sz[2],
3259 (double *)args[3], &sz[3], (double *)args[4], &sz[4],
3260 (double *)args[5], &sz[5], (double *)args[6], &sz[6],
3261 (double *)args[7], &sz[7], (double *)args[8], &sz[8],
3262 (double *)args[9], &sz[9], (double *)args[10], &sz[10],
3263 (double *)args[11], &sz[11], (double *)args[12], &sz[12],
3264 (double *)args[13], &sz[13], (double *)args[14], &sz[14],
3265 (double *)args[15], &sz[15], (double *)args[16], &sz[16],
3266 (double *)args[17], &sz[17]);
3268 /* adjust values of output register */
3269 for (in = 0; in < block->nevout; ++in)
3271 block->evout[in] = block->evout[in] - *t;
3277 /***********************/
3278 /* function type 10002 */
3279 /***********************/
3282 /* This is for compatibility */
3283 /* jroot is returned in g for old type */
3284 if (block->nevprt < 0)
3286 for (j = 0; j < block->ng; ++j)
3288 block->g[j] = (double)block->jroot[j];
3292 /* implicit block, inputs and outputs given by a table of pointers */
3293 /* no zero crossing */
3294 if (block->ztyp == 0)
3296 loci2 = (ScicosFi2) loc;
3297 (*loci2)(flag, &block->nevprt, t, block->res,
3298 block->xd, block->x, &block->nx,
3299 block->z, &block->nz,
3300 block->evout, &block->nevout, block->rpar, &block->nrpar,
3301 block->ipar, &block->nipar, (double **)block->inptr,
3302 block->insz, &block->nin,
3303 (double **)block->outptr, block->outsz, &block->nout);
3305 /* with zero crossing */
3308 loci2z = (ScicosFi2z) loc;
3309 (*loci2z)(flag, &block->nevprt, t, block->res,
3310 block->xd, block->x, &block->nx,
3311 block->z, &block->nz,
3312 block->evout, &block->nevout, block->rpar, &block->nrpar,
3313 block->ipar, &block->nipar,
3314 (double **)block->inptr, block->insz, &block->nin,
3315 (double **)block->outptr, block->outsz, &block->nout,
3316 block->g, &block->ng);
3319 /* adjust values of output register */
3320 for (in = 0; in < block->nevout; ++in)
3322 block->evout[in] = block->evout[in] - *t;
3328 /***********************/
3329 /* function type 10004 */
3330 /***********************/
3333 /* get pointer of the function type 4*/
3334 loc4 = (ScicosF4) loc;
3336 (*loc4)(block, *flag);
3346 sciprint(_("Undefined Function type\n"));
3351 // sciprint("callf end flag=%d\n",*flag);
3352 /* Implicit Solver & explicit block & flag==0 */
3353 /* adjust continuous state vector after call */
3354 if (solver == 100 && block->type < 10000 && *flag == 0)
3359 for (k = 0; k < block->nx; k++)
3361 block->res[k] = block->res[k] - block->xd[k];
3366 for (k = 0; k < block->nx; k++)
3368 block->xd[k] = block->res[k];
3376 if (debug_block > -1)
3378 if (*flag < 0) return; /* error in block */
3379 if (cosd != 3) sciprint(_("Leaving block %d \n"), C2F(curblk).kfun);
3380 call_debug_scicos(block, flag, flagi, debug_block);
3381 /*call_debug_scicos(flag,kf,flagi,debug_block);*/
3385 /*--------------------------------------------------------------------------*/
3386 /* call_debug_scicos */
3387 static void call_debug_scicos(scicos_block *block, scicos_flag *flag, int flagi, int deb_blk)
3390 int solver = C2F(cmsolver).solver, k = 0;
3392 double *ptr_d = NULL;
3394 C2F(cosdebugcounter).counter = C2F(cosdebugcounter).counter + 1;
3395 C2F(scsptr).ptr = Blocks[deb_blk].scsptr;
3397 loc = Blocks[deb_blk].funpt; /* GLOBAL */
3398 loc4 = (ScicosF4) loc;
3400 /* continuous state */
3401 if (solver == 100 && block->type < 10000 && *flag == 0)
3404 block->xd = block->res;
3407 (*loc4)(block, *flag);
3409 /* Implicit Solver & explicit block & flag==0 */
3410 /* adjust continuous state vector after call */
3411 if (solver == 100 && block->type < 10000 && *flag == 0)
3416 for (k = 0; k < block->nx; k++)
3418 block->res[k] = block->res[k] - block->xd[k];
3423 for (k = 0; k < block->nx; k++)
3425 block->xd[k] = block->res[k];
3430 if (*flag < 0) sciprint(_("Error in the Debug block \n"));
3431 } /* call_debug_scicos */
3432 /*--------------------------------------------------------------------------*/
3434 static int simblk(realtype t, N_Vector yy, N_Vector yp, void *f_data)
3436 double tx = 0., *x = NULL, *xd = NULL;
3437 int i = 0, nantest = 0;
3440 x = (double *) NV_DATA_S(yy);
3441 xd = (double *) NV_DATA_S(yp);
3443 for (i = 0; i < *neq; i++) xd[i] = 0; /* à la place de "C2F(dset)(neq, &c_b14,xcdot , &c__1);"*/
3444 C2F(ierode).iero = 0;
3446 odoit(&tx, x, xd, xd);
3447 C2F(ierode).iero = *ierr;
3452 for (i = 0; i < *neq; i++) /* NaN checking */
3454 if ((xd[i] - xd[i] != 0))
3456 sciprint(_("\nWarning: The computing function #%d returns a NaN/Inf"), i);
3461 if (nantest == 1) return 349; /* recoverable error; */
3464 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3467 /*--------------------------------------------------------------------------*/
3469 static int grblk(realtype t, N_Vector yy, realtype *gout, void *g_data)
3471 double tx = 0., *x = NULL;
3472 int jj = 0, nantest = 0;
3475 x = (double *) NV_DATA_S(yy);
3477 C2F(ierode).iero = 0;
3480 zdoit(&tx, x, x, (double*) gout);
3485 for (jj = 0; jj < ng; jj++)
3486 if (gout[jj] - gout[jj] != 0)
3488 sciprint(_("\nWarning: The zero_crossing function #%d returns a NaN/Inf"), jj);
3491 } /* NaN checking */
3492 if (nantest == 1) return 350; /* recoverable error; */
3494 C2F(ierode).iero = *ierr;
3498 /*--------------------------------------------------------------------------*/
3500 static int simblklsodar(int * nequations, realtype * tOld, realtype * actual, realtype * res)
3503 int i = 0, nantest = 0;
3505 tx = (double) *tOld;
3507 for (i = 0; i < *nequations; ++i) res[i] = 0; /* à la place de "C2F(dset)(neq, &c_b14,xcdot , &c__1);"*/
3508 C2F(ierode).iero = 0;
3510 odoit(&tx, actual, res, res);
3511 C2F(ierode).iero = *ierr;
3516 for (i = 0; i < *nequations; i++) /* NaN checking */
3518 if ((res[i] - res[i] != 0))
3520 sciprint(_("\nWarning: The computing function #%d returns a NaN/Inf"), i);
3525 if (nantest == 1) return 349; /* recoverable error; */
3528 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3530 } /* simblklsodar */
3531 /*--------------------------------------------------------------------------*/
3533 static int grblklsodar(int * nequations, realtype * tOld, realtype * actual, int * ngc, realtype * res)
3536 int jj = 0, nantest = 0;
3538 tx = (double) *tOld;
3540 C2F(ierode).iero = 0;
3543 zdoit(&tx, actual, actual, res);
3548 for (jj = 0; jj < *ngc; jj++)
3549 if (res[jj] - res[jj] != 0)
3551 sciprint(_("\nWarning: The zero_crossing function #%d returns a NaN/Inf"), jj);
3554 } /* NaN checking */
3555 if (nantest == 1) return 350; /* recoverable error; */
3557 C2F(ierode).iero = *ierr;
3561 /*--------------------------------------------------------------------------*/
3563 static int simblkdaskr(realtype tres, N_Vector yy, N_Vector yp, N_Vector resval, void *rdata)
3566 double *xc = NULL, *xcdot = NULL, *residual = NULL;
3567 realtype alpha = 0.;
3573 int jj = 0, flag = 0, nantest = 0;
3575 data = (UserData) rdata;
3577 if (get_phase_simulation() == 1)
3579 /* Just to update mode in a very special case, i.e., when initialization using modes fails.
3580 in this case, we relax all modes and try again one more time.
3582 zdoit(&tx, NV_DATA_S(yy), NV_DATA_S(yp), (double *)data->gwork);
3586 flag = IDAGetCurrentStep(data->ida_mem, &hh);
3589 *ierr = 200 + (-flag);
3594 flag = IDAGetCurrentOrder(data->ida_mem, &qlast);
3597 *ierr = 200 + (-flag);
3602 for (jj = 0; jj < qlast; jj++)
3603 alpha = alpha - ONE / (jj + 1);
3605 // CJ=-alpha/hh; // For function Get_Jacobian_cj
3612 xc = (double *) NV_DATA_S(yy);
3613 xcdot = (double *) NV_DATA_S(yp);
3614 residual = (double *) NV_DATA_S(resval);
3617 C2F(dcopy)(neq, xcdot, &c__1, residual, &c__1);
3619 C2F(ierode).iero = 0;
3620 odoit(&tx, xc, xcdot, residual);
3622 C2F(ierode).iero = *ierr;
3627 for (jj = 0; jj < *neq; jj++)
3628 if (residual[jj] - residual[jj] != 0) /* NaN checking */
3630 //sciprint(_("\nWarning: The residual function #%d returns a NaN"),jj);
3634 if (nantest == 1) return 257; /* recoverable error; */
3637 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3639 /*--------------------------------------------------------------------------*/
3641 static int grblkdaskr(realtype t, N_Vector yy, N_Vector yp, realtype *gout, void *g_data)
3644 int jj = 0, nantest = 0;
3649 C2F(ierode).iero = 0;
3650 zdoit(&tx, NV_DATA_S(yy), NV_DATA_S(yp), (double *)gout);
3653 nantest = 0; /* NaN checking */
3654 for (jj = 0; jj < ng; jj++)
3656 if (gout[jj] - gout[jj] != 0)
3658 sciprint(_("\nWarning: The zero-crossing function #%d returns a NaN"), jj);
3665 return 258; /* recoverable error; */
3668 C2F(ierode).iero = *ierr;
3671 /*--------------------------------------------------------------------------*/
3672 /* Subroutine addevs */
3673 static void addevs(double t, int *evtnb, int *ierr1)
3675 static int i = 0, j = 0;
3679 if (evtspt[*evtnb] != -1)
3681 if ((evtspt[*evtnb] == 0) && (*pointi == *evtnb))
3688 if (*pointi == *evtnb)
3690 *pointi = evtspt[*evtnb]; /* remove from chain */
3695 while (*evtnb != evtspt[i])
3699 evtspt[i] = evtspt[*evtnb]; /* remove old evtnb from chain */
3700 if (TCritWarning == 0)
3702 sciprint(_("\n Warning: an event is reprogrammed at t=%g by removing another"), t );
3703 sciprint(_("\n (already programmed) event. There may be an error in"));
3704 sciprint(_("\n your model. Please check your model\n"));
3707 do_cold_restart(); /* the erased event could be a critical
3708 event, so do_cold_restart is added to
3709 refresh the critical event table */
3725 if (t < tevts[*pointi])
3727 evtspt[*evtnb] = *pointi;
3739 if (t >= tevts[evtspt[i]])
3752 evtspt[*evtnb] = evtspt[i];
3756 /*--------------------------------------------------------------------------*/
3757 /* Subroutine putevs */
3758 void putevs(double *t, int *evtnb, int *ierr1)
3762 if (evtspt[*evtnb] != -1)
3777 evtspt[*evtnb] = *pointi;
3780 /*--------------------------------------------------------------------------*/
3781 /* Subroutine idoit */
3782 static void idoit(double *told)
3784 /* initialisation (propagation of constant blocks outputs) */
3785 /* Copyright INRIA */
3788 scicos_flag flag = 0;
3792 ScicosImport *scs_imp = NULL;
3795 scs_imp = getscicosimportptr();
3798 for (j = 0; j < * (scs_imp->niord); j++)
3800 kf = &scs_imp->iord[j];
3801 C2F(curblk).kfun = *kf; /* */
3802 if (scs_imp->funtyp[*kf - 1] > -1)
3804 /* continuous state */
3805 if (scs_imp->blocks[*kf - 1].nx > 0)
3807 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3808 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3810 scs_imp->blocks[*kf - 1].nevprt = scs_imp->iord[j + * (scs_imp->niord)];
3811 /*callf(told, xd, x, x,x,&flag);*/
3812 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3819 if (scs_imp->blocks[*kf - 1].nevout > 0)
3821 if (scs_imp->funtyp[*kf - 1] < 0)
3823 i = synchro_nev(scs_imp, *kf, ierr);
3828 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3829 putevs(told, &i2, &ierr1);
3832 /* event conflict */
3845 /*--------------------------------------------------------------------------*/
3846 /* Subroutine doit */
3847 static void doit(double *told)
3849 /* propagation of blocks outputs on discrete activations */
3850 /* Copyright INRIA */
3853 scicos_flag flag = 0;
3856 int ii = 0, kever = 0;
3858 ScicosImport *scs_imp = NULL;
3861 scs_imp = getscicosimportptr();
3864 *pointi = evtspt[kever];
3867 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
3873 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1 ; ii++)
3875 kf = &scs_imp->ordclk[ii - 1];
3876 C2F(curblk).kfun = *kf;
3877 if (scs_imp->funtyp[*kf - 1] > -1)
3879 /* continuous state */
3880 if (scs_imp->blocks[*kf - 1].nx > 0)
3882 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3883 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3885 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
3887 /*callf(told, xd, x, x,x,&flag);*/
3888 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3896 /* Initialize tvec */
3897 if (scs_imp->blocks[*kf - 1].nevout > 0)
3899 if (scs_imp->funtyp[*kf - 1] < 0)
3901 i = synchro_nev(scs_imp, *kf, ierr);
3906 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3907 putevs(told, &i2, &ierr1);
3910 /* event conflict */
3923 /*--------------------------------------------------------------------------*/
3924 /* Subroutine cdoit */
3925 static void cdoit(double *told)
3927 /* propagation of continuous blocks outputs */
3928 /* Copyright INRIA */
3931 scicos_flag flag = 0;
3935 ScicosImport *scs_imp = NULL;
3938 scs_imp = getscicosimportptr();
3941 for (j = 0; j < * (scs_imp->ncord); j++)
3943 kf = &scs_imp->cord[j];
3944 C2F(curblk).kfun = *kf;
3945 /* continuous state */
3946 if (scs_imp->blocks[*kf - 1].nx > 0)
3948 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3949 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3951 scs_imp->blocks[*kf - 1].nevprt = scs_imp->cord[j + * (scs_imp->ncord)];
3952 if (scs_imp->funtyp[*kf - 1] > -1)
3955 /*callf(told, xd, x, x,x,&flag);*/
3956 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3964 /* Initialize tvec */
3965 if (scs_imp->blocks[*kf - 1].nevout > 0)
3967 if (scs_imp->funtyp[*kf - 1] < 0)
3969 i = synchro_nev(scs_imp, *kf, ierr);
3974 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3975 putevs(told, &i2, &ierr1);
3978 /* event conflict */
3991 /*--------------------------------------------------------------------------*/
3992 /* Subroutine ddoit */
3993 static void ddoit(double *told)
3995 /* update states & event out on discrete activations */
3996 /* Copyright INRIA */
3999 scicos_flag flag = 0;
4001 int i = 0, i3 = 0, ierr1 = 0;
4002 int ii = 0, keve = 0;
4004 ScicosImport *scs_imp = NULL;
4007 scs_imp = getscicosimportptr();
4017 /* update continuous and discrete states on event */
4022 for (i = 0; i < kiwa; i++)
4025 if (critev[keve] != 0)
4029 i2 = scs_imp->ordptr[keve] - 1;
4030 for (ii = scs_imp->ordptr[keve - 1]; ii <= i2; ii++)
4032 kf = &scs_imp->ordclk[ii - 1];
4033 C2F(curblk).kfun = *kf;
4034 /* continuous state */
4035 if (scs_imp->blocks[*kf - 1].nx > 0)
4037 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4038 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4041 scs_imp->blocks[*kf - 1].nevprt = scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1];
4043 if (scs_imp->blocks[*kf - 1].nevout > 0)
4045 if (scs_imp->funtyp[*kf - 1] >= 0)
4047 /* initialize evout */
4048 for (j = 0; j < scs_imp->blocks[*kf - 1].nevout; j++)
4050 scs_imp->blocks[*kf - 1].evout[j] = -1;
4054 if (scs_imp->blocks[*kf - 1].nevprt > 0) /* if event has continuous origin don't call*/
4056 /*callf(told, xd, x, x ,x,&flag);*/
4057 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4065 for (j = 0; j < scs_imp->blocks[*kf - 1].nevout; j++)
4067 if (scs_imp->blocks[*kf - 1].evout[j] >= 0.)
4069 i3 = j + scs_imp->clkptr[*kf - 1] ;
4070 addevs(scs_imp->blocks[*kf - 1].evout[j] + (*told), &i3, &ierr1);
4073 /* event conflict */
4082 if (scs_imp->blocks[*kf - 1].nevprt > 0)
4084 if (scs_imp->blocks[*kf - 1].nx + scs_imp->blocks[*kf - 1].nz + scs_imp->blocks[*kf - 1].noz > 0 || \
4085 *scs_imp->blocks[*kf - 1].work != NULL)
4087 /* if a hidden state exists, must also call (for new scope eg) */
4088 /* to avoid calling non-real activations */
4090 /*callf(told, xd, x, x,x,&flag);*/
4091 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4101 if (*scs_imp->blocks[*kf - 1].work != NULL)
4104 scs_imp->blocks[*kf - 1].nevprt = 0; /* in case some hidden continuous blocks need updating */
4105 /*callf(told, xd, x, x,x,&flag);*/
4106 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4117 /*--------------------------------------------------------------------------*/
4118 /* Subroutine edoit */
4119 static void edoit(double *told, int *kiwa)
4121 /* update blocks output on discrete activations */
4122 /* Copyright INRIA */
4125 scicos_flag flag = 0;
4126 int ierr1 = 0, i = 0;
4127 int kever = 0, ii = 0;
4129 ScicosImport *scs_imp = NULL;
4133 scs_imp = getscicosimportptr();
4138 *pointi = evtspt[kever];
4141 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
4148 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1; ii++)
4150 kf = &scs_imp->ordclk[ii - 1];
4151 C2F(curblk).kfun = *kf;
4153 if (scs_imp->funtyp[*kf - 1] > -1)
4155 /* continuous state */
4156 if (scs_imp->blocks[*kf - 1].nx > 0)
4158 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4159 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4162 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4165 /*callf(told, xd, x, x,x,&flag);*/
4166 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4174 /* Initialize tvec */
4175 if (scs_imp->blocks[*kf - 1].nevout > 0)
4177 if (scs_imp->funtyp[*kf - 1] < 0)
4179 i = synchro_nev(scs_imp, *kf, ierr);
4184 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4185 putevs(told, &i2, &ierr1);
4188 /* event conflict */
4201 /*--------------------------------------------------------------------------*/
4202 /* Subroutine odoit */
4203 static void odoit(double *told, double *xt, double *xtd, double *residual)
4205 /* update blocks derivative of continuous time block */
4206 /* Copyright INRIA */
4209 scicos_flag flag = 0;
4210 int keve = 0, kiwa = 0;
4211 int ierr1 = 0, i = 0;
4214 ScicosImport *scs_imp = NULL;
4217 scs_imp = getscicosimportptr();
4221 for (jj = 0; jj < * (scs_imp->noord); jj++)
4223 kf = &scs_imp->oord[jj];
4224 C2F(curblk).kfun = *kf;
4225 /* continuous state */
4226 if (scs_imp->blocks[*kf - 1].nx > 0)
4228 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4229 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4230 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4233 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4234 if (scs_imp->funtyp[*kf - 1] > -1)
4237 /*callf(told, xtd, xt, residual,x,&flag);*/
4238 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4246 if (scs_imp->blocks[*kf - 1].nevout > 0)
4248 if (scs_imp->funtyp[*kf - 1] < 0)
4250 if (scs_imp->blocks[*kf - 1].nmode > 0)
4252 i2 = scs_imp->blocks[*kf - 1].mode[0] + scs_imp->clkptr[*kf - 1] - 1;
4256 i = synchro_nev(scs_imp, *kf, ierr);
4261 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4263 putevs(told, &i2, &ierr1);
4266 /* event conflict */
4270 ozdoit(told, xt, xtd, &kiwa);
4279 /* update states derivatives */
4280 for (ii = 0; ii < * (scs_imp->noord); ii++)
4282 kf = &scs_imp->oord[ii];
4283 C2F(curblk).kfun = *kf;
4284 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4285 *scs_imp->blocks[*kf - 1].work != NULL)
4287 /* work tests if a hidden state exists, used for delay block */
4289 /* continuous state */
4290 if (scs_imp->blocks[*kf - 1].nx > 0)
4292 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4293 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4294 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4296 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4297 /*callf(told, xtd, xt, residual,xt,&flag);*/
4298 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4308 for (i = 0; i < kiwa; i++)
4311 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4313 kf = &scs_imp->ordclk[ii - 1];
4314 C2F(curblk).kfun = *kf;
4315 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4316 *scs_imp->blocks[*kf - 1].work != NULL)
4318 /* work tests if a hidden state exists */
4320 /* continuous state */
4321 if (scs_imp->blocks[*kf - 1].nx > 0)
4323 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4324 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4325 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4327 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4328 /*callf(told, xtd, xt, residual,xt,&flag);*/
4329 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4340 /*--------------------------------------------------------------------------*/
4341 /* Subroutine reinitdoit */
4342 static void reinitdoit(double *told)
4344 /* update blocks xproperties of continuous time block */
4345 /* Copyright INRIA */
4348 scicos_flag flag = 0;
4349 int keve = 0, kiwa = 0;
4350 int ierr1 = 0, i = 0;
4353 ScicosImport *scs_imp = NULL;
4356 scs_imp = getscicosimportptr();
4360 for (jj = 0; jj < * (scs_imp->noord); jj++)
4362 kf = &scs_imp->oord[jj];
4363 C2F(curblk).kfun = *kf;
4364 /* continuous state */
4365 if (scs_imp->blocks[*kf - 1].nx > 0)
4367 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4368 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4370 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4371 if (scs_imp->funtyp[*kf - 1] > -1)
4374 /*callf(told, xd, x, x,x,&flag);*/
4375 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4383 if (scs_imp->blocks[*kf - 1].nevout > 0 && scs_imp->funtyp[*kf - 1] < 0)
4385 i = synchro_nev(scs_imp, *kf, ierr);
4390 if (scs_imp->blocks[*kf - 1].nmode > 0)
4392 scs_imp->blocks[*kf - 1].mode[0] = i;
4394 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4395 putevs(told, &i2, &ierr1);
4398 /* event conflict */
4411 for (ii = 0; ii < * (scs_imp->noord); ii++)
4413 kf = &scs_imp->oord[ii];
4414 C2F(curblk).kfun = *kf;
4415 if (scs_imp->blocks[*kf - 1].nx > 0)
4418 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4419 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4420 scs_imp->blocks[*kf - 1].res = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4421 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4422 scs_imp->blocks[*kf - 1].xprop = &scs_imp->xprop[-1 + scs_imp->xptr[*kf - 1]];
4423 /*callf(told, xd, x, xd,x,&flag);*/
4424 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4433 for (i = 0; i < kiwa; i++)
4436 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4438 kf = &scs_imp->ordclk[ii - 1];
4439 C2F(curblk).kfun = *kf;
4440 if (scs_imp->blocks[*kf - 1].nx > 0)
4443 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4444 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4445 scs_imp->blocks[*kf - 1].res = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4446 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4447 scs_imp->blocks[*kf - 1].xprop = &scs_imp->xprop[-1 + scs_imp->xptr[*kf - 1]];
4448 /*callf(told, xd, x, xd,x,&flag);*/
4449 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4459 /*--------------------------------------------------------------------------*/
4460 /* Subroutine ozdoit */
4461 static void ozdoit(double *told, double *xt, double *xtd, int *kiwa)
4463 /* update blocks output of continuous time block on discrete activations */
4464 /* Copyright INRIA */
4467 scicos_flag flag = 0;
4469 int ierr1 = 0, i = 0;
4470 int ii = 0, kever = 0;
4472 ScicosImport *scs_imp = NULL;
4475 scs_imp = getscicosimportptr();
4479 *pointi = evtspt[kever];
4482 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
4490 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1; ii++)
4492 kf = &scs_imp->ordclk[ii - 1];
4493 C2F(curblk).kfun = *kf;
4494 if (scs_imp->funtyp[*kf - 1] > -1)
4496 /* continuous state */
4497 if (scs_imp->blocks[*kf - 1].nx > 0)
4499 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4500 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4502 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4504 /*callf(told, xtd, xt, xt,x,&flag);*/
4505 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4513 /* Initialize tvec */
4514 if (scs_imp->blocks[*kf - 1].nevout > 0)
4516 if (scs_imp->funtyp[*kf - 1] < 0)
4518 if (phase == 1 || scs_imp->blocks[*kf - 1].nmode == 0)
4520 i = synchro_nev(scs_imp, *kf, ierr);
4528 i = scs_imp->blocks[*kf - 1].mode[0];
4530 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4531 putevs(told, &i2, &ierr1);
4534 /* event conflict */
4538 ozdoit(told, xt, xtd, kiwa);
4543 /*--------------------------------------------------------------------------*/
4544 /* Subroutine zdoit */
4545 static void zdoit(double *told, double *xt, double *xtd, double *g)
4547 /* update blocks zcross of continuous time block */
4548 /* Copyright INRIA */
4550 scicos_flag flag = 0;
4551 int keve = 0, kiwa = 0;
4552 int ierr1 = 0, i = 0, j = 0;
4555 ScicosImport *scs_imp = NULL;
4558 scs_imp = getscicosimportptr();
4561 for (i = 0; i < * (scs_imp->ng); i++)
4567 for (jj = 0; jj < * (scs_imp->nzord); jj++)
4569 kf = &scs_imp->zord[jj];
4570 C2F(curblk).kfun = *kf;
4571 /* continuous state */
4572 if (scs_imp->blocks[*kf - 1].nx > 0)
4574 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4575 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4577 scs_imp->blocks[*kf - 1].nevprt = scs_imp->zord[jj + * (scs_imp->nzord)];
4579 if (scs_imp->funtyp[*kf - 1] > -1)
4582 /*callf(told, xtd, xt, xt,xt,&flag);*/
4583 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4591 /* Initialize tvec */
4592 if (scs_imp->blocks[*kf - 1].nevout > 0)
4594 if (scs_imp->funtyp[*kf - 1] < 0)
4596 if (phase == 1 || scs_imp->blocks[*kf - 1].nmode == 0)
4598 i = synchro_nev(scs_imp, *kf, ierr);
4606 i = scs_imp->blocks[*kf - 1].mode[0];
4608 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4609 putevs(told, &i2, &ierr1);
4612 /* event conflict */
4616 ozdoit(told, xt, xtd, &kiwa);
4625 /* update zero crossing surfaces */
4626 for (ii = 0; ii < * (scs_imp->nzord); ii++)
4628 kf = &scs_imp->zord[ii];
4629 C2F(curblk).kfun = *kf;
4630 if (scs_imp->blocks[*kf - 1].ng > 0)
4632 /* update g array ptr */
4633 scs_imp->blocks[*kf - 1].g = &g[scs_imp->zcptr[*kf - 1] - 1];
4634 if (scs_imp->funtyp[*kf - 1] > 0)
4637 /* continuous state */
4638 if (scs_imp->blocks[*kf - 1].nx > 0)
4640 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4641 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4643 scs_imp->blocks[*kf - 1].nevprt = scs_imp->zord[ii + * (scs_imp->nzord)];
4644 /*callf(told, xtd, xt, xtd,g,&flag);*/
4645 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4654 j = synchro_g_nev(scs_imp, g, *kf, ierr);
4659 if ( (phase == 1) && (scs_imp->blocks[*kf - 1].nmode > 0) )
4661 scs_imp->blocks[*kf - 1].mode[0] = j;
4665 // scs_imp->blocks[*kf-1].g = &scs_imp->g[scs_imp->zcptr[*kf]-1];
4670 for (i = 0; i < kiwa; i++)
4673 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4675 kf = &scs_imp->ordclk[ii - 1];
4676 C2F(curblk).kfun = *kf;
4677 if (scs_imp->blocks[*kf - 1].ng > 0)
4679 /* update g array ptr */
4680 scs_imp->blocks[*kf - 1].g = &g[scs_imp->zcptr[*kf - 1] - 1];
4681 if (scs_imp->funtyp[*kf - 1] > 0)
4684 /* continuous state */
4685 if (scs_imp->blocks[*kf - 1].nx > 0)
4687 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4688 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4690 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4691 /*callf(told, xtd, xt, xtd,g,&flag);*/
4692 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4701 j = synchro_g_nev(scs_imp, g, *kf, ierr);
4706 if ((phase == 1) && (scs_imp->blocks[*kf - 1].nmode > 0))
4708 scs_imp->blocks[*kf - 1].mode[0] = j;
4712 //scs_imp->blocks[*kf-1].g = &scs_imp->g[scs_imp->zcptr[*kf]-1];
4717 /*--------------------------------------------------------------------------*/
4718 /* Subroutine Jdoit */
4719 void Jdoit(double *told, double *xt, double *xtd, double *residual, int *job)
4721 /* update blocks jacobian of continuous time block */
4722 /* Copyright INRIA */
4725 scicos_flag flag = 0;
4726 int keve = 0, kiwa = 0;
4727 int ierr1 = 0, i = 0;
4730 ScicosImport *scs_imp = NULL;
4733 scs_imp = getscicosimportptr();
4737 for (jj = 0; jj < * (scs_imp->noord); jj++)
4739 kf = &scs_imp->oord[jj];
4740 C2F(curblk).kfun = *kf;
4741 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4742 if (scs_imp->funtyp[*kf - 1] > -1)
4745 /* applying desired output */
4746 if ((*job == 2) && (scs_imp->oord[jj] == AJacobian_block))
4750 /* continuous state */
4751 if (scs_imp->blocks[*kf - 1].nx > 0)
4753 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4754 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4755 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4758 /*callf(told, xtd, xt, residual,x,&flag);*/
4759 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4767 if (scs_imp->blocks[*kf - 1].nevout > 0)
4769 if (scs_imp->funtyp[*kf - 1] < 0)
4771 if (scs_imp->blocks[*kf - 1].nmode > 0)
4773 i2 = scs_imp->blocks[*kf - 1].mode[0] + scs_imp->clkptr[*kf - 1] - 1;
4777 i = synchro_nev(scs_imp, *kf, ierr);
4782 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4784 putevs(told, &i2, &ierr1);
4787 /* event conflict */
4791 ozdoit(told, xt, xtd, &kiwa);
4796 /* update states derivatives */
4797 for (ii = 0; ii < * (scs_imp->noord); ii++)
4799 kf = &scs_imp->oord[ii];
4800 C2F(curblk).kfun = *kf;
4801 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4802 *scs_imp->blocks[*kf - 1].work != NULL)
4804 /* work tests if a hidden state exists, used for delay block */
4806 if (((*job == 1) && (scs_imp->oord[ii] == AJacobian_block)) || (*job != 1))
4808 if (*job == 1) flag = 10;
4809 /* continuous state */
4810 if (scs_imp->blocks[*kf - 1].nx > 0)
4812 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4813 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4814 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4816 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4817 /*callf(told, xtd, xt, residual,xt,&flag);*/
4818 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4828 for (i = 0; i < kiwa; i++)
4831 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4833 kf = &scs_imp->ordclk[ii - 1];
4834 C2F(curblk).kfun = *kf;
4835 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4836 *scs_imp->blocks[*kf - 1].work != NULL)
4838 /* work tests if a hidden state exists */
4840 if (((*job == 1) && (scs_imp->oord[ii - 1] == AJacobian_block)) || (*job != 1))
4842 if (*job == 1) flag = 10;
4843 /* continuous state */
4844 if (scs_imp->blocks[*kf - 1].nx > 0)
4846 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4847 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4848 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4850 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4851 /*callf(told, xtd, xt, residual,xt,&flag);*/
4852 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4863 /*--------------------------------------------------------------------------*/
4864 /* Subroutine synchro_nev */
4865 static int synchro_nev(ScicosImport *scs_imp, int kf, int *ierr)
4867 /* synchro blocks computation */
4868 /* Copyright INRIA */
4869 SCSREAL_COP *outtbdptr = NULL; /*to store double of outtb*/
4870 SCSINT8_COP *outtbcptr = NULL; /*to store int8 of outtb*/
4871 SCSINT16_COP *outtbsptr = NULL; /*to store int16 of outtb*/
4872 SCSINT32_COP *outtblptr = NULL; /*to store int32 of outtb*/
4873 SCSUINT8_COP *outtbucptr = NULL; /*to store unsigned int8 of outtb */
4874 SCSUINT16_COP *outtbusptr = NULL; /*to store unsigned int16 of outtb */
4875 SCSUINT32_COP *outtbulptr = NULL; /*to store unsigned int32 of outtb */
4878 int i = 0; /* return 0 by default */
4880 /* variable for param */
4882 void **outtbptr = NULL;
4888 outtbtyp = scs_imp->outtbtyp;
4889 outtbptr = scs_imp->outtbptr;
4890 funtyp = scs_imp->funtyp;
4891 inplnk = scs_imp->inplnk;
4892 inpptr = scs_imp->inpptr;
4894 /* if-then-else blk */
4895 if (funtyp[kf - 1] == -1)
4897 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
4900 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4901 cond = (*outtbdptr <= 0.);
4905 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4906 cond = (*outtbdptr <= 0.);
4910 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4911 cond = (*outtbcptr <= 0);
4915 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4916 cond = (*outtbsptr <= 0);
4920 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4921 cond = (*outtblptr <= 0);
4925 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4926 cond = (*outtbucptr <= 0);
4930 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4931 cond = (*outtbusptr <= 0);
4935 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4936 cond = (*outtbulptr <= 0);
4939 default : /* Add a message here */
4953 else if (funtyp[kf - 1] == -2)
4955 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
4958 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4959 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
4963 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4964 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
4968 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4969 i = Max(Min((int) * outtbcptr,
4970 scs_imp->blocks[kf - 1].nevout), 1);
4974 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4975 i = Max(Min((int) * outtbsptr, scs_imp->blocks[kf - 1].nevout), 1);
4979 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4980 i = Max(Min((int) * outtblptr, scs_imp->blocks[kf - 1].nevout), 1);
4984 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4985 i = Max(Min((int) * outtbucptr, scs_imp->blocks[kf - 1].nevout), 1);
4989 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4990 i = Max(Min((int) * outtbusptr, scs_imp->blocks[kf - 1].nevout), 1);
4994 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4995 i = Max(Min((int) * outtbulptr, scs_imp->blocks[kf - 1].nevout), 1);
4998 default : /* Add a message here */
5005 /*--------------------------------------------------------------------------*/
5006 /* Subroutine synchro_g_nev */
5007 static int synchro_g_nev(ScicosImport *scs_imp, double *g, int kf, int *ierr)
5009 /* synchro blocks with zcross computation */
5010 /* Copyright INRIA */
5011 SCSREAL_COP *outtbdptr = NULL; /*to store double of outtb*/
5012 SCSINT8_COP *outtbcptr = NULL; /*to store int8 of outtb*/
5013 SCSINT16_COP *outtbsptr = NULL; /*to store int16 of outtb*/
5014 SCSINT32_COP *outtblptr = NULL; /*to store int32 of outtb*/
5015 SCSUINT8_COP *outtbucptr = NULL; /*to store unsigned int8 of outtb */
5016 SCSUINT16_COP *outtbusptr = NULL; /*to store unsigned int16 of outtb */
5017 SCSUINT32_COP *outtbulptr = NULL; /*to store unsigned int32 of outtb */
5020 int i = 0; /* return 0 by default */
5023 /* variable for param */
5024 int *outtbtyp = NULL;
5025 void **outtbptr = NULL;
5032 outtbtyp = scs_imp->outtbtyp;
5033 outtbptr = scs_imp->outtbptr;
5034 funtyp = scs_imp->funtyp;
5035 inplnk = scs_imp->inplnk;
5036 inpptr = scs_imp->inpptr;
5037 zcptr = scs_imp->zcptr;
5039 /* if-then-else blk */
5040 if (funtyp[kf - 1] == -1)
5042 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
5045 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5046 g[zcptr[kf - 1] - 1] = *outtbdptr;
5047 cond = (*outtbdptr <= 0.);
5051 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5052 g[zcptr[kf - 1] - 1] = *outtbdptr;
5053 cond = (*outtbdptr <= 0.);
5057 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5058 g[zcptr[kf - 1] - 1] = (double) * outtbcptr;
5059 cond = (*outtbcptr <= 0);
5063 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5064 g[zcptr[kf - 1] - 1] = (double) * outtbsptr;
5065 cond = (*outtbsptr <= 0);
5069 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5070 g[zcptr[kf - 1] - 1] = (double) * outtblptr;
5071 cond = (*outtblptr <= 0);
5075 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5076 g[zcptr[kf - 1] - 1] = (double) * outtbucptr;
5077 cond = (*outtbucptr <= 0);
5081 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5082 g[zcptr[kf - 1] - 1] = (double) * outtbusptr;
5083 cond = (*outtbusptr <= 0);
5087 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5088 g[zcptr[kf - 1] - 1] = (double) * outtbulptr;
5089 cond = (*outtbulptr <= 0);
5092 default : /* Add a message here */
5106 else if (funtyp[kf - 1] == -2)
5108 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
5111 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5112 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5114 g[zcptr[kf - 1] - 1 + jj] = *outtbdptr - (double)(jj + 2);
5116 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
5120 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5121 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5123 g[zcptr[kf - 1] - 1 + jj] = *outtbdptr - (double)(jj + 2);
5125 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
5129 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5130 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5132 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbcptr - (double)(jj + 2);
5134 i = Max(Min((int) * outtbcptr, scs_imp->blocks[kf - 1].nevout), 1);
5138 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5139 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5141 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbsptr - (double)(jj + 2);
5143 i = Max(Min((int) * outtbsptr, scs_imp->blocks[kf - 1].nevout), 1);
5147 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5148 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5150 g[zcptr[kf - 1] - 1 + jj] = (double) * outtblptr - (double)(jj + 2);
5152 i = Max(Min((int) * outtblptr, scs_imp->blocks[kf - 1].nevout), 1);
5156 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5157 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5159 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbucptr - (double)(jj + 2);
5161 i = Max(Min((int) * outtbucptr, scs_imp->blocks[kf - 1].nevout), 1);
5165 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5166 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5168 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbusptr - (double)(jj + 2);
5170 i = Max(Min((int) * outtbusptr, scs_imp->blocks[kf - 1].nevout), 1);
5174 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5175 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5177 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbulptr - (double)(jj + 2);
5179 i = Max(Min((int) * outtbulptr, scs_imp->blocks[kf - 1].nevout), 1);
5182 default : /* Add a message here */
5188 } /* synchro_g_nev */
5189 /*--------------------------------------------------------------------------*/
5191 static void FREE_blocks()
5194 for (kf = 0; kf < nblk; ++kf)
5196 if (Blocks[kf].insz != NULL)
5198 FREE(Blocks[kf].insz);
5204 if (Blocks[kf].inptr != NULL)
5206 FREE(Blocks[kf].inptr);
5212 if (Blocks[kf].outsz != NULL)
5214 FREE(Blocks[kf].outsz);
5220 if (Blocks[kf].outptr != NULL)
5222 FREE(Blocks[kf].outptr);
5228 if (Blocks[kf].oparsz != NULL)
5230 FREE(Blocks[kf].oparsz);
5236 if (Blocks[kf].ozsz != NULL)
5238 FREE(Blocks[kf].ozsz);
5244 if (Blocks[kf].label != NULL)
5246 FREE(Blocks[kf].label);
5252 if (Blocks[kf].evout != NULL)
5254 FREE(Blocks[kf].evout);
5263 if (nx > 0) FREE(xprop);
5265 if (nmod > 0) FREE(mod);
5267 if (ng > 0) FREE(g);
5271 /*--------------------------------------------------------------------------*/
5272 /* Subroutine funnum */
5273 int C2F(funnum)(char * fname)
5277 while ( tabsim[i].name != (char *) NULL)
5279 if ( strcmp(fname, tabsim[i].name) == 0 ) return(i + 1);
5282 ln = (int)strlen(fname);
5284 //TODO: see in dynamic_lin how to check if a function os already link to Scilab
5285 //C2F(iislink)(fname, &loc);
5286 //C2F(iislink)(fname, &loc);
5287 if (loc >= 0) return(ntabsim + (int)loc + 1);
5290 /*--------------------------------------------------------------------------*/
5291 int get_phase_simulation(void)
5295 /*--------------------------------------------------------------------------*/
5296 void do_cold_restart(void)
5301 /*--------------------------------------------------------------------------*/
5302 /* get_scicos_time : return the current
5305 double get_scicos_time(void)
5309 /*--------------------------------------------------------------------------*/
5310 /* get_block_number : return the current
5313 int get_block_number(void)
5315 return C2F(curblk).kfun;
5317 /*--------------------------------------------------------------------------*/
5318 /* set_block_error : set an error number
5321 void set_block_error(int err)
5325 /*--------------------------------------------------------------------------*/
5326 /* Coserror : copy an error message
5327 * in coserr.buf an set block_error to
5332 #define vsnprintf _vsnprintf
5337 void Coserror(const char *fmt, ...)
5345 retval = vsnprintf(coserr.buf, 4095, fmt, ap);
5347 retval = vsprintf(coserr.buf, fmt, ap);
5352 coserr.buf[0] = '\0';
5357 /* coserror use error number 10 */
5360 /*--------------------------------------------------------------------------*/
5361 /* get_block_error : get the block error
5364 int get_block_error()
5366 return *block_error;
5368 /*--------------------------------------------------------------------------*/
5369 void end_scicos_sim()
5371 C2F(coshlt).halt = 2;
5374 /*--------------------------------------------------------------------------*/
5375 /* get_pointer_xproperty */
5376 int* get_pointer_xproperty()
5378 return &xprop[-1 + xptr[C2F(curblk).kfun]];
5380 /*--------------------------------------------------------------------------*/
5381 /* get_Npointer_xproperty */
5382 int get_npointer_xproperty()
5384 return Blocks[C2F(curblk).kfun - 1].nx;
5386 /*--------------------------------------------------------------------------*/
5387 /* set_pointer_xproperty */
5388 void set_pointer_xproperty(int* pointer)
5391 for (i = 0; i < Blocks[C2F(curblk).kfun - 1].nx; i++)
5393 Blocks[C2F(curblk).kfun - 1].xprop[i] = pointer[i];
5396 /*--------------------------------------------------------------------------*/
5398 void Set_Jacobian_flag(int flag)
5400 Jacobian_Flag = flag;
5403 /*--------------------------------------------------------------------------*/
5404 /* Get_Jacobian_ci et Get_Jacobian_cj were called by the C file only produced
5405 by Modelicac v 1.11.2 */
5406 /* double Get_Jacobian_ci(void)
5410 /*--------------------------------------------------------------------------*/
5411 /* double Get_Jacobian_cj(void)
5415 /*--------------------------------------------------------------------------*/
5416 /* Fonction called by the C file produced by Modelicac 1.7.3 and 1.12.1 */
5417 double Get_Jacobian_parameter(void)
5421 /*--------------------------------------------------------------------------*/
5422 double Get_Scicos_SQUR(void)
5426 /*--------------------------------------------------------------------------*/
5427 static int Jacobians(long int Neq, realtype tt, N_Vector yy, N_Vector yp,
5428 N_Vector resvec, realtype cj, void *jdata, DenseMat Jacque,
5429 N_Vector tempv1, N_Vector tempv2, N_Vector tempv3)
5432 double *xc = NULL, *xcdot = NULL, *residual = NULL;
5434 int i = 0, j = 0, n = 0, nx = 0, ni = 0, no = 0, nb = 0, m = 0, flag = 0;
5435 double *RX = NULL, *Fx = NULL, *Fu = NULL, *Gx = NULL, *Gu = NULL, *ERR1 = NULL, *ERR2 = NULL;
5436 double *Hx = NULL, *Hu = NULL, *Kx = NULL, *Ku = NULL, *HuGx = NULL, *FuKx = NULL, *FuKuGx = NULL, *HuGuKx = NULL;
5441 /* taill1= 3*n+(n+ni)*(n+no)+nx(2*nx+ni+2*m+no)+m*(2*m+no+ni)+2*ni*no*/
5442 double inc = 0., inc_inv = 0., xi = 0., xpi = 0., srur = 0.;
5443 realtype *Jacque_col = NULL;
5448 double *ewt_data = NULL;
5452 data = (UserData) jdata;
5455 flag = IDAGetCurrentStep(data->ida_mem, &hh);
5458 *ierr = 200 + (-flag);
5462 flag = IDAGetErrWeights(data->ida_mem, ewt);
5465 *ierr = 200 + (-flag);
5469 ewt_data = NV_DATA_S(ewt);
5470 xc = (double *) N_VGetArrayPointer(yy);
5471 xcdot = (double *) N_VGetArrayPointer(yp);
5472 /*residual=(double *) NV_DATA_S(resvec);*/
5474 // CJ=(double)cj; // for fonction Get_Jacobian_cj
5475 CJJ = (double)cj; // returned by Get_Jacobian_parameter
5477 srur = (double) RSqrt(UNIT_ROUNDOFF);
5479 if (AJacobian_block > 0)
5481 nx = Blocks[AJacobian_block - 1].nx; /* quant on est là cela signifie que AJacobian_block>0 */
5482 no = Blocks[AJacobian_block - 1].nout;
5483 ni = Blocks[AJacobian_block - 1].nin;
5484 y = (double **)Blocks[AJacobian_block - 1].outptr; /*for compatibility */
5485 u = (double **)Blocks[AJacobian_block - 1].inptr; /*warning pointer of y and u have changed to void ***/
5497 residual = (double *)data->rwork;
5498 ERR1 = residual + n;
5501 Fx = RX + (n + ni) * (n + no); /* car (nx+ni)*(nx+no) peut etre > `a n*n*/
5509 HuGx = Ku + ni * no;
5510 FuKx = HuGx + m * nx;
5511 FuKuGx = FuKx + nx * m;
5512 HuGuKx = FuKuGx + nx * nx;
5513 /* HuGuKx+m*m; => m*m=size of HuGuKx */
5514 /* ------------------ Numerical Jacobian--->> Hx,Kx */
5516 /* read residuals;*/
5518 Jdoit(&ttx, xc, xcdot, residual, &job);
5519 if (*ierr < 0) return -1;
5521 /* "residual" already contains the current residual,
5522 so the first call to Jdoit can be remoevd*/
5524 for (i = 0; i < m; i++)
5525 for (j = 0; j < ni; j++)
5526 Kx[j + i * ni] = u[j][0];
5528 for (i = 0; i < m; i++)
5532 inc = MAX( srur * MAX( ABS(xi), ABS(hh * xpi)), ONE / ewt_data[i] );
5533 if (hh * xpi < ZERO) inc = -inc;
5534 inc = (xi + inc) - xi;
5537 inc = MAX( srur * ABS(hh*xpi),ONE );
5538 if (hh*xpi < ZERO) inc = -inc;
5539 inc = (xpi + inc) - xi;
5542 // xcdot[i] += CJ*inc;
5544 xcdot[i] += CJJ * inc;
5545 /*a= Max(abs(H[0]*xcdot[i]),abs(1.0/Ewt[i]));
5546 b= Max(1.0,abs(xc[i]));
5547 del=SQUR[0]*Max(a,b); */
5548 job = 0; /* read residuals */
5549 Jdoit(&ttx, xc, xcdot, ERR2, &job);
5550 if (*ierr < 0) return -1;
5551 inc_inv = ONE / inc;
5552 for (j = 0; j < m; j++)
5553 Hx[m * i + j] = (ERR2[j] - residual[j]) * inc_inv;
5554 for (j = 0; j < ni; j++)
5555 Kx[j + i * ni] = (u[j][0] - Kx[j + i * ni]) * inc_inv;
5559 /*----- Numerical Jacobian--->> Hu,Ku */
5561 if (AJacobian_block == 0)
5563 for (j = 0; j < m; j++)
5565 Jacque_col = DENSE_COL(Jacque, j);
5566 for (i = 0; i < m; i++)
5568 Jacque_col[i] = Hx[i + j * m];
5571 C2F(ierode).iero = *ierr;
5574 /****------------------***/
5576 Jdoit(&ttx, xc, xcdot, ERR1, &job);
5577 for (i = 0; i < no; i++)
5578 for (j = 0; j < ni; j++)
5579 Ku[j + i * ni] = u[j][0];
5581 for (i = 0; i < no; i++)
5584 inc = srur * MAX( ABS(ysave), 1);
5585 inc = (ysave + inc) - ysave;
5586 /*del=SQUR[0]* Max(1.0,abs(y[i][0]));
5587 del=(y[i][0]+del)-y[i][0];*/
5589 job = 2; /* applying y[i][0] to the output of imp block*/
5590 Jdoit(&ttx, xc, xcdot, ERR2, &job);
5591 if (*ierr < 0) return -1;
5592 inc_inv = ONE / inc;
5593 for (j = 0; j < m; j++)
5594 Hu[m * i + j] = (ERR2[j] - ERR1[j]) * inc_inv;
5595 for (j = 0; j < ni; j++)
5596 Ku[j + i * ni] = (u[j][0] - Ku[j + i * ni]) * inc_inv;
5599 /*----------------------------------------------*/
5600 job = 1; /* read jacobian through flag=10; */
5601 Jdoit(&ttx, xc, xcdot, &Fx[-m], &job);/* Filling up the FX:Fu:Gx:Gu*/
5602 if (*block_error != 0) sciprint(_("\n error in Jacobian"));
5603 /*-------------------------------------------------*/
5605 Multp(Fu, Ku, RX, nx, ni, ni, no);
5606 Multp(RX, Gx, FuKuGx, nx, no, no, nx);
5608 for (j = 0; j < nx; j++)
5610 Jacque_col = DENSE_COL(Jacque, j + m);
5611 for (i = 0; i < nx; i++)
5613 Jacque_col[i + m] = Fx[i + j * nx] + FuKuGx[i + j * nx];
5617 Multp(Hu, Gx, HuGx, m, no, no, nx);
5619 for (i = 0; i < nx; i++)
5621 Jacque_col = DENSE_COL(Jacque, i + m);
5622 for (j = 0; j < m; j++)
5624 Jacque_col[j] = HuGx[j + i * m];
5628 Multp(Fu, Kx, FuKx, nx, ni, ni, m);
5630 for (i = 0; i < m; i++)
5632 Jacque_col = DENSE_COL(Jacque, i);
5633 for (j = 0; j < nx; j++)
5635 Jacque_col[j + m] = FuKx[j + i * nx];
5640 Multp(Hu, Gu, RX, m, no, no, ni);
5641 Multp(RX, Kx, HuGuKx, m, ni, ni, m);
5643 for (j = 0; j < m; j++)
5645 Jacque_col = DENSE_COL(Jacque, j);
5646 for (i = 0; i < m; i++)
5648 Jacque_col[i] = Hx[i + j * m] + HuGuKx[i + j * m];
5652 /* chr='Z'; printf("\n t=%g",ttx); DISP(Z,n,n,chr);*/
5653 C2F(ierode).iero = *ierr;
5657 /*----------------------------------------------------*/
5658 static void Multp(double *A, double *B, double *R, int ra, int rb, int ca, int cb)
5660 int i = 0, j = 0, k = 0;
5661 /*if (ca!=rb) sciprint(_("\n Error in matrix multiplication"));*/
5662 for (i = 0; i < ra; i++)
5663 for (j = 0; j < cb; j++)
5665 R[i + ra * j] = 0.0;
5666 for (k = 0; k < ca; k++)
5667 R[i + ra * j] += A[i + k * ra] * B[k + j * rb];
5671 /*--------------------------------------------------------------------------*/
5672 int read_xml_initial_states(int nvar, const char * xmlfile, char **ids, double *svars)
5674 ezxml_t model, elements;
5675 int result = 0, i = 0;
5678 if (nvar == 0) return 0;
5680 for (i = 0; i < nvar; i++)
5682 if (strcmp(ids[i], "") != 0)
5688 if (result == 0) return 0;
5690 model = ezxml_parse_file(xmlfile);
5694 sciprint(_("Error: Cannot find file '%s'.\n"), xmlfile);
5695 return -1;/* file does not exist*/
5698 elements = ezxml_child(model, "elements");
5699 for (i = 0; i < nvar; i++)
5702 result = read_id(&elements, ids[i], &vr);
5703 if (result == 1) svars[i] = vr;
5708 /*--------------------------------------------------------------------------*/
5709 static int read_id(ezxml_t *elements, char *id, double *value)
5711 char V1[100], V2[100];
5712 int ok = 0, i = 0, ln = 0;
5714 if (strcmp(id, "") == 0) return 0;
5715 ok = search_in_child(elements, id, V1);
5718 /*sciprint(_("Cannot find: %s=%s \n"),id,V1); */
5723 if (Convert_number(V1, value) != 0)
5725 ln = (int)(strlen(V1));
5728 for (i = 1; i <= ln - 2; i++) V2[i - 1] = V1[i];
5730 ok = read_id(elements, V2, value);
5737 /* printf("\n ---->>>%s= %g",V1,*value);*/
5742 /*--------------------------------------------------------------------------*/
5743 int Convert_number(char *s, double *out)
5748 d = strtod(s, &endp);
5749 if (s != endp && *endp == '\0')
5751 /* printf(" It's a float with value %g ", d); */
5757 l = strtol(s, &endp, 0);
5758 if (s != endp && *endp == '\0')
5760 /*printf(" It's an int with value %ld ", 1); */
5766 /*printf(" string "); */
5771 /*--------------------------------------------------------------------------*/
5772 int write_xml_states(int nvar, const char * xmlfile, char **ids, double *x)
5774 ezxml_t model, elements;
5775 int result = 0, i = 0, err = 0;
5780 if (nvar == 0) return 0;
5782 for (i = 0; i < nvar; i++)
5784 if (strcmp(ids[i], "") != 0)
5790 if (result == 0) return 0;
5792 xv = MALLOC(nvar * sizeof(char*));
5793 for (i = 0; i < nvar; i++)
5795 xv[i] = MALLOC(nvar * 100 * sizeof(char));
5796 sprintf(xv[i], "%g", x[i]);
5799 model = ezxml_parse_file(xmlfile);
5802 sciprint(_("Error: Cannot find file '%s'.\n"), xmlfile);
5803 for (i = 0; i < nvar; i++)
5808 return -1;/* file does not exist */
5811 elements = ezxml_child(model, "elements");
5813 for (i = 0; i < nvar; i++)
5815 if (strcmp(ids[i], "") == 0) continue;
5816 result = write_in_child(&elements, ids[i], xv[i]);
5819 /* sciprint(_("cannot find %s in '%s' \n"),ids[i],xmlfile); */
5820 /* err= -1;*/ /* Variable does not exist*/
5824 s = ezxml_toxml(model);
5828 wcfopen(fd, (char*)xmlfile, "wb");
5831 sciprint(_("Error: cannot write to '%s' \n"), xmlfile);
5832 for (i = 0; i < nvar; i++)
5837 return -3;/* cannot write to file*/
5845 /*--------------------------------------------------------------------------*/
5846 int C2F(fx)(double *x, double *residual) /* used for homotopy*/
5848 double *xdot = NULL, t = 0;
5852 C2F(ierode).iero = 0;
5853 odoit(&t, x, xdot, residual);
5854 C2F(ierode).iero = *ierr;
5857 /*--------------------------------------------------------------------------*/
5858 int rho_(double *a, double *L, double *x, double *rho, double *rpar, int *ipar) /* used for homotopy*/
5864 for (i = 0; i < N; i++)
5865 rho[i] += (-1 + *L) * a[i];
5868 /*--------------------------------------------------------------------------*/
5869 int rhojac_(double *a, double *lambda, double *x, double *jac, int *col, double *rpar, int *ipar) /* used for homotopy*/
5871 /* MATRIX [d_RHO/d_LAMBDA, d_RHO/d_X_col] */
5873 double *work = NULL;
5875 double inc = 0., inc_inv = 0., xi = 0., srur = 0.;
5879 for (j = 0; j < N; j++)
5884 if ((work = (double *) MALLOC(N * sizeof(double))) == NULL)
5889 rho_(a, lambda, x, work, rpar, ipar);
5892 inc = srur * Max(fabs(xi), 1);
5893 inc = (xi + inc) - xi;
5897 rho_(a, lambda, x, jac, rpar, ipar);
5898 inc_inv = 1.0 / inc;
5900 for (j = 0; j < N; j++)
5901 jac[j] = (jac[j] - work[j]) * inc_inv;