File indexing completed on 2025-08-05 08:09:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/Propagator/ConstrainedStep.hpp"
0015 #include "Acts/Surfaces/BoundaryCheck.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/Intersection.hpp"
0018 #include "Acts/Utilities/Logger.hpp"
0019
0020 #include <limits>
0021 #include <optional>
0022 #include <sstream>
0023 #include <string>
0024
0025 namespace Acts {
0026
0027
0028 struct PathLimitReached {
0029
0030 double internalLimit = std::numeric_limits<double>::max();
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 template <typename propagator_state_t, typename stepper_t,
0042 typename navigator_t>
0043 bool operator()(propagator_state_t& state, const stepper_t& stepper,
0044 const navigator_t& ,
0045 const Logger& logger) const {
0046
0047 double distance =
0048 std::abs(internalLimit) - std::abs(state.stepping.pathAccumulated);
0049 double tolerance = state.options.surfaceTolerance;
0050 bool limitReached = (std::abs(distance) < std::abs(tolerance));
0051 if (limitReached) {
0052 ACTS_VERBOSE("PathLimit aborter | "
0053 << "Path limit reached at distance " << distance);
0054 return true;
0055 }
0056 stepper.updateStepSize(state.stepping, distance, ConstrainedStep::aborter,
0057 false);
0058 ACTS_VERBOSE("PathLimit aborter | "
0059 << "Target stepSize (path limit) updated to "
0060 << stepper.outputStepSize(state.stepping));
0061 return false;
0062 }
0063 };
0064
0065
0066
0067 struct SurfaceReached {
0068 const Surface* surface = nullptr;
0069 BoundaryCheck boundaryCheck = BoundaryCheck(true);
0070
0071
0072
0073
0074
0075 std::optional<double> overrideNearLimit;
0076
0077 SurfaceReached() = default;
0078 SurfaceReached(double nearLimit) : overrideNearLimit(nearLimit) {}
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 template <typename propagator_state_t, typename stepper_t,
0091 typename navigator_t>
0092 bool operator()(propagator_state_t& state, const stepper_t& stepper,
0093 const navigator_t& navigator, const Logger& logger) const {
0094 if (surface == nullptr) {
0095 ACTS_VERBOSE("SurfaceReached aborter | Target surface not set.");
0096 return false;
0097 }
0098
0099 if (navigator.currentSurface(state.navigation) == surface) {
0100 ACTS_VERBOSE("SurfaceReached aborter | Target surface reached.");
0101 return true;
0102 }
0103
0104
0105
0106
0107
0108 const double nearLimit =
0109 overrideNearLimit.value_or(stepper.overstepLimit(state.stepping));
0110 const double farLimit =
0111 state.stepping.stepSize.value(ConstrainedStep::aborter);
0112 const double tolerance = state.options.surfaceTolerance;
0113
0114 const auto sIntersection = surface->intersect(
0115 state.geoContext, stepper.position(state.stepping),
0116 state.options.direction * stepper.direction(state.stepping),
0117 boundaryCheck, tolerance);
0118 const auto closest = sIntersection.closest();
0119
0120 bool reached = false;
0121
0122 if (closest.status() == Intersection3D::Status::onSurface) {
0123 const double distance = closest.pathLength();
0124 ACTS_VERBOSE(
0125 "SurfaceReached aborter | "
0126 "Target surface reached at distance (tolerance) "
0127 << distance << " (" << tolerance << ")");
0128 reached = true;
0129 }
0130
0131 bool intersectionFound = false;
0132
0133 for (const auto& intersection : sIntersection.split()) {
0134 if (intersection &&
0135 detail::checkIntersection(intersection.intersection(), nearLimit,
0136 farLimit, logger)) {
0137 stepper.updateStepSize(state.stepping, intersection.pathLength(),
0138 ConstrainedStep::aborter, false);
0139 ACTS_VERBOSE(
0140 "SurfaceReached aborter | "
0141 "Target stepSize (surface) updated to "
0142 << stepper.outputStepSize(state.stepping));
0143 intersectionFound = true;
0144 break;
0145 }
0146 }
0147
0148 if (!intersectionFound) {
0149 ACTS_VERBOSE(
0150 "SurfaceReached aborter | "
0151 "Target intersection not found. Maybe next time?");
0152 }
0153 return reached;
0154 }
0155 };
0156
0157
0158
0159
0160 struct ForcedSurfaceReached : SurfaceReached {
0161 ForcedSurfaceReached()
0162 : SurfaceReached(std::numeric_limits<double>::lowest()) {}
0163 };
0164
0165
0166
0167 struct EndOfWorldReached {
0168 EndOfWorldReached() = default;
0169
0170
0171
0172
0173
0174
0175
0176
0177 template <typename propagator_state_t, typename stepper_t,
0178 typename navigator_t>
0179 bool operator()(propagator_state_t& state, const stepper_t& ,
0180 const navigator_t& navigator,
0181 const Logger& ) const {
0182 bool endOfWorld = navigator.endOfWorldReached(state.navigation);
0183 return endOfWorld;
0184 }
0185 };
0186
0187 }