32#include "gsl/gsl_poly.h"
127 for (
unsigned int i = 0; i < 3u; ++ i) {
185 return apply(R, P, t, E, B);
201 <<
"======================================================================\n"
202 <<
"===== " << std::left << std::setw(64) << std::setfill(
'=') <<
name <<
"\n"
203 <<
"======================================================================\n";
209 double bendAngleX = 0.0;
210 double bendAngleY = 0.0;
212 print(msg, bendAngleX, bendAngleY);
224 <<
"======================================================================\n"
225 <<
"======================================================================\n"
228 ERRORMSG(
"There is something wrong with your field map '"
230 endField = startField - 1.0e-3;
266 while (deltaS < bendLength) {
277 pusher_m.kick(
X, P, eField, bField, deltaT);
292 const std::vector<double> &engeCoeff,
295 double &engeFuncDeriv,
296 double &engeFuncSecDerivNorm) {
299 double expSumDeriv = 0.0;
300 double expSumSecDeriv = 0.0;
302 if (polyOrder >= 2) {
304 expSum = engeCoeff.at(0)
305 + engeCoeff.at(1) * zNormalized;
306 expSumDeriv = engeCoeff.at(1);
308 for (
int index = 2; index <= polyOrder; index++) {
309 expSum += engeCoeff.at(index) * std::pow(zNormalized, index);
310 expSumDeriv += index * engeCoeff.at(index)
311 * std::pow(zNormalized, index - 1);
312 expSumSecDeriv += index * (index - 1) * engeCoeff.at(index)
313 * std::pow(zNormalized, index - 2);
316 }
else if (polyOrder == 1) {
318 expSum = engeCoeff.at(0)
319 + engeCoeff.at(1) * zNormalized;
320 expSumDeriv = engeCoeff.at(1);
323 expSum = engeCoeff.at(0);
325 double engeExp = std::exp(expSum);
326 engeFunc = 1.0 / (1.0 + engeExp);
328 if (!std::isnan(engeFunc)) {
330 expSumDeriv /=
gap_m;
331 expSumSecDeriv /= std::pow(
gap_m, 2.0);
332 double engeExpDeriv = expSumDeriv * engeExp;
333 double engeExpSecDeriv = (expSumSecDeriv + std::pow(expSumDeriv, 2.0))
335 double engeFuncSq = std::pow(engeFunc, 2.0);
337 engeFuncDeriv = -engeExpDeriv * engeFuncSq;
338 if (std::isnan(engeFuncDeriv) || std::isinf(engeFuncDeriv))
341 engeFuncSecDerivNorm = -engeExpSecDeriv * engeFunc
342 + 2.0 * std::pow(engeExpDeriv, 2.0)
344 if (std::isnan(engeFuncSecDerivNorm) || std::isinf(engeFuncSecDerivNorm))
345 engeFuncSecDerivNorm = 0.0;
350 engeFuncSecDerivNorm = 0.0;
403 B(1) = (engeFunc - 0.5 * engeFuncSecDeriv * std::pow(Rprime(1), 2.0));
405 B(2) = engeFuncDeriv * Rprime(1);
440 B(1) = (engeFunc - 0.5 * engeFuncSecDeriv * std::pow(Rprime(1), 2.0));
442 B(2) = engeFuncDeriv * Rprime(1);
450 bool verticallyInside = (std::abs(R(1)) < 0.5 *
gap_m);
451 bool horizontallyInside =
false;
454 if (verticallyInside) {
459 if (inEntranceRegion && inExitRegion) {
463 if (std::abs(Rp[2]) < std::abs(Rpp[2])) {
464 inExitRegion =
false;
466 inEntranceRegion =
false;
469 if (inEntranceRegion) {
471 }
else if (inExitRegion) {
482 Vector_t BEntrance(0.0), BExit(0.0);
483 verticallyInside = (std::abs(R(1)) <
gap_m);
488 if (inEntranceRegion) {
489 horizontallyInside =
true;
490 if (verticallyInside) {
496 horizontallyInside =
true;
497 if (verticallyInside) {
504 B = BEntrance + BExit;
506 bool hitMaterial = (horizontallyInside && (!verticallyInside));
512 std::ofstream trajectoryOutput;
518 trajectoryOutput.open(fname);
519 trajectoryOutput.precision(12);
520 trajectoryOutput <<
"# " << std::setw(18) <<
"s"
521 << std::setw(20) <<
"x"
522 << std::setw(20) <<
"z"
523 << std::setw(20) <<
"By"
540 const double stepSize = betaGamma / gamma *
Physics::c * dt;
543 while (deltaS < bendLength) {
556 trajectoryOutput << std::setw(20) << deltaS + 0.5 * stepSize
557 << std::setw(20) <<
X(0)
558 << std::setw(20) <<
X(2)
559 << std::setw(20) << bField(1)
582 double ratioSquared = std::pow(
fieldAmplitude_m / effectiveFieldAmplitude, 2.0);
583 double fieldStep = (
angle_m - actualBendAngle) * effectiveFieldAmplitude;
584 if (ratioSquared < 1.0) {
585 fieldStep = (
angle_m - actualBendAngle) * effectiveFieldAmplitude * std::sqrt(1.0 - ratioSquared);
605 double error = std::abs(actualBendAngle -
angle_m);
607 if (error > 1.0e-6) {
609 double deltaStep = 0.0;
610 if (std::abs(actualBendAngle) < std::abs(
angle_m))
611 deltaStep = -
gap_m / 2.0;
613 deltaStep =
gap_m / 2.0;
616 double bendAngle1 = actualBendAngle;
618 double delta2 = deltaStep;
624 if (std::abs(bendAngle1) > std::abs(
angle_m)) {
625 while (std::abs(bendAngle2) > std::abs(
angle_m)) {
633 while (std::abs(bendAngle2) < std::abs(
angle_m)) {
643 unsigned int iterations = 1;
644 error = std::abs(actualBendAngle -
angle_m);
645 while (error > 1.0e-6 && iterations < 100) {
647 double delta = (delta1 + delta2) / 2.0;
653 error = std::abs(newBendAngle -
angle_m);
655 if (error > 1.0e-6) {
657 if (bendAngle1 -
angle_m < 0.0) {
659 if (newBendAngle -
angle_m < 0.0) {
660 bendAngle1 = newBendAngle;
669 if (newBendAngle -
angle_m < 0.0) {
673 bendAngle1 = newBendAngle;
690 const double tolerance = 1e-7;
693 if (error < tolerance)
698 double amplitude2 = amplitude1;
699 double bendAngle1 = actualBendAngle;
700 double bendAngle2 = bendAngle1;
702 int stepSign = std::abs(bendAngle1) > std::abs(
angle_m) ? -1: 1;
704 amplitude1 = amplitude2;
705 bendAngle1 = bendAngle2;
707 amplitude2 += stepSign * fieldStep;
710 if (stepSign * (std::abs(bendAngle2) - std::abs(
angle_m)) > 0) {
716 unsigned int iterations = 1;
717 while (error > tolerance && iterations < 100) {
724 if (error > tolerance) {
726 if (bendAngle1 -
angle_m < 0.0) {
728 if (newBendAngle -
angle_m < 0.0) {
729 bendAngle1 = newBendAngle;
738 if (newBendAngle -
angle_m < 0.0) {
742 bendAngle1 = newBendAngle;
753 bool reinitialize =
false;
771 if (refCharge < 0.0) {
778 reinitialize =
false;
808 effectiveAngle >= 0.0 && effectiveAngle <
maxAngle_m) {
809 if (effectiveAngle < 0.5 *
maxAngle_m)
return R(2) >= 0.0;
810 return Rprime(2) < 0.0;
827 return (Rprime(2) >= 0 &&
849 <<
"Start of field map: "
851 <<
" m (in s coordinates)"
853 msg <<
"End of field map: "
855 <<
" m (in s coordinates)"
857 msg <<
"Entrance edge of magnet: "
859 <<
" m (in s coordinates)"
862 <<
"Reference Trajectory Properties"
864 <<
"======================================================================"
866 msg <<
"Bend angle magnitude: "
872 msg <<
"Entrance edge angle: "
878 msg <<
"Exit edge angle: "
884 msg <<
"Bend design radius: "
888 msg <<
"Bend design energy: "
893 <<
"Bend Field and Rotation Properties"
895 <<
"======================================================================"
897 msg <<
"Field amplitude: "
901 msg <<
"Field index: "
904 msg <<
"Rotation about z axis: "
911 <<
"Reference Trajectory Properties Through Bend Magnet with Fringe Fields"
913 <<
"======================================================================"
915 msg <<
"Reference particle is bent: "
919 <<
" degrees) in x plane"
921 msg <<
"Reference particle is bent: "
925 <<
" degrees) in y plane"
930 <<
"Effective Field Map\n"
931 <<
"======================================================================\n"
967 unsigned int numStepsEntry = std::ceil(entryLength / stepSize) + 3;
968 double stepSizeEntry = entryLength / (numStepsEntry - 3);
969 std::vector<double> zvalsEntry(numStepsEntry);
970 std::vector<std::vector<double> > fieldValuesEntry(3);
973 unsigned int numStepsExit = std::ceil(exitLength / stepSize) + 3;
974 double stepSizeExit = exitLength / (numStepsExit - 3);
975 std::vector<double> zvalsExit(numStepsExit);
976 std::vector<std::vector<double> > fieldValuesExit(3);
983 for (
unsigned int i = 0; i < 3u; ++ i) {
984 fieldValuesEntry[i].resize(numStepsEntry);
985 fieldValuesExit[i].resize(numStepsExit);
991 for (
unsigned int j = 0; j < numStepsEntry; ++ j) {
995 zvalsEntry[j] = zvalsEntry[j - 1] + stepSizeEntry;
1000 fieldValuesEntry[0][j],
1001 fieldValuesEntry[1][j],
1002 fieldValuesEntry[2][j]);
1003 fieldValuesEntry[2][j] *= fieldValuesEntry[0][j];
1006 for (
unsigned int j = 0; j < numStepsExit; ++ j) {
1010 zvalsExit[j] = zvalsExit[j - 1] + stepSizeExit;
1015 fieldValuesExit[0][j],
1016 fieldValuesExit[1][j],
1017 fieldValuesExit[2][j]);
1018 fieldValuesExit[2][j] *= fieldValuesExit[0][j];
1021 for (
unsigned int i = 0; i < 3u; ++ i) {
1022 gsl_spline_init(
entryFieldValues_m[i], &(zvalsEntry[0]), &(fieldValuesEntry[i][0]), numStepsEntry);
1023 gsl_spline_init(
exitFieldValues_m[i], &(zvalsExit[0]), &(fieldValuesExit[i][0]), numStepsExit);
1033 double error = std::abs(actualBendAngle -
angle_m);
1082 Quaternion_t rotationAboutZ(std::cos(0.5 * rotationAngleAboutZ),
1083 std::sin(0.5 * rotationAngleAboutZ) *
Vector_t(0, 0, 1));
1086 Quaternion_t halfRotationAboutAxis(std::cos(0.5 * (0.5 * bendAngle - entranceAngle)),
1087 std::sin(0.5 * (0.5 * bendAngle - entranceAngle)) * rotationAxis);
1089 std::sin(0.5 * (bendAngle - entranceAngle -
exitAngle_m)) * rotationAxis);
1103 if (rotationCenter(2) < 0.0) {
1106 gsl_poly_solve_quadratic(
dot(P,P),
1111 tau = (std::abs(1.0 - tmp) < std::abs(1.0 - tau)? tmp: tau);
1112 maxAngleEntranceAperture = tau * P;
1116 gsl_poly_solve_quadratic(
dot(P,P),
1121 tau = (std::abs(1.0 - tmp) < std::abs(1.0 - tau)? tmp: tau);
1122 maxAngleEntranceAperture = tau * P;
1128 gsl_poly_solve_quadratic(
dot(P,P),
1133 tau = (std::abs(1.0 - tmp) < std::abs(1.0 - tau)? tmp: tau);
1138 gsl_poly_solve_quadratic(
dot(P,P),
1143 tau = (std::abs(1.0 - tmp) < std::abs(1.0 - tau)? tmp: tau);
1147 maxAngleEntranceAperture -= rotationCenter;
1155 maxAngleExitAperture -= rotationCenter;
1222 ERRORMSG(
"If using \"1DPROFILE1-DEFAULT\" field map you must set the "
1223 "chord length of the bend using the L attribute in the OPAL "
1251 WARNMSG(
"Warning: bend design energy is zero. Treating as drift."
1261 if (std::abs(sinArgument) > 1.0) {
1262 WARNMSG(
"Warning: bend strength and defined reference trajectory "
1263 <<
"chord length are not consistent. Treating bend as drift."
1272 WARNMSG(
"Warning bend angle/strength is zero. Treating as drift."
1282 std::vector<Vector_t> outline;
1284 unsigned int numSteps = 2;
1295 gsl_poly_solve_quadratic(
dot(P,P),
1300 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1301 Vector_t upperCornerAtEntry = tau1 * P;
1304 gsl_poly_solve_quadratic(
dot(P,P),
1309 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1315 numSteps = std::max(2.0, std::ceil(-totalAngle / (5.0 *
Units::deg2rad)));
1316 double dAngle = 0.5 * totalAngle / (1.0 * numSteps - 1.0);
1318 outline.push_back(upperCornerAtEntry);
1320 for (
unsigned int i = 0; i < numSteps; ++ i, angle += dAngle) {
1321 Quaternion rot(std::cos(angle), 0.0, std::sin(angle), 0.0);
1322 outline.push_back(rot.
rotate(upperCornerAtEntry - rotationCenter) + rotationCenter);
1324 outline.push_back(upperCornerAtExit);
1336 gsl_poly_solve_quadratic(
dot(P,P),
1341 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1342 Vector_t lowerCornerAtEntry = tau1 * P;
1345 gsl_poly_solve_quadratic(
dot(P,P),
1350 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1356 double dAngle = 0.5 * totalAngle / (1.0 * numSteps - 1.0);
1358 outline.push_back(lowerCornerAtExit);
1359 double angle = 0.5 * totalAngle;
1360 for (
unsigned int i = 0; i < numSteps; ++ i, angle -= dAngle) {
1361 Quaternion rot(std::cos(angle), 0.0, std::sin(angle), 0.0);
1362 outline.push_back(rot.
rotate(lowerCornerAtEntry - rotationCenter) + rotationCenter);
1364 outline.push_back(lowerCornerAtEntry);
1367 std::ofstream outlineOutput;
1373 outlineOutput.open(fname);
1374 outlineOutput.precision(8);
1376 for (
auto a: outline) {
1377 outlineOutput << std::setw(18) <<
a(2)
1378 << std::setw(18) <<
a(0)
1381 outlineOutput << std::setw(18) << outline.front()(2)
1382 << std::setw(18) << outline.front()(0)
1391 std::vector<Vector_t> outline =
getOutline();
1393 unsigned int size = outline.size();
1394 unsigned int last = size - 1;
1395 unsigned int numSteps = (size - 14) / 2;
1396 unsigned int midIdx = numSteps + 7;
1398 for (
unsigned int i = 0; i < 6; ++ i) {
1399 mesh.
vertices_m.push_back(outline[i] + 2 * hgap);
1401 for (
unsigned int i = 6; i < 6 + numSteps; ++ i) {
1402 mesh.
vertices_m.push_back(outline[i] + hgap);
1404 for (
unsigned int i = 6 + numSteps; i < 13 + numSteps; ++ i) {
1405 mesh.
vertices_m.push_back(outline[i] + 2 * hgap);
1407 for (
unsigned int i = 13 + numSteps; i < 13 + 2 * numSteps; ++ i) {
1408 mesh.
vertices_m.push_back(outline[i] + hgap);
1410 mesh.
vertices_m.push_back(outline[last] + 2 * hgap);
1412 for (
unsigned int i = 0; i < 6; ++ i) {
1413 mesh.
vertices_m.push_back(outline[i] - 2 * hgap);
1415 for (
unsigned int i = 6; i < 6 + numSteps; ++ i) {
1416 mesh.
vertices_m.push_back(outline[i] - hgap);
1418 for (
unsigned int i = 6 + numSteps; i < 13 + numSteps; ++ i) {
1419 mesh.
vertices_m.push_back(outline[i] - 2 * hgap);
1421 for (
unsigned int i = 13 + numSteps; i < 13 + 2 * numSteps; ++ i) {
1422 mesh.
vertices_m.push_back(outline[i] - hgap);
1424 mesh.
vertices_m.push_back(outline[last] - 2 * hgap);
1429 mesh.
vertices_m.push_back(outline[midIdx + 4]);
1467 for (
unsigned int i = 6; i < 5 + numSteps; ++ i) {
1476 for (
unsigned int i = 0; i < size - 2; ++ i) {
1477 if (i == 4u || i == 5u ||
1478 i == 5 + numSteps || i == 6 + numSteps ||
1479 i == 11 + numSteps || i == 12 + numSteps)
continue;
1481 unsigned int next = (i + 1) % size;
1515 Vector_t T =
cross(P1 - rotationCenter, P2 - rotationCenter);
1520 mesh.
decorations_m.push_back(std::make_pair(0.5 * (P1 + P2) - 0.25 * dir1,
1521 0.5 * (P1 + P2) + 0.25 * dir1));
1525 double det = -dir1[0] * dir2[2] + dir1[2] * dir2[0];
1526 inv(0, 0) = -dir2[2] /
det;
1527 inv(0, 2) = dir2[0] /
det;
1529 inv(2, 0) = -dir1[2] /
det;
1530 inv(2, 2) = dir1[0] /
det;
1532 boost::numeric::ublas::vector<double> Tau(3);
1537 Tau = boost::numeric::ublas::prod(inv, Tau);
1539 Vector_t crossPoint = P1 + Tau[0] * dir1;
1540 double angle = std::asin(
cross(dir1, dir2)[1]);
1541 Quaternion halfRot(std::cos(0.25 * angle), std::sin(0.25 * angle) *
Vector_t(0, 1, 0));
1543 Vector_t R = crossPoint - rotationCenter;
1547 gsl_poly_solve_quadratic(
dot(P,P),
1549 dot(R,R) - std::pow(radius, 2),
1553 std::swap(tau1, tau2);
1555 Vector_t lowerCornerFringeLimit = crossPoint + tau1 * P;
1558 gsl_poly_solve_quadratic(
dot(P,P),
1560 dot(R,R) - std::pow(radius, 2),
1564 std::swap(tau1, tau2);
1566 Vector_t upperCornerFringeLimit = crossPoint + tau1 * P;
1568 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimit,
1569 upperCornerFringeLimit));
1576 gsl_poly_solve_quadratic(
dot(P,P),
1581 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1584 gsl_poly_solve_quadratic(
dot(P,P),
1589 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1594 gsl_poly_solve_quadratic(
dot(P,P),
1599 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1602 gsl_poly_solve_quadratic(
dot(P,P),
1607 tau1 = (std::abs(1.0 - tau2) < std::abs(1.0 - tau1)? tau2: tau1);
1610 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimitEntrance, upperCornerFringeLimitEntrance));
1611 mesh.
decorations_m.push_back(std::make_pair(lowerCornerFringeLimitExit, upperCornerFringeLimitExit));
1624 if (std::abs(R(1)) >
gap_m)
return false;
1656 double entrParam1, entrParam2, entrParam3;
1658 fieldmap_m->get1DProfile1EntranceParam(entrParam1,
1662 std::array<double,2> entFFL;
1663 entFFL[0]=entrParam2-entrParam1;
1664 entFFL[1]=entrParam3-entrParam2;
1676 std::array<double,2> extFFL;
1678 double exitParam1, exitParam2, exitParam3;
1680 fieldmap_m->get1DProfile1ExitParam(exitParam1,
1684 extFFL[0]=exitParam3-exitParam2;
1685 extFFL[1]=exitParam2-exitParam1;
1697 std::vector<Vector_t> outline =
getOutline();
1701 for (
int i : {-1, 1}) {
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Quaternion getQuaternion(Vector_t u, Vector_t ref)
std::vector< std::pair< Vector_t, Vector_t > > decorations_m
std::vector< Vektor< unsigned int, 3 > > triangles_m
std::vector< Vector_t > vertices_m
T euclidean_norm(const Vector< T > &)
Euclidean norm.
boost::numeric::ublas::matrix< double > matrix_t
T det(const AntiSymTenzor< T, 3 > &)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
bool writeBendTrajectories
std::string combineFilePath(std::initializer_list< std::string > ilist)
std::string toUpper(const std::string &str)
const PartData * getReference() const
std::string getInputBasename()
get input file name without extension
static OpalData * getInstance()
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
void calculateRefTrajectory(double &angleX, double &angleY)
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
Apply field to particles with coordinates in magnet frame.
Vector_t transformToExitRegion(const Vector_t &R) const
void readFieldMap(Inform &msg)
int polyOrderExit_m
function origin that Enge function ends.
Vector_t calcExitFringeField(const Vector_t &R, double deltaX)
virtual ElementType getType() const override=0
Get element type std::string.
virtual bool findChordLength(double &chordLength)=0
gsl_interp_accel * entryFieldAccel_m
bool inMagnetCentralRegion(const Vector_t &R) const
std::vector< double > engeCoeffsEntry_m
Enge coefficients for map entry and exit regions.
std::array< double, 2 > getEntranceFringeFieldLength() const
Get entrance fringe field length.
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
double deltaEndEntry_m
function origin where Enge function starts.
void setExitAngle(double exitAngle)
bool inMagnetExitRegion(const Vector_t &R) const
CoordinateSystemTrafo beginToEnd_m
CoordinateSystemTrafo getBeginToEnd_local() const
double deltaBeginExit_m
Enge function order for entry region.
Vector_t calcCentralField(const Vector_t &R, double deltaX)
void setEngeOriginDelta(double delta)
double entranceParameter3_m
bool calculateMapField(const Vector_t &R, Vector_t &B)
double widthEntranceFringe_m
End of magnet field map in s coordinates (m).
gsl_spline ** exitFieldValues_m
std::vector< double > engeCoeffsExit_m
double entranceParameter1_m
double designRadius_m
through the bend.
double sinEntranceAngle_m
void setBendEffectiveLength(double startField, double endField)
void setNSlices(const std::size_t &nSlices)
Vector_t calcEntranceFringeField(const Vector_t &R, double deltaX)
bool setupBendGeometry(double &startField, double &endField)
bool findIdealBendParameters(double chordLength)
std::string messageHeader_m
double tanEntranceAngle_m
virtual void setEntranceAngle(double entranceAngle) override
double startField_m
Dipole field index.
virtual void goOnline(const double &kineticEnergy) override
double endField_m
Start of magnet field map in s coordinates (m).
CoordinateSystemTrafo toEntranceRegion_m
bool isPositionInExitField(const Vector_t &R) const
void setFieldBoundaries(double startField, double endField)
gsl_interp_accel * exitFieldAccel_m
double deltaEndExit_m
function origin that Enge function starts.
Vector_t transformToEntranceRegion(const Vector_t &R) const
bool inMagnetEntranceRegion(const Vector_t &R) const
Bend2D(const std::string &name)
Constructor with given name.
void adjustFringeFields(double ratio)
double exitAngle_m
Bend design radius (m).
double fieldIndex_m
and the exit face of the magnet (radians).
MeshData getSurfaceMesh() const
std::array< double, 2 > getExitFringeFieldLength() const
Get exit fringe field length.
CoordinateSystemTrafo beginToEnd_lcs_m
double entranceParameter2_m
int polyOrderEntry_m
function origin that Enge function ends.
double estimateFieldAdjustmentStep(double actualBendAngle)
virtual bool isInside(const Vector_t &r) const override
virtual CoordinateSystemTrafo getEdgeToEnd() const override
bool setupDefaultFieldMap()
BoundingBox getBoundingBoxInLabCoords() const override
std::vector< Vector_t > getOutline() const
CoordinateSystemTrafo toExitRegion_m
gsl_spline ** entryFieldValues_m
bool initializeFieldMap()
CoordinateSystemTrafo computeAngleTrafo_m
void calcEngeFunction(double zNormalized, const std::vector< double > &engeCoeff, int polyOrder, double &engeFunc, double &engeFuncDeriv, double &engeFuncSecDerivNorm)
std::size_t getNSlices() const
void setupPusher(PartBunchBase< double, 3 > *bunch)
void print(Inform &msg, double bendAngleX, double bendAngle)
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
void findBendEffectiveLength(double startField, double endField)
void setGapFromFieldMap()
bool isPositionInEntranceField(const Vector_t &R) const
double cosEntranceAngle_m
Enge function order for entry region.
double calculateBendAngle()
double calcGamma() const
Calculate gamma from design energy.
std::vector< Vector_t > refTrajMap_m
Map of reference particle trajectory.
const bool fast_m
Flag to turn on fast field calculation.
double calcBendAngle(double chordLength, double radius) const
Calculate bend angle from chord length and design radius.
double fieldAmplitude_m
Field amplitude.
double calcBetaGamma() const
Calculate beta*gamma from design energy.
double getChordLength() const
double designEnergy_m
Bend design energy (eV).
double getBendAngle() const
Fieldmap fieldmap_m
Magnet field map.
double gap_m
Full vertical gap of the magnets.
double getEntranceAngle() const
double calcFieldAmplitude(double radius) const
Calculate field amplitude from design energy and radius.
double calcDesignRadius(double fieldAmplitude) const
Calculate design radius from design energy and field amplitude.
double getFullGap() const
double angle_m
Bend angle.
PartBunchBase< double, 3 > * RefPartBunch_m
virtual const std::string & getName() const
Get element name.
bool getFlagDeleteOnTransverseExit() const
virtual double getElementLength() const
Get design length.
virtual void setElementLength(double length)
Set design length.
std::pair< ApertureType, std::vector< double > > aperture_m
virtual CoordinateSystemTrafo getEdgeToBegin() const
double getRotationAboutZ() const
CoordinateSystemTrafo csTrafoGlobal2Local_m
Vector_t rotateFrom(const Vector_t &r) const
Vector_t transformFrom(const Vector_t &r) const
Vector_t transformTo(const Vector_t &r) const
Vector_t rotate(const Vector_t &) const
Quaternion conjugate() const
static Fieldmap getFieldmap(std::string Filename, bool fast=false)
void enlargeToContainPosition(const Vector_t &position)
Vektor< double, 3 > Vector_t