#include "scicos_block4.h" /* Masoud Najafi, Alan Layec September 2007 */ /* Copyright INRIA * Scicos block simulator * From workspace block */ #include "../stack-c.h" #include <stdio.h> #include <string.h> #include "../machine.h" #include <math.h> #ifndef NULL #define NULL 0 #endif #define T0 ptr->workt[0] #define TNm1 ptr->workt[nPoints-1] #define TP (TNm1-0) extern int C2F(cvstr) __PARAMS((integer *,integer *,char *,integer *,unsigned long int)); extern int C2F(mgetnc)(); extern void C2F(mopen)(); extern int C2F(cluni0) __PARAMS((char *name, char *nams, integer *ln, long int name_len, long int nams_len)); extern void C2F(mclose) __PARAMS((integer *fd, double *res)); extern void sciprint __PARAMS((char *fmt,...)); int Mytridiagldltsolve(double *d, double * l, double * b, int n); int Myevalhermite2(double *t, double *xa, double *xb, double *ya, double *yb, double *da, double *db, double *h, double *dh, double *ddh, double *dddh, int *i); /*int Myevalhermite(double *t, double *xa, double *xb, double *ya, double *yb, double *da, double *db, double *h, double *dh, double *ddh, double *dddh, int *i);*/ /* function to check and extract data coming from an hypermat */ int Ishm(int *fd,int *Ytype,int *nPoints,int *my,int *ny,int *YsubType); static char fmtd[3]={'d','l','\000'}; static char fmti[3]={'i','l','\000'}; /* static char fmtl[3]={'l','l','\000'}; */ static char fmts[3]={'s','l','\000'}; static char fmtc[3]={'c','l','\000'}; static char fmtui[3]={'u','i','\000'}; /* static char fmtul[3]={'u','l','\000'}; */ static char fmtus[3]={'u','s','\000'}; static char fmtuc[3]={'u','c','\000'}; #ifdef hppa #undef FILENAME_MAX #define FILENAME_MAX 4096 #endif /* work struct for that block */ typedef struct { int nPoints; int Hmat; int Yt; int Yst; int cnt1; int cnt2; int EVindex; int PerEVcnt; int firstevent; double *D; void *work; double *workt; } fromwork_struct ; void fromws_c(scicos_block *block,int flag) { void **_work=GetPtrWorkPtrs(block); int *_ipar=GetIparPtrs(block); double *_evout= GetNevOutPtrs(block); double t,y1,y2,t1,t2,r; double *spline, *A_d, *A_sd, *qdy; /* double a,b,c,*y;*/ double d1,d2,h, dh, ddh, dddh; /* counter and indexes variables */ int i,inow; int j,jfirst; int cnt1, cnt2, EVindex, PerEVcnt; int Fnlength,*FName,Method,ZC,OutEnd; Fnlength= _ipar[0]; FName= _ipar+1; Method= _ipar[1+Fnlength]; ZC= _ipar[2+Fnlength]; OutEnd= _ipar[3+Fnlength]; /* variables to handle files of TMPDIR/Workspace */ int fd; char *status; int swap = 1; double res; int out_n; long int lout; char filename[FILENAME_MAX]; char str[100]={0}; int ierr; /* variables for type and dims of data coming from scilab */ int Ytype, YsubType, mY, nY; int nPoints; int Ydim[10]; /* variables for type and dims of data of the output port block */ int ytype, my, ny; /* generic pointer */ SCSREAL_COP *y_d,*y_cd,*ptr_d, *ptr_T, *ptr_D; SCSINT8_COP *y_c,*ptr_c; SCSUINT8_COP *y_uc, *ptr_uc; SCSINT16_COP *y_s,*ptr_s; SCSUINT16_COP *y_us,*ptr_us; SCSINT32_COP *y_l,*ptr_l; SCSUINT32_COP *y_ul,*ptr_ul; /* the struct ptr of that block */ fromwork_struct *ptr; /* for path of TMPDIR/workspace */ char env[256]; char sep[2]; #ifdef _MSC_VER sep[0]='\\'; #else sep[0]='/'; #endif sep[1]='\0'; /*retrieve dimensions of output port*/ my = GetOutPortRows(block,1); /* number of rows of Outputs*/ ny = GetOutPortCols(block,1); /* number of cols of Outputs*/ ytype = GetOutType(block,1); /* output type */ ptr_d=NULL; ptr_D=NULL; /* init */ if (flag==4) { /* convert scilab code of the variable name to C string */ C2F(cvstr)(&(Fnlength),FName,str,(j=1,&j),(SCSUINT32_COP)strlen(str)); str[Fnlength] = '\0'; /* retrieve path of TMPDIR/workspace */ strcpy(env,getenv("TMPDIR")); strcat(env,sep); strcat(env,"Workspace"); strcat(env,sep); strcat(env,str); /* open tmp file */ status = "rb"; /* "r" : read */ /* "b" : binary format (required for Windows) */ lout=FILENAME_MAX; C2F(cluni0)(env, filename, &out_n,1,lout); C2F(mopen)(&fd,env,status,&swap,&res,&ierr); if (ierr!=0) { /*sciprint("The '%s' variable does not exist.\n",str); *set_block_error(-3); */ Coserror("The '%s' variable does not exist.\n",str); return; } /* read x */ C2F(mgetnc) (&fd, &Ydim[0], (j=nsiz,&j), fmti, &ierr); /* read sci id */ C2F(mgetnc) (&fd, &Ydim[6], (j=1,&j), fmti, &ierr); /* read sci type */ if (Ydim[6]==17) { if (!Ishm(&fd,&Ytype,&nPoints,&mY,&nY,&YsubType)) { /*Coserror("Invalid variable type.\n");*/ /*sciprint("Invalid variable type.\n"); set_block_error(-3); */ C2F(mclose)(&fd,&res); return; } if (!((Ytype==1) || (Ytype==8))) { Coserror("Invalid variable type.\n"); /*sciprint("Invalid variable type.\n"); set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } } else if ((Ydim[6]==1)||(Ydim[6]==8)) { C2F(mgetnc) (&fd, &Ydim[7], (j=3,&j), fmti, &ierr); /* read sci header */ Ytype = Ydim[6]; /* data type */ nPoints = Ydim[7]; /* number of data */ mY = Ydim[8]; /* first dimension */ nY = 1; /* second dimension */ YsubType = Ydim[9]; /* subtype */ } else { Coserror("Invalid variable type.\n"); /*sciprint("Invalid variable type.\n"); set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } /* check dimension for output port and variable */ if ((mY!=my)||(nY!=ny)) { Coserror("Data dimensions are inconsistent:\n\r Variable size=[%d,%d] \n\r" "Block output size=[%d,%d].\n",mY,nY,my,ny); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } /* check variable data type and output block data type */ if (Ytype==1) { /*real/complex cases*/ switch (YsubType) { case 0: if (ytype!=10) { Coserror("Output should be of Real type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; case 1: if (ytype!=11) { Coserror("Output should be of complex type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; } } else if(Ytype==8) { /*integer cases*/ switch (YsubType) { case 1: if (ytype!=81) { sciprint("Output should be of int8 type.\n"); set_block_error(-3); C2F(mclose)(&fd,&res); return; } break; case 2: if (ytype!=82) { Coserror("Output should be of int16 type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; case 4: if (ytype!=84) { Coserror("Output should be of int32 type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; case 11:if (ytype!=811) { Coserror("Output should be of uint8 type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; case 12:if (ytype!=812) { Coserror("Output should be of uint16 type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; case 14:if (ytype!=814) { Coserror("Output should be of uint32 type.\n"); /*set_block_error(-3);*/ C2F(mclose)(&fd,&res); return; } break; } } /* allocation of the work structure of that block */ if((*(_work)=(fromwork_struct*) scicos_malloc(sizeof(fromwork_struct)))==NULL) { set_block_error(-16); C2F(mclose)(&fd,&res); return; } ptr = *(_work); ptr->D=NULL; ptr->workt=NULL; ptr->work=NULL; if (Ytype==1) { /*real/complex case*/ switch (YsubType) { case 0 : /* Real */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(double)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_d = (SCSREAL_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_d, (j=nPoints*mY*nY,&j), fmtd, &ierr); /* read double data */ break; case 1: /* complex */ if((ptr->work=(void *) scicos_malloc(2*nPoints*mY*nY*sizeof(double)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_d = (SCSREAL_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_d, (j=2*nPoints*mY*nY,&j), fmtd, &ierr); /* read double data */ break; } } else if(Ytype==8) { /*integer case*/ switch (YsubType) { case 1 :/* int8 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(char)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_c = (SCSINT8_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_c, (j=nPoints*mY*nY,&j), fmtc, &ierr); /* read char data */ break; case 2 : /* int16 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(SCSINT16_COP)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_s = (SCSINT16_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_s, (j=nPoints*mY*nY,&j), fmts, &ierr); /* read short data */ break; case 4 : /* int32 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(SCSINT32_COP)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_l = (SCSINT32_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_l, (j=nPoints*mY*nY,&j), fmti, &ierr); /* read short data */ break; case 11 : /* uint8 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(SCSUINT8_COP)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_uc = (SCSUINT8_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_uc, (j=nPoints*mY*nY,&j), fmtuc, &ierr); /* read short data */ break; case 12 : /* uint16 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(SCSUINT16_COP)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_us = (SCSUINT16_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_us, (j=nPoints*mY*nY,&j), fmtus, &ierr); /* read short data */ break; case 14 : /* uint32 */ if((ptr->work=(void *) scicos_malloc(nPoints*mY*nY*sizeof(SCSUINT32_COP)))==NULL) { set_block_error(-16); scicos_free(ptr); *(_work)=NULL; C2F(mclose)(&fd,&res); return; } ptr_ul = (SCSUINT32_COP *) ptr->work; C2F(mgetnc) (&fd, ptr_ul, (j=nPoints*mY*nY,&j), fmtui, &ierr); /* read 32bits data */ break; } } /* check Hmat */ if (Ydim[6]==17) { ptr->Hmat=1; } else { ptr->Hmat=0; } /* read t */ C2F(mgetnc) (&fd, &Ydim[0], (j=nsiz,&j), fmti, &ierr); /* read sci id */ C2F(mgetnc) (&fd, &Ydim[6], (j=1,&j), fmti, &ierr); /* read sci type */ C2F(mgetnc) (&fd, &Ydim[7], (j=3,&j), fmti, &ierr); /* read sci header */ if (nPoints!=Ydim[7]) { Coserror("The size of the Time(%d) and Data(%d) vectors are inconsistent.\n",Ydim[7],nPoints); /*set_block_error(-3);*/ *(_work)=NULL; scicos_free(ptr->work); scicos_free(ptr); C2F(mclose)(&fd,&res); return; } if ((Ydim[6]!=1) | (Ydim[9]!=0)) { Coserror("The Time vector type is not ""double"".\n"); /*set_block_error(-3);*/ *(_work)=NULL; scicos_free(ptr->work); scicos_free(ptr); C2F(mclose)(&fd,&res); return; } if((ptr->workt=(double *) scicos_malloc(nPoints*sizeof(double)))==NULL) { set_block_error(-16); *(_work)=NULL; scicos_free(ptr->work); scicos_free(ptr); C2F(mclose)(&fd,&res); return; } ptr_T = (SCSREAL_COP *) ptr->workt; C2F(mgetnc) (&fd, ptr_T, (j=nPoints,&j), fmtd, &ierr); /* read data of t */ /* close the file*/ C2F(mclose)(&fd,&res); /*================================*/ /* check for an increasing time data */ for(j = 0; j < nPoints-1; j++) { if(ptr_T[j] > ptr_T[j+1]) { Coserror("The time vector should be an increasing vector.\n"); /*set_block_error(-3);*/ *(_work)=NULL; scicos_free(ptr->workt); scicos_free(ptr->work); scicos_free(ptr); return; } } /*=================================*/ if ((Method>1)&&(Ytype==1)&&(!ptr->Hmat)) { /* double or complex */ if (YsubType==0) { /*real*/ if((ptr->D=(double *) scicos_malloc(nPoints*mY*sizeof(double)))==NULL) { set_block_error(-16); *(_work)=NULL; scicos_free(ptr->workt); scicos_free(ptr->work); scicos_free(ptr); return; } } else { /*complex*/ if((ptr->D=(double *) scicos_malloc(2*nPoints*mY*sizeof(double)))==NULL) { set_block_error(-16); *(_work)=NULL; scicos_free(ptr->workt); scicos_free(ptr->work); scicos_free(ptr); return; } } if((spline=(double *) scicos_malloc((3*nPoints-2)*sizeof(double)))==NULL) { Coserror("Allocation problem in spline.\n"); /*set_block_error(-16);*/ *(_work)=NULL; scicos_free(ptr->D); scicos_free(ptr->workt); scicos_free(ptr->work); scicos_free(ptr); return; } A_d = spline; A_sd = A_d + nPoints; qdy = A_sd + nPoints-1; for (j=0;j<mY;j++) { /* real part */ for (i=0;i<=nPoints-2;i++) { A_sd[i] = 1.0 / (ptr_T[i+1] - ptr_T[i]); qdy[i] = (ptr_d[i+1+j*nPoints] - ptr_d[i+j*nPoints]) * A_sd[i]*A_sd[i]; } for (i=1;i<=nPoints-2;i++) { A_d[i] = 2.0*(A_sd[i-1] +A_sd[i]); ptr->D[i+j*nPoints] = 3.0*(qdy[i-1]+qdy[i]); } if (Method==2) { A_d[0] = 2.0*A_sd[0]; ptr->D[0+j*nPoints] = 3.0 * qdy[0]; A_d[nPoints-1] = 2.0*A_sd[nPoints-2]; ptr->D[nPoints-1+j*nPoints] = 3.0 * qdy[nPoints-2]; Mytridiagldltsolve(A_d, A_sd, &ptr->D[j*nPoints], nPoints); } if (Method==3) { /* s'''(x(2)-) = s'''(x(2)+) */ r = A_sd[1]/A_sd[0]; A_d[0]= A_sd[0]/(1.0 + r); ptr->D[j*nPoints]=((3.0*r+2.0)*qdy[0]+r*qdy[1])/((1.0+r)*(1.0+r)); /* s'''(x(n-1)-) = s'''(x(n-1)+) */ r = A_sd[nPoints-3]/A_sd[nPoints-2]; A_d[nPoints-1] = A_sd[nPoints-2]/(1.0 + r); ptr->D[nPoints-1+j*nPoints] = \ ((3.0*r+2.0)*qdy[nPoints-2]+r*qdy[nPoints-3])/((1.0+r)*(1.0+r)); Mytridiagldltsolve(A_d, A_sd, &ptr->D[j*nPoints], nPoints); } } if (YsubType==1) { /* imag part */ for (j=0;j<mY;j++) { for (i=0;i<=nPoints-2;i++) { A_sd[i] = 1.0 / (ptr_T[i+1] - ptr_T[i]); qdy[i] = (ptr_d[nPoints+i+1+j*nPoints] - ptr_d[nPoints+i+j*nPoints]) * A_sd[i]*A_sd[i]; } for (i=1;i<=nPoints-2;i++) { A_d[i] = 2.0*(A_sd[i-1] +A_sd[i]); ptr->D[i+j*nPoints+nPoints] = 3.0*(qdy[i-1]+qdy[i]); } if (Method==2) { A_d[0] = 2.0*A_sd[0]; ptr->D[nPoints+0+j*nPoints] = 3.0 * qdy[0]; A_d[nPoints-1] = 2.0*A_sd[nPoints-2]; ptr->D[nPoints+nPoints-1+j*nPoints] = 3.0 * qdy[nPoints-2]; Mytridiagldltsolve(A_d, A_sd, &ptr->D[nPoints+j*nPoints], nPoints); } if (Method==3) { /* s'''(x(2)-) = s'''(x(2)+) */ r = A_sd[1]/A_sd[0]; A_d[0]= A_sd[0]/(1.0 + r); ptr->D[nPoints+j*nPoints]=((3.0*r+2.0)*qdy[0]+r*qdy[1])/((1.0+r)*(1.0+r)); /* s'''(x(n-1)-) = s'''(x(n-1)+) */ r = A_sd[nPoints-3]/A_sd[nPoints-2]; A_d[nPoints-1] = A_sd[nPoints-2]/(1.0 + r); ptr->D[nPoints+nPoints-1+j*nPoints] = \ ((3.0*r+2.0)*qdy[nPoints-2]+r*qdy[nPoints-3])/((1.0+r)*(1.0+r)); Mytridiagldltsolve(A_d, A_sd, &ptr->D[nPoints+j*nPoints], nPoints); } } } scicos_free(spline); } /*===================================*/ cnt1=nPoints-1; cnt2=nPoints; for (i=0;i<nPoints;i++) { /* finding the first positive time instant */ if (ptr->workt[i]>=0 ) { cnt1=i-1; cnt2=i; break; } } ptr->nPoints=nPoints; ptr->Yt=Ytype; ptr->Yst=YsubType; ptr->cnt1=cnt1; ptr->cnt2=cnt2; ptr->EVindex=0; ptr->PerEVcnt=0; ptr->firstevent=1; return; /*******************************************************/ /*******************************************************/ } else if (flag==1){ /* output computation */ /* retrieve ptr of the structure of that block */ ptr = *(_work); nPoints=ptr->nPoints; cnt1=ptr->cnt1; cnt2=ptr->cnt2; EVindex= ptr->EVindex; PerEVcnt=ptr->PerEVcnt; /* get current simulation time */ t=GetScicosTime(block); t1=t; if (ZC==1){ /*zero crossing enable*/ if (OutEnd==2) { t-=(PerEVcnt)*TP; } inow=nPoints-1; for (i=cnt1;i<nPoints;i++) { if (i==-1) { continue; } if (t<ptr->workt[i]) { inow=i-1; if (inow<cnt2) { cnt2=inow; } else { cnt1=cnt2; cnt2=inow; } break; } } } else { /*zero crossing disable*/ if (OutEnd==2) { if (TP!=0) { r=floor((t/TP)); } else { r=0; } t-=((int)r)*TP; } inow=nPoints-1; for (i=0;i<nPoints;i++) { if (t<ptr->workt[i]) { inow=i-1; break; } } } ptr->cnt1=cnt1; ptr->cnt2=cnt2; ptr->EVindex=EVindex; ptr->PerEVcnt=PerEVcnt; /***************************/ /* hypermatrix case */ if (ptr->Hmat) { for (j=0;j<my*ny;j++) { if (ptr->Yt==1) { if (ptr->Yst==0) { /* real case */ y_d = GetRealOutPortPtrs(block,1); ptr_d=(double*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0){ y_d[j]=0.0; /* outputs set to zero */ } else if (OutEnd==1) { y_d[j]=ptr_d[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_d[j]=0.0; } else { y_d[j]=ptr_d[inow*ny*my+j]; } } } else { /* complexe case */ y_d = GetRealOutPortPtrs(block,1); y_cd = GetImagOutPortPtrs(block,1); ptr_d=(double*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_d[j]=0.0; /* outputs set to zero */ y_cd[j]=0.0; /* outputs set to zero */ } else if (OutEnd==1) { y_d[j]=ptr_d[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ y_cd[j]=ptr_d[nPoints*my*ny+(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_d[j]=0.0; /* outputs set to zero */ y_cd[j]=0.0; /* outputs set to zero */ } else { y_d[j]=ptr_d[inow*ny*my+j]; y_cd[j]=ptr_d[nPoints*my*ny+inow*ny*my+j]; } } } } else if (ptr->Yt==8) { switch (ptr->Yst) { case 1: /* ---------------------int8 char ---------------------------- */ y_c = Getint8OutPortPtrs(block,1); ptr_c=(char*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_c[j]=0; /* outputs set to zero */ } else if (OutEnd==1) { y_c[j]=ptr_c[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_c[j]=0; } else { y_c[j]=ptr_c[inow*ny*my+j]; } } break; case 2: /* ---------------------int16 short--------------------- */ y_s = Getint16OutPortPtrs(block,1); ptr_s=(SCSINT16_COP*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_s[j]=0; /* outputs set to zero */ } else if (OutEnd==1) { y_s[j]=ptr_s[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_s[j]=0; } else { y_s[j]=ptr_s[inow*ny*my+j]; } } break; case 4: /* ---------------------int32 long--------------------- */ y_l = Getint32OutPortPtrs(block,1); ptr_l=(SCSINT32_COP*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_l[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_l[j]=ptr_l[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_l[j]=0; } else { y_l[j]=ptr_l[inow*ny*my+j]; } } break; case 11: /*--------------------- uint8 uchar---------------------*/ y_uc = Getuint8OutPortPtrs(block,1); ptr_uc=(SCSUINT8_COP*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_uc[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_uc[j]=ptr_uc[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_uc[j]=0; } else { y_uc[j]=ptr_uc[inow*ny*my+j]; } } break; case 12: /* ---------------------uint16 ushort--------------------- */ y_us = Getuint16OutPortPtrs(block,1); ptr_us=(SCSUINT16_COP*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_us[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_us[j]=ptr_us[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_us[j]=0; } else { y_us[j]=ptr_us[inow*ny*my+j]; } } break; case 14: /* ---------------------uint32 ulong--------------------- */ y_ul = Getuint32OutPortPtrs(block,1); ptr_ul=(SCSUINT32_COP*) ptr->work; if (inow>=nPoints-1) { if (OutEnd==0) { y_ul[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_ul[j]=ptr_ul[(nPoints-1)*ny*my+j]; /* hold outputs at the end */ } } else { if (inow<0) { y_ul[j]=0; } else { y_ul[j]=ptr_ul[inow*ny*my+j]; } } break; } } } /* for j loop */ } /****************************/ /* scalar of vectorial case */ else { for (j=0;j<my;j++) { if (ptr->Yt==1) { if ((ptr->Yst==0)||(ptr->Yst==1)) { /* if Real or complex*/ y_d = GetRealOutPortPtrs(block,1); ptr_d=(double*) ptr->work; ptr_D=(double*) ptr->D; if (inow>=nPoints-1) { if (OutEnd==0){ y_d[j]=0.0; /* outputs set to zero */ } else if (OutEnd==1) { y_d[j]=ptr_d[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_d[j]=0.0; } else { y_d[j]=ptr_d[inow+(j)*nPoints]; } } else if (Method==1) { if (inow<0) { inow=0; } t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=ptr_d[inow+j*nPoints]; y2=ptr_d[inow+1+j*nPoints]; y_d[j]=(y2-y1)*(t-t1)/(t2-t1)+y1; } else if (Method>=2) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=ptr_d[inow+j*nPoints]; y2=ptr_d[inow+1+j*nPoints]; d1=ptr_D[inow+j*nPoints]; d2=ptr_D[inow+1+j*nPoints]; Myevalhermite2(&t, &t1,&t2, &y1,&y2, &d1,&d2, &h, &dh, &ddh, &dddh, &inow); y_d[j]=h; } } if (ptr->Yst==1) { /* --------------complex----------------------*/ y_cd = GetImagOutPortPtrs(block,1); if (inow>=nPoints-1) { if (OutEnd==0) { y_cd[j]=0.0;/* outputs set to zero*/ } else if (OutEnd==1) { y_cd[j]=ptr_d[nPoints*my+nPoints-1+(j)*nPoints]; // hold outputs at the end } } else if (Method==0){ if (inow<0){ y_cd[j]=0.0; /* outputs set to zero */ } else { y_cd[j]=ptr_d[nPoints*my+inow+(j)*nPoints]; } } else if (Method==1) { if (inow<0) { inow=0; } /* extrapolation for 0<t<X(0) */ t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=ptr_d[nPoints*my+inow+j*nPoints]; y2=ptr_d[nPoints*my+inow+1+j*nPoints]; y_cd[j]=(y2-y1)*(t-t1)/(t2-t1)+y1; } else if (Method>=2) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=ptr_d[inow+j*nPoints+nPoints]; y2=ptr_d[inow+1+j*nPoints+nPoints]; d1=ptr_D[inow+j*nPoints+nPoints]; d2=ptr_D[inow+1+j*nPoints+nPoints]; Myevalhermite2(&t, &t1,&t2, &y1,&y2, &d1,&d2, &h, &dh, &ddh, &dddh, &inow); y_cd[j]=h; } } } else if (ptr->Yt==8) { switch (ptr->Yst) { case 1: /* ---------------------int8 char ---------------------------- */ y_c = Getint8OutPortPtrs(block,1); ptr_c=(char*) ptr->work; /*y_c[j]=ptr_c[inow+(j)*nPoints];*/ if (inow>=nPoints-1) { if (OutEnd==0) { y_c[j]=0; /* outputs set to zero */ } else if (OutEnd==1) { y_c[j]=ptr_c[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_c[j]=0; } else { y_c[j]=ptr_c[inow+(j)*nPoints]; } } else if (Method>=1){ if (inow<0) { inow=0; } t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_c[inow+j*nPoints]; y2=(double)ptr_c[inow+1+j*nPoints]; y_c[j] =(char)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; case 2: /* ---------------------int16 short--------------------- */ y_s = Getint16OutPortPtrs(block,1); ptr_s=(SCSINT16_COP*) ptr->work; /* y_s[j]=ptr_s[inow+(j)*nPoints]; */ if (inow>=nPoints-1) { if (OutEnd==0) { y_s[j]=0; /* outputs set to zero */ } else if (OutEnd==1) { y_s[j]=ptr_s[nPoints-1+(j)*nPoints]; // hold outputs at the end } } else if (Method==0) { if (inow<0) { y_s[j]=0; } else { y_s[j]=ptr_s[inow+(j)*nPoints]; } } else if (Method>=1) { if (inow<0) { inow=0; } t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_s[inow+j*nPoints]; y2=(double)ptr_s[inow+1+j*nPoints]; y_s[j] =(SCSINT16_COP)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; case 4: /* ---------------------int32 long--------------------- */ y_l = Getint32OutPortPtrs(block,1); ptr_l=(SCSINT32_COP*) ptr->work; /*y_l[j]=ptr_l[inow+(j)*nPoints];*/ if (inow>=nPoints-1) { if (OutEnd==0) { y_l[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_l[j]=ptr_l[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_l[j]=0; } else { y_l[j]=ptr_l[inow+(j)*nPoints]; } } else if (Method>=1) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_l[inow+j*nPoints]; y2=(double)ptr_l[inow+1+j*nPoints]; y_l[j] =(SCSINT32_COP)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; case 11: /*--------------------- uint8 uchar---------------------*/ y_uc = Getuint8OutPortPtrs(block,1); ptr_uc=(SCSUINT8_COP*) ptr->work; /*y_uc[j]=ptr_uc[inow+(j)*nPoints];*/ if (inow>=nPoints-1) { if (OutEnd==0) { y_uc[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_uc[j]=ptr_uc[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_uc[j]=0; } else { y_uc[j]=ptr_uc[inow+(j)*nPoints]; } } else if (Method>=1) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_uc[inow+j*nPoints]; y2=(double)ptr_uc[inow+1+j*nPoints]; y_uc[j] =(SCSUINT8_COP)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; case 12: /* ---------------------uint16 ushort--------------------- */ y_us = Getuint16OutPortPtrs(block,1); ptr_us=(SCSUINT16_COP*) ptr->work; /* y_us[j]=ptr_us[inow+(j)*nPoints]; */ if (inow>=nPoints-1) { if (OutEnd==0) { y_us[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_us[j]=ptr_us[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_us[j]=0; } else { y_us[j]=ptr_us[inow+(j)*nPoints]; } } else if (Method>=1) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_us[inow+j*nPoints]; y2=(double)ptr_us[inow+1+j*nPoints]; y_us[j] =(SCSUINT16_COP)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; case 14: /* ---------------------uint32 ulong--------------------- */ y_ul = Getuint32OutPortPtrs(block,1); ptr_ul=(SCSUINT32_COP*) ptr->work; /* y_ul[j]=ptr_ul[inow+(j)*nPoints]; */ if (inow>=nPoints-1) { if (OutEnd==0) { y_ul[j]=0;/* outputs set to zero */ } else if (OutEnd==1) { y_ul[j]=ptr_ul[nPoints-1+(j)*nPoints]; /* hold outputs at the end */ } } else if (Method==0) { if (inow<0) { y_ul[j]=0; } else { y_ul[j]=ptr_ul[inow+(j)*nPoints]; } } else if (Method>=1) { t1=ptr->workt[inow]; t2=ptr->workt[inow+1]; y1=(double)ptr_ul[inow+j*nPoints]; y2=(double)ptr_ul[inow+1+j*nPoints]; y_ul[j] =(SCSUINT32_COP)((y2-y1)*(t-t1)/(t2-t1)+y1); } break; } } } /* for j loop */ } /********************************************************************/ } else if(flag==3) { /* event date computation */ /* retrieve ptr of the structure of that block */ ptr = *(_work); nPoints=ptr->nPoints; cnt1=ptr->cnt1; cnt2=ptr->cnt2; EVindex= ptr->EVindex; PerEVcnt=ptr->PerEVcnt; /* get current simulation time */ t=GetScicosTime(block); if (ZC==1) { /* generate Events only if ZC is active */ if ((Method==1)||(Method==0)) { /*-------------------------*/ if (ptr->firstevent==1) { jfirst=nPoints-1; /* finding first positive time instant */ for (j=0;j<nPoints;j++) { if (ptr->workt[j]>0) { jfirst=j; break; } } _evout[0]=ptr->workt[jfirst]; EVindex=jfirst; ptr->EVindex=EVindex; ptr->firstevent=0; return; } /*------------------------*/ i=EVindex; /*------------------------*/ if (i<nPoints-1) { _evout[0]=ptr->workt[i+1]-ptr->workt[i]; EVindex=i+1; } /*------------------------*/ if (i==nPoints-1) { if (OutEnd==2) {/* Periodic*/ cnt1=-1; cnt2=0; PerEVcnt++;/* When OutEnd==2 (perodic output)*/ jfirst=nPoints-1; /* finding first positive time instant */ for (j=0;j<nPoints;j++) { if (ptr->workt[j]>0) { jfirst=j; break; } } _evout[0]=ptr->workt[jfirst]; EVindex=jfirst; } } /*-------------------------- */ } else if (Method<=3) { if (ptr->firstevent==1) { _evout[0]=TP; ptr->firstevent=0; } else { if (OutEnd==2) { _evout[0]=TP; } PerEVcnt++; } cnt1=-1; cnt2=0; } ptr->cnt1=cnt1; ptr->cnt2=cnt2; ptr->EVindex=EVindex; ptr->PerEVcnt=PerEVcnt; } /***********************************************************************/ } else if (flag==5) { /* finish */ ptr = *(_work); if (ptr!=NULL) { if (ptr->D!=NULL) { scicos_free(ptr->D); } if (ptr->work!=NULL) { scicos_free(ptr->work); } if (ptr->workt!=NULL) { scicos_free(ptr->workt); } scicos_free(ptr); } } /*************************************************************************/ } int Ishm(int *fd,int *Ytype,int *nPoints,int *my,int *ny,int *YsubType) { int *ptr_i; int j,ierr; /*work array to store header of hypermat*/ if((ptr_i=(int *) scicos_malloc(37*sizeof(int)))==NULL) { return 0; } C2F(mgetnc) (fd, ptr_i, (j=37,&j), fmti, &ierr); /* read sci id */ if (ierr!=0) { return 0; } if ((ptr_i[0]!=3) || \ (ptr_i[1]!=1) || \ (ptr_i[5]!=10) || \ (ptr_i[6]!=1) || \ (ptr_i[7]!=3) || \ (ptr_i[8]!=0) || \ (ptr_i[9]!=1) || \ (ptr_i[10]!=ptr_i[9]+2) || \ (ptr_i[11]!=ptr_i[10]+4) || \ (ptr_i[12]!=ptr_i[11]+7) || \ (ptr_i[13]!=17) || \ (ptr_i[14]!=22) || \ (ptr_i[15]!=13) || \ (ptr_i[16]!=18) || \ (ptr_i[17]!=22) || \ (ptr_i[18]!=28) || \ (ptr_i[19]!=14) || \ (ptr_i[20]!=23) || \ (ptr_i[21]!=29) || \ (ptr_i[22]!=27) || \ (ptr_i[23]!=18) || \ (ptr_i[24]!=14) || \ (ptr_i[25]!=28) || \ (ptr_i[26]!=8) || \ (ptr_i[27]!=1) || \ (ptr_i[28]!=3) || \ (ptr_i[29]!=4)) { Coserror("Invalid variable type : error in hypermat scilab coding.\n"); return 0; } *my = ptr_i[30]; /*37*/ *ny = ptr_i[31]; /*38*/ *nPoints = ptr_i[32]; /*39*/ *Ytype = ptr_i[33]; /*40*/ if ((ptr_i[34]!=ptr_i[30]*ptr_i[31]*ptr_i[32]) || \ (ptr_i[35]!=1)) { Coserror("Invalid variable type : error in hypermat scilab coding.\n"); return 0; } *YsubType = ptr_i[36]; /*43*/ scicos_free(ptr_i); return 1; } int Mytridiagldltsolve(double *dA, double * lA, double * B, int N) { double Temp; int j; for (j = 1; j <= N-1; ++j) { Temp = lA[j-1]; lA[j-1] /= dA[j-1]; B[j] -= lA[j-1] * B[j-1]; dA[j] -= Temp * lA[j-1]; } B[N-1] /= dA[N-1]; for (j = N - 2; j >= 0; --j) { B[j] = - lA[j] * B[j + 1] + B[j] / dA[j]; } return 0; } int Myevalhermite2(double *t, double *x1, double *x2, double *y1, double *y2, double *d1, double *d2, double *z, double *dz, double *ddz, double *dddz, int *k) { double Temp, p, p2, p3, D; Temp = *t - *x1; D = 1.0 / (*x2 - *x1); p = (*y2 - *y1) * D; p2 = (p - *d1) * D; p3 = (*d2 - p + (*d1 - p)) * (D * D); *z = p2 + p3 * (*t - *x2); *dz = *z + p3 * Temp; *ddz = (*dz + p3 * Temp) * 2.; *dddz = p3 * 6.0; *z = *d1 + *z * Temp; *dz = *z + *dz * Temp; *z = *y1 + *z * Temp; return 0; }