Changeset 11 in TRACY3 for trunk/tracy/tracy/src/t2elem.cc


Ignore:
Timestamp:
Oct 21, 2013, 10:40:43 AM (11 years ago)
Author:
zhangj
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tracy/tracy/src/t2elem.cc

    r10 r11  
    113113            cout << "        " << 1+x[delta_] << "   " << x[px_] << "   " << x[py_] << endl;
    114114            printf("get_p_s: *** Speed of light exceeded!\n");
    115           // exit_(1);
     115           // exit_(1);
    116116           
    117117        }
     
    124124
    125125 Purpose:
    126  Drift pass
     126 Exact Drift pass in the curvilinear coordinate for the dipole
     127
     128 See Eqn. (10.26) on page 307 in E. Forest's beam dynamics, a new attitude
     129 
     130 H(x,y,cT,px,py,delta) =(1 + h_ref*x) * sqrt((1+delta)^ - px^2 - py^2) + delta                                 
     131
     132 Input:
     133 L:  drift length
     134 &x:  pointer to initial vector: x
     135
     136 Output:
     137 none
     138
     139 Return:
     140 none
     141
     142 Global variables:
     143
     144
     145 Specific functions:
     146 
     147 
     148 
     149 Comments:
     150 
     151 Test version....rewritten by Jianfeng zhang @ LAL, 31/07/2013
     152
     153 ****************************************************************************/
     154
     155
     156template<typename T>
     157void Drift(double L,double h_bend, ss_vect<T> &x) {
     158    T u;
     159    ss_vect<T> x0;
     160
     161    x0=x;
     162   
     163    if (globval.H_exact) {
     164      if(get_p_s(x) == 0)
     165        return;
     166
     167      x[x_] = x0[x_]/cos(L*h_bend)/(1-x0[px_]/get_p_s(x)*tan(L*h_bend));
     168      x[px_]= x0[px_]*cos(L*h_bend) + get_p_s(x)*sin(L*h_bend);
     169      x[y_] = x0[y_]+x0[px_]*x0[x_]*tan(L*h_bend)/get_p_s(x)/(1-x0[px_]/get_p_s(x)*tan(L*h_bend));
     170      x[py_]= x0[py_];
     171      x[ct_]= x0[ct_]+((1+x0[delta_])*x0[x_]*tan(L*h_bend))/get_p_s(x)/(1-x0[px_]/get_p_s(x)*tan(L*h_bend));
     172 
     173   
     174    }
     175}
     176
     177/****************************************************************************/
     178/* Drift(double L, ss_vect<T> &x)
     179
     180 Purpose:
     181 Drift pass in the Cartesian coordinate
    127182
    128183 If H_exact = false, using approximation Hamiltonian (only valid for big ring):
     
    616671    Correction for magnet gap (longitudinal fringe field)
    617672
    618      irho h = 1/rho [1/m]
    619      phi  dipole edge angle
    620      gap  full gap between poles
     673    Input:
     674     irho:         h = 1/rho [1/m]
     675     phi:         dipole edge (entrance or exit) angle
     676     gap:        full gap between poles
    621677
    622678                             2
     
    650706}
    651707
     708/*****************************************************************
     709 * Exact map of the sector dipole
     710 *
     711 * Forest's beam dynamics P.360 Eqn. (12.18)
     712 * Also see Laurent's thesis: P219-220.
     713 *
     714 * Written by Jianfeng Zhang @ LAL, 01/08/2013
     715 *
     716 * Test version........................................
     717 *
     718 * ****************************************************************/
     719template<typename T>
     720void dipole_kick(double L, double h_ref, double h_bend, ss_vect<T> &x){
     721
     722  ss_vect<T> x0;
     723  T ps, u, dpxf;
     724   
     725  x0 = x;
     726  ps = get_p_s(x0);
     727 
     728  u = sqrt(sqr(1+x0[delta_])-sqr(x0[py_]));
     729 
     730  x[py_] = x0[py_];
     731 
     732  x[delta_] =x0[delta_];
     733 
     734  x[px_]= x0[px_]*cos(L*h_ref) + (ps -h_bend*(1/h_ref+x0[x_]))*sin(L*h_ref);
     735 
     736  dpxf = h_ref*sqrt((1+x[delta_])*(1+x[delta_]) - x[px_]*x[px_] - x[py_]*x[py_])-h_bend*(1+h_ref*x[x_]);
     737 
     738 
     739  x[y_] += h_ref/h_bend*x0[py_]*L + x0[py_]/h_bend*(asin(x0[px_]/u)-asin(x[px_]/u));
     740 
     741  x[x_] = 1/(h_bend*h_ref)*(h_ref*sqrt(sqr(1+x[delta_])-sqr(x[px_])-sqr(x[py_]))-dpxf - h_bend);
     742 
     743  x[ct_] += (1+x0[delta_])*h_ref/h_bend*L + (1+x0[delta_])/h_bend*(asin(x0[px_]/u)-asin(x[px_]/u));
     744 
     745}
     746
     747/*****************************************************************
     748 * pure multipole kick
     749 *
     750 * Forest's beam dynamics P.360 Eqn. (12.18)
     751 * Also see Laurent's thesis: P219-220.
     752 *
     753 * Written by Jianfeng Zhang @ LAL, 01/08/2013
     754 *
     755 * Test version........................................
     756 *
     757 * ****************************************************************/
     758template<typename T>
     759void multipole_kick(int Order, double MB[], double L, double h_bend, ss_vect<T> &x){
     760
     761  int j=0;
     762  ss_vect<T> x0;
     763 
     764  T ByoBrho = 0, BxoBrho = 0, ByoBrho1=0 ;
     765 
     766  if ((h_bend != 0.0) || ((1 <= Order) && (Order <= HOMmax))) {
     767        x0 = x;
     768        /* compute the total magnetic field Bx and By with Horner's rule */
     769        ByoBrho = MB[HOMmax + Order]; // normalized By, By/(p0/e)
     770        BxoBrho = MB[HOMmax - Order]; // normalized Bx, Bx/(p0/e)
     771        for (j = Order - 1; j >= 1; j--) {
     772            ByoBrho1 = x0[x_] * ByoBrho - x0[y_] * BxoBrho + MB[j + HOMmax];
     773            BxoBrho = x0[y_] * ByoBrho + x0[x_] * BxoBrho + MB[HOMmax - j];
     774            ByoBrho = ByoBrho1;
     775        }
     776  }
     777 
     778  x[px_] -= L * (ByoBrho + h_bend*1);
     779        //vertical kick due to the magnets
     780        x[py_] += L * BxoBrho;
     781}
     782
    652783/****************************************************************************/
    653784/* template<typename T>
     
    657788        Refer to Tracy 2 manual.
    658789        Calculate multipole kick.
    659  
     790  ,
    660791  (1)     The exact Hamiltonian is
    661792
     
    737868 MB     array of an and bn, magnetic field components
    738869 L      multipole length
    739  h_bend   B_dipole/Brho is the dipole field normalized by the reference momentum 
     870 h_bend   B_dipole/Brho is the dipole field normalized by the reference momentum; one of the example is the combined dipole
    740871 h_ref   1/rho [m^-1] is the curvature of the reference orbit in the dipoles which is used in curvilinear coordinate,
    741872 x      initial coordinates vector
     
    797928              return;
    798929           
    799             u = L * h_ref * x0[x_] /get_p_s(x0);
    800             x[x_] += u * x0[px_];
    801             x[y_] += u * x0[py_];
    802             x[px_]-= L * (-h_ref * get_p_s(x0) + h_bend + h_ref * h_bend
    803                      * x0[x_] + ByoBrho);
    804             x[ct_] += u * (1.0+x0[delta_]);
     930            //dipole kick map from the exact Hamiltonian; not symplectic
     931//          u = L * h_ref * x0[x_] /get_p_s(x0);
     932//             x[x_] += u * x0[px_];
     933//             x[y_] += u * x0[py_];
     934//          x[px_]-= L * (-h_ref * get_p_s(x0) + h_bend + h_ref * h_bend
     935//                   * x0[x_] + ByoBrho);
     936//             x[ct_] += u * (1.0+x0[delta_]);
     937             
     938              //kick map due to the dipole vector potential
     939             // x[px_] -= L*(h_bend + h_ref*h_bend*x0[x_]+ByoBrho);
    805940 
    806941//          sqrtpx = sqrt(sqr(1+x0[delta_])-sqr(x0[py_]));
     
    835970            x[ct_] += L * h_ref * x0[x_];
    836971 
    837             //  second order of the h_ref; has problem when do tracking...
    838            u = L * h_ref * x0[x_] /(1.0+x[delta_]);
     972            //  second order, cubic term of H, H3; has problem when do tracking...works for THOMX!!!!!
     973            // not symplectic????
     974         if(0){
     975            u = L * h_ref * x0[x_] /(1.0+x0[delta_]);
    839976            x[x_] += u * x0[px_];
    840977            x[y_] += u * x0[py_];
    841978            x[ct_] += u*(sqr(x0[px_])+sqr(x0[py_]))/(2.0*(1.0+x0[delta_]));
    842979           
    843             }
     980           // cout << "test......2.....  u = " << u<< endl;
     981          }     
     982      }
    844983         
    845984        }//from other straight magnets
    846985        else
    847             x[px_] -= L * (ByoBrho + h_bend);
     986            x[px_] -= L * (ByoBrho + h_bend*1); //h_bend should be trigger on for combined dipoles
    848987
    849988        //vertical kick due to the magnets
     
    8721011 Compute edge focusing for a dipole
    8731012 There is no radiation coming from the edge
    874  The standard formula used is : (Where these formula comes from?????)
     1013 The standard formula used is : (SLAC-75, K. Brown's first order of fringe field but with the correction of 1/(1+delta) in R43)
    8751014
    8761015       px = px0 +  irho tan(phi) *x0
     
    9131052
    9141053 April 2011, No energy dependence for H-plane according to SSC-141 note (E. Forest)
    915  Agreement better with MAD8 (LNLS), SOLEIL small effect (.1)
     1054 Agreement better with MAD8 (LNLS), SOLEIL small effect (.1). Modified by Laurent Nadolski @ soleil
     1055 Comments: Jianfeng Zhang @ LAL, 05/06/2013
     1056 This model only works for Soleil lattice, but not works for ThomX and SuperB DR lattice.
    9161057 
    917  Add the contribution of x' to the x[py_] for small ring like Thom-X.
    9181058 18/06/2012  Jianfeng Zhang @ LAL
    919  
     1059 Add the contribution of x' to the x[py_] for small ring like Thom-X, using Alexandre Loulergue's correction.
     1060 This models works for ThomX, Soleil, and SuperB DR lattices; and
     1061 close to the Forest's model and K. Brown's models.
    9201062 
    9211063 ****************************************************************************/
     
    9261068    if (true) {
    9271069     
    928         //cout << "With Alex's  correction: " << endl;
     1070       // cout << "Dipole edge effect WITH Alex's  correction: " << endl;
    9291071     
    9301072      //with the contribution from the entrance angle of the particle at the edge
     
    9391081// compared the fringe field model used in Tracy
    9401082// results:  K. Brown's model is wrong for small ring like Thom-X!!!!
    941 // The original model of tracy is correct !!!!!!!!!!
     1083// The original model of tracy is correct for tracking!!!!!!!!!!
    9421084  /*
    9431085  double psi;
     
    9591101    */
    9601102
    961     //add the contribution of the entrance momentum of the particle, from Alex Loulergue. This model is NOT
    962     //correct, because it's not symplectic!!!!!!!!
     1103    //add the contribution of the entrance momentum of the particle, from Alex Loulergue.
    9631104    if(Entrance){
    964        x[px_] += irho * tan(dtor(phi)) * x[x_]/ (1.0 + x[delta_]*0);
    965        x[py_] -= irho * tan(dtor(phi) + x[px_]/(1+x[delta_]*1) - get_psi(irho, phi, gap)) * x[y_]
    966                 / (1.0 + x[delta_]);
     1105       x[px_] += irho * tan(dtor(phi) +x[py_]/(1+x[delta_]*1)) * x[x_]/ (1.0 + x[delta_]*0);
     1106       x[py_] -= irho * tan(dtor(phi) + x[px_]/(1+x[delta_]*1) - get_psi(irho, phi, gap)/(1+x[delta_]*0)) * x[y_]
     1107                / (1.0 + x[delta_]*0);
    9671108    }else{
    968        x[px_] += irho * tan(dtor(phi)) * x[x_]/ (1.0 + x[delta_]*0);
    969        x[py_] -= irho * tan(dtor(phi) - x[px_]/(1+x[delta_]*1) - get_psi(irho, phi, gap)) * x[y_]
    970                 / (1.0 + x[delta_]);
     1109       x[px_] += irho * tan(dtor(phi) - x[py_]/(1+x[delta_]*1)) * x[x_]/ (1.0 + x[delta_]*0);
     1110       x[py_] -= irho * tan(dtor(phi) - x[px_]/(1+x[delta_]*1) - get_psi(irho, phi, gap)/(1+x[delta_]*0)) * x[y_]
     1111                / (1.0 + x[delta_]*0);
    9711112    }
    9721113     
    9731114    } else {//original one
    9741115
    975   //cout << "Without Alex's  correction: " << endl;
     1116   //cout << "Dipole edge effect WITHOUT Alex's  correction: " << endl;
    9761117        x[px_] += irho * tan(dtor(phi)) * x[x_];
    977         x[py_] -= irho * tan(dtor(phi) - get_psi(irho, phi, gap)) * x[y_];
     1118        x[py_] -= irho * tan(dtor(phi) - get_psi(irho, phi, gap)) * x[y_]/ (1.0 + x[delta_]*1);
    9781119    }
    9791120}
     
    9811122
    9821123/******************************************************************
    983  
     1124 template<typename T>
     1125static void BendCurvature(double irho, double H, ss_vect<T> &x)
     1126
     1127The leanding order term T211, T233, and T413 on page 117 & page 118
     1128of the dipole edge effect in SLAC-75, using the symplectic
     1129form in
    9841130 E. Forest: "Fringe field in MAD, Part II: Bend curvature in MAD-X for the
    9851131             mudule PTC".
    9861132             P.10 Eq. (5) and (42).
    9871133 
     1134 For an rectangular dipole, the bending curvature term is zero, since 1/R = 0.
     1135 
     1136 irho:   curvature of the central orbit inside the dipole
     1137 H:      curvature of the entrance/exit pole face of the dipole
     1138 
     1139 Comments:
     1140 Written by Jianfeng Zhang @ LAL, 01/10/2012.
    9881141******************************************************************/
    9891142template<typename T>
    990 static void EdgeFocus(double irho, ss_vect<T> &x) {
     1143static void BendCurvature(double irho,  double H, ss_vect<T> &x) {
     1144 
     1145  if(trace)
     1146  cout << "Forest's bend curvature...."<<endl;
    9911147 
    9921148  T pm2,u, coeff1, coeff2,coeff3;
    9931149 
    994    ss_vect<T> x1;
     1150   ss_vect<T> x0;
    9951151   
    996    x1 = x;
     1152   x0 = x;
    9971153 
    998    pm2 = sqr(1+x1[delta_]) - sqr(x1[px_]);
    999    u = irho*irho/2/pm2;
     1154   pm2 = sqr(1+x0[delta_]) - sqr(x0[px_]);
     1155   u = irho*H/2/pm2;
    10001156   
    1001    coeff1 = u * 2*x1[px_]*(1+x1[delta_])/pm2;
    1002    coeff2 = u * (1+x1[delta_]);
    1003    coeff3 = u *(-1) * (sqr(1+x1[delta_]) + sqr(x1[px_]))/pm2;
     1157   coeff1 = u * 2*x0[px_]*(1+x0[delta_])/pm2; //
     1158   coeff2 = u * (1+x0[delta_]); //
     1159   coeff3 = u * (pm2 - 2*(1+x0[delta_]))/pm2;
    10041160   
    10051161 
    1006    x[x_] = x1[x_]/(1-coeff1*x1[y_]*x1[y_]);
    1007    x[px_] -= coeff2*x1[y_]*x1[y_] - irho*irho/2*sqr(x1[x_]);
    1008    x[py_] -= 2*coeff2*x[x_]*x1[y_];
    1009    x[ct_] -= coeff3*x[x_]*x1[y_]*x1[y_];
     1162   x[x_]  += x0[x_]/(1-coeff1*x0[y_]*x0[y_]);
     1163   x[px_] -= coeff2*x0[y_]*x0[y_] - irho*H/2*sqr(x0[x_]);
     1164   x[py_] -= 2*coeff2*x[x_]*x0[y_];
     1165   x[ct_] -= coeff3*x[x_]*x0[y_]*x0[y_];
    10101166}   
    10111167   
     
    13131469        //fringe field and edge focusing of dipoles
    13141470       if (M->Pirho != 0.0 && M->dipEdge_effect1 == 1){
    1315          if (!globval.H_exact) { //big ring */
    1316            //            EdgeFocus(M->Pirho, M->PTx1, M->Pgap, x,true);
    1317            //} else {//small and big rings
    1318           if(M->PTx1!=0){
    1319             EdgeFocus(M->Pirho, x);
    1320            //p_rot(M->PTx1,  x);
    1321              //rotate from cartesian cooridnate to curlinear curved beam coordinate;
     1471         if (!globval.H_exact) { //big ring */ modified linear term T43 on page 117 & 118 in SLAC-75.
     1472                       EdgeFocus(M->Pirho, M->PTx1, M->Pgap, x,true);
     1473           } else {//small and big rings; Forest's model
     1474          if(M->PH1!=0){
     1475            // curvature of the magnet pole face; for a sector/wedge/rectangular dipole, this term is 0.
     1476           BendCurvature(M->Pirho, M->PH1, x);
     1477          }
     1478           p_rot(M->PTx1,  x);  //rotate from cartesian cooridnate to curlinear curved beam coordinate;
    13221479             // since the map of a sector dipole is used in Tracy 3
    1323           }
    1324            p_rot(M->PTx1,  x);
    13251480           bend_fringe(M->Pirho, M->Pgap, x); //fringe field
    13261481         }
     
    13661521
    13671522    case Meth_Second:
    1368         cout << "Mpole_Pass: Meth_Second not supported" << endl;
    1369         exit_(0);
    1370         break;
    1371 
     1523     
     1524      //  cout << "Mpole_Pass: Meth_Second not supported" << endl;
     1525       // exit_(0);
     1526       // break;
     1527
     1528    //specially for the test of the dipole map,see Forest's beam dynamics, p361. eqn.(12.19)
     1529 
     1530    dL1 = 0.5*dL;
     1531    dL2 = dL;
     1532           
     1533            for (seg = 1; seg <= M->PN; seg++) {
     1534              dipole_kick(dL1,M->Pirho,h_ref,x);
     1535              multipole_kick(M->Porder, M->PB, dkL1, M->Pirho, x);
     1536              dipole_kick(dL1,M->Pirho,h_ref,x);
     1537            }
     1538
     1539           
     1540       
    13721541    case Meth_Fourth:  //forth order symplectic integrator
    13731542        if (M->Pthick == thick) {
     
    13861555                }
    13871556
    1388                 Drift(dL1, x);
     1557                Drift(dL1, x);
    13891558                thin_kick(M->Porder, M->PB, dkL1, M->Pirho, h_ref, x);
    13901559                Drift(dL2, x);
    1391                 thin_kick(M->Porder, M->PB, dkL2, M->Pirho, h_ref, x);
     1560                thin_kick(M->Porder, M->PB, dkL2, M->Pirho, h_ref, x);
    13921561
    13931562                if (globval.emittance && (!globval.Cavity_on) && (M->Pirho
     
    13961565                    dI4 += 4.0 * is_tps<tps>::get_dI4(x);
    13971566                }
    1398 
     1567               
     1568               
    13991569                Drift(dL2, x);
    1400                 thin_kick(M->Porder, M->PB, dkL1, M->Pirho, h_ref, x);
    1401                 Drift(dL1, x);
     1570                thin_kick(M->Porder, M->PB, dkL1, M->Pirho, h_ref, x);
     1571                Drift(dL1, x);
    14021572
    14031573                if (globval.emittance && (!globval.Cavity_on) && (M->Pirho
     
    14281598      /* dipole fringe fields */
    14291599             if (M->Pirho != 0.0 && M->dipEdge_effect2 == 1){
    1430             if (!globval.H_exact) { //big ring
    1431               //                 EdgeFocus(M->Pirho, M->PTx2, M->Pgap, x,false);
    1432               // }else{
    1433              
    1434              
    1435              bend_fringe(-M->Pirho, M->Pgap,x); //fringe field of the dipole
    1436               p_rot(M->PTx2, x);
    1437              if(M->PTx2!=0){
    1438               //p_rot(M->PTx2, x); //rotate back to the cartesian cooridinate
    1439             EdgeFocus(M->Pirho, x);
     1600            if (!globval.H_exact) { //big ring, linear model correction
     1601                               EdgeFocus(M->Pirho, M->PTx2, M->Pgap, x,false);
     1602               }else{
     1603             bend_fringe(-M->Pirho, M->Pgap,x); //Forest's fringe field of the dipole
     1604              p_rot(M->PTx2, x); //rotate back to the cartesian cooridinate
     1605             if(M->PH2!=0){
     1606            // curvature of the magnet pole face; for a sector/wedge/rectangular dipole, this term is 0.
     1607             BendCurvature(M->Pirho, M->PH2, x);
    14401608             }
    1441        
    1442 
    14431609         }
    14441610     }
     
    27622928     corresponding to a half magnet w/ an entrance
    27632929     angle and no exit angle.
    2764      The linear frindge field is taken into account               
     2930     The linear fringe field is taken into account               
    27652931     **************************************************************/
    27662932void Mpole_Setmatrix(int Fnum1, int Knum1, double K) {
     
    32593425        printf("Elem_GetPos: there are no kids in family %d (%s)\n", Fnum1,
    32603426                ElemFam[Fnum1 - 1].ElemF.PName);
    3261         exit_(0);
     3427        exit_(1);
    32623428    }
    32633429
     
    32903456    d_2 = 1e0 - 2e0 * d_1;
    32913457
     3458   
     3459   
     3460   
     3461   
    32923462    // classical radiation
    32933463    //  C_gamma = 8.846056192e-05;
     
    36823852    M->PTx1 = 0.0; /* Entrance angle */
    36833853    M->PTx2 = 0.0; /* Exit angle */
     3854    M->PH1 = 0.0; /* Entrance pole face curvature*/
     3855    M->PH2 = 0.0; /* Exit pole face curvature */
    36843856    M->Pgap = 0.0; /* Gap for fringe field ??? */
    36853857
Note: See TracChangeset for help on using the changeset viewer.