OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
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
29
30#include "Physics/Physics.h"
32
34 : component_m(nullptr),
35 componentPosition_m(0.),
36 componentOrientation_m(0.),
37 startPosition_m(0.),
38 startOrientation_m(0.),
39 endPosition_m(0.),
40 endOrientation_m(0.) {}
41
43 : component_m(nullptr),
44 componentPosition_m(0.),
45 componentOrientation_m(0.),
46 startPosition_m(0.),
47 startOrientation_m(0.),
48 endPosition_m(0.),
49 endOrientation_m(0.) {
50 *this = rhs;
51}
52
54 // if (component_m != nullptr)
55 // delete component_m;
56}
57
58// Assignment operator
60 if (&rhs != this) {
61 component_m = dynamic_cast<Component*>(rhs.component_m->clone());
62 if (component_m == nullptr)
63 throw GeneralOpalException("RingSection::operator=", "Failed to copy RingSection");
70 }
71 return *this;
72}
73
75 Vector_t<double, 3> posTransformed = pos - startPosition_m;
76 // check that pos-startPosition_m is in front of startOrientation_m
77 double normProd = posTransformed(0) * startOrientation_m(0)
78 + posTransformed(1) * startOrientation_m(1)
79 + posTransformed(2) * startOrientation_m(2);
80 // check that pos and startPosition_m are on the same side of the ring
81 double posProd =
82 pos(0) * startPosition_m(0) + pos(1) * startPosition_m(1) + pos(2) * startPosition_m(2);
83 return normProd >= 0. && posProd >= 0.;
84}
85
87 Vector_t<double, 3> posTransformed = pos - endPosition_m;
88 double normProd = posTransformed(0) * endOrientation_m(0)
89 + posTransformed(1) * endOrientation_m(1)
90 + posTransformed(2) * endOrientation_m(2);
91 // check that pos and startPosition_m are on the same side of the ring
92 double posProd =
93 pos(0) * endPosition_m(0) + pos(1) * endPosition_m(1) + pos(2) * endPosition_m(2);
94 return normProd > 0. && posProd > 0.;
95}
96
98 const Vector_t<double, 3>& pos, const Vector_t<double, 3>& /*centroid*/, const double& t,
100 // transform position into local coordinate system
102 rotate(pos_local);
103 rotateToTCoordinates(pos_local);
104 bool outOfBounds = component_m->apply(pos_local, Vector_t<double, 3>(0.0), t, E, B);
105 if (outOfBounds) {
106 return true;
107 }
108 // rotate fields back to global coordinate system
111 rotate_back(E);
112 rotate_back(B);
113 return false;
114}
115
120
121std::vector<Vector_t<double, 3>> RingSection::getVirtualBoundingBox() const {
122 Vector_t<double, 3> startParallel(getStartNormal()(1), -getStartNormal()(0), 0);
123 Vector_t<double, 3> endParallel(getEndNormal()(1), -getEndNormal()(0), 0);
124 normalise(startParallel);
125 normalise(endParallel);
126 double startRadius = 0.99
127 * sqrt(getStartPosition()(0) * getStartPosition()(0)
128 + getStartPosition()(1) * getStartPosition()(1));
129 double endRadius = 0.99
130 * sqrt(getEndPosition()(0) * getEndPosition()(0)
131 + getEndPosition()(1) * getEndPosition()(1));
132 std::vector<Vector_t<double, 3>> bb;
133 bb.push_back(getStartPosition() - startParallel * startRadius);
134 bb.push_back(getStartPosition() + startParallel * startRadius);
135 bb.push_back(getEndPosition() - endParallel * endRadius);
136 bb.push_back(getEndPosition() + endParallel * endRadius);
137 return bb;
138}
139
140// double phi = atan2(r(1), r(0))+Physics::pi;
141bool RingSection::doesOverlap(double phiStart, double phiEnd) const {
142 RingSection phiVirtualORS;
143 // phiStart -= Physics::pi;
144 // phiEnd -= Physics::pi;
145 phiVirtualORS.setStartPosition(Vector_t<double, 3>(sin(phiStart), cos(phiStart), 0.));
146 phiVirtualORS.setStartNormal(Vector_t<double, 3>(cos(phiStart), -sin(phiStart), 0.));
147 phiVirtualORS.setEndPosition(Vector_t<double, 3>(sin(phiEnd), cos(phiEnd), 0.));
148 phiVirtualORS.setEndNormal(Vector_t<double, 3>(cos(phiEnd), -sin(phiEnd), 0.));
149 std::vector<Vector_t<double, 3>> virtualBB = getVirtualBoundingBox();
150 // at least one of the bounding box coordinates is in the defined sector
151 // std::cerr << "RingSection::doesOverlap " << phiStart << " " << phiEnd << " "
152 // << phiVirtualORS.getStartPosition() << " " << phiVirtualORS.getStartNormal() << " "
153 // << phiVirtualORS.getEndPosition() << " " << phiVirtualORS.getEndNormal() << " " <<
154 // std::endl
155 // << " Component " << this << " " << getStartPosition() << " " << getStartNormal()
156 // << " "
157 // << getEndPosition() << " " << getEndNormal() << " " << std::endl;
158 for (size_t i = 0; i < virtualBB.size(); ++i) {
159 // std::cerr << " VBB " << i << " " << virtualBB[i] << std::endl;
160 if (phiVirtualORS.isOnOrPastStartPlane(virtualBB[i])
161 && !phiVirtualORS.isPastEndPlane(virtualBB[i]))
162 return true;
163 }
164 // the bounding box coordinates span the defined sector and the sector
165 // sits inside the bb
166 bool hasBefore = false; // some elements in bb are before phiVirtualORS
167 bool hasAfter = false; // some elements in bb are after phiVirtualORS
168 for (size_t i = 0; i < virtualBB.size(); ++i) {
169 hasBefore = hasBefore || !phiVirtualORS.isOnOrPastStartPlane(virtualBB[i]);
170 hasAfter = hasAfter || phiVirtualORS.isPastEndPlane(virtualBB[i]);
171 // std::cerr << " " << hasBefore << " " << hasAfter << std::endl;
172 }
173 if (hasBefore && hasAfter) return true;
174 // std::cerr << "DOES NOT OVERLAP" << std::endl;
175 return false;
176}
177
179 const Vector_t<double, 3> temp(vector);
180 vector(0) = +cos2_m * temp(0) + sin2_m * temp(1);
181 vector(1) = -sin2_m * temp(0) + cos2_m * temp(1);
182}
183
185 const Vector_t<double, 3> 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}
ippl::Vector< T, Dim > Vector_t
virtual bool apply(const std::shared_ptr< ParticleContainer_t > &pc)
Apply to all particles. Kernel launch moved inside the function.
Definition Component.cpp:57
virtual ElementBase * clone() const =0
Return clone.
Component placement handler in ring geometry.
Definition RingSection.h:67
Vector_t< double, 3 > getStartPosition() const
RingSection & operator=(const RingSection &sec)
Vector_t< double, 3 > componentOrientation_m
void rotateToCyclCoordinates(Vector_t< double, 3 > &vec) const
void setEndPosition(Vector_t< double, 3 > pos)
Vector_t< double, 3 > getEndPosition() const
bool getFieldValue(const Vector_t< double, 3 > &pos, const Vector_t< double, 3 > &centroid, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const
Vector_t< double, 3 > & normalise(Vector_t< double, 3 > &vector) const
void setStartNormal(Vector_t< double, 3 > orientation)
Vector_t< double, 3 > getEndNormal() const
Vector_t< double, 3 > getStartNormal() const
std::vector< Vector_t< double, 3 > > getVirtualBoundingBox() const
void rotateToTCoordinates(Vector_t< double, 3 > &vec) const
bool isOnOrPastStartPlane(const Vector_t< double, 3 > &pos) const
double sin2_m
Component * component_m
bool doesOverlap(double phiStart, double phiEnd) const
Vector_t< double, 3 > endPosition_m
double cos2_m
void updateComponentOrientation()
void setEndNormal(Vector_t< double, 3 > orientation)
Vector_t< double, 3 > startOrientation_m
void setStartPosition(Vector_t< double, 3 > pos)
void rotate_back(Vector_t< double, 3 > &vector) const
Vector_t< double, 3 > componentPosition_m
bool isPastEndPlane(const Vector_t< double, 3 > &pos) const
void rotate(Vector_t< double, 3 > &vector) const
Vector_t< double, 3 > startPosition_m
Vector_t< double, 3 > endOrientation_m