OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
OpalBeamline.cpp
Go to the documentation of this file.
1//
2// Class OpalBeamline
3// :FIXME: add class description
4//
5// Copyright (c) 200x - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
6// All rights reserved
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
19
22#include "Physics/Units.h"
24#include "Utilities/Options.h"
25#include "Utilities/Util.h"
26
27#include <filesystem>
28#include <fstream>
29#include <regex>
30
32 : elements_m(),
33 placementAssembly_m(),
34 prepared_m(false),
35 compatibilityPlacementCompiled_m(false) {}
36
38 : elements_m(),
39 placementAssembly_m(),
40 prepared_m(false),
41 compatibilityPlacementCompiled_m(false),
42 coordTransformationTo_m(origin, rotation) {}
43
45
46std::set<std::shared_ptr<Component>> OpalBeamline::getElements(const Vector_t<double, 3>& x) {
47 std::set<std::shared_ptr<Component>> elementSet;
48 FieldList::iterator it = elements_m.begin();
49 const FieldList::iterator end = elements_m.end();
50 for (; it != end; ++it) {
51 std::shared_ptr<Component> element = (*it).getElement();
53
54 if (element->isInside(r)) {
55 elementSet.insert(element);
56 }
57 }
58
59 return elementSet;
60}
61
62std::set<std::shared_ptr<Component>> OpalBeamline::getElements() {
63 std::set<std::shared_ptr<Component>> elementSet;
64 for (auto& item : elements_m) {
65 elementSet.insert(item.getElement());
66 }
67 return elementSet;
68}
69
71 const unsigned int& /*index*/, const Vector_t<double, 3>& /*pos*/, const long& /*sindex*/,
72 const double& /*t*/, Vector_t<double, 3>& /*E*/, Vector_t<double, 3>& /*B*/) {
73 unsigned long rtv = 0x00;
74
75 return rtv;
76}
77
79 const Vector_t<double, 3>& position, const Vector_t<double, 3>& momentum, const double& t,
81 unsigned long rtv = 0x00;
82
83 std::set<std::shared_ptr<Component>> elements = getElements(position);
84
85 std::set<std::shared_ptr<Component>>::const_iterator it = elements.begin();
86 const std::set<std::shared_ptr<Component>>::const_iterator end = elements.end();
87
88 for (; it != end; ++it) {
89 ElementType type = (*it)->getType();
90 if (type == ElementType::MARKER) continue;
91
92 Vector_t<double, 3> localR = transformToLocalCS(*it, position);
93 Vector_t<double, 3> localP = rotateToLocalCS(*it, momentum);
94 Vector_t<double, 3> localE(0.0), localB(0.0);
95
96 (*it)->applyToReferenceParticle(localR, localP, t, localE, localB);
97
98 Ef += rotateFromLocalCS(*it, localE);
99 Bf += rotateFromLocalCS(*it, localB);
100 }
101
102 // if(section.hasWake()) {
103 // rtv |= BEAMLINE_WAKE;
104 // }
105 // if(section.hasParticleMatterInteraction()) {
106 // rtv |= BEAMLINE_PARTICLEMATTERINTERACTION;
107 // }
108
109 return rtv;
110}
111
113 const double& min, const double& max, const double& kineticEnergy,
114 const bool& /*nomonitors*/) {
115 FieldList::iterator fprev;
116 for (FieldList::iterator flit = elements_m.begin(); flit != elements_m.end(); ++flit) {
117 // don't set online monitors if the centroid of the bunch is allready inside monitor
118 // or if explicitly not desired (eg during auto phasing)
119 if (!(*flit).isOn() && max > (*flit).getStart() && min < (*flit).getEnd()) {
120 (*flit).setOn(kineticEnergy);
121 }
122
123 fprev = flit;
124 }
125}
126
128 for (FieldList::iterator flit = elements_m.begin(); flit != elements_m.end(); ++flit)
129 (*flit).setOff();
130}
131
133 if (elements_m.empty()) {
134 prepared_m = true;
135 return;
136 }
138 for (auto& fieldElement : elements_m) {
139 storePlacedElement(fieldElement.getElement());
140 }
142 prepared_m = true;
143}
144
145void OpalBeamline::print(Inform& /*msg*/) const {}
146
154
156 elements_m.insert(elements_m.end(), rhs.elements_m.begin(), rhs.elements_m.end());
157 placementAssembly_m.clear();
158 prepared_m = false;
160}
161
163 if (type == ElementType::ANY) {
164 return elements_m;
165 }
166
167 FieldList elements_of_requested_type;
168 for (FieldList::iterator fit = elements_m.begin(); fit != elements_m.end(); ++fit) {
169 if ((*fit).getElement()->getType() == type) {
170 elements_of_requested_type.push_back((*fit));
171 }
172 }
173 return elements_of_requested_type;
174}
175
176void OpalBeamline::positionElementRelative(std::shared_ptr<ElementBase> element) {
177 if (!element->isPositioned()) {
178 return;
179 }
180
181 element->releasePosition();
182 CoordinateSystemTrafo toElement = element->getPlacedElement().getNominalBodyTransform();
183 toElement *= coordTransformationTo_m;
184
185 setNominalPlacement(element, toElement);
186 element->fixPosition();
187}
188
190 const std::shared_ptr<ElementBase>& element, const CoordinateSystemTrafo& parentToBody) {
191 element->setPlacementPose(PlacementPose(parentToBody));
192 storePlacedElement(element);
193}
194
195void OpalBeamline::storePlacedElement(const std::shared_ptr<ElementBase>& element) {
196 placementAssembly_m.insert_or_assign(element.get(), element->getPlacedElement());
197}
198
201 return;
202 }
203
204 static unsigned int order = 0;
205 const FieldList::iterator end = elements_m.end();
206
207 unsigned int minOrder = order;
208 {
209 double endPriorPathLength = 0.0;
211
212 FieldList::iterator it = elements_m.begin();
213 for (; it != end; ++it) {
214 std::shared_ptr<Component> element = (*it).getElement();
215 if (element->isPositioned()) {
216 continue;
217 }
218 (*it).order_m = minOrder;
219
220 if (element->getType() != ElementType::SBEND && element->getType() != ElementType::RBEND
221 && element->getType() != ElementType::RBEND3D) {
222 continue;
223 }
224
225 double beginThisPathLength = element->getElementPosition();
226 Vector_t<double, 3> beginThis3D(0, 0, beginThisPathLength - endPriorPathLength);
227 BendBase* bendElement = dynamic_cast<BendBase*>(element.get());
228 double thisLength = bendElement->getChordLength();
229 double bendAngle = bendElement->getBendAngle();
230 double entranceAngle = bendElement->getEntranceAngle();
231 double arcLength = element->getArcLength();
232
233 double rotationAngleAboutZ = bendElement->getRotationAboutZ();
234 Quaternion_t rotationAboutZ(
235 cos(0.5 * rotationAngleAboutZ),
236 sin(-0.5 * rotationAngleAboutZ) * Vector_t<double, 3>(0, 0, 1));
237
238 Vector_t<double, 3> effectiveRotationAxis =
239 rotationAboutZ.rotate(Vector_t<double, 3>(0, -1, 0));
240 effectiveRotationAxis = effectiveRotationAxis / euclidean_norm(effectiveRotationAxis);
241
242 Quaternion_t rotationAboutAxis(
243 cos(0.5 * bendAngle), sin(0.5 * bendAngle) * effectiveRotationAxis);
244 Quaternion_t halfRotationAboutAxis(
245 cos(0.25 * bendAngle), sin(0.25 * bendAngle) * effectiveRotationAxis);
246 Quaternion_t entryFaceRotation(
247 cos(0.5 * entranceAngle), sin(0.5 * entranceAngle) * effectiveRotationAxis);
248
249 if (!Options::idealized) {
250 std::vector<Vector_t<double, 3>> truePath = bendElement->getDesignPath();
251 Quaternion_t directionExitHardEdge(
252 cos(0.5 * (0.5 * bendAngle - entranceAngle)),
253 sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
254 Vector_t<double, 3> exitHardEdge =
255 thisLength * directionExitHardEdge.rotate(Vector_t<double, 3>(0, 0, 1));
256 double distanceEntryHETruePath = euclidean_norm(truePath.front());
257 Vector_t<double, 3> exitDelta =
258 rotationAboutZ.rotate(truePath.back()) - exitHardEdge;
259 double distanceExitHETruePath = euclidean_norm(exitDelta);
260 double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
261 arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
262 }
263
264 Vector_t<double, 3> chord =
265 thisLength * halfRotationAboutAxis.rotate(Vector_t<double, 3>(0, 0, 1));
266 Vector_t<double, 3> endThis3D = beginThis3D + chord;
267 double endThisPathLength = beginThisPathLength + arcLength;
268
269 CoordinateSystemTrafo fromEndLastToBeginThis(
270 beginThis3D, (entryFaceRotation * rotationAboutZ).conjugate());
271 CoordinateSystemTrafo fromEndLastToEndThis(endThis3D, rotationAboutAxis.conjugate());
272
273 setNominalPlacement(element, fromEndLastToBeginThis * currentCoordTrafo);
274
275 currentCoordTrafo = (fromEndLastToEndThis * currentCoordTrafo);
276
277 endPriorPathLength = endThisPathLength;
278 }
279 }
280
281 double endPriorPathLength = 0.0;
283
284 FieldList::iterator it = elements_m.begin();
285 for (; it != end; ++it) {
286 std::shared_ptr<Component> element = (*it).getElement();
287 if (element->isPositioned()) continue;
288
289 (*it).order_m = order++;
290
291 double beginThisPathLength = element->getElementPosition();
292 double thisLength = element->getElementLength();
293 Vector_t<double, 3> beginThis3D(0, 0, beginThisPathLength - endPriorPathLength);
294
295 if (element->getType() == ElementType::SOURCE) {
296 beginThis3D(2) -= thisLength;
297 }
298
299 Vector_t<double, 3> endThis3D;
300 if (element->getType() == ElementType::SBEND || element->getType() == ElementType::RBEND
301 || element->getType() == ElementType::RBEND3D) {
302 BendBase* bendElement = dynamic_cast<BendBase*>(element.get());
303 thisLength = bendElement->getChordLength();
304 double bendAngle = bendElement->getBendAngle();
305
306 double rotationAngleAboutZ = bendElement->getRotationAboutZ();
307 Quaternion_t rotationAboutZ(
308 cos(0.5 * rotationAngleAboutZ),
309 sin(-0.5 * rotationAngleAboutZ) * Vector_t<double, 3>(0, 0, 1));
310
311 Vector_t<double, 3> effectiveRotationAxis =
312 rotationAboutZ.rotate(Vector_t<double, 3>(0, -1, 0));
313 effectiveRotationAxis = effectiveRotationAxis / euclidean_norm(effectiveRotationAxis);
314
315 Quaternion_t rotationAboutAxis(
316 cos(0.5 * bendAngle), sin(0.5 * bendAngle) * effectiveRotationAxis);
317 Quaternion halfRotationAboutAxis(
318 cos(0.25 * bendAngle), sin(0.25 * bendAngle) * effectiveRotationAxis);
319
320 double arcLength = element->getArcLength();
321 if (!Options::idealized) {
322 std::vector<Vector_t<double, 3>> truePath = bendElement->getDesignPath();
323 double entranceAngle = bendElement->getEntranceAngle();
324 Quaternion_t directionExitHardEdge(
325 cos(0.5 * (0.5 * bendAngle - entranceAngle)),
326 sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
327 Vector_t<double, 3> exitHardEdge =
328 thisLength * directionExitHardEdge.rotate(Vector_t<double, 3>(0, 0, 1));
329 double distanceEntryHETruePath = euclidean_norm(truePath.front());
330 Vector_t<double, 3> exitDelta =
331 rotationAboutZ.rotate(truePath.back()) - exitHardEdge;
332 double distanceExitHETruePath = euclidean_norm(exitDelta);
333 double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
334 arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
335 }
336
337 endThis3D =
338 (beginThis3D
339 + halfRotationAboutAxis.rotate(Vector_t<double, 3>(0, 0, thisLength)));
340 CoordinateSystemTrafo fromEndLastToEndThis(endThis3D, rotationAboutAxis.conjugate());
341 currentCoordTrafo = fromEndLastToEndThis * currentCoordTrafo;
342
343 endPriorPathLength = beginThisPathLength + arcLength;
344 } else {
345 double rotationAngleAboutZ = (*it).getElement()->getRotationAboutZ();
346 Quaternion_t rotationAboutZ(
347 cos(0.5 * rotationAngleAboutZ),
348 sin(-0.5 * rotationAngleAboutZ) * Vector_t<double, 3>(0, 0, 1));
349
350 CoordinateSystemTrafo fromLastToThis(beginThis3D, rotationAboutZ);
351
352 setNominalPlacement(element, fromLastToThis * currentCoordTrafo);
353 }
354
355 element->fixPosition();
356 }
357
359}
360
362
364 if (ippl::Comm->rank() != 0 || OpalData::getInstance()->isOptimizerRun()) return;
365
366 elements_m.sort([](const BeamlineFieldElement& a, const BeamlineFieldElement& b) {
367 return a.order_m < b.order_m;
368 });
369
370 FieldList::iterator it = elements_m.begin();
371 FieldList::iterator end = elements_m.end();
372
373 std::ofstream pos;
374 std::string fileName = Util::combineFilePath(
376 OpalData::getInstance()->getInputBasename() + "_ElementPositions.txt"});
378 && std::filesystem::exists(fileName)) {
379 pos.open(fileName, std::ios_base::app);
380 } else {
381 pos.open(fileName);
382 }
383
384 MeshGenerator mesh;
385 for (auto scan = it; scan != end; ++scan) {
386 const std::shared_ptr<Component> scanElement = (*scan).getElement();
387 if (scanElement->getType() == ElementType::DRIFT) {
388 continue;
389 }
390
391 double minor = 0.0;
392 double major = 0.0;
393 if (MeshGenerator::getTransverseSupport(*scanElement, minor, major)) {
394 mesh.setDriftReference(0.5 * minor, 0.5 * major);
395 break;
396 }
397 }
398
399 for (; it != end; ++it) {
400 std::shared_ptr<Component> element = (*it).getElement();
401 PlacedElement placedElement = getPlacedElement(element);
404 Vector_t<double, 3> entry3D = toBegin.getOrigin();
405 Vector_t<double, 3> exit3D = toEnd.getOrigin();
406
407 mesh.add(*(element.get()));
408
409 if (element->getType() == ElementType::SBEND || element->getType() == ElementType::RBEND) {
410 BendBase* bendElement = dynamic_cast<BendBase*>(element.get());
411 std::vector<Vector_t<double, 3>> designPath = bendElement->getDesignPath();
412 unsigned int size = designPath.size();
413
414 unsigned int minNumSteps = std::max(
415 20u, static_cast<unsigned int>(std::ceil(
416 std::abs(bendElement->getBendAngle() * Units::rad2deg))));
417
418 unsigned int frequency =
419 std::max(1u, static_cast<unsigned int>(std::floor((double)size / minNumSteps)));
420
421 pos << std::setw(30) << std::left
422 << std::string("\"ENTRY EDGE: ") + element->getName() + std::string("\"")
423 << std::setw(18) << std::setprecision(10) << entry3D(2) << std::setw(18)
424 << std::setprecision(10) << entry3D(0) << std::setw(18) << std::setprecision(10)
425 << entry3D(1) << "\n";
426
427 Vector_t<double, 3> position =
428 placedElement.getNominalBodyTransform().transformFrom(designPath.front());
429 pos << std::setw(30) << std::left
430 << std::string("\"BEGIN: ") + element->getName() + std::string("\"")
431 << std::setw(18) << std::setprecision(10) << position(2) << std::setw(18)
432 << std::setprecision(10) << position(0) << std::setw(18) << std::setprecision(10)
433 << position(1) << std::endl;
434
435 for (unsigned int i = frequency; i + 1 < size; i += frequency) {
436 position = placedElement.getNominalBodyTransform().transformFrom(designPath[i]);
437 pos << std::setw(30) << std::left
438 << std::string("\"MID: ") + element->getName() + std::string("\"")
439 << std::setw(18) << std::setprecision(10) << position(2) << std::setw(18)
440 << std::setprecision(10) << position(0) << std::setw(18)
441 << std::setprecision(10) << position(1) << std::endl;
442 }
443
444 position = placedElement.getNominalBodyTransform().transformFrom(designPath.back());
445 pos << std::setw(30) << std::left
446 << std::string("\"END: ") + element->getName() + std::string("\"") << std::setw(18)
447 << std::setprecision(10) << position(2) << std::setw(18) << std::setprecision(10)
448 << position(0) << std::setw(18) << std::setprecision(10) << position(1)
449 << std::endl;
450
451 pos << std::setw(30) << std::left
452 << std::string("\"EXIT EDGE: ") + element->getName() + std::string("\"")
453 << std::setw(18) << std::setprecision(10) << exit3D(2) << std::setw(18)
454 << std::setprecision(10) << exit3D(0) << std::setw(18) << std::setprecision(10)
455 << exit3D(1) << std::endl;
456 } else {
457 pos << std::setw(30) << std::left
458 << std::string("\"BEGIN: ") + element->getName() + std::string("\"")
459 << std::setw(18) << std::setprecision(10) << entry3D(2) << std::setw(18)
460 << std::setprecision(10) << entry3D(0) << std::setw(18) << std::setprecision(10)
461 << entry3D(1) << "\n";
462
463 pos << std::setw(30) << std::left
464 << std::string("\"END: ") + element->getName() + std::string("\"") << std::setw(18)
465 << std::setprecision(10) << exit3D(2) << std::setw(18) << std::setprecision(10)
466 << exit3D(0) << std::setw(18) << std::setprecision(10) << exit3D(1) << std::endl;
467 }
468 }
470 mesh.write(OpalData::getInstance()->getInputBasename());
471}
472
473namespace {
474 std::string parseInput() {
475 std::ifstream in(OpalData::getInstance()->getInputFn());
476 std::string source("");
477 std::string str;
478 char testBit;
479 const std::string commentFormat("");
480 const std::regex empty("^[ \t]*$");
481 const std::regex lineEnd(";");
482 const std::string lineEndFormat(";\n");
483 const std::regex cppCommentExpr("//.*");
484 const std::regex cCommentExpr(
485 "/\\*.*?\\*/"); // "/\\*(?>[^*/]+|\\*[^/]|/[^*])*(?>(?R)(?>[^*/]+|\\*[^/]|/[^*])*)*\\*/"
486 bool priorEmpty = true;
487
488 in.get(testBit);
489 while (!in.eof()) {
490 in.putback(testBit);
491
492 std::getline(in, str);
493 str = std::regex_replace(
494 str, cppCommentExpr, commentFormat, std::regex_constants::format_default);
495 str = std::regex_replace(
496 str, empty, commentFormat, std::regex_constants::format_default);
497 if (!str.empty()) {
498 source += str; // + '\n';
499 priorEmpty = false;
500 } else if (!priorEmpty) {
501 source += "##EMPTY_LINE##";
502 priorEmpty = true;
503 }
504
505 in.get(testBit);
506 }
507
508 source = std::regex_replace(source, cCommentExpr, commentFormat);
509 source = std::regex_replace(
510 source, lineEnd, lineEndFormat,
511 std::regex_constants::match_default | std::regex_constants::format_default);
512
513 // Since the positions of the elements are absolute in the laboratory coordinate system we
514 // have to make sure that the line command doesn't provide an origin and orientation.
515 // Everything after the sequence of elements can be deleted and only "LINE = (...);", the
516 // first sub-expression (denoted by '\1'), should be kept.
517 const std::regex lineCommand(
518 "(LINE[ \t]*=[ \t]*\\([^\\)]*\\))[ \t]*,[^;]*;", std::regex::icase);
519 const std::string firstSubExpression("\\1;");
520 source = std::regex_replace(source, lineCommand, firstSubExpression);
521
522 return source;
523 }
524
525 unsigned int getMinimalSignificantDigits(double num, const unsigned int maxDigits) {
526 char buf[32];
527 snprintf(buf, 32, "%.*f", maxDigits + 1, num);
528 std::string numStr(buf);
529 unsigned int length = numStr.length();
530
531 unsigned int numDigits = maxDigits;
532 unsigned int i = 2;
533 while (i < maxDigits + 1 && numStr[length - i] == '0') {
534 --numDigits;
535 ++i;
536 }
537
538 return numDigits;
539 }
540
541 std::string round2string(double num, const unsigned int maxDigits) {
542 char buf[64];
543
544 snprintf(buf, 64, "%.*f", getMinimalSignificantDigits(num, maxDigits), num);
545
546 return std::string(buf);
547 }
548} // namespace
549
551 if (ippl::Comm->rank() != 0 || OpalData::getInstance()->isOptimizerRun()) return;
552
553 FieldList::iterator it = elements_m.begin();
554 FieldList::iterator end = elements_m.end();
555
556 std::string input = parseInput();
557 std::string fname = Util::combineFilePath(
559 OpalData::getInstance()->getInputBasename() + "_3D.opal"});
560 std::ofstream pos(fname);
561
562 for (; it != end; ++it) {
563 std::shared_ptr<Component> element = (*it).getElement();
564 std::string elementName = element->getName();
565 const std::regex replacePSI(
566 "(" + elementName + "\\s*:[^\\n]*)PSI\\s*=[^,;]*,?", std::regex::icase);
567 input = std::regex_replace(input, replacePSI, "\\1\\2");
568
569 const std::regex replaceELEMEDGE(
570 "(" + elementName + "\\s*:[^\\n]*)ELEMEDGE\\s*=[^,;]*(.)", std::regex::icase);
571
573 Vector_t<double, 3> origin = cst.getOrigin();
574 Vector_t<double, 3> orient =
575 Util::getTaitBryantAngles(cst.getRotation().conjugate(), elementName);
576 for (unsigned int d = 0; d < 3; ++d)
577 orient(d) *= Units::rad2deg;
578
579 std::string x =
580 (std::abs(origin(0)) > 1e-10 ? "X = " + round2string(origin(0), 10) + ", " : "");
581 std::string y =
582 (std::abs(origin(1)) > 1e-10 ? "Y = " + round2string(origin(1), 10) + ", " : "");
583 std::string z =
584 (std::abs(origin(2)) > 1e-10 ? "Z = " + round2string(origin(2), 10) + ", " : "");
585
586 std::string theta =
587 (orient(0) > 1e-10 ? "THETA = " + round2string(orient(0), 6) + " * PI / 180, "
588 : "");
589 std::string phi =
590 (orient(1) > 1e-10 ? "PHI = " + round2string(orient(1), 6) + " * PI / 180, " : "");
591 std::string psi =
592 (orient(2) > 1e-10 ? "PSI = " + round2string(orient(2), 6) + " * PI / 180, " : "");
593 std::string coordTrafo = x + y + z + theta + phi + psi;
594 if (coordTrafo.length() > 2) {
595 coordTrafo = coordTrafo.substr(0, coordTrafo.length() - 2); // remove last ', '
596 }
597
598 std::string position = ("\\1" + coordTrafo + "\\2");
599
600 input = std::regex_replace(input, replaceELEMEDGE, position);
601 }
602
603 const std::regex empty("##EMPTY_LINE##");
604 const std::string emptyFormat("\n");
605 input = std::regex_replace(input, empty, emptyFormat);
606
607 pos << input << std::endl;
608}
609
611 auto it = elements_m.begin();
612 const auto end = elements_m.end();
613 double designEnergy = 0.0;
614 for (; it != end; ++it) {
615 std::shared_ptr<Component> element = (*it).getElement();
616 (*it).setOn(designEnergy);
617 element->goOnline(designEnergy);
618 }
619}
std::list< BeamlineFieldElement > FieldList
ippl::Vector< T, Dim > Vector_t
ElementType
Definition ElementBase.h:94
elements
Definition IndexMap.cpp:168
KOKKOS_INLINE_FUNCTION double euclidean_norm(const Vector_t< T, D > &v)
Definition VectorMath.h:15
Beamline component together with its active longitudinal field interval.
static bool SortAsc(const BeamlineFieldElement &fle1, const BeamlineFieldElement &fle2)
Common OPALX interface for analytic horizontal bending magnets.
Definition BendBase.h:32
std::vector< Vector_t< double, 3 > > getDesignPath(std::size_t minSamples=32) const
Sample the local curved reference path of the bend body.
Definition BendBase.cpp:220
double getChordLength() const
Return the geometric chord between entrance and exit frames.
Definition BendBase.cpp:211
double getBendAngle() const
Definition BendBase.h:192
double getEntranceAngle() const
Definition BendBase.h:196
Rigid spatial transform between a parent frame and a local frame.
ippl::Vector< double, 3 > getOrigin() const
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.
Quaternion getRotation() const
double getRotationAboutZ() const
void add(const ElementBase &element)
void setDriftReference(double minor, double major)
Set the drift support radius used when meshing drift spaces.
void write(const std::string &fname)
static bool getTransverseSupport(const ElementBase &element, double &minor, double &major)
Extract a transverse support size suitable for placement/export meshes.
FieldList getElementByType(ElementType)
Vector_t< double, 3 > rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
void positionElementRelative(std::shared_ptr< ElementBase >)
void merge(OpalBeamline &rhs)
bool compatibilityPlacementCompiled_m
unsigned long getFieldAt(const unsigned int &, const Vector_t< double, 3 > &, const long &, const double &, Vector_t< double, 3 > &, Vector_t< double, 3 > &)
CoordinateSystemTrafo getNominalExitTransform(const std::shared_ptr< Component > &comp) const
CoordinateSystemTrafo coordTransformationTo_m
CoordinateSystemTrafo getNominalEntryTransform(const std::shared_ptr< Component > &comp) const
PlacedElement getPlacedElement(const std::shared_ptr< Component > &comp) const
Return the placed-element view used by the bridge stage.
void prepareSections()
void print(Inform &) const
void compute3DLattice()
Vector_t< double, 3 > transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
void setNominalPlacement(const std::shared_ptr< ElementBase > &element, const CoordinateSystemTrafo &parentToBody)
Update the nominal rigid placement transform of one element.
void switchElements(const double &, const double &, const double &kineticEnergy, const bool &nomonitors=false)
void compileCompatibilityPlacement()
Compile legacy reference-order placement into explicit nominal poses.
void switchElementsOff()
void storePlacedElement(const std::shared_ptr< ElementBase > &element)
Refresh the beamline-owned placed-element assembly record.
FieldList elements_m
CoordinateSystemTrafo getCSTrafoLab2Local() const
Vector_t< double, 3 > rotateFromLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
void activateElements()
PlacementAssembly placementAssembly_m
std::set< std::shared_ptr< Component > > getElements()
void swap(OpalBeamline &rhs)
std::string getInputBasename()
get input file name without extension
Definition OpalData.cpp:571
OpenMode getOpenMode() const
Definition OpalData.cpp:300
static OpalData * getInstance()
Definition OpalData.cpp:193
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
Definition OpalData.cpp:567
Geometric placement record for an element instance.
CoordinateSystemTrafo getNominalBodyTransform() const
Nominal rigid placement transform.
Quaternion storage and rotation algebra used by OPALX geometry code.
Quaternion conjugate() const
Return the quaternion conjugate .
ippl::Vector< double, 3 > rotate(const ippl::Vector< double, 3 > &) const
Rotate a spatial vector by a unit quaternion.
bool idealized
Definition Options.cpp:95
constexpr double rad2deg
Definition Units.h:146
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition Util.cpp:193
Vector_t< double, 3 > getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition Util.cpp:110