30 #include "gsl/gsl_poly.h"
46 messageHeader_m(
" * "),
47 pusher_m(right.pusher_m),
48 fieldmap_m(right.fieldmap_m),
49 designRadius_m(right.designRadius_m),
50 exitAngle_m(right.exitAngle_m),
51 fieldIndex_m(right.fieldIndex_m),
52 startField_m(right.startField_m),
53 endField_m(right.endField_m),
54 widthEntranceFringe_m(right.widthEntranceFringe_m),
55 widthExitFringe_m(right.widthExitFringe_m),
56 reinitialize_m(right.reinitialize_m),
57 entranceParameter1_m(right.entranceParameter1_m),
58 entranceParameter2_m(right.entranceParameter2_m),
59 entranceParameter3_m(right.entranceParameter3_m),
60 exitParameter1_m(right.exitParameter1_m),
61 exitParameter2_m(right.exitParameter2_m),
62 exitParameter3_m(right.exitParameter3_m),
63 engeCoeffsEntry_m(right.engeCoeffsEntry_m),
64 engeCoeffsExit_m(right.engeCoeffsExit_m),
65 entryFieldValues_m(NULL),
66 exitFieldValues_m(NULL),
67 entryFieldAccel_m(NULL),
68 exitFieldAccel_m(NULL),
69 deltaBeginEntry_m(right.deltaBeginEntry_m),
70 deltaEndEntry_m(right.deltaEndEntry_m),
71 polyOrderEntry_m(right.polyOrderEntry_m),
72 deltaBeginExit_m(right.deltaBeginExit_m),
73 deltaEndExit_m(right.deltaEndExit_m),
74 polyOrderExit_m(right.polyOrderExit_m),
75 cosEntranceAngle_m(right.cosEntranceAngle_m),
76 sinEntranceAngle_m(right.sinEntranceAngle_m),
77 tanEntranceAngle_m(right.tanEntranceAngle_m),
78 tanExitAngle_m(right.tanExitAngle_m),
79 beginToEnd_m(right.beginToEnd_m),
80 beginToEnd_lcs_m(right.beginToEnd_lcs_m),
81 toEntranceRegion_m(right.toEntranceRegion_m),
82 toExitRegion_m(right.toExitRegion_m),
83 computeAngleTrafo_m(right.computeAngleTrafo_m),
84 maxAngle_m(right.maxAngle_m),
85 nSlices_m(right.nSlices_m){
93 messageHeader_m(
" * "),
101 widthEntranceFringe_m(0.0),
102 widthExitFringe_m(0.0),
103 reinitialize_m(false),
104 entranceParameter1_m(0.0),
105 entranceParameter2_m(0.0),
106 entranceParameter3_m(0.0),
107 exitParameter1_m(0.0),
108 exitParameter2_m(0.0),
109 exitParameter3_m(0.0),
110 entryFieldValues_m(NULL),
111 exitFieldValues_m(NULL),
112 entryFieldAccel_m(NULL),
113 exitFieldAccel_m(NULL),
114 deltaBeginEntry_m(0.0),
115 deltaEndEntry_m(0.0),
117 deltaBeginExit_m(0.0),
120 cosEntranceAngle_m(1.0),
121 sinEntranceAngle_m(0.0),
122 tanEntranceAngle_m(0.0),
133 for (
unsigned int i = 0; i < 3u; ++ i) {
191 return apply(R, P, t, E, B);
207 <<
"======================================================================\n"
208 <<
"===== " << std::left << std::setw(64) << std::setfill(
'=') << name <<
"\n"
209 <<
"======================================================================\n";
215 double bendAngleX = 0.0;
216 double bendAngleY = 0.0;
218 print(msg, bendAngleX, bendAngleY);
230 <<
"======================================================================\n"
231 <<
"======================================================================\n"
234 ERRORMSG(
"There is something wrong with your field map \""
237 endField = startField - 1.0e-3;
263 const double betaGamma =
sqrt(
pow(gamma, 2.0) - 1.0);
273 const Vector_t eField(0.0);
275 while(deltaS < bendLength) {
281 Vector_t bField(0.0, 0.0, 0.0);
302 const std::vector<double> &engeCoeff,
305 double &engeFuncDeriv,
306 double &engeFuncSecDerivNorm) {
309 double expSumDeriv = 0.0;
310 double expSumSecDeriv = 0.0;
314 expSum = engeCoeff.at(0)
315 + engeCoeff.at(1) * zNormalized;
316 expSumDeriv = engeCoeff.at(1);
318 for(
int index = 2; index <= polyOrder; index++) {
319 expSum += engeCoeff.at(index) *
pow(zNormalized, index);
320 expSumDeriv += index * engeCoeff.at(index)
321 *
pow(zNormalized, index - 1);
322 expSumSecDeriv += index * (index - 1) * engeCoeff.at(index)
323 *
pow(zNormalized, index - 2);
326 }
else if(polyOrder == 1) {
328 expSum = engeCoeff.at(0)
329 + engeCoeff.at(1) * zNormalized;
330 expSumDeriv = engeCoeff.at(1);
333 expSum = engeCoeff.at(0);
335 double engeExp =
exp(expSum);
336 engeFunc = 1.0 / (1.0 + engeExp);
340 expSumDeriv /=
gap_m;
342 double engeExpDeriv = expSumDeriv * engeExp;
343 double engeExpSecDeriv = (expSumSecDeriv +
pow(expSumDeriv, 2.0))
345 double engeFuncSq =
pow(engeFunc, 2.0);
347 engeFuncDeriv = -engeExpDeriv * engeFuncSq;
351 engeFuncSecDerivNorm = -engeExpSecDeriv * engeFunc
352 + 2.0 *
pow(engeExpDeriv, 2.0)
355 engeFuncSecDerivNorm = 0.0;
360 engeFuncSecDerivNorm = 0.0;
413 B(1) = (engeFunc - 0.5 * engeFuncSecDeriv *
pow(Rprime(1), 2.0));
415 B(2) = engeFuncDeriv * Rprime(1);
450 B(1) = (engeFunc - 0.5 * engeFuncSecDeriv *
pow(Rprime(1), 2.0));
452 B(2) = engeFuncDeriv * Rprime(1);
461 bool horizontallyInside =
false;
464 if (verticallyInside) {
469 if (inEntranceRegion && inExitRegion) {
474 inExitRegion =
false;
476 inEntranceRegion =
false;
479 if (inEntranceRegion) {
481 }
else if (inExitRegion) {
492 Vector_t BEntrance(0.0), BExit(0.0);
498 if (inEntranceRegion) {
499 horizontallyInside =
true;
500 if (verticallyInside) {
506 horizontallyInside =
true;
507 if (verticallyInside) {
514 B = BEntrance + BExit;
516 bool hitMaterial = (horizontallyInside && (!verticallyInside));
524 const double betaGamma =
sqrt(gamma * gamma - 1.);
527 std::ofstream trajectoryOutput;
530 trajectoryOutput.precision(12);
531 trajectoryOutput <<
"# " << std::setw(18) <<
"s"
532 << std::setw(20) <<
"x"
533 << std::setw(20) <<
"z"
534 << std::setw(20) <<
"By"
549 const Vector_t eField(0.0);
550 const double stepSize = betaGamma / gamma *
Physics::c * dt;
553 while(deltaS < bendLength) {
559 Vector_t bField(0.0, 0.0, 0.0);
560 Vector_t XInBendFrame =
X;
566 trajectoryOutput << std::setw(20) << deltaS + 0.5 * stepSize
567 << std::setw(20) <<
X(0)
568 << std::setw(20) <<
X(2)
569 << std::setw(20) << bField(1)
593 double tmp1 = betaGamma * mass / (2.0 * effectiveLength *
Physics::c);
595 double fieldStep = (
angle_m - actualBendAngle) * tmp1;
621 double deltaStep = 0.0;
623 deltaStep = -
gap_m / 2.0;
625 deltaStep =
gap_m / 2.0;
628 double bendAngle1 = actualBendAngle;
630 double delta2 = deltaStep;
655 unsigned int iterations = 1;
657 while(error > 1.0
e-6 && iterations < 100) {
659 double delta = (delta1 + delta2) / 2.0;
669 if(bendAngle1 -
angle_m < 0.0) {
671 if(newBendAngle -
angle_m < 0.0) {
672 bendAngle1 = newBendAngle;
681 if(newBendAngle -
angle_m < 0.0) {
685 bendAngle1 = newBendAngle;
704 const double tolerance = 1
e-7;
707 if (error < tolerance)
714 double bendAngle1 = actualBendAngle;
722 amplitude1 = amplitude2;
723 bendAngle1 = bendAngle2;
725 amplitude2 += fieldStep;
731 amplitude1 = amplitude2;
732 bendAngle1 = bendAngle2;
734 amplitude2 += fieldStep;
741 unsigned int iterations = 1;
742 while(error > tolerance && iterations < 100) {
749 if(error > tolerance) {
751 if(bendAngle1 -
angle_m < 0.0) {
753 if(newBendAngle -
angle_m < 0.0) {
754 bendAngle1 = newBendAngle;
763 if(newBendAngle -
angle_m < 0.0) {
767 bendAngle1 = newBendAngle;
780 double refBetaGamma =
sqrt(
pow(refGamma, 2.0) - 1.0);
782 bool reinitialize =
false;
796 refBetaGamma * refMass /
802 if(refCharge < 0.0) {
813 reinitialize =
false;
843 effectiveAngle >= 0.0 && effectiveAngle <
maxAngle_m) {
844 if (effectiveAngle < 0.5 *
maxAngle_m)
return R(2) >= 0.0;
845 return Rprime(2) < 0.0;
862 return (Rprime(2) >= 0 &&
884 <<
"Start of field map: "
886 <<
" m (in s coordinates)"
888 msg <<
"End of field map: "
890 <<
" m (in s coordinates)"
892 msg <<
"Entrance edge of magnet: "
894 <<
" m (in s coordinates)"
897 <<
"Reference Trajectory Properties"
899 <<
"======================================================================"
901 msg <<
"Bend angle magnitude: "
907 msg <<
"Entrance edge angle: "
913 msg <<
"Exit edge angle: "
919 msg <<
"Bend design radius: "
923 msg <<
"Bend design energy: "
928 <<
"Bend Field and Rotation Properties"
930 <<
"======================================================================"
932 msg <<
"Field amplitude: "
936 msg <<
"Field index: "
939 msg <<
"Rotation about z axis: "
946 <<
"Reference Trajectory Properties Through Bend Magnet with Fringe Fields"
948 <<
"======================================================================"
950 msg <<
"Reference particle is bent: "
954 <<
" degrees) in x plane"
956 msg <<
"Reference particle is bent: "
960 <<
" degrees) in y plane"
965 <<
"Effective Field Map\n"
966 <<
"======================================================================\n"
1002 unsigned int numStepsEntry =
std::ceil(entryLength / stepSize) + 3;
1003 double stepSizeEntry = entryLength / (numStepsEntry - 3);
1004 std::vector<double> zvalsEntry(numStepsEntry);
1005 std::vector<std::vector<double> > fieldValuesEntry(3);
1008 unsigned int numStepsExit =
std::ceil(exitLength / stepSize) + 3;
1009 double stepSizeExit = exitLength / (numStepsExit - 3);
1010 std::vector<double> zvalsExit(numStepsExit);
1011 std::vector<std::vector<double> > fieldValuesExit(3);
1018 for (
unsigned int i = 0; i < 3u; ++ i) {
1019 fieldValuesEntry[i].resize(numStepsEntry);
1020 fieldValuesExit[i].resize(numStepsExit);
1026 for (
unsigned int j = 0; j < numStepsEntry; ++ j) {
1030 zvalsEntry[j] = zvalsEntry[j - 1] + stepSizeEntry;
1035 fieldValuesEntry[0][j],
1036 fieldValuesEntry[1][j],
1037 fieldValuesEntry[2][j]);
1038 fieldValuesEntry[2][j] *= fieldValuesEntry[0][j];
1041 for (
unsigned int j = 0; j < numStepsExit; ++ j) {
1045 zvalsExit[j] = zvalsExit[j - 1] + stepSizeExit;
1050 fieldValuesExit[0][j],
1051 fieldValuesExit[1][j],
1052 fieldValuesExit[2][j]);
1053 fieldValuesExit[2][j] *= fieldValuesExit[0][j];
1056 for (
unsigned int i = 0; i < 3u; ++ i) {
1057 gsl_spline_init(
entryFieldValues_m[i], &(zvalsEntry[0]), &(fieldValuesEntry[i][0]), numStepsEntry);
1058 gsl_spline_init(
exitFieldValues_m[i], &(zvalsExit[0]), &(fieldValuesExit[i][0]), numStepsExit);
1079 double betaGamma =
sqrt(
pow(gamma, 2.0) - 1.0);
1129 sin(0.5 * rotationAngleAboutZ) *
Vector_t(0, 0, 1));
1132 Quaternion_t halfRotationAboutAxis(
cos(0.5 * (0.5 * bendAngle - entranceAngle)),
1133 sin(0.5 * (0.5 * bendAngle - entranceAngle)) * rotationAxis);
1135 sin(0.5 * (bendAngle - entranceAngle -
exitAngle_m)) * rotationAxis);
1149 if (rotationCenter(2) < 0.0) {
1152 gsl_poly_solve_quadratic(
dot(P,P),
1158 maxAngleEntranceAperture = tau * P;
1162 gsl_poly_solve_quadratic(
dot(P,P),
1168 maxAngleEntranceAperture = tau * P;
1174 gsl_poly_solve_quadratic(
dot(P,P),
1184 gsl_poly_solve_quadratic(
dot(P,P),
1193 maxAngleEntranceAperture -= rotationCenter;
1201 maxAngleExitAperture -= rotationCenter;
1267 ERRORMSG(
"If using \"1DPROFILE1-DEFAULT\" field map you must set the "
1268 "chord length of the bend using the L attribute in the OPAL "
1297 WARNMSG(
"Warning: bend design energy is zero. Treating as drift."
1305 double refBetaGamma =
sqrt(
pow(refGamma, 2.0) - 1.0);
1309 double sinArgument = chordLength / (2.0 * radius);
1312 WARNMSG(
"Warning: bend strength and defined reference trajectory "
1313 <<
"chord length are not consistent. Treating bend as drift."
1323 WARNMSG(
"Warning bend angle/strength is zero. Treating as drift."
1333 std::vector<Vector_t> outline;
1335 unsigned int numSteps = 2;
1346 gsl_poly_solve_quadratic(
dot(P,P),
1352 Vector_t upperCornerAtEntry = tau1 * P;
1355 gsl_poly_solve_quadratic(
dot(P,P),
1367 double dAngle = 0.5 * totalAngle / (1.0 * numSteps - 1.0);
1369 outline.push_back(upperCornerAtEntry);
1371 for (
unsigned int i = 0; i < numSteps; ++ i, angle += dAngle) {
1373 outline.push_back(rot.
rotate(upperCornerAtEntry - rotationCenter) + rotationCenter);
1375 outline.push_back(upperCornerAtExit);
1387 gsl_poly_solve_quadratic(
dot(P,P),
1393 Vector_t lowerCornerAtEntry = tau1 * P;
1396 gsl_poly_solve_quadratic(
dot(P,P),
1407 double dAngle = 0.5 * totalAngle / (1.0 * numSteps - 1.0);
1409 outline.push_back(lowerCornerAtExit);
1410 double angle = 0.5 * totalAngle;
1411 for (
unsigned int i = 0; i < numSteps; ++ i, angle -= dAngle) {
1413 outline.push_back(rot.
rotate(lowerCornerAtEntry - rotationCenter) + rotationCenter);
1415 outline.push_back(lowerCornerAtEntry);
1418 std::ofstream outlineOutput;
1421 outlineOutput.precision(8);
1423 for (
auto a: outline) {
1424 outlineOutput << std::setw(18) << a(2)
1425 << std::setw(18) << a(0)
1428 outlineOutput << std::setw(18) << outline.front()(2)
1429 << std::setw(18) << outline.front()(0)
1438 std::vector<Vector_t> outline =
getOutline();
1440 unsigned int size = outline.size();
1441 unsigned int last = size - 1;
1442 unsigned int numSteps = (size - 14) / 2;
1443 unsigned int midIdx = numSteps + 7;
1445 for (
unsigned int i = 0; i < 6; ++ i) {
1446 mesh.
vertices_m.push_back(outline[i] + 2 * hgap);
1448 for (
unsigned int i = 6; i < 6 + numSteps; ++ i) {
1449 mesh.
vertices_m.push_back(outline[i] + hgap);
1451 for (
unsigned int i = 6 + numSteps; i < 13 + numSteps; ++ i) {
1452 mesh.
vertices_m.push_back(outline[i] + 2 * hgap);
1454 for (
unsigned int i = 13 + numSteps; i < 13 + 2 * numSteps; ++ i) {
1455 mesh.
vertices_m.push_back(outline[i] + hgap);
1457 mesh.
vertices_m.push_back(outline[last] + 2 * hgap);
1459 for (
unsigned int i = 0; i < 6; ++ i) {
1460 mesh.
vertices_m.push_back(outline[i] - 2 * hgap);
1462 for (
unsigned int i = 6; i < 6 + numSteps; ++ i) {
1463 mesh.
vertices_m.push_back(outline[i] - hgap);
1465 for (
unsigned int i = 6 + numSteps; i < 13 + numSteps; ++ i) {
1466 mesh.
vertices_m.push_back(outline[i] - 2 * hgap);
1468 for (
unsigned int i = 13 + numSteps; i < 13 + 2 * numSteps; ++ i) {
1469 mesh.
vertices_m.push_back(outline[i] - hgap);
1471 mesh.
vertices_m.push_back(outline[last] - 2 * hgap);
1476 mesh.
vertices_m.push_back(outline[midIdx + 4]);
1514 for (
unsigned int i = 6; i < 5 + numSteps; ++ i) {
1523 for (
unsigned int i = 0; i < size - 2; ++ i) {
1524 if (i == 4u || i == 5u ||
1525 i == 5 + numSteps || i == 6 + numSteps ||
1526 i == 11 + numSteps || i == 12 + numSteps)
continue;
1528 unsigned int next = (i + 1) % size;
1567 mesh.
decorations_m.push_back(std::make_pair(0.5 * (P1 + P2) - 0.25 * dir1,
1568 0.5 * (P1 + P2) + 0.25 * dir1));
1572 double det = -dir1[0] * dir2[2] + dir1[2] * dir2[0];
1573 inv(0, 0) = -dir2[2] /
det;
1574 inv(0, 2) = dir2[0] /
det;
1576 inv(2, 0) = -dir1[2] /
det;
1577 inv(2, 2) = dir1[0] /
det;
1579 Vector_t crossPoint = P1 + Tau[0] * dir1;
1580 double angle =
asin(
cross(dir1, dir2)[1]);
1583 Vector_t R = crossPoint - rotationCenter;
1587 gsl_poly_solve_quadratic(
dot(P,P),
1593 std::swap(tau1, tau2);
1595 Vector_t lowerCornerFringeLimit = crossPoint + tau1 * P;
1598 gsl_poly_solve_quadratic(
dot(P,P),
1604 std::swap(tau1, tau2);
1606 Vector_t upperCornerFringeLimit = crossPoint + tau1 * P;
1608 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimit,
1609 upperCornerFringeLimit));
1616 gsl_poly_solve_quadratic(
dot(P,P),
1624 gsl_poly_solve_quadratic(
dot(P,P),
1634 gsl_poly_solve_quadratic(
dot(P,P),
1642 gsl_poly_solve_quadratic(
dot(P,P),
1650 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimitEntrance, upperCornerFringeLimitEntrance));
1651 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimitExit, upperCornerFringeLimitExit));
1696 double entrParam1, entrParam2, entrParam3;
1702 std::array<double,2> entFFL;
1703 entFFL[0]=entrParam2-entrParam1;
1704 entFFL[1]=entrParam3-entrParam2;
1716 std::array<double,2> extFFL;
1718 double exitParam1, exitParam2, exitParam3;
1724 extFFL[0]=exitParam3-exitParam2;
1725 extFFL[1]=exitParam2-exitParam1;
std::vector< double > engeCoeffsEntry_m
Enge coefficients for map entry and exit regions.
double entranceParameter3_m
void setBendEffectiveLength(double startField, double endField)
double entranceParameter2_m
virtual void getInfo(Inform *msg)=0
virtual ElementBase::ElementType getType() const =0
Get element type std::string.
void findBendEffectiveLength(double startField, double endField)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
bool isPositionInEntranceField(const Vector_t &R) const
double sinEntranceAngle_m
constexpr double e
The value of .
bool initializeFieldMap(Inform &msg)
double tanEntranceAngle_m
T det(const AntiSymTenzor< T, 3 > &t)
bool setupBendGeometry(Inform &msg, double &startField, double &endField)
void readFieldMap(Inform &msg)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
bool treatAsDrift(Inform &msg, double chordlength)
Tps< T > sin(const Tps< T > &x)
Sine.
virtual double getFieldGap()
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
constexpr double two_pi
The value of .
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
gsl_spline ** entryFieldValues_m
Tps< T > exp(const Tps< T > &x)
Exponential.
std::string toUpper(const std::string &str)
double startField_m
Dipole field index.
const PartData * getReference() const
double getChordLength() const
virtual const std::string & getName() const
Get element name.
Vector_t transformTo(const Vector_t &r) const
Tps< T > tan(const Tps< T > &x)
Tangent.
Quaternion getQuaternion(Vector_t u, Vector_t ref)
static Fieldmap * getFieldmap(std::string Filename, bool fast=false)
gsl_interp_accel * exitFieldAccel_m
constexpr double rad2deg
The conversion factor from radians to degrees.
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField)
bool inMagnetEntranceRegion(const Vector_t &R) const
bool setupDefaultFieldMap(Inform &msg)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
void setNSlices(const std::size_t &nSlices)
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
Apply field to particles with coordinates in magnet frame.
gsl_spline ** exitFieldValues_m
CoordinateSystemTrafo toEntranceRegion_m
virtual void setEntranceAngle(double entranceAngle)
Inform & level2(Inform &inf)
double getBendAngle() const
void setExitAngle(double exitAngle)
static OpalData * getInstance()
double designRadius_m
Flag to turn on fast field calculation.
std::string messageHeader_m
CoordinateSystemTrafo beginToEnd_lcs_m
constexpr double pi
The value of .
MeshData getSurfaceMesh() const
void setElType(ElemType elt)
set the element type as enumeration needed in the envelope tracker
double fieldIndex_m
and the exit face of the magnet (radians).
Vector_t calcExitFringeField(const Vector_t &R, double deltaX)
std::array< double, 2 > getExitFringeFieldLength() const
Get exit fringe field length.
int polyOrderEntry_m
function origin that Enge function ends.
constexpr double c
The velocity of light in m/s.
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
double calculateBendAngle()
void setEngeOriginDelta(double delta)
Vector_t transformToExitRegion(const Vector_t &R) const
void kick(const Vector_t &R, Vector_t &P, const Vector_t &Ef, const Vector_t &Bf, const double &dt) const
std::vector< Vector_t > vertices_m
virtual bool isInside(const Vector_t &r) const
double entranceParameter1_m
CoordinateSystemTrafo toExitRegion_m
bool inMagnetCentralRegion(const Vector_t &R) const
bool calculateMapField(const Vector_t &R, Vector_t &B)
PartBunchBase< double, 3 > * RefPartBunch_m
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
void findBendStrength(double mass, double gamma, double betaGamma, double charge)
std::size_t getNSlices() const
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Vektor< double, 3 > Vector_t
virtual void get1DProfile1EntranceParam(double &entranceParameter1, double &entranceParameter2, double &entranceParameter3)
double deltaBeginExit_m
Enge function order for entry region.
Vector_t calcEntranceFringeField(const Vector_t &R, double deltaX)
bool inMagnetExitRegion(const Vector_t &R) const
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
bool findIdealBendParameters(double chordLength)
virtual bool findChordLength(Inform &msg, double &chordLength)=0
virtual void get1DProfile1EngeCoeffs(std::vector< double > &engeCoeffsEntry, std::vector< double > &engeCoeffsExit)
Tps< T > sqrt(const Tps< T > &x)
Square root.
Vector_t calcCentralField(const Vector_t &R, double deltaX)
std::vector< Vektor< unsigned int, 3 > > triangles_m
CoordinateSystemTrafo beginToEnd_m
const bool fast_m
Magnet field map.
double getRotationAboutZ() const
gsl_interp_accel * entryFieldAccel_m
std::vector< std::pair< Vector_t, Vector_t > > decorations_m
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B)
double deltaEndEntry_m
function origin where Enge function starts.
virtual void goOnline(const double &kineticEnergy)
Tps< T > cos(const Tps< T > &x)
Cosine.
void calculateRefTrajectory(double &angleX, double &angleY)
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Vector_t rotateFrom(const Vector_t &r) const
Vector_t rotate(const Vector_t &) const
double getQ() const
Access to reference data.
double estimateFieldAdjustmentStep(double actualBendAngle, double mass, double betaGamma)
T isnan(T x)
isnan function with adjusted return type
constexpr double deg2rad
The conversion factor from degrees to radians.
void setGapFromFieldMap()
void adjustFringeFields(double ratio)
CoordinateSystemTrafo getBeginToEnd_local() const
void setupPusher(PartBunchBase< double, 3 > *bunch)
std::array< double, 2 > getEntranceFringeFieldLength() const
Get entrance fringe field length.
std::pair< ApertureType, std::vector< double > > aperture_m
double widthEntranceFringe_m
End of magnet field map in s coordinates (m).
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Quaternion conjugate() const
void calcEngeFunction(double zNormalized, const std::vector< double > &engeCoeff, int polyOrder, double &engeFunc, double &engeFuncDeriv, double &engeFuncSecDerivNorm)
CoordinateSystemTrafo computeAngleTrafo_m
std::vector< Vector_t > getOutline() const
double deltaEndExit_m
function origin that Enge function starts.
double gap_m
Angle between incoming reference trajectory.
double getEntranceAngle() const
void print(Inform &msg, double bendAngleX, double bendAngle)
Fieldmap * fieldmap_m
through the bend.
std::vector< double > engeCoeffsExit_m
double exitAngle_m
Bend design radius (m).
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
int polyOrderExit_m
function origin that Enge function ends.
void push(Vector_t &R, const Vector_t &P, const double &dt) const
double endField_m
Start of magnet field map in s coordinates (m).
Inform & endl(Inform &inf)
Vector_t transformToEntranceRegion(const Vector_t &R) const
void setFieldBoundaries(double startField, double endField)
bool isPositionInExitField(const Vector_t &R) const
std::vector< Vector_t > refTrajMap_m
Map of reference particle trajectory.
virtual void get1DProfile1ExitParam(double &exitParameter1, double &exitParameter2, double &exitParameter3)
T isinf(T x)
isinf function with adjusted return type
void initialise(const PartData *ref)
double getFullGap() const
double cosEntranceAngle_m
Enge function order for entry region.
Vector_t transformFrom(const Vector_t &r) const
bool writeBendTrajectories