From d25730490b1466d4faa9b2732ca8521bfb5ed4fb Mon Sep 17 00:00:00 2001 From: Christof Kraus <christof.j.kraus@gmail.com> Date: Thu, 9 Jul 2020 22:43:15 +0200 Subject: [PATCH] current status --- src/Algorithms/OrbitThreader.cpp | 20 +++++- src/Algorithms/OrbitThreader.h | 3 + src/Classic/AbsBeamline/Bend2D.cpp | 12 ++-- src/Classic/AbsBeamline/Bend2D.h | 2 +- src/Classic/AbsBeamline/ElementBase.cpp | 82 ++++++++++++++++++++----- src/Classic/AbsBeamline/ElementBase.h | 22 ++++++- src/Classic/Utilities/ClassicField.h | 5 ++ src/Elements/OpalMarker.cpp | 2 +- src/Elements/OpalRBend.cpp | 2 +- 9 files changed, 121 insertions(+), 29 deletions(-) diff --git a/src/Algorithms/OrbitThreader.cpp b/src/Algorithms/OrbitThreader.cpp index 3559d039d..f24dfc100 100644 --- a/src/Algorithms/OrbitThreader.cpp +++ b/src/Algorithms/OrbitThreader.cpp @@ -86,6 +86,7 @@ OrbitThreader::OrbitThreader(const PartData &ref, void OrbitThreader::execute() { double initialPathLength = pathLength_m; + computeMaximalImplicitDrift2(); double maxDistance = computeMaximalImplicitDrift(); auto allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY); @@ -388,6 +389,22 @@ void OrbitThreader::setDesignEnergy(FieldList &allElements, const std::set<std:: } } +void OrbitThreader::computeMaximalImplicitDrift2() { + FieldList allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY); + FieldList::iterator it = allElements.begin(); + const FieldList::iterator end = allElements.end(); + globalBoundingBox_m.lowerLeftCorner = Vector_t(std::numeric_limits<double>::max()); + globalBoundingBox_m.upperRightCorner = Vector_t(-std::numeric_limits<double>::max()); + + for (; it != end; ++ it) { + if (it->getElement()->getType() == ElementBase::MARKER) { + continue; + } + ElementBase::BoundingBox other = it->getBoundingBoxInLabCoords(); + globalBoundingBox_m.getCombinedBoundingBox(other); + } +} + double OrbitThreader::computeMaximalImplicitDrift() { FieldList allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY); double maxDrift = 0.0; @@ -401,7 +418,6 @@ double OrbitThreader::computeMaximalImplicitDrift() { FieldList::iterator it = allElements.begin(); const FieldList::iterator end = allElements.end(); - for (; it != end; ++ it) { auto element1 = it->getElement(); const auto &toEdge = element1->getCSTrafoGlobal2Local(); @@ -459,4 +475,4 @@ double OrbitThreader::computeMaximalImplicitDrift() { maxDrift = std::min(maxIntegSteps_m * std::abs(dt_m) * Physics::c, maxDrift); return maxDrift; -} +} \ No newline at end of file diff --git a/src/Algorithms/OrbitThreader.h b/src/Algorithms/OrbitThreader.h index 010454157..09fccd121 100644 --- a/src/Algorithms/OrbitThreader.h +++ b/src/Algorithms/OrbitThreader.h @@ -64,6 +64,8 @@ private: std::ofstream logger_m; size_t loggingFrequency_m; + ElementBase::BoundingBox globalBoundingBox_m; + struct elementPosition { double startField_m; double endField_m; @@ -87,6 +89,7 @@ private: void registerElement(const IndexMap::value_t &elementSet, double, const Vector_t &r, const Vector_t &p); void processElementRegister(); void setDesignEnergy(FieldList &allElements, const std::set<std::string> &visitedElements); + void computeMaximalImplicitDrift2(); double computeMaximalImplicitDrift(); }; diff --git a/src/Classic/AbsBeamline/Bend2D.cpp b/src/Classic/AbsBeamline/Bend2D.cpp index 4f64a29f0..56da740a8 100644 --- a/src/Classic/AbsBeamline/Bend2D.cpp +++ b/src/Classic/AbsBeamline/Bend2D.cpp @@ -1682,12 +1682,12 @@ std::array<double,2> Bend2D::getExitFringeFieldLength() const { return extFFL; } -BoundaryBox Bend2D::getBoundaryBoxInLabCoords() const { +ElementBase::BoundingBox Bend2D::getBoundingBoxInLabCoords() const { CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m; CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m; - double &x = aperture_m.second[0]; - double &y = aperture_m.second[1]; + const double &x = aperture_m.second[0]; + const double &y = aperture_m.second[1]; std::vector<Vector_t> corners(8); for (int i = -1; i < 2; i += 2) { @@ -1706,11 +1706,11 @@ BoundaryBox Bend2D::getBoundaryBoxInLabCoords() const { if (bb.lowerLeftCorner(d) > corners[i](d)) { bb.lowerLeftCorner(d) = corners[i](d); } - if (bb.upperLeftCorner(d) < corners[i](d)) { - bb.upperLeftCorner(d) = corners[i](d); + if (bb.upperRightCorner(d) < corners[i](d)) { + bb.upperRightCorner(d) = corners[i](d); } } } return bb; -} +} \ No newline at end of file diff --git a/src/Classic/AbsBeamline/Bend2D.h b/src/Classic/AbsBeamline/Bend2D.h index d8b7638c2..502bf2c09 100644 --- a/src/Classic/AbsBeamline/Bend2D.h +++ b/src/Classic/AbsBeamline/Bend2D.h @@ -129,7 +129,7 @@ public: // Used to create fringe fields in ThickTracker, (before edge[m], after edge[m]) std::array<double,2> getExitFringeFieldLength() const; - BoundaryBox getBoundaryBoxInLabCoords() const override; + BoundingBox getBoundingBoxInLabCoords() const override; protected: void setMessageHeader(const std::string & header); double getStartField() const; diff --git a/src/Classic/AbsBeamline/ElementBase.cpp b/src/Classic/AbsBeamline/ElementBase.cpp index 180a10e7e..540d0731c 100644 --- a/src/Classic/AbsBeamline/ElementBase.cpp +++ b/src/Classic/AbsBeamline/ElementBase.cpp @@ -308,37 +308,87 @@ void ElementBase::setCurrentSCoordinate(double s) { bool ElementBase::isInsideTransverse(const Vector_t &r) const { - double x = aperture_m.second[0]; - double y = aperture_m.second[1]; - double f = 1.0; + const double &xLimit = aperture_m.second[0]; + const double &yLimit = aperture_m.second[1]; + double factor = 1.0; if (aperture_m.first == CONIC_RECTANGULAR || - aperture_m.first == CONIC_ELLIPTIC) { + aperture_m.first == CONIC_ELLIPTICAL) { Vector_t rRelativeToBegin = getEdgeToBegin().transformTo(r); double fractionLength = rRelativeToBegin(2) / getElementLength(); - f = fractionLength * aperture_m.second[2]; + factor = fractionLength * aperture_m.second[2]; } switch(aperture_m.first) { case RECTANGULAR: - return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]); + return (std::abs(r[0]) < xLimit && std::abs(r[1]) < yLimit); case ELLIPTICAL: - return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0); + return (std::pow(r[0] / xLimit, 2) + std::pow(r[1] / yLimit, 2) < 1.0); case CONIC_RECTANGULAR: - return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]); + return (std::abs(r[0]) < factor * xLimit && std::abs(r[1]) < factor * yLimit); case CONIC_ELLIPTICAL: - return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0); + return (std::pow(r[0] / (factor * xLimit), 2) + std::pow(r[1] / (factor * yLimit), 2) < 1.0); default: return false; } } -BoundaryBox ElementBase::getBoundaryBoxInLabCoords() const { +bool ElementBase::BoundingBox::isInside(const Vector_t & position) const { + Vector_t relativePosition = position - lowerLeftCorner; + Vector_t diagonal = upperRightCorner - lowerLeftCorner; + + for (unsigned int d = 0; d < 3; ++ d) { + if (relativePosition[d] < 0.0 || + relativePosition[d] > diagonal[d]) { + return false; + } + } + + return true; +} + +boost::optional<Vector_t> +ElementBase::BoundingBox::getPointOfIntersection(const Vector_t & position, + const Vector_t & direction) const { + Vector_t relativePosition = position - lowerLeftCorner; + Vector_t diagonal = upperRightCorner - lowerLeftCorner; + + for (unsigned int i = 0; i < 2; ++ i) { + for (unsigned int d = 0; d < 3; ++ d) { + double projectedDirection = direction[d]; + if (std::abs(projectedDirection) < 1e-10) { + continue; + } + + double distanceNearestPoint = relativePosition[d]; + double tau = distanceNearestPoint / projectedDirection; + if (tau < 0) { + continue; + } + Vector_t intersectionPoint = relativePosition + tau * direction; + + double sign = 1 - 2 * i; + if (sign * intersectionPoint[(d + 1) % 3] < 0.0 || + sign * intersectionPoint[(d + 1) % 3] > diagonal[(d + 1) % 3] || + sign * intersectionPoint[(d + 2) % 3] < 0.0 || + sign * intersectionPoint[(d + 2) % 3] > diagonal[(d + 2) % 3]) { + continue; + } + + return position + tau * direction; + } + relativePosition = upperRightCorner - position; + } + + return boost::none; +} + +ElementBase::BoundingBox ElementBase::getBoundingBoxInLabCoords() const { CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m; CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m; - double &x = aperture_m.second[0]; - double &y = aperture_m.second[1]; - double &f = aperture_m.second[2]; + const double &x = aperture_m.second[0]; + const double &y = aperture_m.second[1]; + const double &f = aperture_m.second[2]; std::vector<Vector_t> corners(8); for (int i = -1; i < 2; i += 2) { @@ -353,12 +403,12 @@ BoundaryBox ElementBase::getBoundaryBoxInLabCoords() const { bb.lowerLeftCorner = bb.upperRightCorner = corners[0]; for (unsigned int i = 1; i < 8u; ++ i) { - for (unsigned int d; d < 3u; ++ d) { + for (unsigned int d = 0; d < 3u; ++ d) { if (bb.lowerLeftCorner(d) > corners[i](d)) { bb.lowerLeftCorner(d) = corners[i](d); } - if (bb.upperLeftCorner(d) < corners[i](d)) { - bb.upperLeftCorner(d) = corners[i](d); + if (bb.upperRightCorner(d) < corners[i](d)) { + bb.upperRightCorner(d) = corners[i](d); } } } diff --git a/src/Classic/AbsBeamline/ElementBase.h b/src/Classic/AbsBeamline/ElementBase.h index aaa2fd5a4..4c3f6d50c 100644 --- a/src/Classic/AbsBeamline/ElementBase.h +++ b/src/Classic/AbsBeamline/ElementBase.h @@ -71,6 +71,8 @@ #include "Algorithms/CoordinateSystemTrafo.h" #include "Utilities/GeneralClassicException.h" +#include <boost/optional.hpp> + #include <string> #include <queue> @@ -359,10 +361,26 @@ public: void setRotationAboutZ(double rotation); double getRotationAboutZ() const; - virtual BoundaryBox getBoundaryBoxInLabCoords() const; + struct BoundingBox { + Vector_t lowerLeftCorner; + Vector_t upperRightCorner; + + void getCombinedBoundingBox(const BoundingBox & other) { + for (unsigned int d = 0; d < 3; ++ d) { + lowerLeftCorner[d] = std::min(lowerLeftCorner[d], other.lowerLeftCorner[d]); + upperRightCorner[d] = std::max(upperRightCorner[d], other.upperRightCorner[d]); + } + } + + bool isInside(const Vector_t &) const; + boost::optional<Vector_t> getPointOfIntersection(const Vector_t & position, + const Vector_t & direction) const; + }; + + virtual BoundingBox getBoundingBoxInLabCoords() const; protected: - bool isInsideTransverse(const Vector_t &r, double f = 1) const; + bool isInsideTransverse(const Vector_t &r) const; // Sharable flag. // If this flag is true, the element is always shared. diff --git a/src/Classic/Utilities/ClassicField.h b/src/Classic/Utilities/ClassicField.h index 180dd0256..60028adfc 100644 --- a/src/Classic/Utilities/ClassicField.h +++ b/src/Classic/Utilities/ClassicField.h @@ -31,6 +31,7 @@ public: return (fle.getLength() < 1.e-6); } + ElementBase::BoundingBox getBoundingBoxInLabCoords() const; CoordinateSystemTrafo getCoordTransformationTo() const ; void setCoordTransformationTo(const CoordinateSystemTrafo &trafo); @@ -98,4 +99,8 @@ void ClassicField::fixPosition() { element_m->fixPosition(); } +inline +ElementBase::BoundingBox ClassicField::getBoundingBoxInLabCoords() const { + return element_m->getBoundingBoxInLabCoords(); +} #endif // CLASSIC_FIELD_H diff --git a/src/Elements/OpalMarker.cpp b/src/Elements/OpalMarker.cpp index 1bd5eb58b..b7fc5cc0f 100644 --- a/src/Elements/OpalMarker.cpp +++ b/src/Elements/OpalMarker.cpp @@ -70,4 +70,4 @@ void OpalMarker::update() { // Transmit "unknown" attributes. MarkerRep *mark = dynamic_cast<MarkerRep *>(getElement()); OpalElement::updateUnknown(mark); -} +} \ No newline at end of file diff --git a/src/Elements/OpalRBend.cpp b/src/Elements/OpalRBend.cpp index af1f3327e..90fecb7d5 100644 --- a/src/Elements/OpalRBend.cpp +++ b/src/Elements/OpalRBend.cpp @@ -193,7 +193,7 @@ void OpalRBend::update() { bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({hapert, gap, 1.0})); } else { double gap = Attributes::getReal(itsAttr[GAP]); - bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({0.5, gap, 1.0}); + bend->setAperture(ElementBase::RECTANGULAR, std::vector<double>({0.5, gap, 1.0})); } if(itsAttr[LENGTH]) -- GitLab