#include "mex.h" #include #include "elempass.h" #include "atlalib.c" #include "atphyslib.c" #define DRIFT1 0.6756035959798286638 #define DRIFT2 -0.1756035959798286639 #define KICK1 1.351207191959657328 #define KICK2 -1.702414383919314656 #define SQR(X) ((X)*(X)) double B2perp(double bx, double by, double irho, double x, double xpr, double y, double ypr) /* Calculates sqr(|e x B|) , where e is a unit vector in the direction of velocity */ { double v_norm2; v_norm2 = 1/(SQR(1+x*irho)+ SQR(xpr) + SQR(ypr)); /* components of the velocity vector double ex, ey, ez; ex = xpr; ey = ypr; ez = (1+x*irho); */ return((SQR(by*(1+x*irho)) + SQR(bx*(1+x*irho)) + SQR(bx*ypr - by*xpr) )*v_norm2) ; } void bndthinkickrad(double* r, double* A, double* B, double L, double irho, double E0, int max_order) /***************************************************************************** Calculate multipole kick in a curved elemrnt (bending magnet) The reference coordinate system has the curvature given by the inverse (design) radius irho. IMPORTANT !!! The magnetic field Bo that provides this curvature MUST NOT be included in the dipole term PolynomB[1](MATLAB notation)(C: B[0] in this function) of the By field expansion HOWEVER!!! to calculate the effect of classical radiation the full field must be used in the square of the |v x B|. When calling B2perp(Bx, By, ...), use the By = RESum + irho, where ImSum is the sum of the polynomial terms in PolynomB. The kick is given by e L L delta L x theta = - --- B + ------- - ----- , x p y rho 2 0 rho e L theta = --- B y p x 0 Note: in the US convention the transverse multipole field is written as: max_order+1 ---- \ n-1 (B + iB )/ B rho = > (ia + b ) (x + iy) y x / n n ---- n=1 is a polynomial in (x,y) with the highest order = MaxOrder Using different index notation max_order ---- \ n (B + iB )/ B rho = > (iA + B ) (x + iy) y x / n n ---- n=0 A,B: i=0 ... max_order [0] - dipole, [1] - quadrupole, [2] - sextupole ... units for A,B[i] = 1/[m]^(i+1) Coeficients are stroed in the PolynomA, PolynomB field of the element structure in MATLAB A[i] (C++,C) = PolynomA(i+1) (MATLAB) B[i] (C++,C) = PolynomB(i+1) (MATLAB) i = 0 .. MaxOrder ******************************************************************************/ { int i; double ReSumTemp; double ImSum = A[max_order]; double ReSum = B[max_order]; double x ,xpr, y, ypr, p_norm,dp_0, B2P; #define TWOPI 6.28318530717959 #define CGAMMA 8.846056192e-05 double CRAD = CGAMMA*E0*E0*E0/(TWOPI*1e27); /* [m]/[GeV^3] M.Sands (4.1) */ /* recursively calculate the local transvrese magnetic field Bx = ReSum, By = ImSum */ for(i=max_order-1;i>=0;i--) { ReSumTemp = ReSum*r[0] - ImSum*r[2] + B[i]; ImSum = ImSum*r[0] + ReSum*r[2] + A[i]; ReSum = ReSumTemp; } /* calculate angles from momentums */ p_norm = 1/(1+r[4]); x = r[0]; xpr = r[1]*p_norm; y = r[2]; ypr = r[3]*p_norm; B2P = B2perp(ImSum, ReSum +irho, irho, x , xpr, y ,ypr); dp_0 = r[4]; r[4] = r[4] - CRAD*SQR(1+r[4])*B2P*(1 + x*irho + (SQR(xpr)+SQR(ypr))/2 )*L; /* recalculate momentums from angles after losing energy for radiation */ p_norm = 1/(1+r[4]); r[1] = xpr/p_norm; r[3] = ypr/p_norm; r[1] -= L*(ReSum-(dp_0-r[0]*irho)*irho); r[3] += L*ImSum; r[5] += L*irho*r[0]; /* pathlength */ } void BndMPoleSymplectic4RadPass(double *r, double le, double irho, double *A, double *B, int max_order, int num_int_steps, double entrance_angle, double exit_angle, double fint1, double fint2, double gap, double *T1, double *T2, double *R1, double *R2, double E0, int num_particles) { int c,m; double *r6; double SL, L1, L2, K1, K2; bool useT1, useT2, useR1, useR2, useFringe1, useFringe2; SL = le/num_int_steps; L1 = SL*DRIFT1; L2 = SL*DRIFT2; K1 = SL*KICK1; K2 = SL*KICK2; 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; /* if either is 0 - do not calculate fringe effects */ if (fint1==0 || gap==0 || entrance_angle == 0) useFringe1 = false; else useFringe1=true; if (fint2==0 || gap==0 || exit_angle == 0) useFringe2 = false; else useFringe2=true; for(c = 0;c1) /* Required and optional fields */ { plhs[1] = mxCreateCellMatrix(7,1); mxSetCell(plhs[1],0,mxCreateString("FullGap")); mxSetCell(plhs[1],1,mxCreateString("FringeInt1")); mxSetCell(plhs[1],2,mxCreateString("FringeInt2")); mxSetCell(plhs[1],3,mxCreateString("T1")); mxSetCell(plhs[1],4,mxCreateString("T2")); mxSetCell(plhs[1],5,mxCreateString("R1")); mxSetCell(plhs[1],6,mxCreateString("R2")); } } }