OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
ElementBase.cpp
Go to the documentation of this file.
1//
2// Class ElementBase
3// The very base class for beam line representation objects. A beam line
4// is modelled as a composite structure having a single root object
5// (the top level beam line), which contains both ``single'' leaf-type
6// elements (Components), as well as sub-lines (composites).
7//
8// Interface for basic beam line object.
9// This class defines the abstract interface for all objects which can be
10// contained in a beam line. ElementBase forms the base class for two distinct
11// but related hierarchies of objects:
12// [OL]
13// [LI]
14// A set of concrete accelerator element classes, which compose the standard
15// accelerator component library (SACL).
16// [LI]
17// [/OL]
18// Instances of the concrete classes for single elements are by default
19// sharable. Instances of beam lines and integrators are by
20// default non-sharable, but they may be made sharable by a call to
21// [b]makeSharable()[/b].
22// [p]
23// An ElementBase object can return two lengths, which may be different:
24// [OL]
25// [LI]
26// The arc length along the geometry.
27// [LI]
28// The design length, often measured along a straight line.
29// [/OL]
30// Class ElementBase contains a map of name versus value for user-defined
31// attributes (see file AbsBeamline/AttributeSet.hh). The map is primarily
32// intended for processes that require algorithm-specific data in the
33// accelerator model.
34// [P]
35// The class ElementBase is a base class.
36// Virtual derivation is used to make multiple inheritance possible for
37// derived concrete classes. ElementBase implements three copy modes:
38// [OL]
39// [LI]
40// Copy by reference: Use std::shared_ptr to share ownership.
41// [LI]
42// Copy structure: use ElementBase::copyStructure().
43// During copying of the structure, all sharable items are re-used, while
44// all non-sharable ones are cloned.
45// [LI]
46// Copy by cloning: use ElementBase::clone().
47// This returns a full deep copy.
48// [/OL]
49//
50// Copyright (c) 200x - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
51// All rights reserved
52//
53// This file is part of OPAL.
54//
55// OPAL is free software: you can redistribute it and/or modify
56// it under the terms of the GNU General Public License as published by
57// the Free Software Foundation, either version 3 of the License, or
58// (at your option) any later version.
59//
60// You should have received a copy of the GNU General Public License
61// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
62//
64
65#include "Channels/Channel.h"
66
67#include <algorithm>
68#include <cmath>
69#include <filesystem>
70#include <iostream>
71#include <vector>
72
73const std::map<ElementType, std::string> ElementBase::elementTypeToString_s = {
74 {ElementType::ANY, "Any"},
75 {ElementType::BEAMLINE, "Beamline"},
76 {ElementType::DRIFT, "Drift"},
77 {ElementType::LASER, "Laser"},
78 {ElementType::MARKER, "Marker"},
79 {ElementType::MONITOR, "Monitor"},
80 {ElementType::MULTIPOLE, "Multipole"},
81 {ElementType::RFCAVITY, "RFCavity"},
82 {ElementType::TRAVELINGWAVE, "TravelingWave"},
83 {ElementType::SBEND, "SBEND"},
84 {ElementType::RBEND, "RBEND"},
85 {ElementType::RBEND3D, "RBEND3D"},
86 {ElementType::RING, "Ring"},
87 {ElementType::SOURCE, "SOURCE"},
88 {ElementType::SOLENOID, "SOLENOID"},
89 {ElementType::PROBE, "Probe"},
90 {ElementType::VACUUM, "Vacuum"},
91 {ElementType::CONSTANTEFIELDCAVITY, "ConstantEFieldCavity"}};
92
94
96 : std::enable_shared_from_this<ElementBase>(),
97 shareFlag(true),
98 csTrafoGlobal2Local_m(right.csTrafoGlobal2Local_m),
99 misalignment_m(right.misalignment_m),
100 aperture_m(right.aperture_m),
101 elementEdge_m(right.elementEdge_m),
102 rotationZAxis_m(right.rotationZAxis_m),
103 elementID(right.elementID),
104 userAttribs(right.userAttribs),
105 wake_m(right.wake_m),
106 bgeometry_m(right.bgeometry_m),
107 parmatint_m(right.parmatint_m),
108 positionIsFixed(right.positionIsFixed),
109 elementPosition_m(right.elementPosition_m),
110 elemedgeSet_m(right.elemedgeSet_m),
111 outputfn_m(right.outputfn_m),
112 deleteOnTransverseExit_m(right.deleteOnTransverseExit_m) {}
113
114ElementBase::ElementBase(const std::string& name)
115 : shareFlag(true),
116 csTrafoGlobal2Local_m(),
117 misalignment_m(),
118 elementEdge_m(0),
119 rotationZAxis_m(0.0),
120 elementID(name),
121 userAttribs(),
122 wake_m(nullptr),
123 bgeometry_m(nullptr),
124 parmatint_m(nullptr),
125 positionIsFixed(false),
126 elementPosition_m(0.0),
127 elemedgeSet_m(false),
128 outputfn_m("") {}
129
131
132const std::string& ElementBase::getName() const { return elementID; }
133
134void ElementBase::setName(const std::string& name) { elementID = name; }
135
136void ElementBase::setOutputFN(const std::string fn) { outputfn_m = fn; }
137
138std::string ElementBase::getOutputFN() const {
139 if (outputfn_m.empty()) {
140 return getName();
141 } else {
142 std::filesystem::path filePath(outputfn_m);
143 return filePath.replace_extension().native();
144 }
145}
146
147double ElementBase::getAttribute(const std::string& aKey) const {
148 const ConstChannel* aChannel = getConstChannel(aKey);
149
150 if (aChannel != nullptr) {
151 double val = *aChannel;
152 delete aChannel;
153 return val;
154 } else {
155 return 0.0;
156 }
157}
158
159bool ElementBase::hasAttribute(const std::string& aKey) const {
160 const ConstChannel* aChannel = getConstChannel(aKey);
161
162 if (aChannel != nullptr) {
163 delete aChannel;
164 return true;
165 } else {
166 return false;
167 }
168}
169
170void ElementBase::removeAttribute(const std::string& aKey) { userAttribs.removeAttribute(aKey); }
171
172void ElementBase::setAttribute(const std::string& aKey, double val) {
173 Channel* aChannel = getChannel(aKey, true);
174
175 if (aChannel != nullptr && aChannel->isSettable()) {
176 *aChannel = val;
177 delete aChannel;
178 } else
179 std::cout << "Channel nullptr or not Settable" << std::endl;
180}
181
182Channel* ElementBase::getChannel(const std::string& aKey, bool create) {
183 return userAttribs.getChannel(aKey, create);
184}
185
186const ConstChannel* ElementBase::getConstChannel(const std::string& aKey) const {
187 // Use const_cast to allow calling the non-const method GetChannel().
188 // The const return value of this method will nevertheless inhibit set().
189 return const_cast<ElementBase*>(this)->getChannel(aKey);
190}
191
193
195 if (isSharable()) {
196 return this;
197 } else {
198 return clone();
199 }
200}
201
203
205 for (AttributeSet::const_iterator i = set.begin(); i != set.end(); ++i) {
206 setAttribute(i->first, i->second);
207 }
208
209 return true;
210}
211
212void ElementBase::setWake(WakeFunction* wk) {
213 wake_m = wk; //->clone(getName() + std::string("_wake")); }
214}
215
217 bgeometry_m = geo; //->clone(getName() + std::string("_wake")); }
218}
219
220void ElementBase::setParticleMatterInteraction(ParticleMatterInteractionHandler* parmatint) {
221 parmatint_m = parmatint;
222}
223
225 if (!actionRange_m.empty() && actionRange_m.front().second < s) {
226 actionRange_m.pop();
227 if (!actionRange_m.empty()) {
228 elementEdge_m = actionRange_m.front().first;
229 }
230 }
231}
232
234 const double& xLimit = aperture_m.second[0];
235 const double& yLimit = aperture_m.second[1];
236 double factor = 1.0;
239 const double length = getElementLength();
240 if (length > 0.0) {
241 Vector_t<double, 3> rRelativeToBegin = getEdgeToBegin().transformTo(r);
242 double fractionLength = rRelativeToBegin(2) / length;
243 fractionLength = std::clamp(fractionLength, 0.0, 1.0);
244 // Interpolate aperture scaling from begin (1.0) to end (aperture_m.second[2]).
245 factor = 1.0 + fractionLength * (aperture_m.second[2] - 1.0);
246 }
247 }
248
249 switch (aperture_m.first) {
251 return (std::abs(r[0]) < xLimit && std::abs(r[1]) < yLimit);
253 return (std::pow(r[0] / xLimit, 2) + std::pow(r[1] / yLimit, 2) < 1.0);
255 return (std::abs(r[0]) < factor * xLimit && std::abs(r[1]) < factor * yLimit);
257 return (std::pow(r[0] / (factor * xLimit), 2) + std::pow(r[1] / (factor * yLimit), 2)
258 < 1.0);
259 default:
260 return false;
261 }
262}
263
267
268 const double& x = aperture_m.second[0];
269 const double& y = aperture_m.second[1];
270 const double& f = aperture_m.second[2];
271
272 std::vector<Vector_t<double, 3>> corners(8);
273 for (int i = -1; i < 2; i += 2) {
274 for (int j = -1; j < 2; j += 2) {
275 unsigned int idx = (i + 1) / 2 + (j + 1);
276 corners[idx] = toBegin.transformFrom(Vector_t<double, 3>({i * x, j * y, 0.0}));
277 corners[idx + 4] =
278 toEnd.transformFrom(Vector_t<double, 3>({i * f * x, j * f * y, 0.0}));
279 }
280 }
281
282 return BoundingBox::getBoundingBox(corners);
283}
ippl::Vector< T, Dim > Vector_t
ElementType
Definition ElementBase.h:94
@ CONSTANTEFIELDCAVITY
Map of std::string versus double value.
void removeAttribute(const std::string &aKey)
Remove an existing attribute.
const_iterator begin() const
Iterator accessing first member.
NameMap::const_iterator const_iterator
An iterator for a map of name versus value.
Channel * getChannel(const std::string &aKey, bool create=false)
Construct a read/write channel.
const_iterator end() const
Iterator marking the end of the list.
static BoundingBox getBoundingBox(const std::vector< Vector_t< double, 3 > > &positions)
Abstract interface for read/write access to variable.
Definition Channel.h:30
virtual bool isSettable() const
Test if settable.
Definition Channel.cpp:30
Abstract interface for read-only access to variable.
Rigid spatial transform between a parent frame and a local frame.
ippl::Vector< double, 3 > transformFrom(const ippl::Vector< double, 3 > &r) const
Map a point from the local frame back to the parent frame.
ippl::Vector< double, 3 > transformTo(const ippl::Vector< double, 3 > &r) const
Map a point from the parent frame to the local frame.
virtual void setBoundaryGeometry(BoundaryGeometry *geo)
virtual ~ElementBase()
virtual Channel * getChannel(const std::string &aKey, bool create=false)
Construct a read/write channel.
virtual void setName(const std::string &name)
Set element name.
virtual const std::string & getName() const
Get element name.
virtual void removeAttribute(const std::string &aKey)
Remove an existing attribute.
static const std::map< ElementType, std::string > elementTypeToString_s
Definition ElementBase.h:73
virtual double getElementLength() const
Get design length.
bool update(const AttributeSet &)
Update element.
std::string outputfn_m
ParticleMatterInteractionHandler * parmatint_m
virtual const ConstChannel * getConstChannel(const std::string &aKey) const
Construct a read-only channel.
virtual ElementBase * clone() const =0
Return clone.
virtual void setAttribute(const std::string &aKey, double val)
Set value of an attribute.
std::string getOutputFN() const
Get output filename.
void setOutputFN(std::string fn)
Set output filename.
std::pair< ApertureType, std::vector< double > > aperture_m
virtual void setParticleMatterInteraction(ParticleMatterInteractionHandler *spys)
bool isInsideTransverse(const Vector_t< double, 3 > &r) const
virtual void makeSharable()
Set sharable flag.
virtual bool hasAttribute(const std::string &aKey) const
Test for existence of an attribute.
WakeFunction * wake_m
std::queue< std::pair< double, double > > actionRange_m
virtual CoordinateSystemTrafo getEdgeToBegin() const
std::string getTypeString() const
AttributeSet userAttribs
virtual ElementBase * copyStructure()
Make a structural copy.
BoundaryGeometry * bgeometry_m
bool isSharable() const
Test if the element can be shared.
void setCurrentSCoordinate(double s)
std::string elementID
virtual double getAttribute(const std::string &aKey) const
Get attribute value.
virtual CoordinateSystemTrafo getEdgeToEnd() const
virtual void setWake(WakeFunction *wf)
attach a wake field to the element
double elementEdge_m
virtual BoundingBox getBoundingBoxInLabCoords() const
CoordinateSystemTrafo csTrafoGlobal2Local_m
STL namespace.