OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
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
20#include "AbsBeamline/Bend2D.h"
22#include "Physics/Units.h"
24#include "Utilities/Options.h"
25#include "Utilities/Util.h"
26
27#include <algorithm>
28#include <cmath>
29#include <cstdio>
30#include <filesystem>
31#include <fstream>
32#include <iomanip>
33#include <memory>
34#include <regex>
35#include <string>
36#include <vector>
37
39 elements_m(),
40 prepared_m(false),
41 containsSource_m(false)
42{
43}
44
46 const Quaternion& rotation):
47 elements_m(),
48 prepared_m(false),
49 containsSource_m(false),
50 coordTransformationTo_m(origin, rotation)
51{
52}
53
57
58std::set<std::shared_ptr<Component>> OpalBeamline::getElements(const Vector_t &x) {
59 std::set<std::shared_ptr<Component> > elementSet;
60 FieldList::iterator it = elements_m.begin();
61 const FieldList::iterator end = elements_m.end();
62 for (; it != end; ++ it) {
63 std::shared_ptr<Component> element = (*it).getElement();
64 Vector_t r = element->getCSTrafoGlobal2Local().transformTo(x);
65
66 if (element->isInside(r)) {
67 elementSet.insert(element);
68 }
69 }
70
71 return elementSet;
72}
73
74unsigned long OpalBeamline::getFieldAt(const unsigned int &/*index*/, const Vector_t &/*pos*/, const long &/*sindex*/, const double &/*t*/, Vector_t &/*E*/, Vector_t &/*B*/) {
75
76 unsigned long rtv = 0x00;
77
78 return rtv;
79}
80
81unsigned long OpalBeamline::getFieldAt(const Vector_t &position,
82 const Vector_t &momentum,
83 const double &t,
84 Vector_t &Ef,
85 Vector_t &Bf) {
86 unsigned long rtv = 0x00;
87
88 std::set<std::shared_ptr<Component>> elements = getElements(position);
89
90 std::set<std::shared_ptr<Component>>::const_iterator it = elements.begin();
91 const std::set<std::shared_ptr<Component>>::const_iterator end = elements.end();
92
93 for (; it != end; ++ it) {
94 ElementType type = (*it)->getType();
95 if (type == ElementType::MONITOR ||
96 type == ElementType::MARKER ||
97 type == ElementType::CCOLLIMATOR) continue;
98
99 Vector_t localR = transformToLocalCS(*it, position);
100 Vector_t localP = rotateToLocalCS(*it, momentum);
101 Vector_t localE(0.0), localB(0.0);
102
103 (*it)->applyToReferenceParticle(localR, localP, t, localE, localB);
104
105 Ef += rotateFromLocalCS(*it, localE);
106 Bf += rotateFromLocalCS(*it, localB);
107 }
108
109 // if(section.hasWake()) {
110 // rtv |= BEAMLINE_WAKE;
111 // }
112 // if(section.hasParticleMatterInteraction()) {
113 // rtv |= BEAMLINE_PARTICLEMATTERINTERACTION;
114 // }
115
116 return rtv;
117}
118
119void OpalBeamline::switchElements(const double &min, const double &max, const double &kineticEnergy, const bool &nomonitors) {
120
121 FieldList::iterator fprev;
122 for(FieldList::iterator flit = elements_m.begin(); flit != elements_m.end(); ++ flit) {
123 // don't set online monitors if the centroid of the bunch is allready inside monitor
124 // or if explicitly not desired (eg during auto phasing)
125 if(flit->getElement()->getType() == ElementType::MONITOR) {
126 double spos = (max + min) / 2.;
127 if(!nomonitors && spos < (*flit).getStart()) {
128 if(!(*flit).isOn() && max > (*flit).getStart()) {
129 (*flit).setOn(kineticEnergy);
130 }
131 }
132
133 } else {
134 if(!(*flit).isOn() && max > (*flit).getStart() && min < (*flit).getEnd()) {
135 (*flit).setOn(kineticEnergy);
136 }
137
138 //check if multiple degraders follow one another with no other elements in between
139 //if element is off and it is a degrader
140 if (!(*flit).isOn() && flit->getElement()->getType() == ElementType::DEGRADER) {
141 //check if previous element: is on, is a degrader, ends where new element starts
142 if ((*fprev).isOn() && fprev->getElement()->getType() == ElementType::DEGRADER &&
143 ((*fprev).getEnd() + 0.01 > (*flit).getStart()) ) {
144 (*flit).setOn(kineticEnergy);
145 }
146 }
147 }
148
149 fprev = flit;
150 }
151}
152
154 for(FieldList::iterator flit = elements_m.begin(); flit != elements_m.end(); ++ flit)
155 (*flit).setOff();
156}
157
159 if (elements_m.empty()) {
160 prepared_m = true;
161 return;
162 }
164 prepared_m = true;
165}
166
167void OpalBeamline::print(Inform &/*msg*/) const {
168}
169
171 std::swap(elements_m, rhs.elements_m);
172 std::swap(prepared_m, rhs.prepared_m);
174}
175
177 elements_m.insert(elements_m.end(),
178 rhs.elements_m.begin(),
179 rhs.elements_m.end());
180 prepared_m = false;
182}
183
184
186 if (type == ElementType::ANY) {
187 return elements_m;
188 }
189
190 FieldList elements_of_requested_type;
191 for(FieldList::iterator fit = elements_m.begin(); fit != elements_m.end(); ++ fit) {
192 if((*fit).getElement()->getType() == type) {
193 elements_of_requested_type.push_back((*fit));
194 }
195 }
196 return elements_of_requested_type;
197}
198
199void OpalBeamline::positionElementRelative(std::shared_ptr<ElementBase> element) {
200 if (!element->isPositioned()) {
201 return;
202 }
203
204 element->releasePosition();
205 CoordinateSystemTrafo toElement = element->getCSTrafoGlobal2Local();
206 toElement *= coordTransformationTo_m;
207
208 element->setCSTrafoGlobal2Local(toElement);
209 element->fixPosition();
210}
211
213 static unsigned int order = 0;
214 const FieldList::iterator end = elements_m.end();
215
216 unsigned int minOrder = order;
217 {
218 double endPriorPathLength = 0.0;
220
221 FieldList::iterator it = elements_m.begin();
222 for (; it != end; ++ it) {
223 std::shared_ptr<Component> element = (*it).getElement();
224 if (element->isPositioned()) {
225 continue;
226 }
227 (*it).order_m = minOrder;
228
229 if (element->getType() != ElementType::SBEND &&
230 element->getType() != ElementType::RBEND &&
231 element->getType() != ElementType::RBEND3D) {
232 continue;
233 }
234
235 double beginThisPathLength = element->getElementPosition();
236 Vector_t beginThis3D({0, 0, beginThisPathLength - endPriorPathLength});
237 BendBase * bendElement = static_cast<BendBase*>(element.get());
238 double thisLength = bendElement->getChordLength();
239 double bendAngle = bendElement->getBendAngle();
240 double entranceAngle = bendElement->getEntranceAngle();
241 double arcLength = (thisLength * std::abs(bendAngle) / (2 * sin(std::abs(bendAngle) / 2)));
242
243 double rotationAngleAboutZ = bendElement->getRotationAboutZ();
244 Quaternion_t rotationAboutZ(cos(0.5 * rotationAngleAboutZ),
245 sin(-0.5 * rotationAngleAboutZ) * Vector_t({0, 0, 1}));
246
247 Vector_t effectiveRotationAxis = rotationAboutZ.rotate(Vector_t({0, -1, 0}));
248 effectiveRotationAxis /= euclidean_norm(effectiveRotationAxis);
249
250 Quaternion_t rotationAboutAxis(cos(0.5 * bendAngle),
251 sin(0.5 * bendAngle) * effectiveRotationAxis);
252 Quaternion_t halfRotationAboutAxis(cos(0.25 * bendAngle),
253 sin(0.25 * bendAngle) * effectiveRotationAxis);
254 Quaternion_t entryFaceRotation(cos(0.5 * entranceAngle),
255 sin(0.5 * entranceAngle) * effectiveRotationAxis);
256
257 if (!Options::idealized) {
258 std::vector<Vector_t> truePath = bendElement->getDesignPath();
259 Quaternion_t directionExitHardEdge(cos(0.5 * (0.5 * bendAngle - entranceAngle)),
260 sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
261 Vector_t exitHardEdge = thisLength * directionExitHardEdge.rotate(Vector_t({0, 0, 1}));
262 double distanceEntryHETruePath = euclidean_norm(truePath.front());
263 double distanceExitHETruePath = euclidean_norm(rotationAboutZ.rotate(truePath.back()) - exitHardEdge);
264 double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
265 arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
266 }
267
268 Vector_t chord = thisLength * halfRotationAboutAxis.rotate(Vector_t({0, 0, 1}));
269 Vector_t endThis3D = beginThis3D + chord;
270 double endThisPathLength = beginThisPathLength + arcLength;
271
272 CoordinateSystemTrafo fromEndLastToBeginThis(beginThis3D,
273 (entryFaceRotation * rotationAboutZ).conjugate());
274 CoordinateSystemTrafo fromEndLastToEndThis(endThis3D,
275 rotationAboutAxis.conjugate());
276
277 element->setCSTrafoGlobal2Local(fromEndLastToBeginThis * currentCoordTrafo);
278
279 currentCoordTrafo = (fromEndLastToEndThis * currentCoordTrafo);
280
281 endPriorPathLength = endThisPathLength;
282 }
283 }
284
285 double endPriorPathLength = 0.0;
287
288 FieldList::iterator it = elements_m.begin();
289 for (; it != end; ++ it) {
290 std::shared_ptr<Component> element = (*it).getElement();
291 if (element->isPositioned()) continue;
292
293 (*it).order_m = order ++;
294
295 double beginThisPathLength = element->getElementPosition();
296 double thisLength = element->getElementLength();
297 Vector_t beginThis3D({0, 0, beginThisPathLength - endPriorPathLength});
298
299 if (element->getType() == ElementType::SOURCE) {
300 beginThis3D(2) -= thisLength;
301 }
302
303 Vector_t endThis3D;
304 if (element->getType() == ElementType::SBEND ||
305 element->getType() == ElementType::RBEND ||
306 element->getType() == ElementType::RBEND3D) {
307
308 BendBase * bendElement = static_cast<BendBase*>(element.get());
309 thisLength = bendElement->getChordLength();
310 double bendAngle = bendElement->getBendAngle();
311
312 double rotationAngleAboutZ = bendElement->getRotationAboutZ();
313 Quaternion_t rotationAboutZ(cos(0.5 * rotationAngleAboutZ),
314 sin(-0.5 * rotationAngleAboutZ) * Vector_t({0, 0, 1}));
315
316 Vector_t effectiveRotationAxis = rotationAboutZ.rotate(Vector_t({0, -1, 0}));
317 effectiveRotationAxis /= euclidean_norm(effectiveRotationAxis);
318
319 Quaternion_t rotationAboutAxis(cos(0.5 * bendAngle),
320 sin(0.5 * bendAngle) * effectiveRotationAxis);
321 Quaternion halfRotationAboutAxis(cos(0.25 * bendAngle),
322 sin(0.25 * bendAngle) * effectiveRotationAxis);
323
324 double arcLength = (thisLength * std::abs(bendAngle) /
325 (2 * sin(bendAngle / 2)));
326 if (!Options::idealized) {
327 std::vector<Vector_t> truePath = bendElement->getDesignPath();
328 double entranceAngle = bendElement->getEntranceAngle();
329 Quaternion_t directionExitHardEdge(cos(0.5 * (0.5 * bendAngle - entranceAngle)),
330 sin(0.5 * (0.5 * bendAngle - entranceAngle)) * effectiveRotationAxis);
331 Vector_t exitHardEdge = thisLength * directionExitHardEdge.rotate(Vector_t({0, 0, 1}));
332 double distanceEntryHETruePath = euclidean_norm(truePath.front());
333 double distanceExitHETruePath = euclidean_norm(rotationAboutZ.rotate(truePath.back()) - exitHardEdge);
334 double pathLengthTruePath = (*it).getEnd() - (*it).getStart();
335 arcLength = pathLengthTruePath - distanceEntryHETruePath - distanceExitHETruePath;
336 }
337
338 endThis3D = (beginThis3D +
339 halfRotationAboutAxis.rotate(Vector_t({0, 0, thisLength})));
340 CoordinateSystemTrafo fromEndLastToEndThis(endThis3D,
341 rotationAboutAxis.conjugate());
342 currentCoordTrafo = fromEndLastToEndThis * currentCoordTrafo;
343
344 endPriorPathLength = beginThisPathLength + arcLength;
345 } else {
346 double rotationAngleAboutZ = (*it).getElement()->getRotationAboutZ();
347 Quaternion_t rotationAboutZ(cos(0.5 * rotationAngleAboutZ),
348 sin(-0.5 * rotationAngleAboutZ) * Vector_t({0, 0, 1}));
349
350 CoordinateSystemTrafo fromLastToThis(beginThis3D, rotationAboutZ);
351
352 element->setCSTrafoGlobal2Local(fromLastToThis * currentCoordTrafo);
353 }
354
355 element->fixPosition();
356 }
357}
358
360 if (Ippl::myNode() != 0 || OpalData::getInstance()->isOptimizerRun()) return;
361
362 elements_m.sort([](const ClassicField& a, const ClassicField& b) {
363 return a.order_m < b.order_m;
364 });
365
366 FieldList::iterator it = elements_m.begin();
367 FieldList::iterator end = elements_m.end();
368
369 std::ofstream pos;
370 std::string fileName = Util::combineFilePath({
372 OpalData::getInstance()->getInputBasename() + "_ElementPositions.txt"
373 });
375 std::filesystem::exists(fileName)) {
376 pos.open(fileName, std::ios_base::app);
377 } else {
378 pos.open(fileName);
379 }
380
381 MeshGenerator mesh;
382 for (; it != end; ++ it) {
383 std::shared_ptr<Component> element = (*it).getElement();
384 CoordinateSystemTrafo toBegin = element->getEdgeToBegin() * element->getCSTrafoGlobal2Local();
385 CoordinateSystemTrafo toEnd = element->getEdgeToEnd() * element->getCSTrafoGlobal2Local();
386 Vector_t entry3D = toBegin.getOrigin();
387 Vector_t exit3D = toEnd.getOrigin();
388
389 mesh.add(*(element.get()));
390
391 if (element->getType() == ElementType::SBEND ||
392 element->getType() == ElementType::RBEND) {
393
394 Bend2D * bendElement = static_cast<Bend2D*>(element.get());
395 std::vector<Vector_t> designPath = bendElement->getDesignPath();
396 toEnd = bendElement->getBeginToEnd_local() * element->getCSTrafoGlobal2Local();
397 exit3D = toEnd.getOrigin();
398
399 unsigned int size = designPath.size();
400 unsigned int minNumSteps = std::max(20.0,
401 std::abs(bendElement->getBendAngle() * Units::rad2deg));
402 unsigned int frequency = std::floor((double)size / minNumSteps);
403
404 pos << std::setw(30) << std::left << std::string("\"ENTRY EDGE: ") + element->getName() + std::string("\"")
405 << std::setw(18) << std::setprecision(10) << entry3D(2)
406 << std::setw(18) << std::setprecision(10) << entry3D(0)
407 << std::setw(18) << std::setprecision(10) << entry3D(1)
408 << "\n";
409
410 Vector_t position = element->getCSTrafoGlobal2Local().transformFrom(designPath.front());
411 pos << std::setw(30) << std::left << std::string("\"BEGIN: ") + element->getName() + std::string("\"")
412 << std::setw(18) << std::setprecision(10) << position(2)
413 << std::setw(18) << std::setprecision(10) << position(0)
414 << std::setw(18) << std::setprecision(10) << position(1)
415 << std::endl;
416
417 for (unsigned int i = frequency; i + 1 < size; i += frequency) {
418
419 position = element->getCSTrafoGlobal2Local().transformFrom(designPath[i]);
420 pos << std::setw(30) << std::left << std::string("\"MID: ") + element->getName() + std::string("\"")
421 << std::setw(18) << std::setprecision(10) << position(2)
422 << std::setw(18) << std::setprecision(10) << position(0)
423 << std::setw(18) << std::setprecision(10) << position(1)
424 << std::endl;
425 }
426
427 position = element->getCSTrafoGlobal2Local().transformFrom(designPath.back());
428 pos << std::setw(30) << std::left << std::string("\"END: ") + element->getName() + std::string("\"")
429 << std::setw(18) << std::setprecision(10) << position(2)
430 << std::setw(18) << std::setprecision(10) << position(0)
431 << std::setw(18) << std::setprecision(10) << position(1)
432 << std::endl;
433
434 pos << std::setw(30) << std::left << std::string("\"EXIT EDGE: ") + element->getName() + std::string("\"")
435 << std::setw(18) << std::setprecision(10) << exit3D(2)
436 << std::setw(18) << std::setprecision(10) << exit3D(0)
437 << std::setw(18) << std::setprecision(10) << exit3D(1)
438 << std::endl;
439 } else {
440 pos << std::setw(30) << std::left << std::string("\"BEGIN: ") + element->getName() + std::string("\"")
441 << std::setw(18) << std::setprecision(10) << entry3D(2)
442 << std::setw(18) << std::setprecision(10) << entry3D(0)
443 << std::setw(18) << std::setprecision(10) << entry3D(1)
444 << "\n";
445
446 pos << std::setw(30) << std::left << std::string("\"END: ") + element->getName() + std::string("\"")
447 << std::setw(18) << std::setprecision(10) << exit3D(2)
448 << std::setw(18) << std::setprecision(10) << exit3D(0)
449 << std::setw(18) << std::setprecision(10) << exit3D(1)
450 << std::endl;
451 }
452 }
454 mesh.write(OpalData::getInstance()->getInputBasename());
455}
456
457namespace {
458 std::string parseInput() {
459
460 std::ifstream in(OpalData::getInstance()->getInputFn());
461 std::string source("");
462 std::string str;
463 char testBit;
464 const std::string commentFormat("");
465 const std::regex empty("^[ \t]*$");
466 const std::regex lineEnd(";");
467 const std::string lineEndFormat(";\n");
468 const std::regex cppCommentExpr("//.*");
469 const std::regex cCommentExpr("/\\*.*?\\*/"); // "/\\*(?>[^*/]+|\\*[^/]|/[^*])*(?>(?R)(?>[^*/]+|\\*[^/]|/[^*])*)*\\*/"
470 bool priorEmpty = true;
471
472 in.get(testBit);
473 while (!in.eof()) {
474 in.putback(testBit);
475
476 std::getline(in, str);
477 str = std::regex_replace(str, cppCommentExpr, commentFormat);
478 str = std::regex_replace(str, empty, commentFormat);
479 if (!str.empty()) {
480 source += str;// + '\n';
481 priorEmpty = false;
482 } else if (!priorEmpty) {
483 source += "##EMPTY_LINE##";
484 priorEmpty = true;
485 }
486
487 in.get(testBit);
488 }
489
490 source = std::regex_replace(source, cCommentExpr, commentFormat);
491 source = std::regex_replace(source, lineEnd, lineEndFormat, std::regex_constants::match_default |std::regex_constants::format_default);
492
493 // Since the positions of the elements are absolute in the laboratory coordinate system we have to make
494 // sure that the line command doesn't provide an origin and orientation. Everything after the sequence of
495 // elements can be deleted and only "LINE = (...);", the first sub-expression (denoted by '\1'), should be kept.
496 const std::regex lineCommand("(LINE[ \t]*=[ \t]*\\([^\\)]*\\))[ \t]*,[^;]*;", std::regex::icase);
497 const std::string firstSubExpression("\\1;");
498 source = std::regex_replace(source, lineCommand, firstSubExpression);
499
500 return source;
501 }
502
503 unsigned int getMinimalSignificantDigits(double num, const unsigned int maxDigits) {
504 char buf[32];
505 snprintf(buf, 32, "%.*f", maxDigits + 1, num);
506 std::string numStr(buf);
507 unsigned int length = numStr.length();
508
509 unsigned int numDigits = maxDigits;
510 unsigned int i = 2;
511 while (i < maxDigits + 1 && numStr[length - i] == '0') {
512 --numDigits;
513 ++ i;
514 }
515
516 return numDigits;
517 }
518
519 std::string round2string(double num, const unsigned int maxDigits) {
520 char buf[64];
521
522 snprintf(buf, 64, "%.*f", getMinimalSignificantDigits(num, maxDigits), num);
523
524 return std::string(buf);
525 }
526}
527
529 if (Ippl::myNode() != 0 || OpalData::getInstance()->isOptimizerRun()) return;
530
531 FieldList::iterator it = elements_m.begin();
532 FieldList::iterator end = elements_m.end();
533
534 std::string input = parseInput();
535 std::string fname = Util::combineFilePath({
538 });
539 std::ofstream pos(fname);
540
541 for (; it != end; ++ it) {
542 std::shared_ptr<Component> element = (*it).getElement();
543 std::string elementName = element->getName();
544 const std::regex replacePSI("(" + elementName + "\\s*:[^\\n]*)PSI\\s*=[^,;]*,?", std::regex::icase);
545 input = std::regex_replace(input, replacePSI, "\\1\\2");
546
547 const std::regex replaceELEMEDGE("(" + elementName + "\\s*:[^\\n]*)ELEMEDGE\\s*=[^,;]*(.)", std::regex::icase);
548
549 CoordinateSystemTrafo cst = element->getCSTrafoGlobal2Local();
550 Vector_t origin = cst.getOrigin();
551 Vector_t orient = Util::getTaitBryantAngles(cst.getRotation().conjugate(), elementName);
552 for (unsigned int d = 0; d < 3; ++ d)
553 orient(d) *= Units::rad2deg;
554
555 std::string x = (std::abs(origin(0)) > 1e-10? "X = " + round2string(origin(0), 10) + ", ": "");
556 std::string y = (std::abs(origin(1)) > 1e-10? "Y = " + round2string(origin(1), 10) + ", ": "");
557 std::string z = (std::abs(origin(2)) > 1e-10? "Z = " + round2string(origin(2), 10) + ", ": "");
558
559 std::string theta = (orient(0) > 1e-10? "THETA = " + round2string(orient(0), 6) + " * PI / 180, ": "");
560 std::string phi = (orient(1) > 1e-10? "PHI = " + round2string(orient(1), 6) + " * PI / 180, ": "");
561 std::string psi = (orient(2) > 1e-10? "PSI = " + round2string(orient(2), 6) + " * PI / 180, ": "");
562 std::string coordTrafo = x + y + z + theta + phi + psi;
563 if (coordTrafo.length() > 2) {
564 coordTrafo = coordTrafo.substr(0, coordTrafo.length() - 2); // remove last ', '
565 }
566
567 std::string position = ("\\1" + coordTrafo + "\\2");
568
569 input = std::regex_replace(input, replaceELEMEDGE, position);
570
571 if (element->getType() == ElementType::RBEND ||
572 element->getType() == ElementType::SBEND) {
573 const Bend2D* dipole = static_cast<const Bend2D*>(element.get());
574 double angle = dipole->getBendAngle();
575 double E1 = dipole->getEntranceAngle();
576 double E2 = dipole->getExitAngle();
577
578 const std::regex angleR("(" + elementName + "\\s*:[^\\n]*ANGLE\\s*=)[^,;]*(.)");
579 const std::string angleF("\\1 " + round2string(angle * Units::rad2deg, 6) + " / 180 * PI\\2");
580 const std::regex E1R("(" + elementName + "\\s*:[^\\n]*E1\\s*=)[^,;]*(.)");
581 const std::string E1F("\\1 " + round2string(E1 * Units::rad2deg, 6) + " / 180 * PI\\2");
582 const std::regex E2R("(" + elementName + "\\s*:[^\\n]*E2\\s*=)[^,;]*(.)");
583 const std::string E2F("\\1 " + round2string(E2 * Units::rad2deg, 6) + " / 180 * PI\\2");
584 const std::regex noRotation("(" + elementName + "\\s*:[^\\n]*),\\s*ROTATION\\s*=[^,;]*(.)");
585 const std::string noRotationFormat("\\1\\2 ");
586
587 input = std::regex_replace(input, angleR, angleF);
588 input = std::regex_replace(input, E1R, E1F);
589 input = std::regex_replace(input, E2R, E2F);
590 input = std::regex_replace(input, noRotation, noRotationFormat);
591 }
592 }
593
594 const std::regex empty("##EMPTY_LINE##");
595 const std::string emptyFormat("\n");
596 input = std::regex_replace(input, empty, emptyFormat);
597
598 pos << input << std::endl;
599}
600
602 auto it = elements_m.begin();
603 const auto end = elements_m.end();
604
605 double designEnergy = 0.0;
606 for (; it != end; ++ it) {
607 std::shared_ptr<Component> element = (*it).getElement();
608 if (element->getType() == ElementType::SBEND ||
609 element->getType() == ElementType::RBEND) {
610 Bend2D * bendElement = static_cast<Bend2D*>(element.get());
611 designEnergy = bendElement->getDesignEnergy() * Units::eV2MeV;
612 }
613 (*it).setOn(designEnergy);
614 // element->goOnline(designEnergy);
615 }
616}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
ElementType
Definition ElementBase.h:89
std::list< ClassicField > FieldList
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition TpsMath.h:129
Tps< T > sin(const Tps< T > &x)
Sine.
Definition TpsMath.h:111
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition Vector.h:243
elements
Definition IndexMap.cpp:163
std::complex< double > a
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
constexpr double eV2MeV
Definition Units.h:77
constexpr double rad2deg
Definition Units.h:146
bool idealized
Definition Options.cpp:91
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition Util.cpp:200
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition Util.cpp:120
std::string getInputBasename()
get input file name without extension
Definition OpalData.cpp:674
OpenMode getOpenMode() const
Definition OpalData.cpp:353
static OpalData * getInstance()
Definition OpalData.cpp:196
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
Definition OpalData.cpp:666
virtual double getExitAngle() const override
Definition Bend2D.h:326
CoordinateSystemTrafo getBeginToEnd_local() const
Definition Bend2D.h:354
std::vector< Vector_t > getDesignPath() const
Definition BendBase.cpp:43
double getChordLength() const
Definition BendBase.h:82
double getBendAngle() const
Definition BendBase.h:92
double getDesignEnergy() const
Definition BendBase.h:126
double getEntranceAngle() const
Definition BendBase.h:103
double getRotationAboutZ() const
Quaternion getRotation() const
Vector_t rotate(const Vector_t &) const
Quaternion conjugate() const
Definition Quaternion.h:103
void add(const ElementBase &element)
void write(const std::string &fname)
static bool SortAsc(const ClassicField &fle1, const ClassicField &fle2)
unsigned int order_m
FieldList getElementByType(ElementType)
Vector_t rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
void positionElementRelative(std::shared_ptr< ElementBase >)
bool containsSource_m
void merge(OpalBeamline &rhs)
Vector_t transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
Vector_t rotateFromLocalCS(const std::shared_ptr< Component > &comp, const Vector_t &r) const
CoordinateSystemTrafo coordTransformationTo_m
void prepareSections()
void print(Inform &) const
void compute3DLattice()
void switchElements(const double &, const double &, const double &kineticEnergy, const bool &nomonitors=false)
void switchElementsOff()
unsigned long getFieldAt(const unsigned int &, const Vector_t &, const long &, const double &, Vector_t &, Vector_t &)
FieldList elements_m
void activateElements()
std::set< std::shared_ptr< Component > > getElements(const Vector_t &x)
void swap(OpalBeamline &rhs)
static int myNode()
Definition IpplInfo.cpp:691
Vektor< double, 3 > Vector_t
Definition Vektor.h:6