OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
Offset.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 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 "AbsBeamline/Offset.h"
29
30#include <cmath>
31
34#include "Physics/Physics.h"
36
37const double Offset::lengthUnits_m = 1e3;
38double Offset::float_tolerance = 1e-12;
39
40Offset::Offset(const std::string& name) : Component(name), _is_local(false), geometry_m(nullptr) {
42}
43
45}
46
47Offset::Offset(std::string name, const Offset& rhs)
48 : Component(name), _is_local(false), geometry_m(nullptr) {
49 *this = rhs;
50 setName(name);
51}
52
54 : Component(rhs.getName()), _is_local(false), geometry_m(nullptr) {
55 *this = rhs;
56}
57
59 delete geometry_m;
60}
61
63 if (&rhs == this) {
64 return *this;
65 }
66 setName(rhs.getName());
69 _is_local = rhs._is_local;
70
71 if (geometry_m != nullptr)
72 delete geometry_m;
73 if (rhs.geometry_m == nullptr) {
74 geometry_m = nullptr;
75 } else {
77 }
78 setAperture(rhs.getAperture().first, rhs.getAperture().second);
79 return *this;
80}
81
82void Offset::accept(BeamlineVisitor& visitor) const {
83 visitor.visitOffset(*this);
84}
85
87 throw GeneralClassicException("Offset::getField()", "No field defined for Offset");
88}
89
90const EMField& Offset::getField() const {
91 throw GeneralClassicException("Offset::getField() const", "No field defined for Offset");
92}
93
94void Offset::initialise(PartBunch_t* bunch, double& /*startField*/, double& /*endField*/) {
95 RefPartBunch_m = bunch;
96}
97
99 RefPartBunch_m = nullptr;
100}
101
103 return new Offset(*this);
104}
105
107 _end_position = position;
108}
109
113
115 _end_direction = direction;
116}
117
121
122void Offset::setIsLocal(bool isLocal) {
123 _is_local = isLocal;
124}
125
126bool Offset::getIsLocal() const {
127 return _is_local;
128}
129
133
135 return *geometry_m;
136}
137
138// std::ostream& operator<<(std::ostream& out, const Vector_t<double, 3>& vec) {
139// out << "(" << vec(0) << ", " << vec(1) << ", " << vec(2) << ")";
140// return out;
141// }
142
144 if (std::abs(vec1(2)) > 1e-9 || std::abs(vec2(2)) > 1e-9)
146 "Offset::getTheta(...)", "Rotations out of midplane are not implemented");
147 // probably not the most efficient, but only called at set up
148 double theta = std::atan2(vec2(1), vec2(0)) - std::atan2(vec1(1), vec1(0));
149 if (theta < -Physics::pi)
150 theta += 2. * Physics::pi; // force into domain -pi < theta < pi
151 return theta;
152}
153
155 double s = std::sin(theta);
156 double c = std::cos(theta);
157 return Vector_t<double, 3>({+vec(0) * c - vec(1) * s, +vec(0) * s + vec(1) * c, 0.});
158}
159
161 if (!_is_local)
163 "Offset::updateGeometry(...)", "Global offset needs a local coordinate system");
164 Vector_t<double, 3> translation = getEndPosition();
165 double length = std::sqrt(
166 translation(0) * translation(0) + translation(1) * translation(1)
167 + translation(2) * translation(2));
168 double theta_in = getTheta(Vector_t<double, 3>({1., 0., 0.}), translation);
169 double theta_out = getTheta(Vector_t<double, 3>({1., 0., 0.}), getEndDirection());
170 Euclid3D euclid3D(
171 -std::sin(theta_in) * length, 0., std::cos(theta_in) * length, 0., -theta_out, 0.);
172 if (geometry_m != nullptr)
173 delete geometry_m;
174 geometry_m = new Euclid3DGeometry(euclid3D);
175}
176
178 Vector_t<double, 3> /*startPosition*/, Vector_t<double, 3> startDirection) {
179 if (!_is_local) {
180 Vector_t<double, 3> translationGlobal = _end_position;
181 double theta_g2l = getTheta(startDirection, Vector_t<double, 3>({1, 0, 0}));
182 _end_position = rotate(translationGlobal, theta_g2l);
184 _is_local = true;
185 }
187}
188
190 return geometry_m != nullptr;
191}
192
193bool operator==(const Offset& off1, const Offset& off2) {
194 const double tol = Offset::float_tolerance;
195 if (off1.getName() != off2.getName() || off1.getIsLocal() != off2.getIsLocal()) {
196 return false;
197 }
198 for (int i = 0; i < 3; ++i) {
199 if ((std::abs(off1.getEndPosition()(i) - off2.getEndPosition()(i)) > tol)
200 || (std::abs(off1.getEndDirection()(i) - off2.getEndDirection()(i)) > tol))
201 return false;
202 }
203 if ((!off1.isGeometryAllocated() && off2.isGeometryAllocated())
204 || (!off2.isGeometryAllocated() && off1.isGeometryAllocated()))
205 return false;
206 Euclid3D transform1 = off1.getGeometry().getTotalTransform();
207 Euclid3D transform2 = off2.getGeometry().getTotalTransform();
208 Vector3D dTranslation = transform1.getVector() - transform2.getVector();
209 Vector3D dRotation = transform1.getRotation().getAxis() - transform2.getRotation().getAxis();
210 for (size_t i = 0; i < 3; ++i)
211 if (std::abs(dTranslation(i)) > tol || std::abs(dRotation(i)) > tol)
212 return false;
213 return true;
214}
215
216bool operator!=(const Offset& off1, const Offset& off2) {
217 return !(off1 == off2);
218}
219
220std::ostream& operator<<(std::ostream& out, const Offset& off) {
221 out << "Offset " << off.getName() << " local " << off.getIsLocal()
222 << " end pos: " << off.getEndPosition() << " end dir: " << off.getEndDirection()
223 << std::endl;
224 return out;
225}
226
227bool Offset::bends() const {
228 if (geometry_m == nullptr) {
230 "Offset::bends", "Try to determine if Offset bends when geometry_m not allocated");
231 }
232 Rotation3D rotation = geometry_m->getTotalTransform().getRotation();
233 for (size_t i = 0; i < 3; ++i)
234 if (std::abs(rotation.getAxis()(i)) > float_tolerance) {
235 return true;
236 }
237 Vector3D vector = geometry_m->getTotalTransform().getVector();
238 if (std::abs(vector(0)) > float_tolerance || std::abs(vector(1)) > float_tolerance) {
239 return true;
240 }
241 return false;
242}
243
245 std::string name, double phi_in, double phi_out, double displacement) {
246 Offset off(name);
247 displacement *= lengthUnits_m;
249 {std::cos(phi_in) * displacement, std::sin(phi_in) * displacement, 0.}));
250 off.setEndDirection(
251 Vector_t<double, 3>({std::cos(phi_in + phi_out), std::sin(phi_in + phi_out), 0.}));
252 off.setIsLocal(true);
253 off.updateGeometry();
254 return off;
255}
256
258 std::string name, double radius_out, double phi_out, double theta_out) {
259 Offset off(name);
260 radius_out *= lengthUnits_m;
261 off.setEndPosition(
262 Vector_t<double, 3>({std::cos(phi_out) * radius_out, std::sin(phi_out) * radius_out, 0.}));
263 off.setEndDirection(
264 Vector_t<double, 3>({std::sin(phi_out + theta_out), std::cos(phi_out + theta_out), 0.}));
265 off.setIsLocal(false);
266 return off;
267}
268
270 std::string name, Vector_t<double, 3> end_position, Vector_t<double, 3> end_direction) {
271 Offset off(name);
272 end_position = end_position * lengthUnits_m;
273 off.setEndPosition(end_position);
274 off.setEndDirection(end_direction);
275 off.setIsLocal(true);
276 off.updateGeometry();
277 return off;
278}
279
281 std::string name, Vector_t<double, 3> end_position, Vector_t<double, 3> end_direction) {
282 Offset off(name);
283 end_position = end_position * lengthUnits_m;
284 off.setEndPosition(end_position);
285 off.setEndDirection(end_direction);
286 off.setIsLocal(false);
287 return off;
288}
bool operator!=(const Offset &off1, const Offset &off2)
Definition Offset.cpp:216
bool operator==(const Offset &off1, const Offset &off2)
Definition Offset.cpp:193
std::ostream & operator<<(std::ostream &out, const Offset &off)
Definition Offset.cpp:220
PartBunch< PLayout_t< double, 3 >, double, 3 > PartBunch_t
ippl::Vector< T, Dim > Vector_t
constexpr double e
The value of.
Definition Physics.h:39
constexpr double pi
The value of.
Definition Physics.h:30
virtual void visitOffset(const Offset &)=0
Apply the algorithm to an offset (placement).
Component(const std::string &name)
Constructor with given name.
Definition Component.cpp:44
PartBunch_t * RefPartBunch_m
Definition Component.h:185
virtual void setName(const std::string &name)
Set element name.
virtual const std::string & getName() const
Get element name.
void setAperture(const ApertureType &type, const std::vector< double > &args)
std::pair< ApertureType, std::vector< double > > getAperture() const
ElementBase(const std::string &name)
Constructor with given name.
void updateGeometry()
Definition Offset.cpp:160
Vector_t< double, 3 > getEndDirection() const
Definition Offset.cpp:118
Euclid3DGeometry & getGeometry() override
Get geometry.
Definition Offset.cpp:130
void setEndDirection(Vector_t< double, 3 > direction)
Definition Offset.cpp:114
Offset & operator=(const Offset &)
Definition Offset.cpp:62
static Offset localCylindricalOffset(std::string name, double theta_in, double theta_out, double displacement)
Definition Offset.cpp:244
bool isGeometryAllocated() const
Definition Offset.cpp:189
void finalise() override
Definition Offset.cpp:98
static Vector_t< double, 3 > rotate(Vector_t< double, 3 > vec, double theta)
Definition Offset.cpp:154
bool _is_local
Definition Offset.h:210
Vector_t< double, 3 > _end_position
Definition Offset.h:208
static Offset globalCartesianOffset(std::string name, Vector_t< double, 3 > end_position, Vector_t< double, 3 > end_direction)
Definition Offset.cpp:280
~Offset()
Definition Offset.cpp:58
Vector_t< double, 3 > _end_direction
Definition Offset.h:209
static const double lengthUnits_m
Definition Offset.h:213
EMField & getField() override
Not implemented - throws GeneralClassicException.
Definition Offset.cpp:86
Offset()
Definition Offset.cpp:44
static double getTheta(Vector_t< double, 3 > vec1, Vector_t< double, 3 > vec2)
Definition Offset.cpp:143
static double float_tolerance
Definition Offset.h:206
void initialise(PartBunch_t *bunch, double &startField, double &endField) override
Definition Offset.cpp:94
static Offset localCartesianOffset(std::string name, Vector_t< double, 3 > end_position, Vector_t< double, 3 > end_direction)
Definition Offset.cpp:269
Offset(const std::string &name)
Definition Offset.cpp:40
void setEndPosition(Vector_t< double, 3 > position)
Definition Offset.cpp:106
ElementBase * clone() const override
Definition Offset.cpp:102
void accept(BeamlineVisitor &) const override
Definition Offset.cpp:82
static Offset globalCylindricalOffset(std::string name, double radius_out, double phi_out, double theta_out)
Definition Offset.cpp:257
Vector_t< double, 3 > getEndPosition() const
Definition Offset.cpp:110
Euclid3DGeometry * geometry_m
Definition Offset.h:212
bool getIsLocal() const
Definition Offset.cpp:126
void updateGeometry(Vector_t< double, 3 > startPosition, Vector_t< double, 3 > startDirection)
Definition Offset.cpp:177
void setIsLocal(bool isLocal)
Definition Offset.cpp:122
bool bends() const override
Definition Offset.cpp:227
Displacement and rotation in space.
Definition Euclid3D.h:68
const Vector3D & getVector() const
Get displacement.
Definition Euclid3D.cpp:59
const Rotation3D & getRotation() const
Get rotation.
Definition Euclid3D.cpp:64
virtual Euclid3D getTotalTransform() const
Get total transform from beginning to end.
Rotation in 3-dimensional space.
Definition Rotation3D.h:46
Vector3D getAxis() const
Get axis vector.
A 3-dimension vector.
Definition Vector3D.h:31
Abstract base class for electromagnetic fields.
Definition EMField.h:188