/* IdTablePass.c Accelerator Toolbox Created: 13/11/08 Z.Marti­ zeus@cells.es Based in the matlab routine: WigTablePass.m - The tracking table is described in P. Elleaume, "A new approach to the electron beam dynamics in undulators and wigglers", EPAC92. */ #include #include "mex.h" #include "elempass.h" #include "atlalib.c" #include "interpolate.c" #include "matrix.h" #define SQR(X) X*X double *GLOBAL_x,*GLOBAL_y,*GLOBAL_xkick1,*GLOBAL_ykick1,*GLOBAL_xkick,*GLOBAL_ykick,*GLOBAL_xkick2,*GLOBAL_ykick2; int GLOBAL_m,GLOBAL_n; /*Definition of the interpolated functions*/ double Map_x(double x,double y) { double f; /*cubic interpolation*/ /*splin2(GLOBAL_y,GLOBAL_x,GLOBAL_xkick,GLOBAL_xkick2,GLOBAL_n,GLOBAL_m,y,x,&f);*/ /*biliniar interpolation*/ linint(GLOBAL_y,GLOBAL_x,GLOBAL_xkick,GLOBAL_m,GLOBAL_n,y,x,&f); return f; } double Map_y(double x,double y) { double f; /*cubic interpolation*/ /*splin2(GLOBAL_y,GLOBAL_x,GLOBAL_ykick,GLOBAL_ykick2,GLOBAL_m,GLOBAL_n,y,x,&f);*/ /*biliniar interpolation*/ linint(GLOBAL_y,GLOBAL_x,GLOBAL_ykick,GLOBAL_m,GLOBAL_n,y,x,&f); return f; } double Map1_x(double x,double y) { double f; /*cubic interpolation*/ /*splin2(GLOBAL_y,GLOBAL_x,GLOBAL_xkick1,GLOBAL_xkick2,GLOBAL_n,GLOBAL_m,y,x,&f);*/ /*biliniar interpolation*/ linint(GLOBAL_y,GLOBAL_x,GLOBAL_xkick1,GLOBAL_m,GLOBAL_n,y,x,&f); return f; } double Map1_y(double x,double y) { double f; /*cubic interpolation*/ /*splin2(GLOBAL_y,GLOBAL_x,GLOBAL_ykick1,GLOBAL_ykick2,GLOBAL_m,GLOBAL_n,y,x,&f);*/ /*biliniar interpolation*/ linint(GLOBAL_y,GLOBAL_x,GLOBAL_ykick1,GLOBAL_m,GLOBAL_n,y,x,&f); return f; } void markaslost(double *r6) { int i; r6[0] = mxGetNaN(); for(i=1;i<6;i++) r6[i] =0; } /* Set T1, T2, R1, R2 to NULL pointers to ignore misalignmets*/ void IdKickMapModelPass(double *r, double le, double *xkick1, double *ykick1, double *xkick, double *ykick, double *x, double *y,int n,int m, int Nslice, double *T1, double *T2, double *R1, double *R2, int num_particles) { double *r6,f,L1,deltaxp,deltayp,deltaxp1,deltayp1,*limitsptr; int c; bool useT1, useT2, useR1, useR2; /*Act as AperturePass*/ limitsptr=(double*)mxCalloc(4,sizeof(double)); limitsptr[0]=x[0]; limitsptr[1]=x[n-1]; limitsptr[2]=y[0]; limitsptr[3]=y[m-1]; /*globalize*/ /* For cubic interpolation only*/ /*GLOBAL_xkick2=(double*)mxCalloc(n*m,sizeof(double)); GLOBAL_ykick2=(double*)mxCalloc(n*m,sizeof(double)); splie2(y,x,xkick,m,n,GLOBAL_xkick2); splie2(y,x,ykick,m,n,GLOBAL_ykick2); */ GLOBAL_x=x; GLOBAL_y=y; GLOBAL_xkick1=xkick1; GLOBAL_ykick1=ykick1; GLOBAL_xkick=xkick; GLOBAL_ykick=ykick; GLOBAL_m=m; /* y used as colums*/ GLOBAL_n=n; /* x used as rows*/ if(T1==NULL) useT1=false; else useT1=true; if(T2==NULL) useT2=false; else useT2=true; if(R1==NULL) useR1=false; else useR1=true; if(R2==NULL) useR2=false; else useR2=true; L1=le/(2*Nslice); for(c = 0;climitsptr[1] || r6[2]limitsptr[3]) { markaslost(r6); } else { /* Misalignment at entrance */ if(useT1) ATaddvv(r6,T1); if(useR1) ATmultmv(r6,R1); /*Tracking in the main body*/ for(m=0; m < Nslice; m++) /* Loop over slices*/ { r6 = r+c*6; ATdrift6(r6,L1); if (!mxIsNaN(r6[0])&&!mxIsNaN(r6[2])) { /*The kick from IDs varies quadratically, not linearly, with energy. */ deltaxp = (1.0/Nslice)*Map_x(r6[0],r6[2])/(1.0+r6[4]); deltayp = (1.0/Nslice)*Map_y(r6[0],r6[2])/(1.0+r6[4]); deltaxp1 = (1.0/Nslice)*Map1_x(r6[0],r6[2]); deltayp1 = (1.0/Nslice)*Map1_y(r6[0],r6[2]); r6[1] = r6[1] + deltaxp + deltaxp1; r6[3] = r6[3] + deltayp + deltayp1; } ATdrift6(r6,L1); } /* Misalignment at exit */ if(useR2) ATmultmv(r6,R2); if(useT2) ATaddvv(r6,T2); } } } } /*Just for debugg!! Subtitute routine for a drift*/ void DriftPass(double *r_in, double le, int num_particles) /* le - physical length r_in - 6-by-N matrix of initial conditions reshaped into 1-d array of 6*N elements */ { int c, c6; double p_norm, NormL; mexPrintf("Length: %f\n",le); mexPrintf("Initial %e %e %e %e %e %e\n",r_in[0],r_in[1],r_in[2],r_in[3],r_in[4],r_in[5]); for(c = 0;c1) /* Required and optional fields */ { plhs[1] = mxCreateCellMatrix(4,1); mxSetCell(plhs[1],0,mxCreateString("T1")); mxSetCell(plhs[1],1,mxCreateString("T2")); mxSetCell(plhs[1],2,mxCreateString("R1")); mxSetCell(plhs[1],3,mxCreateString("R2")); } } }