OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
#ElementBase.h#
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 has as base class the abstract class RCObject.
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: Call RCObject::addReference() and use [b]this[/b].
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//
63#ifndef CLASSIC_ElementBase_HH
64#define CLASSIC_ElementBase_HH
65
66#include "AbsBeamline/AttributeSet.h"
67#include "Algorithms/CoordinateSystemTrafo.h"
68#include "Algorithms/Quaternion.hpp"
69#include "BeamlineGeometry/Euclid3D.h"
70#include "BeamlineGeometry/Geometry.h"
71#include "MemoryManagement/RCObject.h"
72#include "Structure/BoundingBox.h"
73#include "Utilities/GeneralClassicException.h"
74
75#include <boost/optional.hpp>
76
77#include <map>
78#include <queue>
79#include <string>
80
81class BeamlineVisitor;
82class BoundaryGeometry;
83class Channel;
84class ConstChannel;
85class ParticleMatterInteractionHandler;
86class WakeFunction;
87
88enum class ElementType : unsigned short {
89 ANY,
90 BEAMLINE,
91 DRIFT,
92 MARKER,
93 MULTIPOLE,
94 MULTIPOLET,
95 RFCAVITY,
96 TRAVELINGWAVE,
97 SBEND,
98 RBEND,
99 RBEND3D,
100 RING,
101 PROBE,
102 VACUUM,
103 SOLENOID,
104 SOURCE
105};
106
107enum class ApertureType : unsigned short {
108 RECTANGULAR,
109 ELLIPTICAL,
110 CONIC_RECTANGULAR,
111 CONIC_ELLIPTICAL
112};
113
114class ElementBase : public RCObject {
115public:
116 /// Constructor with given name.
117 explicit ElementBase(const std::string& name);
118
119 ElementBase();
120 ElementBase(const ElementBase&);
121 virtual ~ElementBase();
122
123 /// Get element name.
124 virtual const std::string& getName() const;
125
126 /// Set element name.
127 virtual void setName(const std::string& name);
128
129 /// Get element type std::string.
130 virtual ElementType getType() const = 0;
131
132 std::string getTypeString() const;
133 static std::string getTypeString(ElementType type);
134
135 /// Get geometry.
136 // Return the element geometry.
137 // Version for non-constant object.
138 virtual BGeometryBase& getGeometry() = 0;
139
140 /// Get geometry.
141 // Return the element geometry
142 // Version for constant object.
143 virtual const BGeometryBase& getGeometry() const = 0;
144
145 /// Get arc length.
146 // Return the entire arc length measured along the design orbit
147 virtual double getArcLength() const;
148
149 /// Get design length.
150 // Return the design length defined by the geometry.
151 // This may be the arc length or the straight length.
152 virtual double getElementLength() const;
153
154 /// Set design length.
155 // Set the design length defined by the geometry.
156 // This may be the arc length or the straight length.
157 virtual void setElementLength(double length);
158
159 virtual void getElementDimensions(double& begin, double& end) const {
160 begin = 0.0;
161 end = getElementLength();
162 }
163
164 /// Get origin position.
165 // Return the arc length from the entrance to the origin of the element
166 // (origin >= 0)
167 virtual double getOrigin() const;
168
169 /// Get entrance position.
170 // Return the arc length from the origin to the entrance of the element
171 // (entrance <= 0)
172 virtual double getEntrance() const;
173
174 /// Get exit position.
175 // Return the arc length from the origin to the exit of the element
176 // (exit >= 0)
177 virtual double getExit() const;
178
179 /// Get transform.
180 // Return the transform of the local coordinate system from the
181 // position [b]fromS[/b] to the position [b]toS[/b].
182 virtual Euclid3D getTransform(double fromS, double toS) const;
183
184 /// Get transform.
185 // Equivalent to getTransform(0.0, s).
186 // Return the transform of the local coordinate system from the
187 // origin and [b]s[/b].
188 virtual Euclid3D getTransform(double s) const;
189
190 /// Get transform.
191 // Equivalent to getTransform(getEntrance(), getExit()).
192 // Return the transform of the local coordinate system from the
193 // entrance to the exit of the element.
194 virtual Euclid3D getTotalTransform() const;
195
196 /// Get transform.
197 // Equivalent to getTransform(0.0, getEntrance()).
198 // Return the transform of the local coordinate system from the
199 // origin to the entrance of the element.
200 virtual Euclid3D getEntranceFrame() const;
201
202 /// Get transform.
203 // Equivalent to getTransform(0.0, getExit()).
204 // Return the transform of the local coordinate system from the
205 // origin to the exit of the element.
206 virtual Euclid3D getExitFrame() const;
207
208 /// Get patch.
209 // Returns the entrance patch (transformation) which is used to transform
210 // the global geometry to the local geometry for a misaligned element
211 // at its entrance. The default behaviour returns identity transformation.
212 // This function should be overridden by derived concrete classes which
213 // model complex geometries.
214 virtual Euclid3D getEntrancePatch() const;
215
216 /// Get patch.
217 // Returns the entrance patch (transformation) which is used to transform
218 // the local geometry to the global geometry for a misaligned element
219 // at its exit. The default behaviour returns identity transformation.
220 // This function should be overridden by derived concrete classes which
221 // model complex geometries.
222 virtual Euclid3D getExitPatch() const;
223
224 /// Get attribute value.
225 // If the attribute does not exist, return zero.
226 virtual double getAttribute(const std::string& aKey) const;
227
228 /// Test for existence of an attribute.
229 // If the attribute exists, return true, otherwise false.
230 virtual bool hasAttribute(const std::string& aKey) const;
231
232 /// Remove an existing attribute.
233 virtual void removeAttribute(const std::string& aKey);
234
235 /// Set value of an attribute.
236 virtual void setAttribute(const std::string& aKey, double val);
237
238 /// Construct a read/write channel.
239 // This method constructs a Channel permitting read/write access to
240 // the attribute [b]aKey[/b] and returns it.
241 // If the attribute does not exist, it returns nullptr.
242 virtual Channel* getChannel(const std::string& aKey, bool create = false);
243
244 /// Construct a read-only channel.
245 // This method constructs a Channel permitting read-only access to
246 // the attribute [b]aKey[/b] and returns it.
247 // If the attribute does not exist, it returns nullptr.
248 virtual const ConstChannel* getConstChannel(const std::string& aKey) const;
249
250 /// Apply visitor.
251 // This method must be overridden by derived classes. It should call the
252 // method of the visitor corresponding to the element class.
253 // If any error occurs, this method throws an exception.
254 virtual void accept(BeamlineVisitor& visitor) const = 0;
255
256 /// Return clone.
257 // Return an identical deep copy of the element.
258 virtual ElementBase* clone() const = 0;
259
260 /// Make a structural copy.
261 // Return a fresh copy of any beam line structure is made,
262 // but sharable elements remain shared.
263 virtual ElementBase* copyStructure();
264
265 /// Test if the element can be shared.
266 bool isSharable() const;
267
268 /// Set sharable flag.
269 // The whole structure depending on [b]this[/b] is marked as sharable.
270 // After this call a [b]copyStructure()[/b] call reuses the element.
271 virtual void makeSharable();
272
273 /// Update element.
274 // This method stores all attributes contained in the AttributeSet to
275 // "*this". The return value [b]true[/b] indicates success.
276 bool update(const AttributeSet&);
277
278 ///@{ Access to ELEMEDGE attribute
279 void setElementPosition(double elemedge);
280 double getElementPosition() const;
281 bool isElementPositionSet() const;
282 ///@}
283 /// attach a boundary geometry field to the element
284 virtual void setBoundaryGeometry(BoundaryGeometry* geo);
285
286 /// return the attached boundary geometrt object if there is any
287 virtual BoundaryGeometry* getBoundaryGeometry() const;
288
289 virtual bool hasBoundaryGeometry() const;
290
291 /// attach a wake field to the element
292 virtual void setWake(WakeFunction* wf);
293
294 /// return the attached wake object if there is any
295 virtual WakeFunction* getWake() const;
296
297 virtual bool hasWake() const;
298
299 virtual void setParticleMatterInteraction(ParticleMatterInteractionHandler* spys);
300
301 virtual ParticleMatterInteractionHandler* getParticleMatterInteraction() const;
302
303 virtual bool hasParticleMatterInteraction() const;
304
305 void setCSTrafoGlobal2Local(const CoordinateSystemTrafo& ori);
306 CoordinateSystemTrafo getCSTrafoGlobal2Local() const;
307 void releasePosition();
308 void fixPosition();
309 bool isPositioned() const;
310
311 virtual CoordinateSystemTrafo getEdgeToBegin() const;
312 virtual CoordinateSystemTrafo getEdgeToEnd() const;
313
314 void setAperture(const ApertureType& type, const std::vector<double>& args);
315 std::pair<ApertureType, std::vector<double> > getAperture() const;
316
317 virtual bool isInside(const Vector_t<double, 3>& r) const;
318
319 void setMisalignment(const CoordinateSystemTrafo& cst);
320
321 void getMisalignment(double& x, double& y, double& s) const;
322 CoordinateSystemTrafo getMisalignment() const;
323
324 void setActionRange(const std::queue<std::pair<double, double> >& range);
325 void setCurrentSCoordinate(double s);
326
327 /// Set rotation about z axis in bend frame.
328 void setRotationAboutZ(double rotation);
329 double getRotationAboutZ() const;
330
331 virtual BoundingBox getBoundingBoxInLabCoords() const;
332
333 virtual int getRequiredNumberOfTimeSteps() const;
334
335 /// Set output filename
336 void setOutputFN(std::string fn);
337 /// Get output filename
338 std::string getOutputFN() const;
339
340 void setFlagDeleteOnTransverseExit(bool = true);
341 bool getFlagDeleteOnTransverseExit() const;
342
343protected:
344 bool isInsideTransverse(const Vector_t<double, 3>& r) const;
345
346 // Sharable flag.
347 // If this flag is true, the element is always shared.
348 mutable bool shareFlag;
349
350 CoordinateSystemTrafo csTrafoGlobal2Local_m;
351 CoordinateSystemTrafo misalignment_m;
352
353 std::pair<ApertureType, std::vector<double> > aperture_m;
354
355 double elementEdge_m;
356
357 double rotationZAxis_m;
358
359private:
360 // Not implemented.
361 void operator=(const ElementBase&);
362
363 // The element's name
364 std::string elementID;
365
366 static const std::map<ElementType, std::string> elementTypeToString_s;
367
368 // The user-defined set of attributes.
369 AttributeSet userAttribs;
370
371 WakeFunction* wake_m;
372
373 BoundaryGeometry* bgeometry_m;
374
375 ParticleMatterInteractionHandler* parmatint_m;
376
377 bool positionIsFixed;
378 ///@{ ELEMEDGE attribute
379 double elementPosition_m;
380 bool elemedgeSet_m;
381 ///@}
382 std::queue<std::pair<double, double> > actionRange_m;
383
384 std::string outputfn_m; /**< The name of the outputfile*/
385
386 bool deleteOnTransverseExit_m = true;
387};
388
389// Inline functions.
390// ------------------------------------------------------------------------
391
392inline double ElementBase::getArcLength() const {
393 return getGeometry().getArcLength();
394}
395
396inline double ElementBase::getElementLength() const {
397 return getGeometry().getElementLength();
398}
399
400inline void ElementBase::setElementLength(double length) {
401 getGeometry().setElementLength(length);
402}
403
404inline double ElementBase::getOrigin() const {
405 return getGeometry().getOrigin();
406}
407
408inline double ElementBase::getEntrance() const {
409 return getGeometry().getEntrance();
410}
411
412inline double ElementBase::getExit() const {
413 return getGeometry().getExit();
414}
415
416inline Euclid3D ElementBase::getTransform(double fromS, double toS) const {
417 return getGeometry().getTransform(fromS, toS);
418}
419
420inline Euclid3D ElementBase::getTotalTransform() const {
421 return getGeometry().getTotalTransform();
422}
423
424inline Euclid3D ElementBase::getTransform(double s) const {
425 return getGeometry().getTransform(s);
426}
427
428inline Euclid3D ElementBase::getEntranceFrame() const {
429 return getGeometry().getEntranceFrame();
430}
431
432inline Euclid3D ElementBase::getExitFrame() const {
433 return getGeometry().getExitFrame();
434}
435
436inline Euclid3D ElementBase::getEntrancePatch() const {
437 return getGeometry().getEntrancePatch();
438}
439
440inline Euclid3D ElementBase::getExitPatch() const {
441 return getGeometry().getExitPatch();
442}
443
444inline bool ElementBase::isSharable() const {
445 return shareFlag;
446}
447
448inline WakeFunction* ElementBase::getWake() const {
449 return wake_m;
450}
451
452inline bool ElementBase::hasWake() const {
453 return wake_m != nullptr;
454}
455
456inline BoundaryGeometry* ElementBase::getBoundaryGeometry() const {
457 return bgeometry_m;
458}
459
460inline bool ElementBase::hasBoundaryGeometry() const {
461 return bgeometry_m != nullptr;
462}
463
464inline ParticleMatterInteractionHandler* ElementBase::getParticleMatterInteraction() const {
465 return parmatint_m;
466}
467
468inline bool ElementBase::hasParticleMatterInteraction() const {
469 return parmatint_m != nullptr;
470}
471
472inline void ElementBase::setCSTrafoGlobal2Local(const CoordinateSystemTrafo& trafo) {
473 if (positionIsFixed)
474 return;
475
476 csTrafoGlobal2Local_m = trafo;
477}
478
479inline CoordinateSystemTrafo ElementBase::getCSTrafoGlobal2Local() const {
480 return csTrafoGlobal2Local_m;
481}
482
483inline CoordinateSystemTrafo ElementBase::getEdgeToBegin() const {
484 CoordinateSystemTrafo ret(Vector_t<double, 3>({0, 0, 0}), Quaternion(1, 0, 0, 0));
485 return ret;
486}
487
488inline CoordinateSystemTrafo ElementBase::getEdgeToEnd() const {
489 CoordinateSystemTrafo ret(
490 Vector_t<double, 3>({0, 0, getElementLength()}), Quaternion(1, 0, 0, 0));
491
492 return ret;
493}
494
495inline void ElementBase::setAperture(const ApertureType& type, const std::vector<double>& args) {
496 aperture_m.first = type;
497 aperture_m.second = args;
498}
499
500inline std::pair<ApertureType, std::vector<double> > ElementBase::getAperture() const {
501 return aperture_m;
502}
503
504inline bool ElementBase::isInside(const Vector_t<double, 3>& r) const {
505 const double length = getElementLength();
506 return r(2) >= 0.0 && r(2) < length && isInsideTransverse(r);
507}
508
509inline void ElementBase::setMisalignment(const CoordinateSystemTrafo& cst) {
510 misalignment_m = cst;
511}
512
513inline CoordinateSystemTrafo ElementBase::getMisalignment() const {
514 return misalignment_m;
515}
516
517inline void ElementBase::releasePosition() {
518 positionIsFixed = false;
519}
520
521inline void ElementBase::fixPosition() {
522 positionIsFixed = true;
523}
524
525inline bool ElementBase::isPositioned() const {
526 return positionIsFixed;
527}
528
529inline void ElementBase::setActionRange(const std::queue<std::pair<double, double> >& range) {
530 actionRange_m = range;
531
532 if (!actionRange_m.empty())
533 elementEdge_m = actionRange_m.front().first;
534}
535
536inline void ElementBase::setRotationAboutZ(double rotation) {
537 rotationZAxis_m = rotation;
538}
539
540inline double ElementBase::getRotationAboutZ() const {
541 return rotationZAxis_m;
542}
543
544inline std::string ElementBase::getTypeString() const {
545 return getTypeString(getType());
546}
547
548inline void ElementBase::setElementPosition(double elemedge) {
549 elementPosition_m = elemedge;
550 elemedgeSet_m = true;
551}
552
553inline double ElementBase::getElementPosition() const {
554 if (elemedgeSet_m)
555 return elementPosition_m;
556
557 throw GeneralClassicException(
558 "ElementBase::getElementPosition()",
559 std::string("ELEMEDGE for \"") + getName() + "\" not set");
560}
561
562inline bool ElementBase::isElementPositionSet() const {
563 return elemedgeSet_m;
564}
565
566inline int ElementBase::getRequiredNumberOfTimeSteps() const {
567 return 10;
568}
569
570inline void ElementBase::setFlagDeleteOnTransverseExit(bool flag) {
571 deleteOnTransverseExit_m = flag;
572}
573
574inline bool ElementBase::getFlagDeleteOnTransverseExit() const {
575 return deleteOnTransverseExit_m;
576}
577
578#endif // CLASSIC_ElementBase_HH