41#define HITMATERIAL 0x80000000
43#define EVERYTHINGFINE 0x00000000
54 stepSizes_m(stepSizes),
55 zstop_m(stepSizes.getFinalZStop() +
std::copysign(1.0, dt) * 2 * maxDiffZBunch),
56 itsOpalBeamline_m(bl),
61 if (ippl::Comm->rank() == 0 && !opal->isOptimizerRun()) {
63 {opal->getAuxiliaryOutputDirectory(),
64 opal->getInputBasename() +
"_DesignPath.dat"});
66 || !std::filesystem::exists(fileName)) {
68 logger_m <<
"#" << std::setw(17) <<
"1 - s" << std::setw(18) <<
"2 - Rx"
69 << std::setw(18) <<
"3 - Ry" << std::setw(18) <<
"4 - Rz" << std::setw(18)
70 <<
"5 - Px" << std::setw(18) <<
"6 - Py" << std::setw(18) <<
"7 - Pz"
71 << std::setw(18) <<
"8 - Efx" << std::setw(18) <<
"9 - Efy" << std::setw(18)
72 <<
"10 - Efz" << std::setw(18) <<
"11 - Bfx" << std::setw(18) <<
"12 - Bfy"
73 << std::setw(18) <<
"13 - Bfz" << std::setw(18) <<
"14 - Ekin" << std::setw(18)
74 <<
"15 - t" << std::endl;
76 logger_m.open(fileName, std::ios_base::app);
102 for (
const std::shared_ptr<Component>& field : fields) {
103 double fieldBegin = 0.0;
104 double fieldEnd = 0.0;
105 field->getFieldExtend(fieldBegin, fieldEnd);
107 const double length = std::abs(fieldEnd - fieldBegin);
108 const int numSteps = field->getRequiredNumberOfTimeSteps();
110 if (length < numSteps * driftLength) {
112 "The time step is too long compared to the length of the\n"
113 "element '" + field->getName() +
"'\n" +
114 "The field-support extent of the element is: "
115 + std::to_string(length) +
"\n"
116 "The distance the particles drift in " + std::to_string(numSteps) +
117 " time step(s) is: " + std::to_string(numSteps * driftLength));
126 std::set<std::string> visitedElements;
138 std::set<std::shared_ptr<Component>> intersection, currentSet;
141 *
gmsg <<
"* OrbitThreader dt_m= " <<
dt_m << endl;
156 *
gmsg <<
"* OrbitThreader maxDistance= " << maxDistance << endl;
157 *
gmsg <<
"* OrbitThreader #elements = " << elementSet.size() << endl;
169 IndexMap::value_t::const_iterator it = elementSet.begin();
170 const IndexMap::value_t::const_iterator end = elementSet.end();
171 for (; it != end; ++it) {
172 visitedElements.insert((*it)->getName());
177 currentSet = elementSet;
185 intersection.clear();
186 std::set_intersection(
187 currentSet.begin(), currentSet.end(), elementSet.begin(), elementSet.end(),
188 std::inserter(intersection, intersection.begin()));
191 && !(elementSet.empty() || currentSet.empty())));
205 IndexMap::value_t::const_iterator it = activeSet.begin();
206 const IndexMap::value_t::const_iterator end = activeSet.end();
214 std::string names(
"\t");
215 for (; it != end; ++it) {
220 if ((*it)->applyToReferenceParticle(
221 localR, localP,
time_m + 0.5 *
dt_m, localE, localB)) {
225 names += (*it)->getName() +
", ";
236 logger_m << std::setw(18) << std::setprecision(8)
238 << std::setprecision(8) <<
r_m(0) << std::setw(18) << std::setprecision(8)
239 <<
r_m(1) << std::setw(18) << std::setprecision(8) <<
r_m(2) << std::setw(18)
240 << std::setprecision(8) <<
p_m(0) << std::setw(18) << std::setprecision(8)
241 <<
p_m(1) << std::setw(18) << std::setprecision(8) <<
p_m(2) << std::setw(18)
242 << std::setprecision(8) << Ef(0) << std::setw(18) << std::setprecision(8)
243 << Ef(1) << std::setw(18) << std::setprecision(8) << Ef(2) << std::setw(18)
244 << std::setprecision(8) << Bf(0) << std::setw(18) << std::setprecision(8)
245 << Bf(1) << std::setw(18) << std::setprecision(8) << Bf(2) << std::setw(18)
246 << std::setprecision(8)
249 << names << std::endl;
268 if (activeSet.empty()
280 IndexMap::value_t::const_iterator it = activeSet.begin();
281 const IndexMap::value_t::const_iterator end = activeSet.end();
283 for (; it != end; ++it) {
294 const IndexMap::value_t& activeSet,
const std::set<std::string>& visitedElements) {
297 IndexMap::value_t::const_iterator it = activeSet.begin();
298 const IndexMap::value_t::const_iterator end = activeSet.end();
300 for (; it != end; ++it) {
303 && visitedElements.find((*it)->getName()) == visitedElements.end()) {
314 IndexMap::value_t::const_iterator it = elementSet.begin();
315 const IndexMap::value_t::const_iterator end = elementSet.end();
317 double designEnergy = 0.0;
318 for (; it != end; ++it) {
360 IndexMap::value_t::const_iterator it = elementSet.begin();
361 const IndexMap::value_t::const_iterator end = elementSet.end();
363 for (; it != end; ++it) {
367 for (
auto pit = prior.first; pit != prior.second; ++pit) {
368 if (std::abs((*pit).second.endField_m - start) < 1e-10) {
379 double elementEdge = start - initialR(2) *
euclidean_norm(initialP) / initialP(2);
387 using registry_key_t = std::shared_ptr<Component>;
388 using registry_map_t = std::map<
389 registry_key_t, std::set<elementPosition, elementPositionComp>,
390 std::owner_less<registry_key_t>>;
391 registry_map_t tmpRegistry;
394 const registry_key_t& element = (*it).first;
397 auto prior = tmpRegistry.find(element);
398 if (prior == tmpRegistry.end()) {
399 std::set<elementPosition, elementPositionComp> tmpSet;
401 tmpRegistry.insert(std::make_pair(element, tmpSet));
405 std::set<elementPosition, elementPositionComp>& set = (*prior).second;
410 std::vector<ReferencePathSegment> registeredSegments;
411 for (
auto& [element, set] : tmpRegistry) {
412 std::queue<std::pair<double, double>> range;
414 for (
auto sit = set.begin(); sit != set.end(); ++sit) {
415 range.push(std::make_pair((*sit).elementEdge_m, (*sit).endField_m));
417 (*sit).startField_m, (*sit).endField_m,
420 element->setActionRange(range);
424 registeredSegments.begin(), registeredSegments.end(),
426 if (lhs.getBegin() < rhs.getBegin()) {
435 for (
const auto& segment : registeredSegments) {
436 actionRangeRegistrationModel_m.addSegment(segment);
441 FieldList& allElements,
const std::set<std::string>& visitedElements) {
444 FieldList::iterator it = allElements.begin();
445 const FieldList::iterator end = allElements.end();
446 for (; it != end; ++it) {
447 std::shared_ptr<Component> element = (*it).getElement();
448 if (visitedElements.find(element->getName()) == visitedElements.end()
451 element->setDesignEnergy(kineticEnergyeV);
458 FieldList::iterator it = allElements.begin();
459 const FieldList::iterator end = allElements.end();
460 for (; it != end; ++it) {
464 BoundingBox other = it->getBoundingBoxInLabCoords();
472 std::array<Vector_t<double, 3>, 2> positions = {
r_m - 10 * dR,
r_m + 10 * dR};
484 std::optional<Vector_t<double, 3>> intersectionPoint =
486 if (intersectionPoint) {
493 return std::numeric_limits<double>::max();
std::list< BeamlineFieldElement > FieldList
ippl::Vector< T, Dim > Vector_t
ippl::Vector< T, Dim > Vector
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
KOKKOS_INLINE_FUNCTION double euclidean_norm(const Vector_t< T, D > &v)
KOKKOS_INLINE_FUNCTION void kick(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &P, const Vector_t< double, 3 > &Ef, const Vector_t< double, 3 > &Bf, const double &dt, const double &mass, const double &charge) const
KOKKOS_INLINE_FUNCTION void push(Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &dt) const
void enlargeToContainPosition(const Vector_t< double, 3 > &position)
std::optional< Vector_t< double, 3 > > getIntersectionPoint(const Vector_t< double, 3 > &position, const Vector_t< double, 3 > &direction) const
void enlargeToContainBoundingBox(const BoundingBox &boundingBox)
double getPhaseAtMaxEnergy(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, double t, double dt)
Rigid spatial transform between a parent frame and a local frame.
void add(key_t::first_type initialStep, key_t::second_type finalStep, const value_t &val)
void tidyUp(double zstop)
std::set< std::shared_ptr< Component > > value_t
void saveSDDS(double startS) const
FieldList getElementByType(ElementType)
Vector_t< double, 3 > rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
CoordinateSystemTrafo getCSTrafoLab2Local(const std::shared_ptr< Component > &comp) const
Return the nominal rigid placement transform .
Vector_t< double, 3 > transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
std::set< std::shared_ptr< Component > > getElements(const Vector_t< double, 3 > &x)
Vector_t< double, 3 > rotateFromLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
static OpalData * getInstance()
void processElementRegister()
Vector_t< double, 3 > r_m
position of reference particle in lab coordinates
Vector_t< double, 3 > p_m
momentum of reference particle
void updateBoundingBoxWithCurrentPosition()
void checkElementLengths(const std::set< std::shared_ptr< Component > > &elements)
void registerElement(const IndexMap::value_t &elementSet, double, const Vector_t< double, 3 > &r, const Vector_t< double, 3 > &p)
double computeDriftLengthToBoundingBox(const std::set< std::shared_ptr< Component > > &elements, const Vector_t< double, 3 > &position, const Vector_t< double, 3 > &direction) const
void setDesignEnergy(FieldList &allElements, const std::set< std::string > &visitedElements)
ValueRange< double > pathLengthRange_m
ValueRange< long > stepRange_m
std::multimap< std::shared_ptr< Component >, elementPosition, std::owner_less< std::shared_ptr< Component > > > elementRegistry_m
double time_m
the simulated time
OpalBeamline & itsOpalBeamline_m
const PartData & reference_m
BoundingBox globalBoundingBox_m
bool containsCavity(const IndexMap::value_t &activeSet)
void integrate(const IndexMap::value_t &activeSet, double maxDrift=10.0)
StepSizeConfig stepSizes_m
final position in path length
double getMaxDesignEnergy(const IndexMap::value_t &elementSet) const
ReferencePathModel actionRangeRegistrationModel_m
double pathLength_m
position of reference particle in path length
void autophaseCavities(const IndexMap::value_t &activeSet, const std::set< std::string > &visitedElements)
void computeBoundingBox()
size_t loggingFrequency_m
OrbitThreader(const PartData &ref, const Vector_t< double, 3 > &r, const Vector_t< double, 3 > &p, double s, double maxDiffZBunch, double t, double dT, StepSizeConfig stepSizes, OpalBeamline &bl)
KOKKOS_INLINE_FUNCTION double getM() const
The constant mass per particle.
KOKKOS_INLINE_FUNCTION double getQ() const
The constant charge per particle.
Interface for standing wave cavities.
virtual double getDesignEnergy() const override
Reference-coordinate interval with optional legacy ELEMEDGE anchor.
std::set< std::shared_ptr< Component > > element_set_t
unsigned long long getNumStepsFinestResolution() const
ValueRange< double > getPathLengthRange() const
bool isOutside(T value) const
void enlargeIfOutside(T value)
bool isInside(T value) const
constexpr double c
The velocity of light in m/s.
std::string combineFilePath(std::initializer_list< std::string > ilist)
double getGamma(ippl::Vector< double, 3 > p)