|
| 1 | +#include "DanilovEnvelopeSolver22.hh" |
| 2 | + |
| 3 | +DanilovEnvelopeSolver22::DanilovEnvelopeSolver22(double perveance) : CppPyWrapper(NULL) { |
| 4 | + Q = perveance; |
| 5 | +} |
| 6 | + |
| 7 | +void DanilovEnvelopeSolver22::setPerveance(double perveance) { |
| 8 | + Q = perveance; |
| 9 | +} |
| 10 | + |
| 11 | +double DanilovEnvelopeSolver22::getPerveance() { |
| 12 | + return Q; |
| 13 | +} |
| 14 | + |
| 15 | +void DanilovEnvelopeSolver22::trackBunch(Bunch *bunch, double length) { |
| 16 | + // Compute ellipse size and orientation. |
| 17 | + double a = bunch->x(0); |
| 18 | + double b = bunch->x(1); |
| 19 | + double e = bunch->y(0); |
| 20 | + double f = bunch->y(1); |
| 21 | + |
| 22 | + double cov_xx = a * a + b * b; // 4 * <x^2> |
| 23 | + double cov_yy = e * e + f * f; // 4 * <y^2> |
| 24 | + double cov_xy = a * e + b * f; // 4 * <xy> |
| 25 | + |
| 26 | + double phi = -0.5 * atan2(2.0 * cov_xy, cov_xx - cov_yy); |
| 27 | + |
| 28 | + double _cos = cos(phi); |
| 29 | + double _sin = sin(phi); |
| 30 | + double cos2 = _cos * _cos; |
| 31 | + double sin2 = _sin * _sin; |
| 32 | + double sin_cos = _sin * _cos; |
| 33 | + |
| 34 | + double cxn = sqrt(abs(cov_xx * cos2 + cov_yy * sin2 - 2.0 * cov_xy * sin_cos)); |
| 35 | + double cyn = sqrt(abs(cov_xx * sin2 + cov_yy * cos2 + 2.0 * cov_xy * sin_cos)); |
| 36 | + double factor = length * (2.0 * Q / (cxn + cyn)); |
| 37 | + |
| 38 | + // Track envelope |
| 39 | + if (cxn > 0.0) { |
| 40 | + bunch->xp(0) += factor * (a * cos2 - e * sin_cos) / cxn; |
| 41 | + bunch->xp(1) += factor * (b * cos2 - f * sin_cos) / cxn; |
| 42 | + bunch->yp(0) += factor * (e * sin2 - a * sin_cos) / cxn; |
| 43 | + bunch->yp(1) += factor * (f * sin2 - b * sin_cos) / cxn; |
| 44 | + } |
| 45 | + if (cyn > 0.0) { |
| 46 | + bunch->xp(0) += factor * (a * sin2 + e * sin_cos) / cyn; |
| 47 | + bunch->xp(1) += factor * (b * sin2 + f * sin_cos) / cyn; |
| 48 | + bunch->yp(0) += factor * (e * cos2 + a * sin_cos) / cyn; |
| 49 | + bunch->yp(1) += factor * (f * cos2 + b * sin_cos) / cyn; |
| 50 | + } |
| 51 | + |
| 52 | + // Track test particles |
| 53 | + double cxn2 = cxn * cxn; |
| 54 | + double cyn2 = cyn * cyn; |
| 55 | + double x; |
| 56 | + double y; |
| 57 | + double x2; |
| 58 | + double y2; |
| 59 | + |
| 60 | + double xn; |
| 61 | + double yn; |
| 62 | + double xn2; |
| 63 | + double yn2; |
| 64 | + |
| 65 | + double t1; |
| 66 | + double B; |
| 67 | + double C; |
| 68 | + double Dx; |
| 69 | + double Dy; |
| 70 | + |
| 71 | + double delta_xp; |
| 72 | + double delta_yp; |
| 73 | + double delta_xpn; |
| 74 | + double delta_ypn; |
| 75 | + bool in_ellipse; |
| 76 | + |
| 77 | + for (int i = 2; i < bunch->getSize(); i++) { |
| 78 | + x = bunch->x(i); |
| 79 | + y = bunch->y(i); |
| 80 | + |
| 81 | + x2 = x * x; |
| 82 | + y2 = y * y; |
| 83 | + |
| 84 | + xn = x * _cos - y * _sin; |
| 85 | + yn = x * _sin + y * _cos; |
| 86 | + |
| 87 | + xn2 = xn * xn; |
| 88 | + yn2 = yn * yn; |
| 89 | + |
| 90 | + in_ellipse = ((xn2 / cxn2) + (yn2 / cyn2)) <= 1.0; |
| 91 | + |
| 92 | + if (in_ellipse) { |
| 93 | + if (cxn > 0.0) { |
| 94 | + delta_xpn = factor * xn / cxn; |
| 95 | + } |
| 96 | + if (cyn > 0.0) { |
| 97 | + delta_ypn = factor * yn / cyn; |
| 98 | + } |
| 99 | + } else { |
| 100 | + // https://arxiv.org/abs/physics/0108040 |
| 101 | + B = xn2 + yn2 - cxn2 - cyn2; |
| 102 | + C = xn2 * cyn2 + yn2 * cxn2 - cxn2 * cyn2; |
| 103 | + t1 = pow(0.25 * B * B + C, 0.5) + 0.5 * B; |
| 104 | + Dx = pow(cxn2 + t1, 0.5); |
| 105 | + Dy = pow(cyn2 + t1, 0.5); |
| 106 | + delta_xpn = 2.0 * Q * xn / (Dx * (Dx + Dy)); |
| 107 | + delta_ypn = 2.0 * Q * yn / (Dy * (Dx + Dy)); |
| 108 | + } |
| 109 | + delta_xp = +delta_xpn * _cos + delta_ypn * _sin; |
| 110 | + delta_yp = -delta_xpn * _sin + delta_ypn * _cos; |
| 111 | + bunch->xp(i) += delta_xp; |
| 112 | + bunch->yp(i) += delta_yp; |
| 113 | + } |
| 114 | +} |
0 commit comments