49 planarArcGeometry_m(1, 1),
50 refPartBunch_m(nullptr),
57 latticeThetaInit_m(0.),
75 planarArcGeometry_m(ring.planarArcGeometry_m),
77 beamRInit_m(ring.beamRInit_m),
78 beamPRInit_m(ring.beamPRInit_m),
79 beamPhiInit_m(ring.beamPhiInit_m),
80 latticeRInit_m(ring.latticeRInit_m),
81 latticePhiInit_m(ring.latticePhiInit_m),
82 latticeThetaInit_m(ring.latticeThetaInit_m),
83 willDoAperture_m(ring.willDoAperture_m),
84 minR2_m(ring.minR2_m),
85 maxR2_m(ring.maxR2_m),
86 isLocked_m(ring.isLocked_m),
87 isClosed_m(ring.isClosed_m),
88 symmetry_m(ring.symmetry_m),
89 cyclHarm_m(ring.cyclHarm_m),
90 phiStep_m(ring.phiStep_m),
92 section_list_m(ring.section_list_m.size()) {
96 "Ring::Ring(const Ring&)",
97 "Can't copy construct LossDataSink so copy constructor fails");
112 auto Rview = pc->R.getView();
113 auto Pview = pc->P.getView();
118 bool flagNeedUpdate =
apply(R, P, t, E, B);
119 if (flagNeedUpdate) {
122 auto Qview = pc->Q.getView();
123 auto Mview = pc->M.getView();
124 auto Binview = pc->Bin.getView();
126 const double Q = Qview(
id);
127 const double M = Mview(
id);
130 gmsgALL <<
getName() <<
": particle " <<
id <<
" at " << R
131 <<
" m out of the field map boundary" <<
endl;
137 return flagNeedUpdate;
146 std::vector<RingSection*> sections =
148 bool outOfBounds =
true;
151 double rSquared = R[0] * R[0] + R[1] * R[1];
152 if (rSquared < minR2_m || rSquared >
maxR2_m) {
157 for (
size_t i = 0; i < sections.size(); ++i) {
162 outOfBounds &= sections[i]->getFieldValue(
211 double deltaAngle = std::atan2(rotationTest(2), rotationTest(0));
213 return elementRotation;
221 "Ring::checkMidplane",
222 std::string(
"Placement of elements out of the ") +
"midplane is not supported by Ring");
230 Euclid3D euclid(v(2), v(0), -v(1), r(2), r(0), -r(1));
255 "Ring::appendElement",
256 "Attempt to append element " + element.
getName() +
" when ring is locked");
273 double startF = std::atan2(startNorm(1), startNorm(0));
277 +delta.
getVector()(0) * std::sin(startF) + delta.
getVector()(1) * std::cos(startF), 0})
284 {+startNorm(0) * std::cos(endF) + startNorm(1) * std::sin(endF),
285 -startNorm(0) * std::sin(endF) + startNorm(1) * std::cos(endF), 0});
293 double dphi = atan2(startNorm(0), startNorm(1));
295 msg <<
"* Added " << element.
getName() <<
" to Ring" <<
endl;
310 "Ring::lockRing",
"Attempt to lock ring when it is already locked");
314 if (sectionListSize == 0) {
320 msg <<
"Applying symmetry to Ring" <<
endl;
322 for (
size_t j = 0; j < sectionListSize; ++j) {
356 for (
int i = 0; i < 3; ++i) {
367 ringSections_m = std::vector<std::vector<RingSection*> >(nSections);
391 if (minR < 0 || maxR < 0) {
393 "Ring::setRingAperture",
"Could not parse negative or undefined aperture limit");
Inform & endl(Inform &inf)
constexpr double e
The value of.
constexpr double pi
The value of.
virtual void visitRing(const Ring &)=0
Apply the algorithm to a Ring element.
Interface for a single beam element.
PartBunch_t * RefPartBunch_m
virtual const std::string & getName() const
Get element name.
virtual ElementBase * clone() const =0
Return clone.
virtual BGeometryBase & getGeometry()=0
Get geometry.
Ring describes a ring type geometry for tracking.
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField) override
Initialise the Ring.
Rotation3D getRotationStartToEnd(Euclid3D delta) const
static bool sectionCompare(RingSection const *const sec1, RingSection const *const sec2)
virtual void finalise() override
Clean up the Ring.
Vector_t< double, 3 > getNextPosition() const
Get the initial element's start position in cartesian coordinates.
virtual ~Ring()
Destructor - deletes lossDS_m if not nullptr.
Vector_t< double, 3 > getNextNormal() const
Get the initial element's start normal in cartesian coordinates.
RingSection * getLastSectionPlaced() const
Get the last section placed or nullptr if no sections were placed yet.
virtual bool apply(const size_t &id, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) override
Overwrite data in vector E and B with electric and magnetic field.
double latticeThetaInit_m
std::vector< RingSectionList > ringSections_m
virtual void accept(BeamlineVisitor &visitor) const override
Accept the BeamlineVisitor.
void setRingAperture(double minR, double maxR)
Set the ring aperture limits.
RingSectionList section_list_m
std::vector< RingSection * > getSectionsAt(const Vector_t< double, 3 > &pos)
Get the list of sections at position pos.
void checkMidplane(Euclid3D delta) const
void setLossDataSink(LossDataSink *sink)
Set LossDataSink to sink.
PartBunch_t * refPartBunch_m
void setRefPartBunch(PartBunch_t *bunch)
Set RefPartBunch_t to bunch.
virtual void getDimensions(double &zBegin, double &zEnd) const override
Not implemented - always throws an exception.
void lockRing()
Lock the ring.
void appendElement(const Component &element)
Add element to the ring.
void rotateToCyclCoordinates(Euclid3D &euclid3d) const
static const double lengthTolerance_m
static const double angleTolerance_m
std::shared_ptr< ParticleContainer_t > getParticleContainer()
Vector_t< T, Dim > get_centroid() const
Displacement and rotation in space.
const Vector3D & getVector() const
Get displacement.
const Rotation3D & getRotation() const
Get rotation.
virtual Euclid3D getTotalTransform() const
Get transform.
Rotation in 3-dimensional space.
static Rotation3D ZRotation(double angle)
Make rotation.
Vector3D getAxis() const
Get axis vector.
void save(unsigned int numSets=1, OpalData::OpenMode openMode=OpalData::OpenMode::UNDEFINED)
void addParticle(const OpalParticle &, const boost::optional< std::pair< int, short int > > &turnBunchNumPair=boost::none)
Component placement handler in ring geometry.
void setComponentOrientation(Vector_t< double, 3 > orientation)
Set the rotation for the component relative to the section start.
Vector_t< double, 3 > getStartPosition() const
Get a position on the plane of the section start.
void setEndPosition(Vector_t< double, 3 > pos)
Set a position on the section end plane.
Vector_t< double, 3 > getEndPosition() const
Get a position on the section end plane.
void setComponent(Component *component)
Set the component wrapped by RingSection.
void setStartNormal(Vector_t< double, 3 > orientation)
Set the normal vector to the section start plane.
Vector_t< double, 3 > getEndNormal() const
Get the normal vector to the section end plane.
void setComponentPosition(Vector_t< double, 3 > position)
Set the displacement for the component relative to the section start.
Vector_t< double, 3 > getStartNormal() const
Get the normal vector to the section start plane.
void setEndNormal(Vector_t< double, 3 > orientation)
Set the normal vector to the section end plane
void setStartPosition(Vector_t< double, 3 > pos)
Set a position on the plane of the section start.