Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:22

0001 /// @file HalfSpaceImplementation.h
0002 /// @brief Navigation kernel for the infinite half-space primitive.
0003 
0004 #ifndef VECGEOM_VOLUMES_KERNEL_HALFSPACEIMPLEMENTATION_H_
0005 #define VECGEOM_VOLUMES_KERNEL_HALFSPACEIMPLEMENTATION_H_
0006 
0007 #include "VecGeom/base/Global.h"
0008 #include "VecGeom/base/Vector3D.h"
0009 #include "VecGeom/volumes/HalfSpaceStruct.h"
0010 #include "VecGeom/volumes/SurfaceHitView.h"
0011 
0012 #include <VecCore/VecCore>
0013 
0014 namespace vecgeom {
0015 
0016 VECGEOM_DEVICE_FORWARD_DECLARE(struct HalfSpaceImplementation;);
0017 VECGEOM_DEVICE_DECLARE_CONV(struct, HalfSpaceImplementation);
0018 
0019 inline namespace VECGEOM_IMPL_NAMESPACE {
0020 
0021 class PlacedHalfSpace;
0022 class UnplacedHalfSpace;
0023 
0024 /// @brief Kernel implementation for a plane-bounded infinite half-space.
0025 /// @details The stored normal is a unit vector pointing outside the material
0026 /// side. Points with signed distance `(p - point).Dot(normal) <= 0` are in the
0027 /// half-space, with the usual VecGeom tolerance band classified as surface.
0028 struct HalfSpaceImplementation {
0029   using PlacedShape_t    = PlacedHalfSpace;
0030   using UnplacedStruct_t = HalfSpaceStruct<Precision>;
0031   using UnplacedVolume_t = UnplacedHalfSpace;
0032 
0033   /// @brief Compute signed distance to the limiting plane.
0034   /// @tparam Real_v Scalar floating-point type used by the kernel.
0035   /// @param halfspace Plane data with normalized outward normal.
0036   /// @param point Query point in local coordinates.
0037   /// @return Positive distance on the outside side, negative on the material side.
0038   template <typename Real_v>
0039   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Real_v SignedDistance(UnplacedStruct_t const &halfspace,
0040                                                                             Vector3D<Real_v> const &point)
0041   {
0042     return (point - Vector3D<Real_v>(halfspace.fPoint)).Dot(Vector3D<Real_v>(halfspace.fNormal));
0043   }
0044 
0045   /// @brief Test whether a point is contained by the tolerated half-space.
0046   /// @param halfspace Plane data with normalized outward normal.
0047   /// @param point Query point in local coordinates.
0048   /// @param[out] inside True for material-side and surface-band points.
0049   template <typename Real_v>
0050   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Contains(UnplacedStruct_t const &halfspace,
0051                                                                     Vector3D<Real_v> const &point, bool &inside)
0052   {
0053     inside = SignedDistance(halfspace, point) <= Real_v(kTolerance);
0054   }
0055 
0056   /// @brief Classify a point with the half-space inside convention.
0057   /// @param halfspace Plane data with normalized outward normal.
0058   /// @param point Query point in local coordinates.
0059   /// @param[out] inside `kInside`, `kSurface`, or `kOutside`.
0060   template <typename Real_v>
0061   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Inside(UnplacedStruct_t const &halfspace,
0062                                                                   Vector3D<Real_v> const &point, Inside_t &inside)
0063   {
0064     const Real_v signedDistance = SignedDistance(halfspace, point);
0065     inside                      = EInside::kSurface;
0066     if (signedDistance < Real_v(-kTolerance)) inside = Inside_t(EInside::kInside);
0067     if (signedDistance > Real_v(kTolerance)) inside = Inside_t(EInside::kOutside);
0068   }
0069 
0070   /// @brief Compute distance from outside to enter the half-space.
0071   /// @param halfspace Plane data with normalized outward normal.
0072   /// @param point Query point in local coordinates.
0073   /// @param direction Unit ray direction in local coordinates.
0074   /// @param stepMax Maximum accepted step.
0075   /// @param[out] distance Entry distance, `kInfLength` for a miss, or `-1` when already inside.
0076   /// @details A surface point only enters at zero when the direction points
0077   /// toward the material side.
0078   template <typename Real_v>
0079   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToIn(UnplacedStruct_t const &halfspace,
0080                                                                         Vector3D<Real_v> const &point,
0081                                                                         Vector3D<Real_v> const &direction,
0082                                                                         Real_v const &stepMax, Real_v &distance)
0083   {
0084     distance                    = kInfLength;
0085     const Real_v signedDistance = SignedDistance(halfspace, point);
0086     if (signedDistance < Real_v(-kTolerance)) {
0087       distance = Real_v(-1.);
0088       return;
0089     }
0090 
0091     const Real_v nDotDir = Vector3D<Real_v>(halfspace.fNormal).Dot(direction);
0092     if (signedDistance <= Real_v(kTolerance)) {
0093       if (nDotDir < Real_v(-kTolerance)) distance = Real_v(0.);
0094       return;
0095     }
0096 
0097     if (nDotDir >= Real_v(-kTolerance)) return;
0098     const Real_v candidate = -signedDistance / nDotDir;
0099     if (candidate >= Real_v(0.) && candidate < stepMax) distance = candidate;
0100   }
0101 
0102   /// @brief Compute distance from inside to leave the half-space.
0103   /// @param halfspace Plane data with normalized outward normal.
0104   /// @param point Query point in local coordinates.
0105   /// @param direction Unit ray direction in local coordinates.
0106   /// @param stepMax Maximum accepted step.
0107   /// @param[out] distance Exit distance, `kInfLength` for no plane crossing, or `-1` when already outside.
0108   /// @param[out] hitInfo Optional unit exit normal and supporting-plane result.
0109   /// @details A surface point only exits at zero when the direction points
0110   /// along the outward normal. Every accepted exit plane supports the entire
0111   /// half-space. Misses and wrong-side starts clear the flag without writing a normal.
0112   template <typename Real_v>
0113   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToOut(UnplacedStruct_t const &halfspace,
0114                                                                          Vector3D<Real_v> const &point,
0115                                                                          Vector3D<Real_v> const &direction,
0116                                                                          Real_v const &stepMax, Real_v &distance,
0117                                                                          SurfaceHitView<Real_v> *hitInfo = nullptr)
0118   {
0119     if (hitInfo) hitInfo->Clear();
0120     distance                    = kInfLength;
0121     const Real_v signedDistance = SignedDistance(halfspace, point);
0122     if (signedDistance > Real_v(kTolerance)) {
0123       distance = Real_v(-1.);
0124       return;
0125     }
0126 
0127     const Real_v nDotDir = Vector3D<Real_v>(halfspace.fNormal).Dot(direction);
0128     if (signedDistance >= Real_v(-kTolerance)) {
0129       if (nDotDir > Real_v(kTolerance)) {
0130         distance = Real_v(0.);
0131         if (hitInfo) {
0132           hitInfo->SetLeftBehind(true);
0133           hitInfo->SetNormal(Vector3D<Real_v>(halfspace.fNormal));
0134         }
0135       }
0136       return;
0137     }
0138 
0139     if (nDotDir <= Real_v(kTolerance)) return;
0140     const Real_v candidate = -signedDistance / nDotDir;
0141     if (candidate >= Real_v(0.) && candidate < stepMax) {
0142       distance = candidate;
0143       if (hitInfo) {
0144         hitInfo->SetLeftBehind(true);
0145         hitInfo->SetNormal(Vector3D<Real_v>(halfspace.fNormal));
0146       }
0147     }
0148   }
0149 
0150   /// @brief Compute safety from outside to the half-space boundary.
0151   /// @param halfspace Plane data with normalized outward normal.
0152   /// @param point Query point in local coordinates.
0153   /// @param[out] safety Positive outside distance, zero in the surface band, or `-1` when already inside.
0154   template <typename Real_v>
0155   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToIn(UnplacedStruct_t const &halfspace,
0156                                                                       Vector3D<Real_v> const &point, Real_v &safety)
0157   {
0158     const Real_v signedDistance = SignedDistance(halfspace, point);
0159     safety                      = signedDistance;
0160     if (signedDistance < Real_v(-kTolerance)) {
0161       safety = Real_v(-1.);
0162       return;
0163     }
0164     if (signedDistance <= Real_v(kTolerance)) safety = Real_v(0.);
0165   }
0166 
0167   /// @brief Compute safety from inside to the half-space boundary.
0168   /// @param halfspace Plane data with normalized outward normal.
0169   /// @param point Query point in local coordinates.
0170   /// @param[out] safety Positive material-side distance, zero in the surface band, or `-1` when outside.
0171   template <typename Real_v>
0172   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToOut(UnplacedStruct_t const &halfspace,
0173                                                                        Vector3D<Real_v> const &point, Real_v &safety)
0174   {
0175     const Real_v signedDistance = SignedDistance(halfspace, point);
0176     safety                      = -signedDistance;
0177     if (signedDistance > Real_v(kTolerance)) {
0178       safety = Real_v(-1.);
0179       return;
0180     }
0181     if (signedDistance >= Real_v(-kTolerance)) safety = Real_v(0.);
0182   }
0183 
0184   /// @brief Return the outward plane normal at a local query point.
0185   /// @param halfspace Plane data with normalized outward normal.
0186   /// @param point Query point in local coordinates.
0187   /// @param[out] valid True when @p point lies in the tolerated surface band.
0188   /// @return Unit outward plane normal.
0189   template <typename Real_v>
0190   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &halfspace,
0191                                                                                     Vector3D<Real_v> const &point,
0192                                                                                     bool &valid)
0193   {
0194     valid = Abs(SignedDistance(halfspace, point)) <= Real_v(kTolerance);
0195     return Vector3D<Real_v>(halfspace.fNormal);
0196   }
0197 };
0198 
0199 } // namespace VECGEOM_IMPL_NAMESPACE
0200 } // namespace vecgeom
0201 
0202 #endif // VECGEOM_VOLUMES_KERNEL_HALFSPACEIMPLEMENTATION_H_