File indexing completed on 2025-11-04 09:21:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Propagator/ConstrainedStep.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/Enumerate.hpp"
0016 #include "Acts/Utilities/Intersection.hpp"
0017 #include "Acts/Utilities/Logger.hpp"
0018
0019 #include <limits>
0020
0021 namespace Acts {
0022
0023
0024 struct PathLimitReached {
0025
0026 double internalLimit = std::numeric_limits<double>::max();
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 template <typename propagator_state_t, typename stepper_t,
0040 typename navigator_t>
0041 bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0042 const navigator_t& navigator, const Logger& logger) const {
0043 (void)navigator;
0044
0045
0046 double distance =
0047 std::abs(internalLimit) - std::abs(state.stepping.pathAccumulated);
0048 double tolerance = state.options.surfaceTolerance;
0049 bool limitReached = (std::abs(distance) < std::abs(tolerance));
0050 if (limitReached) {
0051 ACTS_VERBOSE("PathLimit aborter | " << "Path limit reached at distance "
0052 << distance);
0053 return true;
0054 }
0055 stepper.updateStepSize(state.stepping, distance,
0056 ConstrainedStep::Type::Actor);
0057 ACTS_VERBOSE("PathLimit aborter | "
0058 << "Target stepSize (path limit) updated to "
0059 << stepper.outputStepSize(state.stepping));
0060 return false;
0061 }
0062 };
0063
0064
0065
0066 struct SurfaceReached {
0067
0068 const Surface* surface = nullptr;
0069
0070 BoundaryTolerance boundaryTolerance = BoundaryTolerance::None();
0071
0072
0073
0074
0075
0076 double nearLimit = -100 * UnitConstants::um;
0077
0078 SurfaceReached() = default;
0079
0080
0081 explicit SurfaceReached(double nLimit) : nearLimit(nLimit) {}
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename propagator_state_t, typename stepper_t,
0095 typename navigator_t>
0096 bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0097 const navigator_t& navigator, const Logger& logger) const {
0098 if (surface == nullptr) {
0099 ACTS_VERBOSE("SurfaceReached aborter | Target surface not set.");
0100 return false;
0101 }
0102
0103 if (navigator.currentSurface(state.navigation) == surface) {
0104 ACTS_VERBOSE("SurfaceReached aborter | Target surface reached.");
0105 return true;
0106 }
0107
0108
0109
0110
0111
0112 const double farLimit = std::numeric_limits<double>::max();
0113 const double tolerance = state.options.surfaceTolerance;
0114
0115 const MultiIntersection3D multiIntersection = surface->intersect(
0116 state.geoContext, stepper.position(state.stepping),
0117 state.options.direction * stepper.direction(state.stepping),
0118 boundaryTolerance, tolerance);
0119 const Intersection3D closestIntersection = multiIntersection.closest();
0120
0121 bool reached = false;
0122
0123 if (closestIntersection.status() == IntersectionStatus::onSurface) {
0124 const double distance = closestIntersection.pathLength();
0125 ACTS_VERBOSE(
0126 "SurfaceReached aborter | "
0127 "Target surface reached at distance (tolerance) "
0128 << distance << " (" << tolerance << ")");
0129 reached = true;
0130 }
0131
0132 bool intersectionFound = false;
0133
0134 for (auto [intersectionIndex, intersection] :
0135 Acts::enumerate(multiIntersection)) {
0136 if (intersection.isValid() &&
0137 detail::checkPathLength(intersection.pathLength(), nearLimit,
0138 farLimit, logger)) {
0139 stepper.updateStepSize(state.stepping, intersection.pathLength(),
0140 ConstrainedStep::Type::Actor);
0141 ACTS_VERBOSE(
0142 "SurfaceReached aborter | "
0143 "Target stepSize (surface) updated to "
0144 << stepper.outputStepSize(state.stepping));
0145 intersectionFound = true;
0146 break;
0147 }
0148 }
0149
0150 if (!intersectionFound) {
0151 ACTS_VERBOSE(
0152 "SurfaceReached aborter | "
0153 "Target intersection not found. Maybe next time?");
0154 }
0155 return reached;
0156 }
0157 };
0158
0159
0160
0161
0162 struct ForcedSurfaceReached : SurfaceReached {
0163 ForcedSurfaceReached()
0164 : SurfaceReached(std::numeric_limits<double>::lowest()) {}
0165 };
0166
0167
0168
0169 struct EndOfWorldReached {
0170
0171
0172
0173
0174
0175
0176
0177
0178 template <typename propagator_state_t, typename stepper_t,
0179 typename navigator_t>
0180 bool checkAbort(propagator_state_t& state, const stepper_t& ,
0181 const navigator_t& navigator,
0182 const Logger& ) const {
0183 bool endOfWorld = navigator.endOfWorldReached(state.navigation);
0184 return endOfWorld;
0185 }
0186 };
0187
0188
0189
0190 struct VolumeConstraintAborter {
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 template <typename propagator_state_t, typename stepper_t,
0201 typename navigator_t>
0202 bool checkAbort(propagator_state_t& state, const stepper_t& ,
0203 const navigator_t& navigator, const Logger& logger) const {
0204 const auto& constrainToVolumeIds = state.options.constrainToVolumeIds;
0205 const auto& endOfWorldVolumeIds = state.options.endOfWorldVolumeIds;
0206
0207 if (constrainToVolumeIds.empty() && endOfWorldVolumeIds.empty()) {
0208 return false;
0209 }
0210 const auto* currentVolume = navigator.currentVolume(state.navigation);
0211
0212
0213 if (currentVolume == nullptr) {
0214 return false;
0215 }
0216
0217 const auto currentVolumeId =
0218 static_cast<std::uint32_t>(currentVolume->geometryId().volume());
0219
0220 if (!constrainToVolumeIds.empty() &&
0221 std::find(constrainToVolumeIds.begin(), constrainToVolumeIds.end(),
0222 currentVolumeId) == constrainToVolumeIds.end()) {
0223 ACTS_VERBOSE(
0224 "VolumeConstraintAborter aborter | Abort with volume constrain "
0225 << currentVolumeId);
0226 return true;
0227 }
0228
0229 if (!endOfWorldVolumeIds.empty() &&
0230 std::find(endOfWorldVolumeIds.begin(), endOfWorldVolumeIds.end(),
0231 currentVolumeId) != endOfWorldVolumeIds.end()) {
0232 ACTS_VERBOSE(
0233 "VolumeConstraintAborter aborter | Abort with additional end of "
0234 "world volume "
0235 << currentVolumeId);
0236 return true;
0237 }
0238
0239 return false;
0240 }
0241 };
0242
0243
0244 struct AnySurfaceReached {
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <typename propagator_state_t, typename stepper_t,
0255 typename navigator_t>
0256 bool checkAbort(propagator_state_t& state, const stepper_t& stepper,
0257 const navigator_t& navigator, const Logger& logger) const {
0258 (void)stepper;
0259 (void)logger;
0260
0261 const Surface* startSurface = navigator.startSurface(state.navigation);
0262 const Surface* targetSurface = navigator.targetSurface(state.navigation);
0263 const Surface* currentSurface = navigator.currentSurface(state.navigation);
0264
0265
0266
0267 if (currentSurface != nullptr && currentSurface != startSurface &&
0268 currentSurface != targetSurface) {
0269 return true;
0270 }
0271
0272 return false;
0273 }
0274 };
0275
0276 }