File indexing completed on 2026-04-25 08:25:46
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef VECGEOM_VOLUMES_KERNEL_CUTTUBEIMPLEMENTATION_H_
0009 #define VECGEOM_VOLUMES_KERNEL_CUTTUBEIMPLEMENTATION_H_
0010
0011 #include <cstdio>
0012
0013 #include "VecGeom/base/Vector3D.h"
0014 #include "VecGeom/volumes/kernel/GenericKernels.h"
0015 #include "VecGeom/volumes/CutTubeStruct.h"
0016 #include "TubeImplementation.h"
0017
0018 namespace vecgeom {
0019
0020 VECGEOM_DEVICE_FORWARD_DECLARE(struct CutTubeImplementation;);
0021 VECGEOM_DEVICE_DECLARE_CONV(struct, CutTubeImplementation);
0022
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024
0025 class PlacedCutTube;
0026 class UnplacedCutTube;
0027
0028 template <typename T>
0029 struct CutTubeStruct;
0030
0031 struct CutTubeImplementation {
0032
0033 using PlacedShape_t = PlacedCutTube;
0034 using UnplacedStruct_t = CutTubeStruct<Precision>;
0035 using UnplacedVolume_t = UnplacedCutTube;
0036
0037 template <typename Real_v, typename Bool_v>
0038 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Contains(UnplacedStruct_t const &unplaced,
0039 Vector3D<Real_v> const &point, Bool_v &inside);
0040
0041 template <typename Real_v, typename Inside_t>
0042 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Inside(UnplacedStruct_t const &unplaced,
0043 Vector3D<Real_v> const &point, Inside_t &inside);
0044
0045 template <typename Real_v>
0046 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToIn(UnplacedStruct_t const &unplaced,
0047 Vector3D<Real_v> const &point,
0048 Vector3D<Real_v> const &direction,
0049 Real_v const &stepMax, Real_v &distance);
0050
0051 template <typename Real_v>
0052 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToInKernel(UnplacedStruct_t const &unplaced,
0053 Vector3D<Real_v> const &point,
0054 Vector3D<Real_v> const &direction,
0055 Real_v const &stepMax, Real_v &distance);
0056
0057 template <typename Real_v>
0058 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToOut(UnplacedStruct_t const &unplaced,
0059 Vector3D<Real_v> const &point,
0060 Vector3D<Real_v> const &direction,
0061 Real_v const &stepMax, Real_v &distance);
0062
0063 template <typename Real_v>
0064 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToIn(UnplacedStruct_t const &unplaced,
0065 Vector3D<Real_v> const &point, Real_v &safety);
0066
0067 template <typename Real_v>
0068 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToOut(UnplacedStruct_t const &unplaced,
0069 Vector3D<Real_v> const &point, Real_v &safety);
0070
0071 template <typename Real_v, typename Bool_v>
0072 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void NormalKernel(UnplacedStruct_t const &unplaced,
0073 Vector3D<Real_v> const &point,
0074 Vector3D<Real_v> &normal, Bool_v &valid);
0075 };
0076
0077
0078
0079
0080
0081
0082 template <typename Real_v, typename Bool_v>
0083 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::Contains(UnplacedStruct_t const &unplaced,
0084 Vector3D<Real_v> const &point,
0085 Bool_v &contains)
0086 {
0087 contains = Bool_v(false);
0088 Bool_v inside_cutplanes = Bool_v(false);
0089
0090 unplaced.GetCutPlanes().Contains<Real_v, Bool_v>(point, inside_cutplanes);
0091 if (vecCore::EarlyReturnAllowed()) {
0092 if (vecCore::MaskEmpty(inside_cutplanes)) return;
0093 }
0094
0095 TubeImplementation<TubeTypes::UniversalTube>::Contains<Real_v>(unplaced.GetTubeStruct(), point, contains);
0096 contains &= inside_cutplanes;
0097 }
0098
0099
0100 template <typename Real_v, typename Inside_t>
0101 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::Inside(UnplacedStruct_t const &unplaced,
0102 Vector3D<Real_v> const &point,
0103 Inside_t &inside)
0104 {
0105 inside = Inside_t(EInside::kOutside);
0106 Inside_t inside_cutplanes = Inside_t(EInside::kOutside);
0107
0108 unplaced.GetCutPlanes().Inside<Real_v, Inside_t>(point, inside_cutplanes);
0109 if (vecCore::EarlyReturnAllowed()) {
0110 if (vecCore::MaskFull(inside_cutplanes == inside)) return;
0111 }
0112
0113 TubeImplementation<TubeTypes::UniversalTube>::Inside<Real_v, Inside_t>(unplaced.GetTubeStruct(), point, inside);
0114 vecCore::MaskedAssign(inside,
0115 (inside_cutplanes == EInside::kOutside) ||
0116 (inside_cutplanes == EInside::kSurface && inside != EInside::kOutside),
0117 inside_cutplanes);
0118 }
0119
0120 template <typename Real_v>
0121 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::DistanceToIn(UnplacedStruct_t const &unplaced,
0122 Vector3D<Real_v> const &pointT,
0123 Vector3D<Real_v> const &dir,
0124 Real_v const &stepMax,
0125 Real_v &distance)
0126 {
0127
0128 Vector3D<Real_v> point = pointT;
0129 Real_v ptDist = point.Mag();
0130 Real_v distToMove(0.);
0131 using Bool_v = vecCore::Mask_v<Real_v>;
0132 Precision order = 100.;
0133
0134 Bool_v cond = (ptDist > order * unplaced.fMaxVal);
0135
0136
0137
0138
0139
0140
0141
0142
0143 vecCore__MaskedAssignFunc(distToMove, cond, (ptDist - Real_v(order * unplaced.fMaxVal)));
0144 vecCore__MaskedAssignFunc(point, cond, point + distToMove * dir);
0145 DistanceToInKernel<Real_v>(unplaced, point, dir, stepMax, distance);
0146 distance += distToMove;
0147 }
0148
0149 template <typename Real_v>
0150 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::DistanceToInKernel(
0151 UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Vector3D<Real_v> const &direction,
0152 Real_v const &stepMax, Real_v &distance)
0153 {
0154
0155 #define USE_CONV_WRONG_SIDE 1
0156 #define USE_CONV_FROM_BOUNDARY 1
0157
0158 using Bool_v = vecCore::Mask_v<Real_v>;
0159 distance = InfinityLength<Real_v>();
0160
0161 #if USE_CONV_WRONG_SIDE == 1
0162 using Inside_v = vecCore::Index_v<Real_v>;
0163
0164 Inside_v inside_cutplanes;
0165 unplaced.GetCutPlanes().Inside<Real_v, Inside_v>(point, inside_cutplanes);
0166 Inside_v instart;
0167
0168 TubeImplementation<TubeTypes::UniversalTube>::Inside<Real_v, Inside_v>(unplaced.GetTubeStruct(), point, instart);
0169 vecCore::MaskedAssign(instart,
0170 (inside_cutplanes == EInside::kOutside) ||
0171 (inside_cutplanes == EInside::kSurface && instart != EInside::kOutside),
0172 inside_cutplanes);
0173
0174 vecCore__MaskedAssignFunc(distance, instart == EInside::kInside, Real_v(-1.));
0175 #endif
0176
0177 Bool_v inside;
0178 Real_v dplanes, safplanes;
0179
0180 unplaced.GetCutPlanes().DistanceToIn<Real_v>(point, direction, dplanes);
0181
0182
0183 unplaced.GetCutPlanes().SafetyToIn<Real_v>(point, safplanes);
0184
0185
0186 Bool_v hitplanes = vecCore::math::Abs(dplanes) < stepMax && safplanes > Real_v(-kTolerance);
0187
0188 #if USE_CONV_WRONG_SIDE == 1
0189 if (vecCore::EarlyReturnAllowed()) {
0190 if (vecCore::MaskFull((inside_cutplanes != EInside::kInside) && !hitplanes))
0191 return;
0192 }
0193 #endif
0194
0195
0196 Vector3D<Real_v> propagated = point;
0197 vecCore__MaskedAssignFunc(dplanes, !hitplanes, Real_v(0.));
0198 if (vecCore::EarlyReturnAllowed()) {
0199 if (!vecCore::MaskEmpty(hitplanes)) {
0200 propagated += dplanes * direction;
0201
0202 unplaced.GetCutPlanes().Inside<Real_v, Inside_v>(propagated, inside_cutplanes);
0203 }
0204 } else {
0205
0206 propagated += dplanes * direction;
0207
0208 unplaced.GetCutPlanes().Inside<Real_v, Inside_v>(propagated, inside_cutplanes);
0209 }
0210 Bool_v done = inside_cutplanes == EInside::kOutside;
0211 #if USE_CONV_WRONG_SIDE == 1
0212 done |= instart == EInside::kInside;
0213 #endif
0214
0215 if (vecCore::EarlyReturnAllowed()) {
0216 if (vecCore::MaskFull(done))
0217 return;
0218 }
0219
0220
0221
0222 TubeImplementation<TubeTypes::UniversalTube>::Inside<Real_v>(unplaced.GetTubeStruct(), propagated, instart);
0223 inside = hitplanes && (instart != EInside::kOutside);
0224 vecCore::MaskedAssign(distance, inside && !done, dplanes);
0225 done |= inside;
0226
0227 if (vecCore::EarlyReturnAllowed()) {
0228 if (vecCore::MaskFull(done)) {
0229
0230 vecCore__MaskedAssignFunc(distance, vecCore::math::Abs(distance) < Real_v(kTolerance), Real_v(0.));
0231 return;
0232 }
0233 }
0234
0235
0236
0237 Real_v dexit = InfinityLength<Real_v>();
0238 unplaced.GetCutPlanes().DistanceToOut<Real_v>(propagated, direction, dexit);
0239
0240
0241 Real_v dtube = InfinityLength<Real_v>();
0242 TubeImplementation<TubeTypes::UniversalTube>::DistanceToInKernel<Real_v>(unplaced.GetTubeStruct(), propagated,
0243 direction, stepMax, dtube);
0244
0245
0246 vecCore__MaskedAssignFunc(dtube, dtube < Real_v(0.), Real_v(0.));
0247 vecCore__MaskedAssignFunc(dtube, dexit < dtube, InfinityLength<Real_v>());
0248 vecCore__MaskedAssignFunc(distance, !done && (dtube + dplanes) < stepMax, dtube + dplanes);
0249
0250 #if USE_CONV_FROM_BOUNDARY == 1
0251
0252 #endif
0253 }
0254
0255
0256 template <typename Real_v>
0257 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::DistanceToOut(
0258 UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Vector3D<Real_v> const &direction,
0259 Real_v const &stepMax, Real_v &distance)
0260 {
0261
0262 distance = InfinityLength<Real_v>();
0263 unplaced.GetCutPlanes().DistanceToOut<Real_v>(point, direction, distance);
0264
0265
0266 Real_v dtube = InfinityLength<Real_v>();
0267 TubeImplementation<TubeTypes::UniversalTube>::DistanceToOut<Real_v>(unplaced.GetTubeStruct(), point, direction,
0268 stepMax, dtube);
0269 vecCore::MaskedAssign(distance, dtube < distance, dtube);
0270
0271
0272
0273
0274 }
0275
0276
0277 template <typename Real_v>
0278 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::SafetyToIn(UnplacedStruct_t const &unplaced,
0279 Vector3D<Real_v> const &point,
0280 Real_v &safety)
0281 {
0282
0283
0284 unplaced.GetCutPlanes().SafetyToIn<Real_v>(point, safety);
0285 Real_v saftube;
0286
0287 TubeImplementation<TubeTypes::UniversalTube>::SafetyToIn<Real_v>(unplaced.GetTubeStruct(), point, saftube);
0288
0289 vecCore::MaskedAssign(safety, saftube > safety, saftube);
0290
0291
0292 }
0293
0294
0295 template <typename Real_v>
0296 VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::SafetyToOut(UnplacedStruct_t const &unplaced,
0297 Vector3D<Real_v> const &point, Real_v &safety)
0298 {
0299
0300
0301 unplaced.GetCutPlanes().SafetyToOut<Real_v>(point, safety);
0302 Real_v saftube;
0303
0304 TubeImplementation<TubeTypes::UniversalTube>::SafetyToOut<Real_v>(unplaced.GetTubeStruct(), point, saftube);
0305
0306 vecCore::MaskedAssign(safety, saftube < safety, saftube);
0307
0308
0309 }
0310
0311
0312 template <typename Real_v, typename Bool_v>
0313 VECCORE_ATT_HOST_DEVICE void CutTubeImplementation::NormalKernel(UnplacedStruct_t const &unplaced,
0314 Vector3D<Real_v> const &point,
0315 Vector3D<Real_v> &normal, Bool_v &valid)
0316 {
0317
0318 valid = Bool_v(true);
0319 Real_v safcut;
0320 unplaced.GetCutPlanes().SafetyToOut<Real_v>(point, safcut);
0321
0322 Real_v saftube;
0323 TubeImplementation<TubeTypes::UniversalTube>::SafetyToOut<Real_v>(unplaced.GetTubeStruct(), point, saftube);
0324 Bool_v istube = vecCore::math::Abs(saftube) < vecCore::math::Abs(safcut);
0325
0326 if (istube) {
0327 TubeImplementation<TubeTypes::UniversalTube>::NormalKernel<Real_v, Bool_v>(unplaced.GetTubeStruct(), point, normal,
0328 valid);
0329 return;
0330 }
0331
0332 if (point.z() < 0)
0333 normal = unplaced.fCutPlanes.GetNormal(0);
0334 else
0335 normal = unplaced.fCutPlanes.GetNormal(1);
0336 }
0337
0338
0339
0340
0341 }
0342 }
0343
0344 #endif