OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
RingSection.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2014, Chris Rogers
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  * this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  * this list of conditions and the following disclaimer in the documentation
10  * and/or other materials provided with the distribution.
11  * 3. Neither the name of STFC nor the names of its contributors may be used to
12  * endorse or promote products derived from this software without specific
13  * prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "Utilities/RingSection.h"
29 
30 #include "Physics/Physics.h"
32 
34  : component_m(NULL),
35  componentPosition_m(0.), componentOrientation_m(0.),
36  startPosition_m(0.), startOrientation_m(0.),
37  endPosition_m(0.), endOrientation_m(0.) {
38 }
39 
41  : component_m(NULL),
42  componentPosition_m(0.), componentOrientation_m(0.),
43  startPosition_m(0.), startOrientation_m(0.),
44  endPosition_m(0.), endOrientation_m(0.) {
45  *this = rhs;
46 }
47 
49  //if (component_m != NULL)
50  // delete component_m;
51 }
52 
53 // Assignment operator
55  if (&rhs != this) {
56  component_m = dynamic_cast<Component*>(rhs.component_m->clone());
57  if (component_m == NULL)
58  throw GeneralClassicException("RingSection::operator=",
59  "Failed to copy RingSection");
66  }
67  return *this;
68 }
69 
71  Vector_t posTransformed = pos-startPosition_m;
72  // check that pos-startPosition_m is in front of startOrientation_m
73  double normProd = posTransformed(0)*startOrientation_m(0)+
74  posTransformed(1)*startOrientation_m(1)+
75  posTransformed(2)*startOrientation_m(2);
76  // check that pos and startPosition_m are on the same side of the ring
77  double posProd = pos(0)*startPosition_m(0)+
78  pos(1)*startPosition_m(1)+
79  pos(2)*startPosition_m(2);
80  return normProd >= 0. && posProd >= 0.;
81 }
82 
83 bool RingSection::isPastEndPlane(const Vector_t& pos) const {
84  Vector_t posTransformed = pos-endPosition_m;
85  double normProd = posTransformed(0)*endOrientation_m(0)+
86  posTransformed(1)*endOrientation_m(1)+
87  posTransformed(2)*endOrientation_m(2);
88  // check that pos and startPosition_m are on the same side of the ring
89  double posProd = pos(0)*endPosition_m(0)+
90  pos(1)*endPosition_m(1)+
91  pos(2)*endPosition_m(2);
92  return normProd > 0. && posProd > 0.;
93 }
94 
96  const Vector_t& centroid, const double& t,
97  Vector_t& E, Vector_t& B) const {
98  // transform position into local coordinate system
99  Vector_t pos_local = pos-componentPosition_m;
100  rotate(pos_local);
101  rotateToTCoordinates(pos_local);
102  bool outOfBounds = component_m->apply(pos_local, Vector_t(0.0), t, E, B);
103  if (outOfBounds) {
104  return true;
105  }
106  // rotate fields back to global coordinate system
109  rotate_back(E);
110  rotate_back(B);
111  return false;
112 }
113 
117 }
118 
119 std::vector<Vector_t> RingSection::getVirtualBoundingBox() const {
120  Vector_t startParallel(getStartNormal()(1), -getStartNormal()(0), 0);
121  Vector_t endParallel(getEndNormal()(1), -getEndNormal()(0), 0);
122  normalise(startParallel);
123  normalise(endParallel);
124  double startRadius = 0.99*sqrt(getStartPosition()(0)*getStartPosition()(0)+
126  double endRadius = 0.99*sqrt(getEndPosition()(0)*getEndPosition()(0)+
127  getEndPosition()(1)*getEndPosition()(1));
128  std::vector<Vector_t> bb;
129  bb.push_back(getStartPosition()-startParallel*startRadius);
130  bb.push_back(getStartPosition()+startParallel*startRadius);
131  bb.push_back(getEndPosition()-endParallel*endRadius);
132  bb.push_back(getEndPosition()+endParallel*endRadius);
133  return bb;
134 }
135 
136 // double phi = atan2(r(1), r(0))+Physics::pi;
137 bool RingSection::doesOverlap(double phiStart, double phiEnd) const {
138  RingSection phiVirtualORS;
139  // phiStart -= Physics::pi;
140  // phiEnd -= Physics::pi;
141  phiVirtualORS.setStartPosition(Vector_t(sin(phiStart),
142  cos(phiStart),
143  0.));
144  phiVirtualORS.setStartNormal(Vector_t(cos(phiStart),
145  -sin(phiStart),
146  0.));
147  phiVirtualORS.setEndPosition(Vector_t(sin(phiEnd),
148  cos(phiEnd),
149  0.));
150  phiVirtualORS.setEndNormal(Vector_t(cos(phiEnd),
151  -sin(phiEnd),
152  0.));
153  std::vector<Vector_t> virtualBB = getVirtualBoundingBox();
154  // at least one of the bounding box coordinates is in the defined sector
155  // std::cerr << "RingSection::doesOverlap " << phiStart << " " << phiEnd << " "
156  // << phiVirtualORS.getStartPosition() << " " << phiVirtualORS.getStartNormal() << " "
157  // << phiVirtualORS.getEndPosition() << " " << phiVirtualORS.getEndNormal() << " " << std::endl
158  // << " Component " << this << " " << getStartPosition() << " " << getStartNormal() << " "
159  // << getEndPosition() << " " << getEndNormal() << " " << std::endl;
160  for (size_t i = 0; i < virtualBB.size(); ++i) {
161  // std::cerr << " VBB " << i << " " << virtualBB[i] << std::endl;
162  if (phiVirtualORS.isOnOrPastStartPlane(virtualBB[i]) &&
163  !phiVirtualORS.isPastEndPlane(virtualBB[i]))
164  return true;
165  }
166  // the bounding box coordinates span the defined sector and the sector
167  // sits inside the bb
168  bool hasBefore = false; // some elements in bb are before phiVirtualORS
169  bool hasAfter = false; // some elements in bb are after phiVirtualORS
170  for (size_t i = 0; i < virtualBB.size(); ++i) {
171  hasBefore = hasBefore ||
172  !phiVirtualORS.isOnOrPastStartPlane(virtualBB[i]);
173  hasAfter = hasAfter ||
174  phiVirtualORS.isPastEndPlane(virtualBB[i]);
175  // std::cerr << " " << hasBefore << " " << hasAfter << std::endl;
176  }
177  if (hasBefore && hasAfter)
178  return true;
179  // std::cerr << "DOES NOT OVERLAP" << std::endl;
180  return false;
181 }
182 
183 
184 void RingSection::rotate(Vector_t& vector) const {
185  const Vector_t temp(vector);
186  vector(0) = +cos2_m * temp(0) + sin2_m * temp(1);
187  vector(1) = -sin2_m * temp(0) + cos2_m * temp(1);
188 }
189 
190 void RingSection::rotate_back(Vector_t& vector) const {
191  const Vector_t temp(vector);
192  vector(0) = +cos2_m * temp(0) - sin2_m * temp(1);
193  vector(1) = +sin2_m * temp(0) + cos2_m * temp(1);
194 }
void setStartNormal(Vector_t orientation)
Definition: RingSection.h:206
void rotateToCyclCoordinates(Vector_t &vec) const
Definition: RingSection.h:228
Vector_t startPosition_m
Definition: RingSection.h:188
double cos2_m
Definition: RingSection.h:196
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B)
Definition: Component.cpp:99
void setEndNormal(Vector_t orientation)
Definition: RingSection.h:210
Component * component_m
Definition: RingSection.h:183
RingSection & operator=(const RingSection &sec)
Definition: RingSection.cpp:54
void rotate_back(Vector_t &vector) const
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
void rotate(Vector_t &vector) const
void setStartPosition(Vector_t pos)
Definition: RingSection.h:142
Vector_t componentOrientation_m
Definition: RingSection.h:186
bool doesOverlap(double phiStart, double phiEnd) const
bool getFieldValue(const Vector_t &pos, const Vector_t &centroid, const double &t, Vector_t &E, Vector_t &B) const
Definition: RingSection.cpp:95
std::vector< Vector_t > getVirtualBoundingBox() const
Vector_t getStartNormal() const
Definition: RingSection.h:151
void updateComponentOrientation()
bool isPastEndPlane(const Vector_t &pos) const
Definition: RingSection.cpp:83
Vector_t getEndPosition() const
Definition: RingSection.h:157
Component placement handler in ring geometry.
Definition: RingSection.h:67
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
virtual ElementBase * clone() const =0
Return clone.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
Vector_t endOrientation_m
Definition: RingSection.h:192
bool isOnOrPastStartPlane(const Vector_t &pos) const
Definition: RingSection.cpp:70
void setEndPosition(Vector_t pos)
Definition: RingSection.h:154
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Vector_t & normalise(Vector_t &vector) const
Definition: RingSection.h:214
Vector_t getStartPosition() const
Definition: RingSection.h:145
Vector_t componentPosition_m
Definition: RingSection.h:185
void rotateToTCoordinates(Vector_t &vec) const
Definition: RingSection.h:224
Vector_t getEndNormal() const
Definition: RingSection.h:163
Interface for a single beam element.
Definition: Component.h:51
Vector_t endPosition_m
Definition: RingSection.h:191
Vector_t startOrientation_m
Definition: RingSection.h:189
double sin2_m
Definition: RingSection.h:195