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 GetDynFunc(i, &Blocks[kf].funpt);
533 if ( Blocks[kf].funpt == (voidf) 0)
535 sciprint(_("Function not found\n"));
536 *ierr = 1000 + kf + 1;
540 Blocks[kf].scsptr = 0; /* this is done for being able to test if a block
541 is a scilab block in the debugging phase when
545 /* 2 : Dimension properties */
546 Blocks[kf].ztyp = ztyp[kf + 1];
547 Blocks[kf].nx = xptr[kf + 2] - xptr[kf + 1]; /* continuuous state dimension*/
548 Blocks[kf].ng = zcptr[kf + 2] - zcptr[kf + 1]; /* number of zero crossing surface*/
549 Blocks[kf].nz = zptr[kf + 2] - zptr[kf + 1]; /* number of double discrete state*/
550 Blocks[kf].noz = ozptr[kf + 2] - ozptr[kf + 1]; /* number of other discrete state*/
551 Blocks[kf].nrpar = rpptr[kf + 2] - rpptr[kf + 1]; /* size of double precision parameter vector*/
552 Blocks[kf].nipar = ipptr[kf + 2] - ipptr[kf + 1]; /* size of integer precision parameter vector*/
553 Blocks[kf].nopar = opptr[kf + 2] - opptr[kf + 1]; /* number of other parameters (matrix, data structure,..)*/
554 Blocks[kf].nin = inpptr[kf + 2] - inpptr[kf + 1]; /* number of input ports */
555 Blocks[kf].nout = outptr[kf + 2] - outptr[kf + 1]; /* number of output ports */
557 /* 3 : input port properties */
558 /* in insz, we store :
559 * - insz[0..nin-1] : first dimension of input ports
560 * - insz[nin..2*nin-1] : second dimension of input ports
561 * - insz[2*nin..3*nin-1] : type of data of input ports
563 /* allocate size and pointer arrays (number of input ports)*/
564 Blocks[kf].insz = NULL;
565 Blocks[kf].inptr = NULL;
566 if (Blocks[kf].nin != 0)
568 if ((Blocks[kf].insz = MALLOC(Blocks[kf].nin * 3 * sizeof(int))) == NULL )
574 if ((Blocks[kf].inptr = MALLOC(Blocks[kf].nin * sizeof(double*))) == NULL )
581 for (in = 0; in < Blocks[kf].nin; in++)
583 lprt = inplnk[inpptr[kf + 1] + in];
584 Blocks[kf].inptr[in] = outtbptr[lprt - 1]; /* pointer on the data*/
585 Blocks[kf].insz[in] = outtbsz[lprt - 1]; /* row dimension of the input port*/
586 Blocks[kf].insz[Blocks[kf].nin + in] = outtbsz[(lprt - 1) + nlnk]; /* column dimension of the input port*/
587 Blocks[kf].insz[2 * Blocks[kf].nin + in] = outtbtyp[lprt - 1]; /*type of data of the input port*/
589 /* 4 : output port properties */
590 /* in outsz, we store :
591 * - outsz[0..nout-1] : first dimension of output ports
592 * - outsz[nout..2*nout-1] : second dimension of output ports
593 * - outsz[2*nout..3*nout-1] : type of data of output ports
595 /* allocate size and pointer arrays (number of output ports)*/
596 Blocks[kf].outsz = NULL;
597 Blocks[kf].outptr = NULL;
598 if (Blocks[kf].nout != 0)
600 if ((Blocks[kf].outsz = MALLOC(Blocks[kf].nout * 3 * sizeof(int))) == NULL )
606 if ((Blocks[kf].outptr = MALLOC(Blocks[kf].nout * sizeof(double*))) == NULL )
614 for (out = 0; out < Blocks[kf].nout; out++) /*for each output port */
616 lprt = outlnk[outptr[kf + 1] + out];
617 Blocks[kf].outptr[out] = outtbptr[lprt - 1]; /*pointer on data */
618 Blocks[kf].outsz[out] = outtbsz[lprt - 1]; /*row dimension of output port*/
619 Blocks[kf].outsz[Blocks[kf].nout + out] = outtbsz[(lprt - 1) + nlnk]; /*column dimension of output ports*/
620 Blocks[kf].outsz[2 * Blocks[kf].nout + out] = outtbtyp[lprt - 1]; /*type of data of output port */
623 /* 5 : event output port properties */
624 Blocks[kf].evout = NULL;
625 Blocks[kf].nevout = clkptr[kf + 2] - clkptr[kf + 1];
626 if (Blocks[kf].nevout != 0)
628 if ((Blocks[kf].evout = CALLOC(Blocks[kf].nevout, sizeof(double))) == NULL )
636 /* 6 : pointer on the begining of the double discrete state array ( z) */
637 Blocks[kf].z = &(z__[zptr[kf + 1] - 1]);
639 /* 7 : type, size and pointer on the other discrete states data structures (oz) */
640 Blocks[kf].ozsz = NULL;
641 if (Blocks[kf].noz == 0)
643 Blocks[kf].ozptr = NULL;
644 Blocks[kf].oztyp = NULL;
648 Blocks[kf].ozptr = &(oz[ozptr[kf + 1] - 1]);
649 if ((Blocks[kf].ozsz = MALLOC(Blocks[kf].noz * 2 * sizeof(int))) == NULL )
655 for (i = 0; i < Blocks[kf].noz; i++)
657 Blocks[kf].ozsz[i] = ozsz[(ozptr[kf + 1] - 1) + i];
658 Blocks[kf].ozsz[i + Blocks[kf].noz] = ozsz[(ozptr[kf + 1] - 1 + noz) + i];
660 Blocks[kf].oztyp = &(oztyp[ozptr[kf + 1] - 1]);
663 /* 8 : pointer on the begining of the double parameter array ( rpar ) */
664 Blocks[kf].rpar = &(rpar[rpptr[kf + 1] - 1]);
666 /* 9 : pointer on the begining of the integer parameter array ( ipar ) */
667 Blocks[kf].ipar = &(ipar[ipptr[kf + 1] - 1]);
669 /* 10 : type, size and pointer on the other parameters data structures (opar) */
670 Blocks[kf].oparsz = NULL;
671 if (Blocks[kf].nopar == 0)
673 Blocks[kf].oparptr = NULL;
674 Blocks[kf].opartyp = NULL;
678 Blocks[kf].oparptr = &(opar[opptr[kf + 1] - 1]);
679 if ((Blocks[kf].oparsz = MALLOC(Blocks[kf].nopar * 2 * sizeof(int))) == NULL)
685 for (i = 0; i < Blocks[kf].nopar; i++)
687 Blocks[kf].oparsz[i] = oparsz[(opptr[kf + 1] - 1) + i];
688 Blocks[kf].oparsz[i + Blocks[kf].nopar] = oparsz[(opptr[kf + 1] - 1 + nopar) + i];
690 Blocks[kf].opartyp = &(opartyp[opptr[kf + 1] - 1]);
693 /* 10 : pointer on the beginning of the residual array (res) */
694 Blocks[kf].res = NULL;
695 if (Blocks[kf].nx != 0)
697 if ((Blocks[kf].res = MALLOC(Blocks[kf].nx * sizeof(double))) == NULL)
705 /* 11 : block label (label) */
706 i1 = izptr[kf + 2] - izptr[kf + 1];
707 if ((Blocks[kf].label = MALLOC(sizeof(char) * (i1 + 1))) == NULL)
713 Blocks[kf].label[i1] = '\0';
714 C2F(cvstr)(&i1, &(iz[izptr[kf + 1] - 1]), Blocks[kf].label, &job, i1);
716 /* 12 : block array of crossed surfaces (jroot) */
717 Blocks[kf].jroot = NULL;
718 if (Blocks[kf].ng != 0)
720 if ((Blocks[kf].jroot = CALLOC(Blocks[kf].ng, sizeof(int))) == NULL)
728 /* 13 : block work array (work) */
729 Blocks[kf].work = (void **)(((double *)work) + kf);
731 /* 14 : block modes array (mode) */
732 Blocks[kf].nmode = modptr[kf + 2] - modptr[kf + 1];
733 if (Blocks[kf].nmode != 0)
735 Blocks[kf].mode = &(mod[modptr[kf + 1] - 1]);
738 /* 15 : block xprop array (xprop) */
739 Blocks[kf].xprop = NULL;
740 if (Blocks[kf].nx != 0)
742 Blocks[kf].xprop = &(xprop[xptr[kf + 1] - 1]);
745 /* 16 : pointer on the zero crossing surface computation function of the block (g) */
747 if (Blocks[kf].ng != 0)
749 Blocks[kf].g = &(g[zcptr[kf + 1] - 1]);
752 /** all block properties are stored in the Blocks array **/
758 if ((iwa = MALLOC(sizeof(int) * (*nevts))) == NULL)
766 /* save ptr of scicos in import structure */
767 C2F(makescicosimport)(x, &nx, &xptr[1], &zcptr[1], z__, &nz, &zptr[1],
768 &noz, oz, ozsz, oztyp, &ozptr[1],
769 g, &ng, mod, &nmod, &modptr[1], iz, &izptr[1],
770 &inpptr[1], &inplnk[1], &outptr[1], &outlnk[1],
771 outtbptr, outtbsz, outtbtyp,
773 &nlnk, rpar, &rpptr[1], ipar, &ipptr[1],
774 opar, oparsz, opartyp, &opptr[1],
775 &nblk, subscr, nsubs,
776 &tevts[1], &evtspt[1], nevts, pointi,
777 &iord[1], &niord, &oord[1], &noord, &zord[1], &nzord,
778 funptr, &funtyp[1], &ztyp[1],
779 &cord[1], &ncord, &ordclk[1], &nordclk, &clkptr[1],
780 &ordptr[1], &nordptr, &critev[1], iwa, Blocks,
781 t0, tf, &Atol, &rtol, &ttol, &deltat, &hmax,
784 if (*flag__ == 1) /*start*/
786 /* initialisation des blocks */
787 for (kf = 0; kf < nblk; ++kf)
789 *(Blocks[kf].work) = NULL;
795 kfun0 = C2F(curblk).kfun;
798 C2F(curblk).kfun = kfun0;
802 else if (*flag__ == 2) /*run*/
806 if (C2F(cmsolver).solver == 0) /* LSODAR: Method: DYNAMIC, Nonlinear solver= DYNAMIC */
810 else if (C2F(cmsolver).solver == 1) /* CVODE: Method: BDF, Nonlinear solver= NEWTON */
814 else if (C2F(cmsolver).solver == 2) /* CVODE: Method: BDF, Nonlinear solver= FUNCTIONAL */
818 else if (C2F(cmsolver).solver == 3) /* CVODE: Method: ADAMS, Nonlinear solver= NEWTON */
822 else if (C2F(cmsolver).solver == 4) /* CVODE: Method: ADAMS, Nonlinear solver= FUNCTIONAL */
826 else if (C2F(cmsolver).solver == 5) /* DOPRI: Method: Dormand-Prince, Nonlinear solver= */
830 else if (C2F(cmsolver).solver == 6) /* RK45: Method: Runge-Kutta, Nonlinear solver= */
834 else if (C2F(cmsolver).solver == 7) /* ImpRK45: Method: Runge-Kutta, Nonlinear solver= FIXED-POINT */
838 else if (C2F(cmsolver).solver == 100) /* IDA : Method: , Nonlinear solver= */
844 /* add a warning message please */
849 kfun0 = C2F(curblk).kfun;
852 C2F(curblk).kfun = kfun0;
856 else if (*flag__ == 3) /*finish*/
858 /* fermeture des blocks */
861 else if (*flag__ == 4) /*linear*/
867 if ((W = MALLOC(sizeof(double) * (Max(nx, ng)))) == NULL )
875 /*---------à la place de old simblk--------*/
876 /* C2F(simblk)(&nx, t0, x, W); */
878 if (ng > 0 && nmod > 0)
880 zdoit(t0, x, x + nx, W); /* updating modes as a function of state values; this was necessary in iGUI*/
882 for (jj = 0; jj < nx; jj++) W[jj] = 0.0;
883 C2F(ierode).iero = 0;
885 if (C2F(cmsolver).solver < 100)
891 odoit(t0, x, x + nx, W);
893 C2F(ierode).iero = *ierr;
894 /*-----------------------------------------*/
895 for (i = 0; i < nx; ++i)
902 else if (*flag__ == 5) /* initial_KINSOL= "Kinsol" */
904 C2F(ierode).iero = 0;
908 *ierr = C2F(ierode).iero;
915 C2F(clearscicosimport)();
918 /*--------------------------------------------------------------------------*/
920 static int check_flag(void *flagvalue, char *funcname, int opt)
924 /* Check if SUNDIALS function returned NULL pointer - no memory allocated */
925 if (opt == 0 && flagvalue == NULL)
927 sciprint(_("\nSUNDIALS_ERROR: %s() failed - returned NULL pointer\n\n"), funcname);
930 /* Check if flag < 0 */
933 errflag = (int *) flagvalue;
936 sciprint(_("\nSUNDIALS_ERROR: %s() failed with flag = %d\n\n"),
941 /* Check if function returned NULL pointer - no memory allocated */
942 else if (opt == 2 && flagvalue == NULL)
944 sciprint(_("\nMEMORY_ERROR: %s() failed - returned NULL pointer\n\n"), funcname);
951 /*--------------------------------------------------------------------------*/
952 static void cosini(double *told)
954 static scicos_flag flag__ = 0;
957 static int kfune = 0;
960 SCSREAL_COP *outtbd = NULL; /*to save double of outtb*/
961 SCSINT8_COP *outtbc = NULL; /*to save int8 of outtb*/
962 SCSINT16_COP *outtbs = NULL; /*to save int16 of outtb*/
963 SCSINT32_COP *outtbl = NULL; /*to save int32 of outtb*/
964 SCSUINT8_COP *outtbuc = NULL; /*to save unsigned int8 of outtb*/
965 SCSUINT16_COP *outtbus = NULL; /*to save unsigned int16 of outtb*/
966 SCSUINT32_COP *outtbul = NULL; /*to save unsigned int32 of outtb*/
967 int szouttbd = 0; /*size of arrays*/
968 int szouttbc = 0, szouttbs = 0, szouttbl = 0;
969 int szouttbuc = 0, szouttbus = 0, szouttbul = 0;
970 int curouttbd = 0; /*current position in arrays*/
971 int curouttbc = 0, curouttbs = 0, curouttbl = 0;
972 int curouttbuc = 0, curouttbus = 0, curouttbul = 0;
974 int ii = 0, kk = 0; /*local counters*/
975 int sszz = 0; /*local size of element of outtb*/
976 /*Allocation of arrays for outtb*/
977 for (ii = 0; ii < nlnk; ii++)
979 switch (outtbtyp[ii])
982 szouttbd += outtbsz[ii] * outtbsz[ii + nlnk]; /*double real matrix*/
983 outtbd = (SCSREAL_COP *) REALLOC (outtbd, szouttbd * sizeof(SCSREAL_COP));
987 szouttbd += 2 * outtbsz[ii] * outtbsz[ii + nlnk]; /*double complex matrix*/
988 outtbd = (SCSCOMPLEX_COP *) REALLOC (outtbd, szouttbd * sizeof(SCSCOMPLEX_COP));
992 szouttbc += outtbsz[ii] * outtbsz[ii + nlnk]; /*int8*/
993 outtbc = (SCSINT8_COP *) REALLOC (outtbc, szouttbc * sizeof(SCSINT8_COP));
997 szouttbs += outtbsz[ii] * outtbsz[ii + nlnk]; /*int16*/
998 outtbs = (SCSINT16_COP *) REALLOC (outtbs, szouttbs * sizeof(SCSINT16_COP));
1002 szouttbl += outtbsz[ii] * outtbsz[ii + nlnk]; /*int32*/
1003 outtbl = (SCSINT32_COP *) REALLOC (outtbl, szouttbl * sizeof(SCSINT32_COP));
1007 szouttbuc += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint8*/
1008 outtbuc = (SCSUINT8_COP *) REALLOC (outtbuc, szouttbuc * sizeof(SCSUINT8_COP));
1012 szouttbus += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint16*/
1013 outtbus = (SCSUINT16_COP *) REALLOC (outtbus, szouttbus * sizeof(SCSUINT16_COP));
1017 szouttbul += outtbsz[ii] * outtbsz[ii + nlnk]; /*uint32*/
1018 outtbul = (SCSUINT32_COP *) REALLOC (outtbul, szouttbul * sizeof(SCSUINT32_COP));
1021 default : /* Add a message here */
1027 AJacobian_block = 0;
1032 /* initialization (flag 4) */
1033 /* loop on blocks */
1034 C2F(dset)(&ng, &c_b14, g, &c__1);
1036 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1039 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1041 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1042 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1044 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1045 if (funtyp[C2F(curblk).kfun] >= 0) /* debug_block is not called here */
1047 /*callf(told, xd, x, x,g,&flag__);*/
1049 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1050 if (flag__ < 0 && *ierr == 0)
1053 kfune = C2F(curblk).kfun;
1055 if ((Jacobian_Flag == 1) && (AJacobian_block == 0)) AJacobian_block = C2F(curblk).kfun;
1060 C2F(curblk).kfun = kfune;
1065 /* initialization (flag 6) */
1067 for (jj = 1; jj <= ncord; ++jj)
1069 C2F(curblk).kfun = cord[jj];
1070 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1071 if (funtyp[C2F(curblk).kfun] >= 0)
1073 /*callf(told, xd, x, x,g,&flag__);*/
1074 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1084 /* point-fix iterations */
1086 for (i = 1; i <= nblk + 1; ++i) /*for each block*/
1088 /* loop on blocks */
1089 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1091 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
1092 if (funtyp[C2F(curblk).kfun] >= 0)
1094 /*callf(told, xd, x, x,g,&flag__);*/
1095 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1106 for (jj = 1; jj <= ncord; ++jj) /*for each continous block*/
1108 C2F(curblk).kfun = cord[jj];
1109 if (funtyp[C2F(curblk).kfun] >= 0)
1111 /*callf(told, xd, x, x,g,&flag__);*/
1112 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1122 /*comparison between outtb and arrays*/
1130 for (jj = 0; jj < nlnk; jj++)
1132 switch (outtbtyp[jj]) /*for each type of ports*/
1135 outtbdptr = (SCSREAL_COP *)outtbptr[jj]; /*double real matrix*/
1136 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1137 for (kk = 0; kk < sszz; kk++)
1139 if (outtbdptr[kk] != (SCSREAL_COP)outtbd[curouttbd + kk]) goto L30;
1145 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[jj]; /*double complex matrix*/
1146 sszz = 2 * outtbsz[jj] * outtbsz[jj + nlnk];
1147 for (kk = 0; kk < sszz; kk++)
1149 if (outtbdptr[kk] != (SCSCOMPLEX_COP)outtbd[curouttbd + kk]) goto L30;
1155 outtbcptr = (SCSINT8_COP *)outtbptr[jj]; /*int8*/
1156 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1157 for (kk = 0; kk < sszz; kk++)
1159 if (outtbcptr[kk] != (SCSINT8_COP)outtbc[curouttbc + kk]) goto L30;
1165 outtbsptr = (SCSINT16_COP *)outtbptr[jj]; /*int16*/
1166 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1167 for (kk = 0; kk < sszz; kk++)
1169 if (outtbsptr[kk] != (SCSINT16_COP)outtbs[curouttbs + kk]) goto L30;
1175 outtblptr = (SCSINT32_COP *)outtbptr[jj]; /*int32*/
1176 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1177 for (kk = 0; kk < sszz; kk++)
1179 if (outtblptr[kk] != (SCSINT32_COP)outtbl[curouttbl + kk]) goto L30;
1185 outtbucptr = (SCSUINT8_COP *)outtbptr[jj]; /*uint8*/
1186 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1187 for (kk = 0; kk < sszz; kk++)
1189 if (outtbucptr[kk] != (SCSUINT8_COP)outtbuc[curouttbuc + kk]) goto L30;
1195 outtbusptr = (SCSUINT16_COP *)outtbptr[jj]; /*uint16*/
1196 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1197 for (kk = 0; kk < sszz; kk++)
1199 if (outtbusptr[kk] != (SCSUINT16_COP)outtbus[curouttbus + kk]) goto L30;
1205 outtbulptr = (SCSUINT32_COP *)outtbptr[jj]; /*uint32*/
1206 sszz = outtbsz[jj] * outtbsz[jj + nlnk];
1207 for (kk = 0; kk < sszz; kk++)
1209 if (outtbulptr[kk] != (SCSUINT32_COP)outtbul[curouttbul + kk]) goto L30;
1214 default : /* Add a message here */
1222 /*Save data of outtb in arrays*/
1230 for (ii = 0; ii < nlnk; ii++) /*for each link*/
1232 switch (outtbtyp[ii]) /*switch to type of outtb object*/
1235 outtbdptr = (SCSREAL_COP *)outtbptr[ii]; /*double real matrix*/
1236 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1237 C2F(dcopy)(&sszz, outtbdptr, &c__1, &outtbd[curouttbd], &c__1);
1242 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[ii]; /*double complex matrix*/
1243 sszz = 2 * outtbsz[ii] * outtbsz[ii + nlnk];
1244 C2F(dcopy)(&sszz, outtbdptr, &c__1, &outtbd[curouttbd], &c__1);
1249 outtbcptr = (SCSINT8_COP *)outtbptr[ii]; /*int8*/
1250 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1251 for (kk = 0; kk < sszz; kk++) outtbc[curouttbc + kk] = (SCSINT8_COP)outtbcptr[kk];
1256 outtbsptr = (SCSINT16_COP *)outtbptr[ii]; /*int16*/
1257 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1258 for (kk = 0; kk < sszz; kk++) outtbs[curouttbs + kk] = (SCSINT16_COP)outtbsptr[kk];
1263 outtblptr = (SCSINT32_COP *)outtbptr[ii]; /*int32*/
1264 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1265 for (kk = 0; kk < sszz; kk++) outtbl[curouttbl + kk] = (SCSINT32_COP)outtblptr[kk];
1270 outtbucptr = (SCSUINT8_COP *)outtbptr[ii]; /*uint8*/
1271 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1272 for (kk = 0; kk < sszz; kk++) outtbuc[curouttbuc + kk] = (SCSUINT8_COP)outtbucptr[kk];
1277 outtbusptr = (SCSUINT16_COP *)outtbptr[ii]; /*uint16*/
1278 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1279 for (kk = 0; kk < sszz; kk++) outtbus[curouttbus + kk] = (SCSUINT16_COP)outtbusptr[kk];
1284 outtbulptr = (SCSUINT32_COP *)outtbptr[ii]; /*uint32*/
1285 sszz = outtbsz[ii] * outtbsz[ii + nlnk];
1286 for (kk = 0; kk < sszz; kk++) outtbul[curouttbul + kk] = (SCSUINT32_COP)outtbulptr[kk];
1290 default : /* Add a message here */
1299 /*--------------------------------------------------------------------------*/
1300 static void cossim(double *told)
1302 /* System generated locals */
1305 //** used for the [stop] button
1306 static char CommandToUnstack[1024];
1307 static int CommandLength = 0;
1308 static int SeqSync = 0;
1311 /* Local variables */
1312 static scicos_flag flag__ = 0;
1313 static int ierr1 = 0;
1314 static int j = 0, k = 0;
1315 static double t = 0.;
1317 static double rhotmp = 0., tstop = 0.;
1318 static int inxsci = 0;
1319 static int kpo = 0, kev = 0;
1320 int Discrete_Jump = 0;
1321 int *jroot = NULL, *zcros = NULL;
1322 realtype reltol = 0., abstol = 0.;
1324 void *cvode_mem = NULL;
1325 int flag = 0, flagr = 0;
1330 if ((jroot = MALLOC(sizeof(int) * ng)) == NULL )
1337 for ( jj = 0 ; jj < ng ; jj++ )
1343 if ((zcros = MALLOC(sizeof(int) * ng)) == NULL )
1346 if (ng > 0) FREE(jroot);
1351 reltol = (realtype) rtol;
1352 abstol = (realtype) Atol; /* Ith(abstol,1) = realtype) Atol;*/
1354 if (*neq > 0) /* Unfortunately CVODE does not work with NEQ==0 */
1356 y = N_VNewEmpty_Serial(*neq);
1357 if (check_flag((void *)y, "N_VNewEmpty_Serial", 0))
1360 if (ng > 0) FREE(jroot);
1361 if (ng > 0) FREE(zcros);
1369 /* Set extension of Sundials for scicos */
1370 set_sundials_with_extension(TRUE);
1372 switch (C2F(cmsolver).solver)
1375 cvode_mem = LSodarCreate(neq, ng); /* Create the lsodar problem */
1378 cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
1381 cvode_mem = CVodeCreate(CV_BDF, CV_FUNCTIONAL);
1384 cvode_mem = CVodeCreate(CV_ADAMS, CV_NEWTON);
1387 cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);
1390 cvode_mem = CVodeCreate(CV_DOPRI, CV_FUNCTIONAL);
1393 cvode_mem = CVodeCreate(CV_ExpRK, CV_FUNCTIONAL);
1396 cvode_mem = CVodeCreate(CV_ImpRK, CV_FUNCTIONAL);
1400 /* cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);*/
1402 if (check_flag((void *)cvode_mem, "CVodeCreate", 0))
1405 N_VDestroy_Serial(y);
1411 if (!C2F(cmsolver).solver)
1413 flag = LSodarMalloc(cvode_mem, simblklsodar, T0, y, CV_SS, reltol, &abstol);
1416 flag = CVodeMalloc(cvode_mem, simblk, T0, y, CV_SS, reltol, &abstol);
1417 if (check_flag(&flag, "CVodeMalloc", 1))
1419 *ierr = 300 + (-flag);
1424 if (!C2F(cmsolver).solver)
1426 flag = LSodarRootInit(cvode_mem, ng, grblklsodar, NULL);
1429 flag = CVodeRootInit(cvode_mem, ng, grblk, NULL);
1430 if (check_flag(&flag, "CVodeRootInit", 1))
1432 *ierr = 300 + (-flag);
1437 if (C2F(cmsolver).solver)
1438 /* Call CVDense to specify the CVDENSE dense linear solver */
1439 flag = CVDense(cvode_mem, *neq);
1440 if (check_flag(&flag, "CVDense", 1))
1442 *ierr = 300 + (-flag);
1449 if (!C2F(cmsolver).solver)
1451 flag = LSodarSetMaxStep(cvode_mem, (realtype) hmax);
1454 flag = CVodeSetMaxStep(cvode_mem, (realtype) hmax);
1455 if (check_flag(&flag, "CVodeSetMaxStep", 1))
1457 *ierr = 300 + (-flag);
1462 /* Set the Jacobian routine to Jac (user-supplied)
1463 flag = CVDenseSetJacFn(cvode_mem, Jac, NULL);
1464 if (check_flag(&flag, "CVDenseSetJacFn", 1)) return(1); */
1466 }/* testing if neq>0 */
1469 C2F(coshlt).halt = 0;
1472 C2F(xscion)(&inxsci);
1473 /* initialization */
1474 C2F(realtimeinit)(told, &C2F(rtfactor).scale);
1480 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
1482 if (Blocks[C2F(curblk).kfun - 1].ng >= 1)
1484 zcros[jj] = C2F(curblk).kfun;
1488 /* . Il faut: ng >= jj */
1493 /* initialisation (propagation of constant blocks outputs) */
1500 /*--discrete zero crossings----dzero--------------------*/
1501 if (ng > 0) /* storing ZC signs just after a solver call*/
1503 /*zdoit(told, g, x, x);*/
1504 zdoit(told, x, x, g);
1510 for (jj = 0; jj < ng; ++jj)
1511 if (g[jj] >= 0) jroot[jj] = 5;
1512 else jroot[jj] = -5;
1514 /*--discrete zero crossings----dzero--------------------*/
1516 /* main loop on time */
1519 while (ismenu()) //** if the user has done something, do the actions
1522 SeqSync = GetCommand(CommandToUnstack); //** get at the action
1523 CommandLength = (int)strlen(CommandToUnstack);
1524 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
1526 if (C2F(coshlt).halt != 0)
1528 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
1529 C2F(coshlt).halt = 0;
1541 if (fabs(t - *told) < ttol)
1544 /* update output part */
1548 /* ! scheduling problem */
1555 if (xptr[nblk + 1] == 1)
1557 /* . no continuous state */
1558 if (*told + deltat + ttol > t)
1566 /* . update outputs of 'c' type blocks with no continuous state */
1569 /* . we are at the end, update continuous part before leaving */
1581 rhotmp = *tf + ttol;
1586 if (critev[kpo] == 1)
1588 rhotmp = tevts[kpo];
1603 t = Min(*told + deltat, Min(t, *tf + ttol));
1605 if (ng > 0 && hot == 0 && nmod > 0)
1607 zdoit(told, x, x, g);
1615 if (hot == 0) /* hot==0 : cold restart*/
1617 if (!C2F(cmsolver).solver)
1619 flag = LSodarSetStopTime(cvode_mem, (realtype)tstop);
1622 flag = CVodeSetStopTime(cvode_mem, (realtype)tstop); /* Setting the stop time*/
1623 if (check_flag(&flag, "CVodeSetStopTime", 1))
1625 *ierr = 300 + (-flag);
1630 if (!C2F(cmsolver).solver)
1632 flag = LSodarReInit(cvode_mem, simblklsodar, (realtype)(*told), y, CV_SS, reltol, &abstol);
1635 flag = CVodeReInit(cvode_mem, simblk, (realtype)(*told), y, CV_SS, reltol, &abstol);
1636 if (check_flag(&flag, "CVodeReInit", 1))
1638 *ierr = 300 + (-flag);
1644 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1646 sciprint(_("****SUNDIALS.Cvode from: %f to %f hot= %d \n"), *told, t, hot);
1649 /*--discrete zero crossings----dzero--------------------*/
1650 /*--check for Dzeros after Mode settings or ddoit()----*/
1653 if (ng > 0 && hot == 0)
1655 zdoit(told, x, x, g);
1661 for (jj = 0; jj < ng; ++jj)
1663 if ((g[jj] >= 0.0) && (jroot[jj] == -5))
1668 else if ((g[jj] < 0.0) && (jroot[jj] == 5))
1676 /*--discrete zero crossings----dzero--------------------*/
1678 if (Discrete_Jump == 0) /* if there was a dzero, its event should be activated*/
1681 if (!C2F(cmsolver).solver)
1683 flag = LSodar(cvode_mem, t, y, told, LS_NORMAL);
1686 flag = CVode(cvode_mem, t, y, told, CV_NORMAL_TSTOP);
1696 flag = CV_ROOT_RETURN; /* in order to handle discrete jumps */
1699 /* . update outputs of 'c' type blocks if we are at the end*/
1712 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1713 sciprint(_("****SUNDIALS.Cvode reached: %f\n"), *told);
1717 else if ( flag == CV_TOO_MUCH_WORK || flag == CV_CONV_FAILURE || flag == CV_ERR_FAILURE)
1719 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1720 sciprint(_("****SUNDIALS.Cvode: too much work at time=%g (stiff region, change RTOL and ATOL)\n"), *told);
1725 *ierr = 300 + (-flag);
1732 if (flag < 0) *ierr = 300 + (-flag); /* raising errors due to internal errors, other wise erros due to flagr*/
1737 if (flag == CV_ZERO_DETACH_RETURN)
1740 }; /* new feature of sundials, detects zero-detaching */
1742 if (flag == CV_ROOT_RETURN)
1744 /* . at a least one root has been found */
1746 if (Discrete_Jump == 0)
1748 if (!C2F(cmsolver).solver)
1750 flagr = LSodarGetRootInfo(cvode_mem, jroot);
1753 flagr = CVodeGetRootInfo(cvode_mem, jroot);
1754 if (check_flag(&flagr, "CVodeGetRootInfo", 1))
1756 *ierr = 300 + (-flagr);
1761 /* . at a least one root has been found */
1762 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1764 sciprint(_("root found at t=: %f\n"), *told);
1766 /* . update outputs affecting ztyp blocks ONLY FOR OLD BLOCKS */
1767 zdoit(told, x, xd, g);
1773 for (jj = 0; jj < ng; ++jj)
1775 C2F(curblk).kfun = zcros[ jj];
1776 if (C2F(curblk).kfun == -1)
1782 for (j = zcptr[C2F(curblk).kfun] - 1 ;
1783 j < zcptr[C2F(curblk).kfun + 1] - 1 ; ++j)
1794 Blocks[C2F(curblk).kfun - 1].jroot = &jroot[zcptr[C2F(curblk).kfun] - 1];
1795 if (funtyp[C2F(curblk).kfun] > 0)
1798 if (Blocks[C2F(curblk).kfun - 1].nevout > 0)
1801 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1803 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1804 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1806 /* call corresponding block to determine output event (kev) */
1807 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
1808 /*callf(told, xd, x, x,g,&flag__);*/
1809 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1816 /* . update event agenda */
1817 for (k = 0; k < Blocks[C2F(curblk).kfun - 1].nevout; ++k)
1819 if (Blocks[C2F(curblk).kfun - 1].evout[k] >= 0.)
1821 i3 = k + clkptr[C2F(curblk).kfun] ;
1822 addevs(Blocks[C2F(curblk).kfun - 1].evout[k] + (*told), &i3, &ierr1);
1825 /* . nevts too small */
1833 /* . update state */
1834 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
1836 /* . call corresponding block to update state */
1838 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
1839 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
1840 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
1841 /*callf(told, xd, x, x,g,&flag__);*/
1842 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
1856 /*--discrete zero crossings----dzero--------------------*/
1857 if (ng > 0) /* storing ZC signs just after a sundials call*/
1859 zdoit(told, x, x, g);
1865 for (jj = 0; jj < ng; ++jj)
1877 /*--discrete zero crossings----dzero--------------------*/
1879 C2F(realtime)(told);
1884 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1886 sciprint(_("Event: %d activated at t=%f\n"), *pointi, *told);
1887 for (kev = 0; kev < nblk; kev++)
1889 if (Blocks[kev].nmode > 0)
1891 sciprint(_("mode of block %d=%d, "), kev, Blocks[kev].mode[0]);
1894 sciprint(_("**mod**\n"));
1898 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
1900 sciprint(_("End of activation\n"));
1909 /* end of main loop on time */
1914 /*--------------------------------------------------------------------------*/
1915 static void cossimdaskr(double *told)
1917 /* System generated locals */
1919 //** used for the [stop] button
1920 static char CommandToUnstack[1024];
1921 static int CommandLength = 0;
1922 static int SeqSync = 0;
1925 /* Local variables */
1926 static scicos_flag flag__ = 0;
1927 static int ierr1 = 0;
1928 static int j = 0, k = 0;
1929 static double t = 0.;
1930 static int jj = 0, jt = 0;
1931 static double rhotmp = 0., tstop = 0.;
1932 static int inxsci = 0;
1933 static int kpo = 0, kev = 0;
1935 int *jroot = NULL, *zcros = NULL;
1937 int *Mode_save = NULL;
1938 int Mode_change = 0;
1940 int flag = 0, flagr = 0;
1941 N_Vector yy = NULL, yp = NULL;
1942 realtype reltol = 0., abstol = 0.;
1943 int Discrete_Jump = 0;
1944 N_Vector IDx = NULL;
1945 realtype *scicos_xproperty = NULL;
1946 DenseMat TJacque = NULL;
1948 void *ida_mem = NULL;
1949 UserData data = NULL;
1950 IDAMem copy_IDA_mem = NULL;
1951 int maxnj = 0, maxnit = 0;
1952 /*-------------------- Analytical Jacobian memory allocation ----------*/
1953 int Jn = 0, Jnx = 0, Jno = 0, Jni = 0, Jactaille = 0;
1955 int cnt = 0, N_iters = 0;
1959 /* Set extension of Sundials for scicos */
1960 set_sundials_with_extension(TRUE);
1962 // CI=1.0; /* for function Get_Jacobian_ci */
1966 if ((jroot = MALLOC(sizeof(int) * ng)) == NULL )
1972 for ( jj = 0 ; jj < ng ; jj++ ) jroot[jj] = 0 ;
1977 if ((zcros = MALLOC(sizeof(int) * ng)) == NULL )
1980 if (ng != 0) FREE(jroot);
1988 if ((Mode_save = MALLOC(sizeof(int) * nmod)) == NULL )
1991 if (ng != 0) FREE(jroot);
1992 if (ng != 0) FREE(zcros);
1997 reltol = (realtype) rtol;
1998 abstol = (realtype) Atol; /* Ith(abstol,1) = realtype) Atol;*/
2003 yy = N_VNewEmpty_Serial(*neq);
2004 if (check_flag((void *)yy, "N_VNew_Serial", 0))
2006 if (ng != 0) FREE(jroot);
2007 if (ng != 0) FREE(zcros);
2008 if (nmod != 0) FREE(Mode_save);
2013 yp = N_VNewEmpty_Serial(*neq);
2014 if (check_flag((void *)yp, "N_VNew_Serial", 0))
2016 if (*neq > 0) N_VDestroy_Serial(yy);
2017 if (ng != 0) FREE(jroot);
2018 if (ng != 0) FREE(zcros);
2019 if (nmod != 0) FREE(Mode_save);
2025 IDx = N_VNew_Serial(*neq);
2026 if (check_flag((void *)IDx, "N_VNew_Serial", 0))
2029 if (*neq > 0) N_VDestroy_Serial(yp);
2030 if (*neq > 0) N_VDestroy_Serial(yy);
2031 if (ng != 0) FREE(jroot);
2032 if (ng != 0) FREE(zcros);
2033 if (nmod != 0) FREE(Mode_save);
2037 /* Call IDACreate and IDAMalloc to initialize IDA memory */
2039 ida_mem = IDACreate();
2040 if (check_flag((void *)ida_mem, "IDACreate", 0))
2042 if (*neq > 0) N_VDestroy_Serial(IDx);
2043 if (*neq > 0) N_VDestroy_Serial(yp);
2044 if (*neq > 0) N_VDestroy_Serial(yy);
2045 if (ng != 0) FREE(jroot);
2046 if (ng != 0) FREE(zcros);
2047 if (nmod != 0) FREE(Mode_save);
2050 copy_IDA_mem = (IDAMem) ida_mem;
2052 flag = IDAMalloc(ida_mem, simblkdaskr, T0, yy, yp, IDA_SS, reltol, &abstol);
2053 if (check_flag(&flag, "IDAMalloc", 1))
2055 *ierr = 200 + (-flag);
2056 if (*neq > 0)IDAFree(&ida_mem);
2057 if (*neq > 0)N_VDestroy_Serial(IDx);
2058 if (*neq > 0) N_VDestroy_Serial(yp);
2059 if (*neq > 0)N_VDestroy_Serial(yy);
2060 if (ng != 0) FREE(jroot);
2061 if (ng != 0) FREE(zcros);
2062 if (nmod != 0) FREE(Mode_save);
2067 flag = IDARootInit(ida_mem, ng, grblkdaskr, NULL);
2068 if (check_flag(&flag, "IDARootInit", 1))
2070 *ierr = 200 + (-flag);
2071 if (*neq > 0)IDAFree(&ida_mem);
2072 if (*neq > 0)N_VDestroy_Serial(IDx);
2073 if (*neq > 0)N_VDestroy_Serial(yp);
2074 if (*neq > 0)N_VDestroy_Serial(yy);
2075 if (ng != 0) FREE(jroot);
2076 if (ng != 0) FREE(zcros);
2077 if (nmod != 0) FREE(Mode_save);
2082 flag = IDADense(ida_mem, *neq);
2083 if (check_flag(&flag, "IDADense", 1))
2085 *ierr = 200 + (-flag);
2086 if (*neq > 0)IDAFree(&ida_mem);
2087 if (*neq > 0)N_VDestroy_Serial(IDx);
2088 if (*neq > 0)N_VDestroy_Serial(yp);
2089 if (*neq > 0)N_VDestroy_Serial(yy);
2090 if (ng != 0) FREE(jroot);
2091 if (ng != 0) FREE(zcros);
2092 if (nmod != 0) FREE(Mode_save);
2097 if ((data = (UserData) MALLOC(sizeof(*data))) == NULL)
2100 if (*neq > 0)IDAFree(&ida_mem);
2101 if (*neq > 0)N_VDestroy_Serial(IDx);
2102 if (*neq > 0)N_VDestroy_Serial(yp);
2103 if (*neq > 0)N_VDestroy_Serial(yy);
2104 if (ng != 0) FREE(jroot);
2105 if (ng != 0) FREE(zcros);
2106 if (nmod != 0) FREE(Mode_save);
2109 data->ida_mem = ida_mem;
2115 data->ewt = N_VNew_Serial(*neq);
2116 if (check_flag((void *)data->ewt, "N_VNew_Serial", 0))
2118 *ierr = 200 + (-flag);
2119 if (*neq > 0)FREE(data);
2120 if (*neq > 0)IDAFree(&ida_mem);
2121 if (*neq > 0) N_VDestroy_Serial(IDx);
2122 if (*neq > 0) N_VDestroy_Serial(yp);
2123 if (*neq > 0) N_VDestroy_Serial(yy);
2124 if (ng != 0) FREE(jroot);
2125 if (ng != 0) FREE(zcros);
2126 if (nmod != 0) FREE(Mode_save);
2131 if ((data->gwork = (double *) MALLOC(ng * sizeof(double))) == NULL)
2133 if (*neq > 0) N_VDestroy_Serial(data->ewt);
2134 if (*neq > 0)FREE(data);
2135 if (*neq > 0)IDAFree(&ida_mem);
2136 if (*neq > 0)N_VDestroy_Serial(IDx);
2137 if (*neq > 0)N_VDestroy_Serial(yp);
2138 if (*neq > 0)N_VDestroy_Serial(yy);
2139 if (ng != 0) FREE(jroot);
2140 if (ng != 0) FREE(zcros);
2141 if (nmod != 0) FREE(Mode_save);
2145 /*Jacobian_Flag=0; */
2146 if (AJacobian_block > 0) /* set by the block with A-Jac in flag-4 using Set_Jacobian_flag(1); */
2149 Jnx = Blocks[AJacobian_block - 1].nx;
2150 Jno = Blocks[AJacobian_block - 1].nout;
2151 Jni = Blocks[AJacobian_block - 1].nin;
2160 Jactaille = 3 * Jn + (Jn + Jni) * (Jn + Jno) + Jnx * (Jni + 2 * Jn + Jno) + (Jn - Jnx) * (2 * (Jn - Jnx) + Jno + Jni) + 2 * Jni * Jno;
2162 if ((data->rwork = (double *) MALLOC(Jactaille * sizeof(double))) == NULL)
2164 if ( ng > 0 ) FREE(data->gwork);
2165 if (*neq > 0)N_VDestroy_Serial(data->ewt);
2166 if (*neq > 0)FREE(data);
2167 if (*neq > 0)IDAFree(&ida_mem);
2168 if (*neq > 0)N_VDestroy_Serial(IDx);
2169 if (*neq > 0)N_VDestroy_Serial(yp);
2170 if (*neq > 0)N_VDestroy_Serial(yy);
2171 if (ng != 0) FREE(jroot);
2172 if (ng != 0) FREE(zcros);
2173 if (nmod != 0) FREE(Mode_save);
2178 flag = IDADenseSetJacFn(ida_mem, Jacobians, data);
2179 if (check_flag(&flag, "IDADenseSetJacFn", 1))
2181 *ierr = 200 + (-flag);
2186 TJacque = (DenseMat) DenseAllocMat(*neq, *neq);
2188 flag = IDASetRdata(ida_mem, data);
2189 if (check_flag(&flag, "IDASetRdata", 1))
2191 *ierr = 200 + (-flag);
2198 flag = IDASetMaxStep(ida_mem, (realtype) hmax);
2199 if (check_flag(&flag, "IDASetMaxStep", 1))
2201 *ierr = 200 + (-flag);
2207 maxnj = 100; /* setting the maximum number of Jacobian evaluation during a Newton step */
2208 flag = IDASetMaxNumJacsIC(ida_mem, maxnj);
2209 if (check_flag(&flag, "IDASetMaxNumJacsIC", 1))
2211 *ierr = 200 + (-flag);
2216 maxnit = 10; /* setting the maximum number of Newton iterations in any one attemp to solve CIC */
2217 flag = IDASetMaxNumItersIC(ida_mem, maxnit);
2218 if (check_flag(&flag, "IDASetMaxNumItersIC", 1))
2220 *ierr = 200 + (-flag);
2225 /* setting the maximum number of steps in an integration interval */
2226 flag = IDASetMaxNumSteps(ida_mem, 2000);
2227 if (check_flag(&flag, "IDASetMaxNumSteps", 1))
2229 *ierr = 200 + (-flag);
2234 } /* testing if neq>0 */
2239 uround = uround * 0.5;
2241 while ( 1.0 + uround != 1.0);
2242 uround = uround * 2.0;
2243 SQuround = sqrt(uround);
2246 C2F(coshlt).halt = 0;
2255 C2F(xscion)(&inxsci);
2256 /* initialization */
2257 C2F(realtimeinit)(told, &C2F(rtfactor).scale);
2258 /* ATOL and RTOL are scalars */
2261 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
2263 if (Blocks[C2F(curblk).kfun - 1].ng >= 1)
2265 zcros[jj] = C2F(curblk).kfun;
2269 /* . Il faut: ng >= jj */
2274 /* initialisation (propagation of constant blocks outputs) */
2282 /*--discrete zero crossings----dzero--------------------*/
2283 if (ng > 0) /* storing ZC signs just after a solver call*/
2285 zdoit(told, x, x, g);
2291 for (jj = 0; jj < ng; ++jj)
2292 if (g[jj] >= 0) jroot[jj] = 5;
2293 else jroot[jj] = -5;
2295 /* main loop on time */
2298 while (ismenu()) //** if the user has done something, do the actions
2301 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2302 CommandLength = (int)strlen(CommandToUnstack);
2303 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2305 if (C2F(coshlt).halt != 0)
2307 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2308 C2F(coshlt).halt = 0;
2320 if (fabs(t - *told) < ttol)
2323 /* update output part */
2327 /* ! scheduling problem */
2334 if (xptr[nblk + 1] == 1)
2336 /* . no continuous state */
2337 if (*told + deltat + ttol > t)
2345 /* . update outputs of 'c' type blocks with no continuous state */
2348 /* . we are at the end, update continuous part before leaving */
2356 rhotmp = *tf + ttol;
2361 if (critev[kpo] == 1)
2363 rhotmp = tevts[kpo];
2374 hot = 0;/* Do cold-restart the solver:if the new TSTOP isn't beyong the previous one*/
2378 t = Min(*told + deltat, Min(t, *tf + ttol));
2380 if (hot == 0) /* CIC calculation when hot==0 */
2383 /* Setting the stop time*/
2384 flag = IDASetStopTime(ida_mem, (realtype)tstop);
2385 if (check_flag(&flag, "IDASetStopTime", 1))
2387 *ierr = 200 + (-flag);
2392 if (ng > 0 && nmod > 0)
2395 zdoit(told, x, xd, g);
2403 /*----------ID setting/checking------------*/
2404 N_VConst(ONE, IDx); /* Initialize id to 1's. */
2405 scicos_xproperty = NV_DATA_S(IDx);
2412 for (jj = 0; jj < *neq; jj++)
2414 if (xprop[jj] == 1) scicos_xproperty[jj] = ONE;
2415 if (xprop[jj] == -1) scicos_xproperty[jj] = ZERO;
2417 /* CI=0.0;CJ=100.0; // for functions Get_Jacobian_ci and Get_Jacobian_cj
2418 Jacobians(*neq, (realtype) (*told), yy, yp, bidon, (realtype) CJ, data, TJacque, tempv1, tempv2, tempv3);
2419 for (jj=0;jj<*neq;jj++){
2420 Jacque_col=DENSE_COL(TJacque,jj);
2422 for (kk=0;kk<*neq;kk++){
2423 if ((Jacque_col[kk]-Jacque_col[kk]!=0)) {
2427 if (Jacque_col[kk]!=0){
2433 if (CI>=ZERO){ scicos_xproperty[jj]=CI;}else{fprintf(stderr,"\nWarinng! Xproperties are not match for i=%d!",jj);}
2435 /* printf("\n"); for(jj=0;jj<*neq;jj++) { printf("x%d=%g ",jj,scicos_xproperty[jj]); }*/
2437 flag = IDASetId(ida_mem, IDx);
2438 if (check_flag(&flag, "IDASetId", 1))
2440 *ierr = 200 + (-flag);
2444 // CI=1.0; // for function Get_Jacobian_ci
2445 /*--------------------------------------------*/
2446 // maxnj=100; /* setting the maximum number of Jacobian evaluation during a Newton step */
2447 // flag=IDASetMaxNumJacsIC(ida_mem, maxnj);
2448 // if (check_flag(&flag, "IDASetMaxNumItersIC", 1)) {
2449 // *ierr=200+(-flag);
2453 // flag=IDASetLineSearchOffIC(ida_mem,FALSE); /* (def=false) */
2454 // if (check_flag(&flag, "IDASetLineSearchOffIC", 1)) {
2455 // *ierr=200+(-flag);
2459 // flag=IDASetMaxNumItersIC(ida_mem, 10);/* (def=10) setting the maximum number of Newton iterations in any one attemp to solve CIC */
2460 // if (check_flag(&flag, "IDASetMaxNumItersIC", 1)) {
2461 // *ierr=200+(-flag);
2466 N_iters = 4 + nmod * 4;
2467 for (j = 0; j <= N_iters; j++)
2469 /* counter to reevaluate the
2470 modes in mode->CIC->mode->CIC-> loop
2471 do it once in the absence of mode (nmod=0) */
2472 /* updating the modes through Flag==9, Phase==1 */
2474 /* Serge Steer 29/06/2009 */
2475 while (ismenu()) //** if the user has done something, do the actions
2478 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2479 CommandLength = (int)strlen(CommandToUnstack);
2480 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2482 if (C2F(coshlt).halt != 0)
2484 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2485 C2F(coshlt).halt = 0;
2491 flag = IDAReInit(ida_mem, simblkdaskr, (realtype)(*told), yy, yp, IDA_SS, reltol, &abstol);
2492 if (check_flag(&flag, "CVodeReInit", 1))
2494 *ierr = 200 + (-flag);
2499 phase = 2; /* IDACalcIC: PHI-> yy0: if (ok) yy0_cic-> PHI*/
2500 copy_IDA_mem->ida_kk = 1;
2502 // the initial conditons y0 and yp0 do not satisfy the DAE
2503 flagr = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, (realtype)(t));
2506 flag = IDAGetConsistentIC(ida_mem, yy, yp); /* PHI->YY */
2508 if (*ierr > 5) /* *ierr>5 => singularity in block */
2514 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2518 sciprint(_("**** SUNDIALS.IDA successfully initialized *****\n") );
2522 sciprint(_("**** SUNDIALS.IDA failed to initialize ->try again *****\n") );
2525 /*-------------------------------------*/
2526 /* saving the previous modes*/
2527 for (jj = 0; jj < nmod; ++jj)
2529 Mode_save[jj] = mod[jj];
2531 if (ng > 0 && nmod > 0)
2534 zdoit(told, x, xd, g);
2541 /*------------------------------------*/
2543 for (jj = 0; jj < nmod; ++jj)
2545 if (Mode_save[jj] != mod[jj])
2551 if (Mode_change == 0)
2555 break; /* if (flagr>=0) break; else{ *ierr=200+(-flagr); freeallx; return; }*/
2557 else if (j >= (int)( N_iters / 2))
2559 /* IDASetMaxNumStepsIC(mem,10); */ /* maxnh (def=5) */
2560 IDASetMaxNumJacsIC(ida_mem, 10); /* maxnj 100 (def=4)*/
2561 /* IDASetMaxNumItersIC(mem,100000); */ /* maxnit in IDANewtonIC (def=10) */
2562 IDASetLineSearchOffIC(ida_mem, TRUE); /* (def=false) */
2563 /* IDASetNonlinConvCoefIC(mem,1.01);*/ /* (def=0.01-0.33*/
2564 flag = IDASetMaxNumItersIC(ida_mem, 1000);
2565 if (check_flag(&flag, "IDASetMaxNumItersIC", 1))
2567 *ierr = 200 + (-flag);
2573 }/* mode-CIC counter*/
2574 if (Mode_change == 1)
2576 /* In tghis case, we try again by relaxing all modes and calling IDA_calc again
2579 copy_IDA_mem->ida_kk = 1;
2580 flagr = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, (realtype)(t));
2582 flag = IDAGetConsistentIC(ida_mem, yy, yp); /* PHI->YY */
2583 if ((flagr < 0) || (*ierr > 5)) /* *ierr>5 => singularity in block */
2590 /*-----If flagr<0 the initialization solver has not converged-----*/
2598 } /* CIC calculation when hot==0 */
2600 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2602 sciprint(_("****daskr from: %f to %f hot= %d \n"), *told, t, hot);
2605 /*--discrete zero crossings----dzero--------------------*/
2606 /*--check for Dzeros after Mode settings or ddoit()----*/
2608 if (ng > 0 && hot == 0)
2610 zdoit(told, x, xd, g);
2616 for (jj = 0; jj < ng; ++jj)
2618 if ((g[jj] >= 0.0) && ( jroot[jj] == -5))
2623 else if ((g[jj] < 0.0) && ( jroot[jj] == 5))
2632 /*--discrete zero crossings----dzero--------------------*/
2633 if (Discrete_Jump == 0) /* if there was a dzero, its event should be activated*/
2636 flagr = IDASolve(ida_mem, t, told, yy, yp, IDA_NORMAL_TSTOP);
2646 flagr = IDA_ROOT_RETURN; /* in order to handle discrete jumps */
2650 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2651 sciprint(_("****SUNDIALS.Ida reached: %f\n"), *told);
2655 else if ( flagr == IDA_TOO_MUCH_WORK || flagr == IDA_CONV_FAIL || flagr == IDA_ERR_FAIL)
2657 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2658 sciprint(_("**** SUNDIALS.Ida: too much work at time=%g (stiff region, change RTOL and ATOL)\n"), *told);
2663 *ierr = 200 + (-flagr);
2670 if (flagr < 0) *ierr = 200 + (-flagr); /* raising errors due to internal errors, other wise erros due to flagr*/
2675 /* update outputs of 'c' type blocks if we are at the end*/
2683 if (flagr == IDA_ZERO_DETACH_RETURN)
2686 }; /* new feature of sundials, detects unmasking */
2687 if (flagr == IDA_ROOT_RETURN)
2689 /* . at a least one root has been found */
2691 if (Discrete_Jump == 0)
2693 flagr = IDAGetRootInfo(ida_mem, jroot);
2694 if (check_flag(&flagr, "IDAGetRootInfo", 1))
2696 *ierr = 200 + (-flagr);
2702 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2704 sciprint(_("root found at t=: %f\n"), *told);
2706 /* . update outputs affecting ztyp blocks ONLY FOR OLD BLOCKS*/
2707 zdoit(told, x, xd, g);
2713 for (jj = 0; jj < ng; ++jj)
2715 C2F(curblk).kfun = zcros[jj];
2716 if (C2F(curblk).kfun == -1)
2721 for (j = zcptr[C2F(curblk).kfun] - 1 ;
2722 j < zcptr[C2F(curblk).kfun + 1] - 1 ; ++j)
2732 Blocks[C2F(curblk).kfun - 1].jroot = &jroot[zcptr[C2F(curblk).kfun] - 1];
2733 if (funtyp[C2F(curblk).kfun] > 0)
2735 if (Blocks[C2F(curblk).kfun - 1].nevout > 0)
2738 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2740 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2741 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2743 /* call corresponding block to determine output event (kev) */
2744 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
2745 /*callf(told, xd, x, x,g,&flag__);*/
2746 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2753 /* update event agenda */
2754 for (k = 0; k < Blocks[C2F(curblk).kfun - 1].nevout; ++k)
2756 if (Blocks[C2F(curblk).kfun - 1].evout[k] >= 0)
2758 i3 = k + clkptr[C2F(curblk).kfun] ;
2759 addevs(Blocks[C2F(curblk).kfun - 1].evout[k] + (*told), &i3, &ierr1);
2762 /* . nevts too small */
2771 if ((Blocks[C2F(curblk).kfun - 1].nx > 0) || (*Blocks[C2F(curblk).kfun - 1].work != NULL) )
2773 /* call corresponding block to update state */
2775 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2777 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2778 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2780 Blocks[C2F(curblk).kfun - 1].nevprt = -kev;
2782 Blocks[C2F(curblk).kfun - 1].xprop = &xprop[-1 + xptr[C2F(curblk).kfun]];
2783 /*callf(told, xd, x, x,g,&flag__);*/
2784 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2792 for (j = 0; j < *neq; j++) /* Adjust xprop for IDx */
2794 if (xprop[j] == 1) scicos_xproperty[j] = ONE;
2795 if (xprop[j] == -1) scicos_xproperty[j] = ZERO;
2802 /* Serge Steer 29/06/2009 */
2803 while (ismenu()) //** if the user has done something, do the actions
2806 SeqSync = GetCommand(CommandToUnstack); //** get at the action
2807 CommandLength = (int)strlen(CommandToUnstack);
2808 syncexec(CommandToUnstack, &CommandLength, &ierr2, &one, CommandLength); //** execute it
2811 if (C2F(coshlt).halt != 0)
2813 if (C2F(coshlt).halt == 2) *told = *tf; /* end simulation */
2814 C2F(coshlt).halt = 0;
2831 /*--discrete zero crossings----dzero--------------------*/
2832 if (ng > 0) /* storing ZC signs just after a ddaskr call*/
2834 zdoit(told, x, xd, g);
2840 for (jj = 0; jj < ng; ++jj)
2852 /*--discrete zero crossings----dzero--------------------*/
2854 C2F(realtime)(told);
2859 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2861 sciprint(_("Event: %d activated at t=%f\n"), *pointi, *told);
2865 if ((C2F(cosdebug).cosd >= 1) && (C2F(cosdebug).cosd != 3))
2867 sciprint(_("End of activation"));
2875 /* end of main loop on time */
2878 } /* cossimdaskr_ */
2879 /*--------------------------------------------------------------------------*/
2880 /* Subroutine cosend */
2881 static void cosend(double *told)
2883 /* Local variables */
2884 static scicos_flag flag__ = 0;
2886 static int kfune = 0;
2890 /* loop on blocks */
2891 for (C2F(curblk).kfun = 1; C2F(curblk).kfun <= nblk; ++C2F(curblk).kfun)
2894 Blocks[C2F(curblk).kfun - 1].nevprt = 0;
2895 if (funtyp[C2F(curblk).kfun] >= 0)
2897 if (Blocks[C2F(curblk).kfun - 1].nx > 0)
2899 Blocks[C2F(curblk).kfun - 1].x = &x[xptr[C2F(curblk).kfun] - 1];
2900 Blocks[C2F(curblk).kfun - 1].xd = &xd[xptr[C2F(curblk).kfun] - 1];
2902 /*callf(told, xd, x, x,x,&flag__);*/
2903 callf(told, &Blocks[C2F(curblk).kfun - 1], &flag__);
2904 if (flag__ < 0 && *ierr == 0)
2907 kfune = C2F(curblk).kfun;
2913 C2F(curblk).kfun = kfune;
2917 /*--------------------------------------------------------------------------*/
2919 void callf(double *t, scicos_block *block, scicos_flag *flag)
2921 double* args[SZ_SIZE];
2923 double intabl[TB_SIZE];
2924 double outabl[TB_SIZE];
2926 int ii = 0, in = 0, out = 0, ki = 0, ko = 0, no = 0, ni = 0, k = 0, j = 0;
2927 int szi = 0, flagi = 0;
2928 double *ptr_d = NULL;
2930 /* function pointers type def */
2934 /* ScicosFm1 loc3;*/
2942 int solver = C2F(cmsolver).solver;
2943 int cosd = C2F(cosdebug).cosd;
2944 /*int kf = C2F(curblk).kfun;*/
2946 block_error = (int*) flag;
2948 /* debug block is never called */
2949 /*if (kf==(debug_block+1)) return;*/
2950 if (block->type == 99) return;
2952 /* flag 7 implicit initialization */
2953 flagi = (int) * flag;
2954 /* change flag to zero if flagi==7 for explicit block */
2955 if (flagi == 7 && block->type < 10000)
2960 /* display information for debugging mode */
2965 sciprint(_("block %d is called "), C2F(curblk).kfun);
2966 sciprint(_("with flag %d "), *flag);
2967 sciprint(_("at time %f \n"), *t);
2969 if (debug_block > -1)
2971 if (cosd != 3) sciprint(_("Entering the block \n"));
2972 call_debug_scicos(block, flag, flagi, debug_block);
2973 if (*flag < 0) return; /* error in debug block */
2977 C2F(scsptr).ptr = block->scsptr;
2979 /* get pointer of the function */
2982 /* continuous state */
2983 if (solver == 100 && block->type < 10000 && *flag == 0)
2986 block->xd = block->res;
2990 //sciprint("callf type=%d flag=%d\n",block->type,flagi);
2991 switch (block->type)
2993 /*******************/
2994 /* function type 0 */
2995 /*******************/
2998 /* This is for compatibility */
2999 /* jroot is returned in g for old type */
3000 if (block->nevprt < 0)
3002 for (j = 0; j < block->ng; ++j)
3004 block->g[j] = (double)block->jroot[j];
3008 /* concatenated entries and concatened outputs */
3009 /* catenate inputs if necessary */
3014 for (in = 0; in < block->nin; in++)
3016 szi = block->insz[in] * block->insz[in + block->nin];
3017 for (ii = 0; ii < szi; ii++)
3019 intabl[ki++] = *((double *)(block->inptr[in]) + ii);
3023 args[0] = &(intabl[0]);
3027 if (block->nin == 0)
3033 args[0] = (double *)(block->inptr[0]);
3034 ni = block->insz[0] * block->insz[1];
3038 /* catenate outputs if necessary */
3040 if (block->nout > 1)
3043 for (out = 0; out < block->nout; out++)
3045 szi = block->outsz[out] * block->outsz[out + block->nout];
3046 for (ii = 0; ii < szi; ii++)
3048 outabl[ko++] = *((double *)(block->outptr[out]) + ii);
3052 args[1] = &(outabl[0]);
3056 if (block->nout == 0)
3062 args[1] = (double *)(block->outptr[0]);
3063 no = block->outsz[0] * block->outsz[1];
3067 loc0 = (ScicosF0) loc;
3069 (*loc0)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3070 block->z, &block->nz,
3071 block->evout, &block->nevout, block->rpar, &block->nrpar,
3072 block->ipar, &block->nipar, (double *)args[0], &ni,
3073 (double *)args[1], &no);
3075 /* split output vector on each port if necessary */
3076 if (block->nout > 1)
3079 for (out = 0; out < block->nout; out++)
3081 szi = block->outsz[out] * block->outsz[out + block->nout];
3082 for (ii = 0; ii < szi; ii++)
3084 *((double *)(block->outptr[out]) + ii) = outabl[ko++];
3089 /* adjust values of output register */
3090 for (in = 0; in < block->nevout; ++in)
3092 block->evout[in] = block->evout[in] - *t;
3098 /*******************/
3099 /* function type 1 */
3100 /*******************/
3103 /* This is for compatibility */
3104 /* jroot is returned in g for old type */
3105 if (block->nevprt < 0)
3107 for (j = 0; j < block->ng; ++j)
3109 block->g[j] = (double)block->jroot[j];
3113 /* one entry for each input or output */
3114 for (in = 0 ; in < block->nin ; in++)
3116 args[in] = block->inptr[in];
3117 sz[in] = block->insz[in];
3119 for (out = 0; out < block->nout; out++)
3121 args[in + out] = block->outptr[out];
3122 sz[in + out] = block->outsz[out];
3124 /* with zero crossing */
3125 if (block->ztyp > 0)
3127 args[block->nin + block->nout] = block->g;
3128 sz[block->nin + block->nout] = block->ng;
3131 loc1 = (ScicosF) loc;
3133 (*loc1)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3134 block->z, &block->nz,
3135 block->evout, &block->nevout, block->rpar, &block->nrpar,
3136 block->ipar, &block->nipar,
3137 (double *)args[0], &sz[0],
3138 (double *)args[1], &sz[1], (double *)args[2], &sz[2],
3139 (double *)args[3], &sz[3], (double *)args[4], &sz[4],
3140 (double *)args[5], &sz[5], (double *)args[6], &sz[6],
3141 (double *)args[7], &sz[7], (double *)args[8], &sz[8],
3142 (double *)args[9], &sz[9], (double *)args[10], &sz[10],
3143 (double *)args[11], &sz[11], (double *)args[12], &sz[12],
3144 (double *)args[13], &sz[13], (double *)args[14], &sz[14],
3145 (double *)args[15], &sz[15], (double *)args[16], &sz[16],
3146 (double *)args[17], &sz[17]);
3148 /* adjust values of output register */
3149 for (in = 0; in < block->nevout; ++in)
3151 block->evout[in] = block->evout[in] - *t;
3157 /*******************/
3158 /* function type 2 */
3159 /*******************/
3162 /* This is for compatibility */
3163 /* jroot is returned in g for old type */
3164 if (block->nevprt < 0)
3166 for (j = 0; j < block->ng; ++j)
3168 block->g[j] = (double)block->jroot[j];
3172 /* no zero crossing */
3173 if (block->ztyp == 0)
3175 loc2 = (ScicosF2) loc;
3176 (*loc2)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3177 block->z, &block->nz,
3178 block->evout, &block->nevout, block->rpar, &block->nrpar,
3179 block->ipar, &block->nipar, (double **)block->inptr,
3180 block->insz, &block->nin,
3181 (double **)block->outptr, block->outsz, &block->nout);
3183 /* with zero crossing */
3186 loc2z = (ScicosF2z) loc;
3187 (*loc2z)(flag, &block->nevprt, t, block->xd, block->x, &block->nx,
3188 block->z, &block->nz,
3189 block->evout, &block->nevout, block->rpar, &block->nrpar,
3190 block->ipar, &block->nipar, (double **)block->inptr,
3191 block->insz, &block->nin,
3192 (double **)block->outptr, block->outsz, &block->nout,
3193 block->g, &block->ng);
3196 /* adjust values of output register */
3197 for (in = 0; in < block->nevout; ++in)
3199 block->evout[in] = block->evout[in] - *t;
3205 /*******************/
3206 /* function type 4 */
3207 /*******************/
3210 /* get pointer of the function type 4*/
3211 loc4 = (ScicosF4) loc;
3213 (*loc4)(block, *flag);
3218 /***********************/
3219 /* function type 10001 */
3220 /***********************/
3223 /* This is for compatibility */
3224 /* jroot is returned in g for old type */
3225 if (block->nevprt < 0)
3227 for (j = 0; j < block->ng; ++j)
3229 block->g[j] = (double)block->jroot[j];
3233 /* implicit block one entry for each input or output */
3234 for (in = 0 ; in < block->nin ; in++)
3236 args[in] = block->inptr[in];
3237 sz[in] = block->insz[in];
3239 for (out = 0; out < block->nout; out++)
3241 args[in + out] = block->outptr[out];
3242 sz[in + out] = block->outsz[out];
3244 /* with zero crossing */
3245 if (block->ztyp > 0)
3247 args[block->nin + block->nout] = block->g;
3248 sz[block->nin + block->nout] = block->ng;
3251 loci1 = (ScicosFi) loc;
3252 (*loci1)(flag, &block->nevprt, t, block->res, block->xd, block->x,
3253 &block->nx, block->z, &block->nz,
3254 block->evout, &block->nevout, block->rpar, &block->nrpar,
3255 block->ipar, &block->nipar,
3256 (double *)args[0], &sz[0],
3257 (double *)args[1], &sz[1], (double *)args[2], &sz[2],
3258 (double *)args[3], &sz[3], (double *)args[4], &sz[4],
3259 (double *)args[5], &sz[5], (double *)args[6], &sz[6],
3260 (double *)args[7], &sz[7], (double *)args[8], &sz[8],
3261 (double *)args[9], &sz[9], (double *)args[10], &sz[10],
3262 (double *)args[11], &sz[11], (double *)args[12], &sz[12],
3263 (double *)args[13], &sz[13], (double *)args[14], &sz[14],
3264 (double *)args[15], &sz[15], (double *)args[16], &sz[16],
3265 (double *)args[17], &sz[17]);
3267 /* adjust values of output register */
3268 for (in = 0; in < block->nevout; ++in)
3270 block->evout[in] = block->evout[in] - *t;
3276 /***********************/
3277 /* function type 10002 */
3278 /***********************/
3281 /* This is for compatibility */
3282 /* jroot is returned in g for old type */
3283 if (block->nevprt < 0)
3285 for (j = 0; j < block->ng; ++j)
3287 block->g[j] = (double)block->jroot[j];
3291 /* implicit block, inputs and outputs given by a table of pointers */
3292 /* no zero crossing */
3293 if (block->ztyp == 0)
3295 loci2 = (ScicosFi2) loc;
3296 (*loci2)(flag, &block->nevprt, t, block->res,
3297 block->xd, block->x, &block->nx,
3298 block->z, &block->nz,
3299 block->evout, &block->nevout, block->rpar, &block->nrpar,
3300 block->ipar, &block->nipar, (double **)block->inptr,
3301 block->insz, &block->nin,
3302 (double **)block->outptr, block->outsz, &block->nout);
3304 /* with zero crossing */
3307 loci2z = (ScicosFi2z) loc;
3308 (*loci2z)(flag, &block->nevprt, t, block->res,
3309 block->xd, block->x, &block->nx,
3310 block->z, &block->nz,
3311 block->evout, &block->nevout, block->rpar, &block->nrpar,
3312 block->ipar, &block->nipar,
3313 (double **)block->inptr, block->insz, &block->nin,
3314 (double **)block->outptr, block->outsz, &block->nout,
3315 block->g, &block->ng);
3318 /* adjust values of output register */
3319 for (in = 0; in < block->nevout; ++in)
3321 block->evout[in] = block->evout[in] - *t;
3327 /***********************/
3328 /* function type 10004 */
3329 /***********************/
3332 /* get pointer of the function type 4*/
3333 loc4 = (ScicosF4) loc;
3335 (*loc4)(block, *flag);
3345 sciprint(_("Undefined Function type\n"));
3350 // sciprint("callf end flag=%d\n",*flag);
3351 /* Implicit Solver & explicit block & flag==0 */
3352 /* adjust continuous state vector after call */
3353 if (solver == 100 && block->type < 10000 && *flag == 0)
3358 for (k = 0; k < block->nx; k++)
3360 block->res[k] = block->res[k] - block->xd[k];
3365 for (k = 0; k < block->nx; k++)
3367 block->xd[k] = block->res[k];
3375 if (debug_block > -1)
3377 if (*flag < 0) return; /* error in block */
3378 if (cosd != 3) sciprint(_("Leaving block %d \n"), C2F(curblk).kfun);
3379 call_debug_scicos(block, flag, flagi, debug_block);
3380 /*call_debug_scicos(flag,kf,flagi,debug_block);*/
3384 /*--------------------------------------------------------------------------*/
3385 /* call_debug_scicos */
3386 static void call_debug_scicos(scicos_block *block, scicos_flag *flag, int flagi, int deb_blk)
3389 int solver = C2F(cmsolver).solver, k = 0;
3391 double *ptr_d = NULL;
3393 C2F(cosdebugcounter).counter = C2F(cosdebugcounter).counter + 1;
3394 C2F(scsptr).ptr = Blocks[deb_blk].scsptr;
3396 loc = Blocks[deb_blk].funpt; /* GLOBAL */
3397 loc4 = (ScicosF4) loc;
3399 /* continuous state */
3400 if (solver == 100 && block->type < 10000 && *flag == 0)
3403 block->xd = block->res;
3406 (*loc4)(block, *flag);
3408 /* Implicit Solver & explicit block & flag==0 */
3409 /* adjust continuous state vector after call */
3410 if (solver == 100 && block->type < 10000 && *flag == 0)
3415 for (k = 0; k < block->nx; k++)
3417 block->res[k] = block->res[k] - block->xd[k];
3422 for (k = 0; k < block->nx; k++)
3424 block->xd[k] = block->res[k];
3429 if (*flag < 0) sciprint(_("Error in the Debug block \n"));
3430 } /* call_debug_scicos */
3431 /*--------------------------------------------------------------------------*/
3433 static int simblk(realtype t, N_Vector yy, N_Vector yp, void *f_data)
3435 double tx = 0., *x = NULL, *xd = NULL;
3436 int i = 0, nantest = 0;
3439 x = (double *) NV_DATA_S(yy);
3440 xd = (double *) NV_DATA_S(yp);
3442 for (i = 0; i < *neq; i++) xd[i] = 0; /* à la place de "C2F(dset)(neq, &c_b14,xcdot , &c__1);"*/
3443 C2F(ierode).iero = 0;
3445 odoit(&tx, x, xd, xd);
3446 C2F(ierode).iero = *ierr;
3451 for (i = 0; i < *neq; i++) /* NaN checking */
3453 if ((xd[i] - xd[i] != 0))
3455 sciprint(_("\nWarning: The computing function #%d returns a NaN/Inf"), i);
3460 if (nantest == 1) return 349; /* recoverable error; */
3463 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3466 /*--------------------------------------------------------------------------*/
3468 static int grblk(realtype t, N_Vector yy, realtype *gout, void *g_data)
3470 double tx = 0., *x = NULL;
3471 int jj = 0, nantest = 0;
3474 x = (double *) NV_DATA_S(yy);
3476 C2F(ierode).iero = 0;
3479 zdoit(&tx, x, x, (double*) gout);
3484 for (jj = 0; jj < ng; jj++)
3485 if (gout[jj] - gout[jj] != 0)
3487 sciprint(_("\nWarning: The zero_crossing function #%d returns a NaN/Inf"), jj);
3490 } /* NaN checking */
3491 if (nantest == 1) return 350; /* recoverable error; */
3493 C2F(ierode).iero = *ierr;
3497 /*--------------------------------------------------------------------------*/
3499 static int simblklsodar(int * nequations, realtype * tOld, realtype * actual, realtype * res)
3502 int i = 0, nantest = 0;
3504 tx = (double) *tOld;
3506 for (i = 0; i < *nequations; ++i) res[i] = 0; /* à la place de "C2F(dset)(neq, &c_b14,xcdot , &c__1);"*/
3507 C2F(ierode).iero = 0;
3509 odoit(&tx, actual, res, res);
3510 C2F(ierode).iero = *ierr;
3515 for (i = 0; i < *nequations; i++) /* NaN checking */
3517 if ((res[i] - res[i] != 0))
3519 sciprint(_("\nWarning: The computing function #%d returns a NaN/Inf"), i);
3524 if (nantest == 1) return 349; /* recoverable error; */
3527 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3529 } /* simblklsodar */
3530 /*--------------------------------------------------------------------------*/
3532 static int grblklsodar(int * nequations, realtype * tOld, realtype * actual, int * ngc, realtype * res)
3535 int jj = 0, nantest = 0;
3537 tx = (double) *tOld;
3539 C2F(ierode).iero = 0;
3542 zdoit(&tx, actual, actual, res);
3547 for (jj = 0; jj < *ngc; jj++)
3548 if (res[jj] - res[jj] != 0)
3550 sciprint(_("\nWarning: The zero_crossing function #%d returns a NaN/Inf"), jj);
3553 } /* NaN checking */
3554 if (nantest == 1) return 350; /* recoverable error; */
3556 C2F(ierode).iero = *ierr;
3560 /*--------------------------------------------------------------------------*/
3562 static int simblkdaskr(realtype tres, N_Vector yy, N_Vector yp, N_Vector resval, void *rdata)
3565 double *xc = NULL, *xcdot = NULL, *residual = NULL;
3566 realtype alpha = 0.;
3572 int jj = 0, flag = 0, nantest = 0;
3574 data = (UserData) rdata;
3576 if (get_phase_simulation() == 1)
3578 /* Just to update mode in a very special case, i.e., when initialization using modes fails.
3579 in this case, we relax all modes and try again one more time.
3581 zdoit(&tx, NV_DATA_S(yy), NV_DATA_S(yp), (double *)data->gwork);
3585 flag = IDAGetCurrentStep(data->ida_mem, &hh);
3588 *ierr = 200 + (-flag);
3593 flag = IDAGetCurrentOrder(data->ida_mem, &qlast);
3596 *ierr = 200 + (-flag);
3601 for (jj = 0; jj < qlast; jj++)
3602 alpha = alpha - ONE / (jj + 1);
3604 // CJ=-alpha/hh; // For function Get_Jacobian_cj
3611 xc = (double *) NV_DATA_S(yy);
3612 xcdot = (double *) NV_DATA_S(yp);
3613 residual = (double *) NV_DATA_S(resval);
3616 C2F(dcopy)(neq, xcdot, &c__1, residual, &c__1);
3618 C2F(ierode).iero = 0;
3619 odoit(&tx, xc, xcdot, residual);
3621 C2F(ierode).iero = *ierr;
3626 for (jj = 0; jj < *neq; jj++)
3627 if (residual[jj] - residual[jj] != 0) /* NaN checking */
3629 //sciprint(_("\nWarning: The residual function #%d returns a NaN"),jj);
3633 if (nantest == 1) return 257; /* recoverable error; */
3636 return (abs(*ierr)); /* ierr>0 recoverable error; ierr>0 unrecoverable error; ierr=0: ok*/
3638 /*--------------------------------------------------------------------------*/
3640 static int grblkdaskr(realtype t, N_Vector yy, N_Vector yp, realtype *gout, void *g_data)
3643 int jj = 0, nantest = 0;
3648 C2F(ierode).iero = 0;
3649 zdoit(&tx, NV_DATA_S(yy), NV_DATA_S(yp), (double *)gout);
3652 nantest = 0; /* NaN checking */
3653 for (jj = 0; jj < ng; jj++)
3655 if (gout[jj] - gout[jj] != 0)
3657 sciprint(_("\nWarning: The zero-crossing function #%d returns a NaN"), jj);
3664 return 258; /* recoverable error; */
3667 C2F(ierode).iero = *ierr;
3670 /*--------------------------------------------------------------------------*/
3671 /* Subroutine addevs */
3672 static void addevs(double t, int *evtnb, int *ierr1)
3674 static int i = 0, j = 0;
3678 if (evtspt[*evtnb] != -1)
3680 if ((evtspt[*evtnb] == 0) && (*pointi == *evtnb))
3687 if (*pointi == *evtnb)
3689 *pointi = evtspt[*evtnb]; /* remove from chain */
3694 while (*evtnb != evtspt[i])
3698 evtspt[i] = evtspt[*evtnb]; /* remove old evtnb from chain */
3699 if (TCritWarning == 0)
3701 sciprint(_("\n Warning: an event is reprogrammed at t=%g by removing another"), t );
3702 sciprint(_("\n (already programmed) event. There may be an error in"));
3703 sciprint(_("\n your model. Please check your model\n"));
3706 do_cold_restart(); /* the erased event could be a critical
3707 event, so do_cold_restart is added to
3708 refresh the critical event table */
3724 if (t < tevts[*pointi])
3726 evtspt[*evtnb] = *pointi;
3738 if (t >= tevts[evtspt[i]])
3751 evtspt[*evtnb] = evtspt[i];
3755 /*--------------------------------------------------------------------------*/
3756 /* Subroutine putevs */
3757 void putevs(double *t, int *evtnb, int *ierr1)
3761 if (evtspt[*evtnb] != -1)
3776 evtspt[*evtnb] = *pointi;
3779 /*--------------------------------------------------------------------------*/
3780 /* Subroutine idoit */
3781 static void idoit(double *told)
3783 /* initialisation (propagation of constant blocks outputs) */
3784 /* Copyright INRIA */
3787 scicos_flag flag = 0;
3791 ScicosImport *scs_imp = NULL;
3794 scs_imp = getscicosimportptr();
3797 for (j = 0; j < * (scs_imp->niord); j++)
3799 kf = &scs_imp->iord[j];
3800 C2F(curblk).kfun = *kf; /* */
3801 if (scs_imp->funtyp[*kf - 1] > -1)
3803 /* continuous state */
3804 if (scs_imp->blocks[*kf - 1].nx > 0)
3806 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3807 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3809 scs_imp->blocks[*kf - 1].nevprt = scs_imp->iord[j + * (scs_imp->niord)];
3810 /*callf(told, xd, x, x,x,&flag);*/
3811 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3818 if (scs_imp->blocks[*kf - 1].nevout > 0)
3820 if (scs_imp->funtyp[*kf - 1] < 0)
3822 i = synchro_nev(scs_imp, *kf, ierr);
3827 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3828 putevs(told, &i2, &ierr1);
3831 /* event conflict */
3844 /*--------------------------------------------------------------------------*/
3845 /* Subroutine doit */
3846 static void doit(double *told)
3848 /* propagation of blocks outputs on discrete activations */
3849 /* Copyright INRIA */
3852 scicos_flag flag = 0;
3855 int ii = 0, kever = 0;
3857 ScicosImport *scs_imp = NULL;
3860 scs_imp = getscicosimportptr();
3863 *pointi = evtspt[kever];
3866 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
3872 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1 ; ii++)
3874 kf = &scs_imp->ordclk[ii - 1];
3875 C2F(curblk).kfun = *kf;
3876 if (scs_imp->funtyp[*kf - 1] > -1)
3878 /* continuous state */
3879 if (scs_imp->blocks[*kf - 1].nx > 0)
3881 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3882 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3884 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
3886 /*callf(told, xd, x, x,x,&flag);*/
3887 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3895 /* Initialize tvec */
3896 if (scs_imp->blocks[*kf - 1].nevout > 0)
3898 if (scs_imp->funtyp[*kf - 1] < 0)
3900 i = synchro_nev(scs_imp, *kf, ierr);
3905 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3906 putevs(told, &i2, &ierr1);
3909 /* event conflict */
3922 /*--------------------------------------------------------------------------*/
3923 /* Subroutine cdoit */
3924 static void cdoit(double *told)
3926 /* propagation of continuous blocks outputs */
3927 /* Copyright INRIA */
3930 scicos_flag flag = 0;
3934 ScicosImport *scs_imp = NULL;
3937 scs_imp = getscicosimportptr();
3940 for (j = 0; j < * (scs_imp->ncord); j++)
3942 kf = &scs_imp->cord[j];
3943 C2F(curblk).kfun = *kf;
3944 /* continuous state */
3945 if (scs_imp->blocks[*kf - 1].nx > 0)
3947 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
3948 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
3950 scs_imp->blocks[*kf - 1].nevprt = scs_imp->cord[j + * (scs_imp->ncord)];
3951 if (scs_imp->funtyp[*kf - 1] > -1)
3954 /*callf(told, xd, x, x,x,&flag);*/
3955 callf(told, &scs_imp->blocks[*kf - 1], &flag);
3963 /* Initialize tvec */
3964 if (scs_imp->blocks[*kf - 1].nevout > 0)
3966 if (scs_imp->funtyp[*kf - 1] < 0)
3968 i = synchro_nev(scs_imp, *kf, ierr);
3973 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
3974 putevs(told, &i2, &ierr1);
3977 /* event conflict */
3990 /*--------------------------------------------------------------------------*/
3991 /* Subroutine ddoit */
3992 static void ddoit(double *told)
3994 /* update states & event out on discrete activations */
3995 /* Copyright INRIA */
3998 scicos_flag flag = 0;
4000 int i = 0, i3 = 0, ierr1 = 0;
4001 int ii = 0, keve = 0;
4003 ScicosImport *scs_imp = NULL;
4006 scs_imp = getscicosimportptr();
4016 /* update continuous and discrete states on event */
4021 for (i = 0; i < kiwa; i++)
4024 if (critev[keve] != 0)
4028 i2 = scs_imp->ordptr[keve] - 1;
4029 for (ii = scs_imp->ordptr[keve - 1]; ii <= i2; ii++)
4031 kf = &scs_imp->ordclk[ii - 1];
4032 C2F(curblk).kfun = *kf;
4033 /* continuous state */
4034 if (scs_imp->blocks[*kf - 1].nx > 0)
4036 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4037 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4040 scs_imp->blocks[*kf - 1].nevprt = scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1];
4042 if (scs_imp->blocks[*kf - 1].nevout > 0)
4044 if (scs_imp->funtyp[*kf - 1] >= 0)
4046 /* initialize evout */
4047 for (j = 0; j < scs_imp->blocks[*kf - 1].nevout; j++)
4049 scs_imp->blocks[*kf - 1].evout[j] = -1;
4053 if (scs_imp->blocks[*kf - 1].nevprt > 0) /* if event has continuous origin don't call*/
4055 /*callf(told, xd, x, x ,x,&flag);*/
4056 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4064 for (j = 0; j < scs_imp->blocks[*kf - 1].nevout; j++)
4066 if (scs_imp->blocks[*kf - 1].evout[j] >= 0.)
4068 i3 = j + scs_imp->clkptr[*kf - 1] ;
4069 addevs(scs_imp->blocks[*kf - 1].evout[j] + (*told), &i3, &ierr1);
4072 /* event conflict */
4081 if (scs_imp->blocks[*kf - 1].nevprt > 0)
4083 if (scs_imp->blocks[*kf - 1].nx + scs_imp->blocks[*kf - 1].nz + scs_imp->blocks[*kf - 1].noz > 0 || \
4084 *scs_imp->blocks[*kf - 1].work != NULL)
4086 /* if a hidden state exists, must also call (for new scope eg) */
4087 /* to avoid calling non-real activations */
4089 /*callf(told, xd, x, x,x,&flag);*/
4090 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4100 if (*scs_imp->blocks[*kf - 1].work != NULL)
4103 scs_imp->blocks[*kf - 1].nevprt = 0; /* in case some hidden continuous blocks need updating */
4104 /*callf(told, xd, x, x,x,&flag);*/
4105 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4116 /*--------------------------------------------------------------------------*/
4117 /* Subroutine edoit */
4118 static void edoit(double *told, int *kiwa)
4120 /* update blocks output on discrete activations */
4121 /* Copyright INRIA */
4124 scicos_flag flag = 0;
4125 int ierr1 = 0, i = 0;
4126 int kever = 0, ii = 0;
4128 ScicosImport *scs_imp = NULL;
4132 scs_imp = getscicosimportptr();
4137 *pointi = evtspt[kever];
4140 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
4147 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1; ii++)
4149 kf = &scs_imp->ordclk[ii - 1];
4150 C2F(curblk).kfun = *kf;
4152 if (scs_imp->funtyp[*kf - 1] > -1)
4154 /* continuous state */
4155 if (scs_imp->blocks[*kf - 1].nx > 0)
4157 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4158 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4161 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4164 /*callf(told, xd, x, x,x,&flag);*/
4165 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4173 /* Initialize tvec */
4174 if (scs_imp->blocks[*kf - 1].nevout > 0)
4176 if (scs_imp->funtyp[*kf - 1] < 0)
4178 i = synchro_nev(scs_imp, *kf, ierr);
4183 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4184 putevs(told, &i2, &ierr1);
4187 /* event conflict */
4200 /*--------------------------------------------------------------------------*/
4201 /* Subroutine odoit */
4202 static void odoit(double *told, double *xt, double *xtd, double *residual)
4204 /* update blocks derivative of continuous time block */
4205 /* Copyright INRIA */
4208 scicos_flag flag = 0;
4209 int keve = 0, kiwa = 0;
4210 int ierr1 = 0, i = 0;
4213 ScicosImport *scs_imp = NULL;
4216 scs_imp = getscicosimportptr();
4220 for (jj = 0; jj < * (scs_imp->noord); jj++)
4222 kf = &scs_imp->oord[jj];
4223 C2F(curblk).kfun = *kf;
4224 /* continuous state */
4225 if (scs_imp->blocks[*kf - 1].nx > 0)
4227 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4228 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4229 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4232 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4233 if (scs_imp->funtyp[*kf - 1] > -1)
4236 /*callf(told, xtd, xt, residual,x,&flag);*/
4237 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4245 if (scs_imp->blocks[*kf - 1].nevout > 0)
4247 if (scs_imp->funtyp[*kf - 1] < 0)
4249 if (scs_imp->blocks[*kf - 1].nmode > 0)
4251 i2 = scs_imp->blocks[*kf - 1].mode[0] + scs_imp->clkptr[*kf - 1] - 1;
4255 i = synchro_nev(scs_imp, *kf, ierr);
4260 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4262 putevs(told, &i2, &ierr1);
4265 /* event conflict */
4269 ozdoit(told, xt, xtd, &kiwa);
4278 /* update states derivatives */
4279 for (ii = 0; ii < * (scs_imp->noord); ii++)
4281 kf = &scs_imp->oord[ii];
4282 C2F(curblk).kfun = *kf;
4283 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4284 *scs_imp->blocks[*kf - 1].work != NULL)
4286 /* work tests if a hidden state exists, used for delay block */
4288 /* continuous state */
4289 if (scs_imp->blocks[*kf - 1].nx > 0)
4291 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4292 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4293 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4295 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4296 /*callf(told, xtd, xt, residual,xt,&flag);*/
4297 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4307 for (i = 0; i < kiwa; i++)
4310 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4312 kf = &scs_imp->ordclk[ii - 1];
4313 C2F(curblk).kfun = *kf;
4314 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4315 *scs_imp->blocks[*kf - 1].work != NULL)
4317 /* work tests if a hidden state exists */
4319 /* continuous state */
4320 if (scs_imp->blocks[*kf - 1].nx > 0)
4322 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4323 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4324 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4326 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4327 /*callf(told, xtd, xt, residual,xt,&flag);*/
4328 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4339 /*--------------------------------------------------------------------------*/
4340 /* Subroutine reinitdoit */
4341 static void reinitdoit(double *told)
4343 /* update blocks xproperties of continuous time block */
4344 /* Copyright INRIA */
4347 scicos_flag flag = 0;
4348 int keve = 0, kiwa = 0;
4349 int ierr1 = 0, i = 0;
4352 ScicosImport *scs_imp = NULL;
4355 scs_imp = getscicosimportptr();
4359 for (jj = 0; jj < * (scs_imp->noord); jj++)
4361 kf = &scs_imp->oord[jj];
4362 C2F(curblk).kfun = *kf;
4363 /* continuous state */
4364 if (scs_imp->blocks[*kf - 1].nx > 0)
4366 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4367 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4369 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4370 if (scs_imp->funtyp[*kf - 1] > -1)
4373 /*callf(told, xd, x, x,x,&flag);*/
4374 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4382 if (scs_imp->blocks[*kf - 1].nevout > 0 && scs_imp->funtyp[*kf - 1] < 0)
4384 i = synchro_nev(scs_imp, *kf, ierr);
4389 if (scs_imp->blocks[*kf - 1].nmode > 0)
4391 scs_imp->blocks[*kf - 1].mode[0] = i;
4393 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4394 putevs(told, &i2, &ierr1);
4397 /* event conflict */
4410 for (ii = 0; ii < * (scs_imp->noord); ii++)
4412 kf = &scs_imp->oord[ii];
4413 C2F(curblk).kfun = *kf;
4414 if (scs_imp->blocks[*kf - 1].nx > 0)
4417 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4418 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4419 scs_imp->blocks[*kf - 1].res = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4420 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4421 scs_imp->blocks[*kf - 1].xprop = &scs_imp->xprop[-1 + scs_imp->xptr[*kf - 1]];
4422 /*callf(told, xd, x, xd,x,&flag);*/
4423 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4432 for (i = 0; i < kiwa; i++)
4435 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4437 kf = &scs_imp->ordclk[ii - 1];
4438 C2F(curblk).kfun = *kf;
4439 if (scs_imp->blocks[*kf - 1].nx > 0)
4442 scs_imp->blocks[*kf - 1].x = &scs_imp->x[scs_imp->xptr[*kf - 1] - 1];
4443 scs_imp->blocks[*kf - 1].xd = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4444 scs_imp->blocks[*kf - 1].res = &scs_imp->xd[scs_imp->xptr[*kf - 1] - 1];
4445 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4446 scs_imp->blocks[*kf - 1].xprop = &scs_imp->xprop[-1 + scs_imp->xptr[*kf - 1]];
4447 /*callf(told, xd, x, xd,x,&flag);*/
4448 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4458 /*--------------------------------------------------------------------------*/
4459 /* Subroutine ozdoit */
4460 static void ozdoit(double *told, double *xt, double *xtd, int *kiwa)
4462 /* update blocks output of continuous time block on discrete activations */
4463 /* Copyright INRIA */
4466 scicos_flag flag = 0;
4468 int ierr1 = 0, i = 0;
4469 int ii = 0, kever = 0;
4471 ScicosImport *scs_imp = NULL;
4474 scs_imp = getscicosimportptr();
4478 *pointi = evtspt[kever];
4481 nord = scs_imp->ordptr[kever] - scs_imp->ordptr[kever - 1];
4489 for (ii = scs_imp->ordptr[kever - 1]; ii <= scs_imp->ordptr[kever] - 1; ii++)
4491 kf = &scs_imp->ordclk[ii - 1];
4492 C2F(curblk).kfun = *kf;
4493 if (scs_imp->funtyp[*kf - 1] > -1)
4495 /* continuous state */
4496 if (scs_imp->blocks[*kf - 1].nx > 0)
4498 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4499 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4501 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4503 /*callf(told, xtd, xt, xt,x,&flag);*/
4504 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4512 /* Initialize tvec */
4513 if (scs_imp->blocks[*kf - 1].nevout > 0)
4515 if (scs_imp->funtyp[*kf - 1] < 0)
4517 if (phase == 1 || scs_imp->blocks[*kf - 1].nmode == 0)
4519 i = synchro_nev(scs_imp, *kf, ierr);
4527 i = scs_imp->blocks[*kf - 1].mode[0];
4529 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4530 putevs(told, &i2, &ierr1);
4533 /* event conflict */
4537 ozdoit(told, xt, xtd, kiwa);
4542 /*--------------------------------------------------------------------------*/
4543 /* Subroutine zdoit */
4544 static void zdoit(double *told, double *xt, double *xtd, double *g)
4546 /* update blocks zcross of continuous time block */
4547 /* Copyright INRIA */
4549 scicos_flag flag = 0;
4550 int keve = 0, kiwa = 0;
4551 int ierr1 = 0, i = 0, j = 0;
4554 ScicosImport *scs_imp = NULL;
4557 scs_imp = getscicosimportptr();
4560 for (i = 0; i < * (scs_imp->ng); i++)
4566 for (jj = 0; jj < * (scs_imp->nzord); jj++)
4568 kf = &scs_imp->zord[jj];
4569 C2F(curblk).kfun = *kf;
4570 /* continuous state */
4571 if (scs_imp->blocks[*kf - 1].nx > 0)
4573 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4574 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4576 scs_imp->blocks[*kf - 1].nevprt = scs_imp->zord[jj + * (scs_imp->nzord)];
4578 if (scs_imp->funtyp[*kf - 1] > -1)
4581 /*callf(told, xtd, xt, xt,xt,&flag);*/
4582 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4590 /* Initialize tvec */
4591 if (scs_imp->blocks[*kf - 1].nevout > 0)
4593 if (scs_imp->funtyp[*kf - 1] < 0)
4595 if (phase == 1 || scs_imp->blocks[*kf - 1].nmode == 0)
4597 i = synchro_nev(scs_imp, *kf, ierr);
4605 i = scs_imp->blocks[*kf - 1].mode[0];
4607 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4608 putevs(told, &i2, &ierr1);
4611 /* event conflict */
4615 ozdoit(told, xt, xtd, &kiwa);
4624 /* update zero crossing surfaces */
4625 for (ii = 0; ii < * (scs_imp->nzord); ii++)
4627 kf = &scs_imp->zord[ii];
4628 C2F(curblk).kfun = *kf;
4629 if (scs_imp->blocks[*kf - 1].ng > 0)
4631 /* update g array ptr */
4632 scs_imp->blocks[*kf - 1].g = &g[scs_imp->zcptr[*kf - 1] - 1];
4633 if (scs_imp->funtyp[*kf - 1] > 0)
4636 /* continuous state */
4637 if (scs_imp->blocks[*kf - 1].nx > 0)
4639 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4640 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4642 scs_imp->blocks[*kf - 1].nevprt = scs_imp->zord[ii + * (scs_imp->nzord)];
4643 /*callf(told, xtd, xt, xtd,g,&flag);*/
4644 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4653 j = synchro_g_nev(scs_imp, g, *kf, ierr);
4658 if ( (phase == 1) && (scs_imp->blocks[*kf - 1].nmode > 0) )
4660 scs_imp->blocks[*kf - 1].mode[0] = j;
4664 // scs_imp->blocks[*kf-1].g = &scs_imp->g[scs_imp->zcptr[*kf]-1];
4669 for (i = 0; i < kiwa; i++)
4672 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4674 kf = &scs_imp->ordclk[ii - 1];
4675 C2F(curblk).kfun = *kf;
4676 if (scs_imp->blocks[*kf - 1].ng > 0)
4678 /* update g array ptr */
4679 scs_imp->blocks[*kf - 1].g = &g[scs_imp->zcptr[*kf - 1] - 1];
4680 if (scs_imp->funtyp[*kf - 1] > 0)
4683 /* continuous state */
4684 if (scs_imp->blocks[*kf - 1].nx > 0)
4686 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4687 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4689 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4690 /*callf(told, xtd, xt, xtd,g,&flag);*/
4691 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4700 j = synchro_g_nev(scs_imp, g, *kf, ierr);
4705 if ((phase == 1) && (scs_imp->blocks[*kf - 1].nmode > 0))
4707 scs_imp->blocks[*kf - 1].mode[0] = j;
4711 //scs_imp->blocks[*kf-1].g = &scs_imp->g[scs_imp->zcptr[*kf]-1];
4716 /*--------------------------------------------------------------------------*/
4717 /* Subroutine Jdoit */
4718 void Jdoit(double *told, double *xt, double *xtd, double *residual, int *job)
4720 /* update blocks jacobian of continuous time block */
4721 /* Copyright INRIA */
4724 scicos_flag flag = 0;
4725 int keve = 0, kiwa = 0;
4726 int ierr1 = 0, i = 0;
4729 ScicosImport *scs_imp = NULL;
4732 scs_imp = getscicosimportptr();
4736 for (jj = 0; jj < * (scs_imp->noord); jj++)
4738 kf = &scs_imp->oord[jj];
4739 C2F(curblk).kfun = *kf;
4740 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[jj + * (scs_imp->noord)];
4741 if (scs_imp->funtyp[*kf - 1] > -1)
4744 /* applying desired output */
4745 if ((*job == 2) && (scs_imp->oord[jj] == AJacobian_block))
4749 /* continuous state */
4750 if (scs_imp->blocks[*kf - 1].nx > 0)
4752 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4753 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4754 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4757 /*callf(told, xtd, xt, residual,x,&flag);*/
4758 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4766 if (scs_imp->blocks[*kf - 1].nevout > 0)
4768 if (scs_imp->funtyp[*kf - 1] < 0)
4770 if (scs_imp->blocks[*kf - 1].nmode > 0)
4772 i2 = scs_imp->blocks[*kf - 1].mode[0] + scs_imp->clkptr[*kf - 1] - 1;
4776 i = synchro_nev(scs_imp, *kf, ierr);
4781 i2 = i + scs_imp->clkptr[*kf - 1] - 1;
4783 putevs(told, &i2, &ierr1);
4786 /* event conflict */
4790 ozdoit(told, xt, xtd, &kiwa);
4795 /* update states derivatives */
4796 for (ii = 0; ii < * (scs_imp->noord); ii++)
4798 kf = &scs_imp->oord[ii];
4799 C2F(curblk).kfun = *kf;
4800 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4801 *scs_imp->blocks[*kf - 1].work != NULL)
4803 /* work tests if a hidden state exists, used for delay block */
4805 if (((*job == 1) && (scs_imp->oord[ii] == AJacobian_block)) || (*job != 1))
4807 if (*job == 1) flag = 10;
4808 /* continuous state */
4809 if (scs_imp->blocks[*kf - 1].nx > 0)
4811 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4812 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4813 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4815 scs_imp->blocks[*kf - 1].nevprt = scs_imp->oord[ii + * (scs_imp->noord)];
4816 /*callf(told, xtd, xt, residual,xt,&flag);*/
4817 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4827 for (i = 0; i < kiwa; i++)
4830 for (ii = scs_imp->ordptr[keve - 1]; ii <= scs_imp->ordptr[keve] - 1; ii++)
4832 kf = &scs_imp->ordclk[ii - 1];
4833 C2F(curblk).kfun = *kf;
4834 if (scs_imp->blocks[*kf - 1].nx > 0 || \
4835 *scs_imp->blocks[*kf - 1].work != NULL)
4837 /* work tests if a hidden state exists */
4839 if (((*job == 1) && (scs_imp->oord[ii - 1] == AJacobian_block)) || (*job != 1))
4841 if (*job == 1) flag = 10;
4842 /* continuous state */
4843 if (scs_imp->blocks[*kf - 1].nx > 0)
4845 scs_imp->blocks[*kf - 1].x = &xt[scs_imp->xptr[*kf - 1] - 1];
4846 scs_imp->blocks[*kf - 1].xd = &xtd[scs_imp->xptr[*kf - 1] - 1];
4847 scs_imp->blocks[*kf - 1].res = &residual[scs_imp->xptr[*kf - 1] - 1];
4849 scs_imp->blocks[*kf - 1].nevprt = abs(scs_imp->ordclk[ii + * (scs_imp->nordclk) - 1]);
4850 /*callf(told, xtd, xt, residual,xt,&flag);*/
4851 callf(told, &scs_imp->blocks[*kf - 1], &flag);
4862 /*--------------------------------------------------------------------------*/
4863 /* Subroutine synchro_nev */
4864 static int synchro_nev(ScicosImport *scs_imp, int kf, int *ierr)
4866 /* synchro blocks computation */
4867 /* Copyright INRIA */
4868 SCSREAL_COP *outtbdptr = NULL; /*to store double of outtb*/
4869 SCSINT8_COP *outtbcptr = NULL; /*to store int8 of outtb*/
4870 SCSINT16_COP *outtbsptr = NULL; /*to store int16 of outtb*/
4871 SCSINT32_COP *outtblptr = NULL; /*to store int32 of outtb*/
4872 SCSUINT8_COP *outtbucptr = NULL; /*to store unsigned int8 of outtb */
4873 SCSUINT16_COP *outtbusptr = NULL; /*to store unsigned int16 of outtb */
4874 SCSUINT32_COP *outtbulptr = NULL; /*to store unsigned int32 of outtb */
4877 int i = 0; /* return 0 by default */
4879 /* variable for param */
4881 void **outtbptr = NULL;
4887 outtbtyp = scs_imp->outtbtyp;
4888 outtbptr = scs_imp->outtbptr;
4889 funtyp = scs_imp->funtyp;
4890 inplnk = scs_imp->inplnk;
4891 inpptr = scs_imp->inpptr;
4893 /* if-then-else blk */
4894 if (funtyp[kf - 1] == -1)
4896 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
4899 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4900 cond = (*outtbdptr <= 0.);
4904 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4905 cond = (*outtbdptr <= 0.);
4909 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4910 cond = (*outtbcptr <= 0);
4914 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4915 cond = (*outtbsptr <= 0);
4919 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4920 cond = (*outtblptr <= 0);
4924 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4925 cond = (*outtbucptr <= 0);
4929 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4930 cond = (*outtbusptr <= 0);
4934 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4935 cond = (*outtbulptr <= 0);
4938 default : /* Add a message here */
4952 else if (funtyp[kf - 1] == -2)
4954 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
4957 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4958 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
4962 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4963 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
4967 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4968 i = Max(Min((int) * outtbcptr,
4969 scs_imp->blocks[kf - 1].nevout), 1);
4973 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4974 i = Max(Min((int) * outtbsptr, scs_imp->blocks[kf - 1].nevout), 1);
4978 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4979 i = Max(Min((int) * outtblptr, scs_imp->blocks[kf - 1].nevout), 1);
4983 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4984 i = Max(Min((int) * outtbucptr, scs_imp->blocks[kf - 1].nevout), 1);
4988 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4989 i = Max(Min((int) * outtbusptr, scs_imp->blocks[kf - 1].nevout), 1);
4993 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
4994 i = Max(Min((int) * outtbulptr, scs_imp->blocks[kf - 1].nevout), 1);
4997 default : /* Add a message here */
5004 /*--------------------------------------------------------------------------*/
5005 /* Subroutine synchro_g_nev */
5006 static int synchro_g_nev(ScicosImport *scs_imp, double *g, int kf, int *ierr)
5008 /* synchro blocks with zcross computation */
5009 /* Copyright INRIA */
5010 SCSREAL_COP *outtbdptr = NULL; /*to store double of outtb*/
5011 SCSINT8_COP *outtbcptr = NULL; /*to store int8 of outtb*/
5012 SCSINT16_COP *outtbsptr = NULL; /*to store int16 of outtb*/
5013 SCSINT32_COP *outtblptr = NULL; /*to store int32 of outtb*/
5014 SCSUINT8_COP *outtbucptr = NULL; /*to store unsigned int8 of outtb */
5015 SCSUINT16_COP *outtbusptr = NULL; /*to store unsigned int16 of outtb */
5016 SCSUINT32_COP *outtbulptr = NULL; /*to store unsigned int32 of outtb */
5019 int i = 0; /* return 0 by default */
5022 /* variable for param */
5023 int *outtbtyp = NULL;
5024 void **outtbptr = NULL;
5031 outtbtyp = scs_imp->outtbtyp;
5032 outtbptr = scs_imp->outtbptr;
5033 funtyp = scs_imp->funtyp;
5034 inplnk = scs_imp->inplnk;
5035 inpptr = scs_imp->inpptr;
5036 zcptr = scs_imp->zcptr;
5038 /* if-then-else blk */
5039 if (funtyp[kf - 1] == -1)
5041 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
5044 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5045 g[zcptr[kf - 1] - 1] = *outtbdptr;
5046 cond = (*outtbdptr <= 0.);
5050 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5051 g[zcptr[kf - 1] - 1] = *outtbdptr;
5052 cond = (*outtbdptr <= 0.);
5056 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5057 g[zcptr[kf - 1] - 1] = (double) * outtbcptr;
5058 cond = (*outtbcptr <= 0);
5062 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5063 g[zcptr[kf - 1] - 1] = (double) * outtbsptr;
5064 cond = (*outtbsptr <= 0);
5068 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5069 g[zcptr[kf - 1] - 1] = (double) * outtblptr;
5070 cond = (*outtblptr <= 0);
5074 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5075 g[zcptr[kf - 1] - 1] = (double) * outtbucptr;
5076 cond = (*outtbucptr <= 0);
5080 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5081 g[zcptr[kf - 1] - 1] = (double) * outtbusptr;
5082 cond = (*outtbusptr <= 0);
5086 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5087 g[zcptr[kf - 1] - 1] = (double) * outtbulptr;
5088 cond = (*outtbulptr <= 0);
5091 default : /* Add a message here */
5105 else if (funtyp[kf - 1] == -2)
5107 switch (outtbtyp[-1 + inplnk[inpptr[kf - 1] - 1]])
5110 outtbdptr = (SCSREAL_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5111 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5113 g[zcptr[kf - 1] - 1 + jj] = *outtbdptr - (double)(jj + 2);
5115 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
5119 outtbdptr = (SCSCOMPLEX_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5120 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5122 g[zcptr[kf - 1] - 1 + jj] = *outtbdptr - (double)(jj + 2);
5124 i = Max(Min((int) * outtbdptr, scs_imp->blocks[kf - 1].nevout), 1);
5128 outtbcptr = (SCSINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5129 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5131 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbcptr - (double)(jj + 2);
5133 i = Max(Min((int) * outtbcptr, scs_imp->blocks[kf - 1].nevout), 1);
5137 outtbsptr = (SCSINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5138 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5140 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbsptr - (double)(jj + 2);
5142 i = Max(Min((int) * outtbsptr, scs_imp->blocks[kf - 1].nevout), 1);
5146 outtblptr = (SCSINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5147 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5149 g[zcptr[kf - 1] - 1 + jj] = (double) * outtblptr - (double)(jj + 2);
5151 i = Max(Min((int) * outtblptr, scs_imp->blocks[kf - 1].nevout), 1);
5155 outtbucptr = (SCSUINT8_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5156 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5158 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbucptr - (double)(jj + 2);
5160 i = Max(Min((int) * outtbucptr, scs_imp->blocks[kf - 1].nevout), 1);
5164 outtbusptr = (SCSUINT16_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5165 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5167 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbusptr - (double)(jj + 2);
5169 i = Max(Min((int) * outtbusptr, scs_imp->blocks[kf - 1].nevout), 1);
5173 outtbulptr = (SCSUINT32_COP *)outtbptr[-1 + inplnk[inpptr[kf - 1] - 1]];
5174 for (jj = 0; jj < scs_imp->blocks[kf - 1].nevout - 1; jj++)
5176 g[zcptr[kf - 1] - 1 + jj] = (double) * outtbulptr - (double)(jj + 2);
5178 i = Max(Min((int) * outtbulptr, scs_imp->blocks[kf - 1].nevout), 1);
5181 default : /* Add a message here */
5187 } /* synchro_g_nev */
5188 /*--------------------------------------------------------------------------*/
5190 static void FREE_blocks()
5193 for (kf = 0; kf < nblk; ++kf)
5195 if (Blocks[kf].insz != NULL)
5197 FREE(Blocks[kf].insz);
5203 if (Blocks[kf].inptr != NULL)
5205 FREE(Blocks[kf].inptr);
5211 if (Blocks[kf].outsz != NULL)
5213 FREE(Blocks[kf].outsz);
5219 if (Blocks[kf].outptr != NULL)
5221 FREE(Blocks[kf].outptr);
5227 if (Blocks[kf].oparsz != NULL)
5229 FREE(Blocks[kf].oparsz);
5235 if (Blocks[kf].ozsz != NULL)
5237 FREE(Blocks[kf].ozsz);
5243 if (Blocks[kf].label != NULL)
5245 FREE(Blocks[kf].label);
5251 if (Blocks[kf].evout != NULL)
5253 FREE(Blocks[kf].evout);
5262 if (nx > 0) FREE(xprop);
5264 if (nmod > 0) FREE(mod);
5266 if (ng > 0) FREE(g);
5270 /*--------------------------------------------------------------------------*/
5271 /* Subroutine funnum */
5272 int C2F(funnum)(char * fname)
5276 while ( tabsim[i].name != (char *) NULL)
5278 if ( strcmp(fname, tabsim[i].name) == 0 ) return(i + 1);
5281 ln = (int)strlen(fname);
5282 C2F(iislink)(fname, &loc);
5283 C2F(iislink)(fname, &loc);
5284 if (loc >= 0) return(ntabsim + (int)loc + 1);
5287 /*--------------------------------------------------------------------------*/
5288 int get_phase_simulation(void)
5292 /*--------------------------------------------------------------------------*/
5293 void do_cold_restart(void)
5298 /*--------------------------------------------------------------------------*/
5299 /* get_scicos_time : return the current
5302 double get_scicos_time(void)
5306 /*--------------------------------------------------------------------------*/
5307 /* get_block_number : return the current
5310 int get_block_number(void)
5312 return C2F(curblk).kfun;
5314 /*--------------------------------------------------------------------------*/
5315 /* set_block_error : set an error number
5318 void set_block_error(int err)
5322 /*--------------------------------------------------------------------------*/
5323 /* Coserror : copy an error message
5324 * in coserr.buf an set block_error to
5329 #define vsnprintf _vsnprintf
5334 void Coserror(const char *fmt, ...)
5342 retval = vsnprintf(coserr.buf, 4095, fmt, ap);
5344 retval = vsprintf(coserr.buf, fmt, ap);
5349 coserr.buf[0] = '\0';
5354 /* coserror use error number 10 */
5357 /*--------------------------------------------------------------------------*/
5358 /* get_block_error : get the block error
5361 int get_block_error()
5363 return *block_error;
5365 /*--------------------------------------------------------------------------*/
5366 void end_scicos_sim()
5368 C2F(coshlt).halt = 2;
5371 /*--------------------------------------------------------------------------*/
5372 /* get_pointer_xproperty */
5373 int* get_pointer_xproperty()
5375 return &xprop[-1 + xptr[C2F(curblk).kfun]];
5377 /*--------------------------------------------------------------------------*/
5378 /* get_Npointer_xproperty */
5379 int get_npointer_xproperty()
5381 return Blocks[C2F(curblk).kfun - 1].nx;
5383 /*--------------------------------------------------------------------------*/
5384 /* set_pointer_xproperty */
5385 void set_pointer_xproperty(int* pointer)
5388 for (i = 0; i < Blocks[C2F(curblk).kfun - 1].nx; i++)
5390 Blocks[C2F(curblk).kfun - 1].xprop[i] = pointer[i];
5393 /*--------------------------------------------------------------------------*/
5395 void Set_Jacobian_flag(int flag)
5397 Jacobian_Flag = flag;
5400 /*--------------------------------------------------------------------------*/
5401 /* Get_Jacobian_ci et Get_Jacobian_cj were called by the C file only produced
5402 by Modelicac v 1.11.2 */
5403 /* double Get_Jacobian_ci(void)
5407 /*--------------------------------------------------------------------------*/
5408 /* double Get_Jacobian_cj(void)
5412 /*--------------------------------------------------------------------------*/
5413 /* Fonction called by the C file produced by Modelicac 1.7.3 and 1.12.1 */
5414 double Get_Jacobian_parameter(void)
5418 /*--------------------------------------------------------------------------*/
5419 double Get_Scicos_SQUR(void)
5423 /*--------------------------------------------------------------------------*/
5424 static int Jacobians(long int Neq, realtype tt, N_Vector yy, N_Vector yp,
5425 N_Vector resvec, realtype cj, void *jdata, DenseMat Jacque,
5426 N_Vector tempv1, N_Vector tempv2, N_Vector tempv3)
5429 double *xc = NULL, *xcdot = NULL, *residual = NULL;
5431 int i = 0, j = 0, n = 0, nx = 0, ni = 0, no = 0, nb = 0, m = 0, flag = 0;
5432 double *RX = NULL, *Fx = NULL, *Fu = NULL, *Gx = NULL, *Gu = NULL, *ERR1 = NULL, *ERR2 = NULL;
5433 double *Hx = NULL, *Hu = NULL, *Kx = NULL, *Ku = NULL, *HuGx = NULL, *FuKx = NULL, *FuKuGx = NULL, *HuGuKx = NULL;
5438 /* taill1= 3*n+(n+ni)*(n+no)+nx(2*nx+ni+2*m+no)+m*(2*m+no+ni)+2*ni*no*/
5439 double inc = 0., inc_inv = 0., xi = 0., xpi = 0., srur = 0.;
5440 realtype *Jacque_col = NULL;
5445 double *ewt_data = NULL;
5449 data = (UserData) jdata;
5452 flag = IDAGetCurrentStep(data->ida_mem, &hh);
5455 *ierr = 200 + (-flag);
5459 flag = IDAGetErrWeights(data->ida_mem, ewt);
5462 *ierr = 200 + (-flag);
5466 ewt_data = NV_DATA_S(ewt);
5467 xc = (double *) N_VGetArrayPointer(yy);
5468 xcdot = (double *) N_VGetArrayPointer(yp);
5469 /*residual=(double *) NV_DATA_S(resvec);*/
5471 // CJ=(double)cj; // for fonction Get_Jacobian_cj
5472 CJJ = (double)cj; // returned by Get_Jacobian_parameter
5474 srur = (double) RSqrt(UNIT_ROUNDOFF);
5476 if (AJacobian_block > 0)
5478 nx = Blocks[AJacobian_block - 1].nx; /* quant on est là cela signifie que AJacobian_block>0 */
5479 no = Blocks[AJacobian_block - 1].nout;
5480 ni = Blocks[AJacobian_block - 1].nin;
5481 y = (double **)Blocks[AJacobian_block - 1].outptr; /*for compatibility */
5482 u = (double **)Blocks[AJacobian_block - 1].inptr; /*warning pointer of y and u have changed to void ***/
5494 residual = (double *)data->rwork;
5495 ERR1 = residual + n;
5498 Fx = RX + (n + ni) * (n + no); /* car (nx+ni)*(nx+no) peut etre > `a n*n*/
5506 HuGx = Ku + ni * no;
5507 FuKx = HuGx + m * nx;
5508 FuKuGx = FuKx + nx * m;
5509 HuGuKx = FuKuGx + nx * nx;
5510 /* HuGuKx+m*m; => m*m=size of HuGuKx */
5511 /* ------------------ Numerical Jacobian--->> Hx,Kx */
5513 /* read residuals;*/
5515 Jdoit(&ttx, xc, xcdot, residual, &job);
5516 if (*ierr < 0) return -1;
5518 /* "residual" already contains the current residual,
5519 so the first call to Jdoit can be remoevd*/
5521 for (i = 0; i < m; i++)
5522 for (j = 0; j < ni; j++)
5523 Kx[j + i * ni] = u[j][0];
5525 for (i = 0; i < m; i++)
5529 inc = MAX( srur * MAX( ABS(xi), ABS(hh * xpi)), ONE / ewt_data[i] );
5530 if (hh * xpi < ZERO) inc = -inc;
5531 inc = (xi + inc) - xi;
5534 inc = MAX( srur * ABS(hh*xpi),ONE );
5535 if (hh*xpi < ZERO) inc = -inc;
5536 inc = (xpi + inc) - xi;
5539 // xcdot[i] += CJ*inc;
5541 xcdot[i] += CJJ * inc;
5542 /*a= Max(abs(H[0]*xcdot[i]),abs(1.0/Ewt[i]));
5543 b= Max(1.0,abs(xc[i]));
5544 del=SQUR[0]*Max(a,b); */
5545 job = 0; /* read residuals */
5546 Jdoit(&ttx, xc, xcdot, ERR2, &job);
5547 if (*ierr < 0) return -1;
5548 inc_inv = ONE / inc;
5549 for (j = 0; j < m; j++)
5550 Hx[m * i + j] = (ERR2[j] - residual[j]) * inc_inv;
5551 for (j = 0; j < ni; j++)
5552 Kx[j + i * ni] = (u[j][0] - Kx[j + i * ni]) * inc_inv;
5556 /*----- Numerical Jacobian--->> Hu,Ku */
5558 if (AJacobian_block == 0)
5560 for (j = 0; j < m; j++)
5562 Jacque_col = DENSE_COL(Jacque, j);
5563 for (i = 0; i < m; i++)
5565 Jacque_col[i] = Hx[i + j * m];
5568 C2F(ierode).iero = *ierr;
5571 /****------------------***/
5573 Jdoit(&ttx, xc, xcdot, ERR1, &job);
5574 for (i = 0; i < no; i++)
5575 for (j = 0; j < ni; j++)
5576 Ku[j + i * ni] = u[j][0];
5578 for (i = 0; i < no; i++)
5581 inc = srur * MAX( ABS(ysave), 1);
5582 inc = (ysave + inc) - ysave;
5583 /*del=SQUR[0]* Max(1.0,abs(y[i][0]));
5584 del=(y[i][0]+del)-y[i][0];*/
5586 job = 2; /* applying y[i][0] to the output of imp block*/
5587 Jdoit(&ttx, xc, xcdot, ERR2, &job);
5588 if (*ierr < 0) return -1;
5589 inc_inv = ONE / inc;
5590 for (j = 0; j < m; j++)
5591 Hu[m * i + j] = (ERR2[j] - ERR1[j]) * inc_inv;
5592 for (j = 0; j < ni; j++)
5593 Ku[j + i * ni] = (u[j][0] - Ku[j + i * ni]) * inc_inv;
5596 /*----------------------------------------------*/
5597 job = 1; /* read jacobian through flag=10; */
5598 Jdoit(&ttx, xc, xcdot, &Fx[-m], &job);/* Filling up the FX:Fu:Gx:Gu*/
5599 if (*block_error != 0) sciprint(_("\n error in Jacobian"));
5600 /*-------------------------------------------------*/
5602 Multp(Fu, Ku, RX, nx, ni, ni, no);
5603 Multp(RX, Gx, FuKuGx, nx, no, no, nx);
5605 for (j = 0; j < nx; j++)
5607 Jacque_col = DENSE_COL(Jacque, j + m);
5608 for (i = 0; i < nx; i++)
5610 Jacque_col[i + m] = Fx[i + j * nx] + FuKuGx[i + j * nx];
5614 Multp(Hu, Gx, HuGx, m, no, no, nx);
5616 for (i = 0; i < nx; i++)
5618 Jacque_col = DENSE_COL(Jacque, i + m);
5619 for (j = 0; j < m; j++)
5621 Jacque_col[j] = HuGx[j + i * m];
5625 Multp(Fu, Kx, FuKx, nx, ni, ni, m);
5627 for (i = 0; i < m; i++)
5629 Jacque_col = DENSE_COL(Jacque, i);
5630 for (j = 0; j < nx; j++)
5632 Jacque_col[j + m] = FuKx[j + i * nx];
5637 Multp(Hu, Gu, RX, m, no, no, ni);
5638 Multp(RX, Kx, HuGuKx, m, ni, ni, m);
5640 for (j = 0; j < m; j++)
5642 Jacque_col = DENSE_COL(Jacque, j);
5643 for (i = 0; i < m; i++)
5645 Jacque_col[i] = Hx[i + j * m] + HuGuKx[i + j * m];
5649 /* chr='Z'; printf("\n t=%g",ttx); DISP(Z,n,n,chr);*/
5650 C2F(ierode).iero = *ierr;
5654 /*----------------------------------------------------*/
5655 static void Multp(double *A, double *B, double *R, int ra, int rb, int ca, int cb)
5657 int i = 0, j = 0, k = 0;
5658 /*if (ca!=rb) sciprint(_("\n Error in matrix multiplication"));*/
5659 for (i = 0; i < ra; i++)
5660 for (j = 0; j < cb; j++)
5662 R[i + ra * j] = 0.0;
5663 for (k = 0; k < ca; k++)
5664 R[i + ra * j] += A[i + k * ra] * B[k + j * rb];
5668 /*--------------------------------------------------------------------------*/
5669 int read_xml_initial_states(int nvar, const char * xmlfile, char **ids, double *svars)
5671 ezxml_t model, elements;
5672 int result = 0, i = 0;
5675 if (nvar == 0) return 0;
5677 for (i = 0; i < nvar; i++)
5679 if (strcmp(ids[i], "") != 0)
5685 if (result == 0) return 0;
5687 model = ezxml_parse_file(xmlfile);
5691 sciprint(_("Error: Cannot find file '%s'.\n"), xmlfile);
5692 return -1;/* file does not exist*/
5695 elements = ezxml_child(model, "elements");
5696 for (i = 0; i < nvar; i++)
5699 result = read_id(&elements, ids[i], &vr);
5700 if (result == 1) svars[i] = vr;
5705 /*--------------------------------------------------------------------------*/
5706 static int read_id(ezxml_t *elements, char *id, double *value)
5708 char V1[100], V2[100];
5709 int ok = 0, i = 0, ln = 0;
5711 if (strcmp(id, "") == 0) return 0;
5712 ok = search_in_child(elements, id, V1);
5715 /*sciprint(_("Cannot find: %s=%s \n"),id,V1); */
5720 if (Convert_number(V1, value) != 0)
5722 ln = (int)(strlen(V1));
5725 for (i = 1; i <= ln - 2; i++) V2[i - 1] = V1[i];
5727 ok = read_id(elements, V2, value);
5734 /* printf("\n ---->>>%s= %g",V1,*value);*/
5739 /*--------------------------------------------------------------------------*/
5740 int Convert_number(char *s, double *out)
5745 d = strtod(s, &endp);
5746 if (s != endp && *endp == '\0')
5748 /* printf(" It's a float with value %g ", d); */
5754 l = strtol(s, &endp, 0);
5755 if (s != endp && *endp == '\0')
5757 /*printf(" It's an int with value %ld ", 1); */
5763 /*printf(" string "); */
5768 /*--------------------------------------------------------------------------*/
5769 int write_xml_states(int nvar, const char * xmlfile, char **ids, double *x)
5771 ezxml_t model, elements;
5772 int result = 0, i = 0, err = 0;
5777 if (nvar == 0) return 0;
5779 for (i = 0; i < nvar; i++)
5781 if (strcmp(ids[i], "") != 0)
5787 if (result == 0) return 0;
5789 xv = MALLOC(nvar * sizeof(char*));
5790 for (i = 0; i < nvar; i++)
5792 xv[i] = MALLOC(nvar * 100 * sizeof(char));
5793 sprintf(xv[i], "%g", x[i]);
5796 model = ezxml_parse_file(xmlfile);
5799 sciprint(_("Error: Cannot find file '%s'.\n"), xmlfile);
5800 for (i = 0; i < nvar; i++)
5805 return -1;/* file does not exist */
5808 elements = ezxml_child(model, "elements");
5810 for (i = 0; i < nvar; i++)
5812 if (strcmp(ids[i], "") == 0) continue;
5813 result = write_in_child(&elements, ids[i], xv[i]);
5816 /* sciprint(_("cannot find %s in '%s' \n"),ids[i],xmlfile); */
5817 /* err= -1;*/ /* Variable does not exist*/
5821 s = ezxml_toxml(model);
5825 wcfopen(fd, (char*)xmlfile, "wb");
5828 sciprint(_("Error: cannot write to '%s' \n"), xmlfile);
5829 for (i = 0; i < nvar; i++)
5834 return -3;/* cannot write to file*/
5842 /*--------------------------------------------------------------------------*/
5843 int C2F(fx)(double *x, double *residual) /* used for homotopy*/
5845 double *xdot = NULL, t = 0;
5849 C2F(ierode).iero = 0;
5850 odoit(&t, x, xdot, residual);
5851 C2F(ierode).iero = *ierr;
5854 /*--------------------------------------------------------------------------*/
5855 int rho_(double *a, double *L, double *x, double *rho, double *rpar, int *ipar) /* used for homotopy*/
5861 for (i = 0; i < N; i++)
5862 rho[i] += (-1 + *L) * a[i];
5865 /*--------------------------------------------------------------------------*/
5866 int rhojac_(double *a, double *lambda, double *x, double *jac, int *col, double *rpar, int *ipar) /* used for homotopy*/
5868 /* MATRIX [d_RHO/d_LAMBDA, d_RHO/d_X_col] */
5870 double *work = NULL;
5872 double inc = 0., inc_inv = 0., xi = 0., srur = 0.;
5876 for (j = 0; j < N; j++)
5881 if ((work = (double *) MALLOC(N * sizeof(double))) == NULL)
5886 rho_(a, lambda, x, work, rpar, ipar);
5889 inc = srur * Max(fabs(xi), 1);
5890 inc = (xi + inc) - xi;
5894 rho_(a, lambda, x, jac, rpar, ipar);
5895 inc_inv = 1.0 / inc;
5897 for (j = 0; j < N; j++)
5898 jac[j] = (jac[j] - work[j]) * inc_inv;