9#include <Kokkos_Core.hpp>
18 for (
int row = 0; row < 3; ++row) {
19 for (
int col = 0; col < 3; ++col) {
20 rotation(row, col) = euclidRotation(row, col);
26 displacement.
getX(), displacement.
getY(), displacement.
getZ());
36 startField_m(right.startField_m),
37 endField_m(right.endField_m),
38 angle_m(right.angle_m),
39 entranceAngle_m(right.entranceAngle_m),
40 exitAngle_m(right.exitAngle_m),
42 designEnergy_m(right.designEnergy_m),
43 designEnergyChangeable_m(true),
44 fieldAmplitudeX_m(right.fieldAmplitudeX_m),
45 fieldAmplitudeY_m(right.fieldAmplitudeY_m),
46 fieldAmplitude_m(right.fieldAmplitude_m),
47 fileName_m(right.fileName_m),
48 entryFaceRotation_m(right.entryFaceRotation_m),
49 exitFaceRotation_m(right.exitFaceRotation_m),
50 entryFaceCurvature_m(right.entryFaceCurvature_m),
51 exitFaceCurvature_m(right.exitFaceCurvature_m),
52 slices_m(right.slices_m),
53 stepSize_m(right.stepSize_m),
54 nSlices_m(right.nSlices_m),
66 designEnergyChangeable_m(true),
67 fieldAmplitudeX_m(0.0),
68 fieldAmplitudeY_m(0.0),
69 fieldAmplitude_m(0.0),
71 entryFaceRotation_m(0.0),
72 exitFaceRotation_m(0.0),
73 entryFaceCurvature_m(0.0),
74 exitFaceCurvature_m(0.0),
93 auto Rview = pc->R.getView();
94 auto Eview = pc->E.getView();
95 auto Bview = pc->B.getView();
96 const size_t nLocal = pc->getLocalNum();
99 const int order = field.
order();
100 Kokkos::View<double*> normal(
"BendBase::normal", order);
101 Kokkos::View<double*> skew(
"BendBase::skew", order);
102 auto normalHost = Kokkos::create_mirror_view(normal);
103 auto skewHost = Kokkos::create_mirror_view(skew);
104 for (
int i = 0; i < order; ++i) {
108 Kokkos::deep_copy(normal, normalHost);
109 Kokkos::deep_copy(skew, skewHost);
113 Kokkos::parallel_for(
114 "BendBase::apply", nLocal, KOKKOS_LAMBDA(
const size_t i) {
115 if (Rview(i)(2) < 0.0 || Rview(i)(2) > elemLength) {
120 const double x = Rview(i)(0);
121 const double y = Rview(i)(1);
123 if (normal.extent(0) > 0) {
126 if (skew.extent(0) > 0) {
129 if (normal.extent(0) > 1) {
130 Bf(0) += normal(1) * y;
131 Bf(1) += normal(1) * x;
133 if (skew.extent(0) > 1) {
134 Bf(0) -= skew(1) * x;
135 Bf(1) += skew(1) * y;
138 for (
unsigned d = 0; d < 3; ++d) {
140 Bview(i)(d) += Bf(d);
149 std::shared_ptr<ParticleContainer_t> pc =
RefPartBunch_m->getParticleContainer();
223 const double span = std::abs(sEnd - sBegin);
224 const std::size_t samples =
225 std::max<std::size_t>(minSamples,
static_cast<std::size_t
>(std::ceil(span / 0.01)) + 1);
227 std::vector<Vector_t<double, 3>> path;
228 path.reserve(samples);
229 for (std::size_t i = 0; i < samples; ++i) {
231 (samples > 1) ?
static_cast<double>(i) /
static_cast<double>(samples - 1) : 0.0;
232 const double s = sBegin + alpha * (sEnd - sBegin);
234 path.emplace_back(pose.getX(), pose.getY(), pose.getZ());
242 const double mass = reference.
getM();
244 const double charge = reference.getQ();
245 return std::abs(betaGamma * mass / (
Physics::c * fieldAmplitude * charge));
250 const double mass = reference.
getM();
252 const double charge = reference.getQ();
253 return betaGamma * mass / (
Physics::c * radius * charge);
257 return 2.0 * std::asin(chordLength / (2.0 * radius));
261 return chordLength / (2.0 * std::sin(angle / 2.0));
266 const double mass = reference.
getM();
272 return std::sqrt(gamma * gamma - 1.0);
277 const int order = field.
order();
ippl::Vector< T, Dim > Vector_t
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
The magnetic field of a multipole.
int order() const
Return order.
double getNormalComponent(int n) const
Get component.
double getSkewComponent(int n) const
Get component.
Common OPALX interface for analytic horizontal bending magnets.
bool apply(const std::shared_ptr< ParticleContainer_t > &pc) override
Apply to all particles. Kernel launch moved inside the function.
virtual BMultipoleField & getField() override=0
Return field.
std::vector< Vector_t< double, 3 > > getDesignPath(std::size_t minSamples=32) const
Sample the local curved reference path of the bend body.
double calcBendAngle(double chordLength, double radius) const
bool applyToReferenceParticle(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
Apply to reference particle with position R and momemtum P.
double calcBetaGamma() const
double getChordLength() const
Return the geometric chord between entrance and exit frames.
CoordinateSystemTrafo getEdgeToBegin() const override
void initialise(PartBunch_t *bunch, double &startField, double &endField) override
CoordinateSystemTrafo getEdgeToEnd() const override
void getFieldExtend(double &zBegin, double &zEnd) const override
Return the field-support extent of the component.
double calcFieldAmplitude(double radius) const
double calcDesignRadius(double fieldAmplitude) const
static void computeFieldHost(const Vector_t< double, 3 > &R, const BMultipoleField &field, Vector_t< double, 3 > &B)
bool isInside(const Vector_t< double, 3 > &r) const override
PartBunch_t * RefPartBunch_m
Rigid spatial transform between a parent frame and a local frame.
virtual double getExit() const
Get exit position.
bool getFlagDeleteOnTransverseExit() const
virtual double getElementLength() const
Get design length.
virtual Euclid3D getExitFrame() const
Get transform.
virtual Euclid3D getEntranceFrame() const
Get transform.
bool isInsideTransverse(const Vector_t< double, 3 > &r) const
virtual Euclid3D getTransform(double fromS, double toS) const
Get transform.
virtual double getEntrance() const
Get entrance position.
Displacement and rotation in space.
const Vector3D & getVector() const
Get displacement.
const Rotation3D & getRotation() const
Get rotation.
Vector_t< double, Dim > R(size_t)
Do not use; throws (access positions via ParticleContainer::R).
const PartData * getReference() const
KOKKOS_INLINE_FUNCTION double getM() const
The constant mass per particle.
Quaternion storage and rotation algebra used by OPALX geometry code.
Rotation in 3-dimensional space.
double getY() const
Get component.
double getX() const
Get component.
double getZ() const
Get component.
constexpr double c
The velocity of light in m/s.