OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
RingSection.cpp
Go to the documentation of this file.
1//
2// Class RingSection
3// Defines the component placement handler in ring geometry.
4//
5// Copyright (c) 2012 - 2023, Chris Rogers, STFC Rutherford Appleton Laboratory, Didcot, UK
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
19
20#include "AbsBeamline/Offset.h"
21#include "Physics/Physics.h"
23
24
31
39
41 //if (component_m != nullptr)
42 // delete component_m;
43}
44
45// Assignment operator
47 if (&rhs != this) {
48 component_m = dynamic_cast<Component*>(rhs.component_m->clone());
49 if (component_m == nullptr) {
50 throw GeneralClassicException("RingSection::operator=",
51 "Failed to copy RingSection");
52 }
59 }
60 return *this;
61}
62
64 Vector_t posTransformed = pos - startPosition_m;
65 // check that pos-startPosition_m is in front of startOrientation_m
66 double normProd = posTransformed(0) * startOrientation_m(0) +
67 posTransformed(1) * startOrientation_m(1) +
68 posTransformed(2) * startOrientation_m(2);
69 // check that pos and startPosition_m are on the same side of the ring
70 double posProd = pos(0) * startPosition_m(0) +
71 pos(1) * startPosition_m(1) +
72 pos(2) * startPosition_m(2);
73 return normProd >= 0. && posProd >= 0.;
74}
75
76bool RingSection::isPastEndPlane(const Vector_t& pos) const {
77 Vector_t posTransformed = pos - endPosition_m;
78 double normProd = posTransformed(0) * endOrientation_m(0) +
79 posTransformed(1) * endOrientation_m(1)+
80 posTransformed(2) * endOrientation_m(2);
81 // check that pos and endPosition_m are on the same side of the ring
82 double posProd = pos(0) * endPosition_m(0) +
83 pos(1) * endPosition_m(1) +
84 pos(2) * endPosition_m(2);
85 return normProd > 0. && posProd > 0.;
86}
87
89 const Vector_t& /*centroid*/, const double& t,
90 Vector_t& E, Vector_t& B) const {
91 // transform position into local coordinate system
92 Vector_t pos_local = pos-componentPosition_m;
93 rotate(pos_local);
94 rotateToTCoordinates(pos_local);
95 bool outOfBounds = component_m->apply(pos_local, Vector_t(0.0), t, E, B);
96 if (outOfBounds) {
97 return true;
98 }
99 // rotate fields back to global coordinate system
102 rotate_back(E);
103 rotate_back(B);
104 return false;
105}
106
111
112std::vector<Vector_t> RingSection::getVirtualBoundingBox() const {
113 Vector_t startParallel(getStartNormal()(1), -getStartNormal()(0), 0);
114 Vector_t endParallel(getEndNormal()(1), -getEndNormal()(0), 0);
115 normalise(startParallel);
116 normalise(endParallel);
117 double startRadius = 0.99 * std::sqrt(getStartPosition()(0) * getStartPosition()(0) +
119 double endRadius = 0.99 * std::sqrt(getEndPosition()(0) * getEndPosition()(0) +
120 getEndPosition()(1) * getEndPosition()(1));
121 std::vector<Vector_t> bb;
122 bb.push_back(getStartPosition() - startParallel * startRadius);
123 bb.push_back(getStartPosition() + startParallel * startRadius);
124 bb.push_back(getEndPosition() - endParallel * endRadius);
125 bb.push_back(getEndPosition() + endParallel * endRadius);
126 return bb;
127}
128
129// double phi = atan2(r(1), r(0))+Physics::pi;
130bool RingSection::doesOverlap(double phiStart, double phiEnd) const {
131 RingSection phiVirtualORS;
132 phiVirtualORS.setStartPosition(Vector_t(std::sin(phiStart),
133 std::cos(phiStart),
134 0.));
135 phiVirtualORS.setStartNormal(Vector_t(std::cos(phiStart),
136 -std::sin(phiStart),
137 0.));
138 phiVirtualORS.setEndPosition(Vector_t(std::sin(phiEnd),
139 std::cos(phiEnd),
140 0.));
141 phiVirtualORS.setEndNormal(Vector_t(std::cos(phiEnd),
142 -std::sin(phiEnd),
143 0.));
144 std::vector<Vector_t> virtualBB = getVirtualBoundingBox();
145 // at least one of the bounding box coordinates is in the defined sector
146 // std::cerr << "RingSection::doesOverlap " << phiStart << " " << phiEnd << " "
147 // << phiVirtualORS.getStartPosition() << " " << phiVirtualORS.getStartNormal() << " "
148 // << phiVirtualORS.getEndPosition() << " " << phiVirtualORS.getEndNormal() << " " << std::endl
149 // << " Component " << this << " " << getStartPosition() << " " << getStartNormal() << " "
150 // << getEndPosition() << " " << getEndNormal() << " " << std::endl;
151 for (size_t i = 0; i < virtualBB.size(); ++i) {
152 // std::cerr << " VBB " << i << " " << virtualBB[i] << std::endl;
153 if (phiVirtualORS.isOnOrPastStartPlane(virtualBB[i]) &&
154 !phiVirtualORS.isPastEndPlane(virtualBB[i]))
155 return true;
156 }
157 // the bounding box coordinates span the defined sector and the sector
158 // sits inside the bb
159 bool hasBefore = false; // some elements in bb are before phiVirtualORS
160 bool hasAfter = false; // some elements in bb are after phiVirtualORS
161 for (size_t i = 0; i < virtualBB.size(); ++i) {
162 hasBefore = hasBefore ||
163 !phiVirtualORS.isOnOrPastStartPlane(virtualBB[i]);
164 hasAfter = hasAfter ||
165 phiVirtualORS.isPastEndPlane(virtualBB[i]);
166 // std::cerr << " " << hasBefore << " " << hasAfter << std::endl;
167 }
168 if (hasBefore && hasAfter)
169 return true;
170 // std::cerr << "DOES NOT OVERLAP" << std::endl;
171 return false;
172}
173
174
175void RingSection::rotate(Vector_t& vector) const {
176 const Vector_t temp(vector);
177 vector(0) = +cos2_m * temp(0) + sin2_m * temp(1);
178 vector(1) = +sin2_m * temp(0) - cos2_m * temp(1);
179}
180
182 const Vector_t temp(vector);
183 vector(0) = +cos2_m * temp(0) + sin2_m * temp(1);
184 vector(1) = +sin2_m * temp(0) - cos2_m * temp(1);
185}
186
188 Offset* offsetCast = dynamic_cast<Offset*>(component_m);
189 if (offsetCast == nullptr) {
190 return; // nothing to do, it wasn't an offset at all
191 }
193}
194
Interface for a single beam element.
Definition Component.h:50
virtual ElementBase * clone() const =0
Return clone.
void updateGeometry(Vector_t startPosition, Vector_t startDirection)
Definition Offset.cpp:178
Vector_t componentOrientation_m
void setStartNormal(Vector_t orientation)
RingSection & operator=(const RingSection &sec)
void rotate(Vector_t &vector) const
void handleOffset()
void setStartPosition(Vector_t pos)
Vector_t getStartNormal() const
Vector_t startPosition_m
bool getFieldValue(const Vector_t &pos, const Vector_t &centroid, const double &t, Vector_t &E, Vector_t &B) const
void rotateToCyclCoordinates(Vector_t &vec) const
Vector_t endOrientation_m
void rotate_back(Vector_t &vector) const
Vector_t startOrientation_m
bool isOnOrPastStartPlane(const Vector_t &pos) const
Vector_t componentPosition_m
double sin2_m
Component * component_m
bool doesOverlap(double phiStart, double phiEnd) const
Vector_t getEndPosition() const
double cos2_m
void updateComponentOrientation()
Vector_t getStartPosition() const
void setEndPosition(Vector_t pos)
Vector_t getEndNormal() const
void setEndNormal(Vector_t orientation)
Vector_t endPosition_m
Vector_t & normalise(Vector_t &vector) const
std::vector< Vector_t > getVirtualBoundingBox() const
void rotateToTCoordinates(Vector_t &vec) const
bool isPastEndPlane(const Vector_t &pos) const
Vektor< double, 3 > Vector_t