Changeset 11 in TRACY3 for trunk/tracy/tracy/src/t2elem.cc
- Timestamp:
- Oct 21, 2013, 10:40:43 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tracy/tracy/src/t2elem.cc
r10 r11 113 113 cout << " " << 1+x[delta_] << " " << x[px_] << " " << x[py_] << endl; 114 114 printf("get_p_s: *** Speed of light exceeded!\n"); 115 //exit_(1);115 // exit_(1); 116 116 117 117 } … … 124 124 125 125 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 156 template<typename T> 157 void 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 127 182 128 183 If H_exact = false, using approximation Hamiltonian (only valid for big ring): … … 616 671 Correction for magnet gap (longitudinal fringe field) 617 672 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 621 677 622 678 2 … … 650 706 } 651 707 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 * ****************************************************************/ 719 template<typename T> 720 void 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 * ****************************************************************/ 758 template<typename T> 759 void 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 652 783 /****************************************************************************/ 653 784 /* template<typename T> … … 657 788 Refer to Tracy 2 manual. 658 789 Calculate multipole kick. 659 790 , 660 791 (1) The exact Hamiltonian is 661 792 … … 737 868 MB array of an and bn, magnetic field components 738 869 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 740 871 h_ref 1/rho [m^-1] is the curvature of the reference orbit in the dipoles which is used in curvilinear coordinate, 741 872 x initial coordinates vector … … 797 928 return; 798 929 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); 805 940 806 941 // sqrtpx = sqrt(sqr(1+x0[delta_])-sqr(x0[py_])); … … 835 970 x[ct_] += L * h_ref * x0[x_]; 836 971 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_]); 839 976 x[x_] += u * x0[px_]; 840 977 x[y_] += u * x0[py_]; 841 978 x[ct_] += u*(sqr(x0[px_])+sqr(x0[py_]))/(2.0*(1.0+x0[delta_])); 842 979 843 } 980 // cout << "test......2..... u = " << u<< endl; 981 } 982 } 844 983 845 984 }//from other straight magnets 846 985 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 848 987 849 988 //vertical kick due to the magnets … … 872 1011 Compute edge focusing for a dipole 873 1012 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) 875 1014 876 1015 px = px0 + irho tan(phi) *x0 … … 913 1052 914 1053 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. 916 1057 917 Add the contribution of x' to the x[py_] for small ring like Thom-X.918 1058 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. 920 1062 921 1063 ****************************************************************************/ … … 926 1068 if (true) { 927 1069 928 //cout << "WithAlex's correction: " << endl;1070 // cout << "Dipole edge effect WITH Alex's correction: " << endl; 929 1071 930 1072 //with the contribution from the entrance angle of the particle at the edge … … 939 1081 // compared the fringe field model used in Tracy 940 1082 // 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!!!!!!!!!! 942 1084 /* 943 1085 double psi; … … 959 1101 */ 960 1102 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. 963 1104 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); 967 1108 }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); 971 1112 } 972 1113 973 1114 } else {//original one 974 1115 975 //cout << "WithoutAlex's correction: " << endl;1116 //cout << "Dipole edge effect WITHOUT Alex's correction: " << endl; 976 1117 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); 978 1119 } 979 1120 } … … 981 1122 982 1123 /****************************************************************** 983 1124 template<typename T> 1125 static void BendCurvature(double irho, double H, ss_vect<T> &x) 1126 1127 The leanding order term T211, T233, and T413 on page 117 & page 118 1128 of the dipole edge effect in SLAC-75, using the symplectic 1129 form in 984 1130 E. Forest: "Fringe field in MAD, Part II: Bend curvature in MAD-X for the 985 1131 mudule PTC". 986 1132 P.10 Eq. (5) and (42). 987 1133 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. 988 1141 ******************************************************************/ 989 1142 template<typename T> 990 static void EdgeFocus(double irho, ss_vect<T> &x) { 1143 static void BendCurvature(double irho, double H, ss_vect<T> &x) { 1144 1145 if(trace) 1146 cout << "Forest's bend curvature...."<<endl; 991 1147 992 1148 T pm2,u, coeff1, coeff2,coeff3; 993 1149 994 ss_vect<T> x 1;1150 ss_vect<T> x0; 995 1151 996 x 1= x;1152 x0 = x; 997 1153 998 pm2 = sqr(1+x 1[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; 1000 1156 1001 coeff1 = u * 2*x 1[px_]*(1+x1[delta_])/pm2;1002 coeff2 = u * (1+x 1[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; 1004 1160 1005 1161 1006 x[x_] = x1[x_]/(1-coeff1*x1[y_]*x1[y_]);1007 x[px_] -= coeff2*x 1[y_]*x1[y_] - irho*irho/2*sqr(x1[x_]);1008 x[py_] -= 2*coeff2*x[x_]*x 1[y_];1009 x[ct_] -= coeff3*x[x_]*x 1[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_]; 1010 1166 } 1011 1167 … … 1313 1469 //fringe field and edge focusing of dipoles 1314 1470 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; 1322 1479 // since the map of a sector dipole is used in Tracy 3 1323 }1324 p_rot(M->PTx1, x);1325 1480 bend_fringe(M->Pirho, M->Pgap, x); //fringe field 1326 1481 } … … 1366 1521 1367 1522 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 1372 1541 case Meth_Fourth: //forth order symplectic integrator 1373 1542 if (M->Pthick == thick) { … … 1386 1555 } 1387 1556 1388 1557 Drift(dL1, x); 1389 1558 thin_kick(M->Porder, M->PB, dkL1, M->Pirho, h_ref, x); 1390 1559 Drift(dL2, x); 1391 1560 thin_kick(M->Porder, M->PB, dkL2, M->Pirho, h_ref, x); 1392 1561 1393 1562 if (globval.emittance && (!globval.Cavity_on) && (M->Pirho … … 1396 1565 dI4 += 4.0 * is_tps<tps>::get_dI4(x); 1397 1566 } 1398 1567 1568 1399 1569 Drift(dL2, x); 1400 1401 1570 thin_kick(M->Porder, M->PB, dkL1, M->Pirho, h_ref, x); 1571 Drift(dL1, x); 1402 1572 1403 1573 if (globval.emittance && (!globval.Cavity_on) && (M->Pirho … … 1428 1598 /* dipole fringe fields */ 1429 1599 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); 1440 1608 } 1441 1442 1443 1609 } 1444 1610 } … … 2762 2928 corresponding to a half magnet w/ an entrance 2763 2929 angle and no exit angle. 2764 The linear frin dge field is taken into account2930 The linear fringe field is taken into account 2765 2931 **************************************************************/ 2766 2932 void Mpole_Setmatrix(int Fnum1, int Knum1, double K) { … … 3259 3425 printf("Elem_GetPos: there are no kids in family %d (%s)\n", Fnum1, 3260 3426 ElemFam[Fnum1 - 1].ElemF.PName); 3261 exit_( 0);3427 exit_(1); 3262 3428 } 3263 3429 … … 3290 3456 d_2 = 1e0 - 2e0 * d_1; 3291 3457 3458 3459 3460 3461 3292 3462 // classical radiation 3293 3463 // C_gamma = 8.846056192e-05; … … 3682 3852 M->PTx1 = 0.0; /* Entrance angle */ 3683 3853 M->PTx2 = 0.0; /* Exit angle */ 3854 M->PH1 = 0.0; /* Entrance pole face curvature*/ 3855 M->PH2 = 0.0; /* Exit pole face curvature */ 3684 3856 M->Pgap = 0.0; /* Gap for fringe field ??? */ 3685 3857
Note: See TracChangeset
for help on using the changeset viewer.