File indexing completed on 2026-09-19 09:40:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef VECGEOM_VOLUMES_KERNEL_PARALLELEPIPEDIMPLEMENTATION_H_
0011 #define VECGEOM_VOLUMES_KERNEL_PARALLELEPIPEDIMPLEMENTATION_H_
0012
0013 #include "VecGeom/base/Vector3D.h"
0014 #include "VecGeom/volumes/ParallelepipedStruct.h"
0015 #include "VecGeom/volumes/kernel/GenericKernels.h"
0016 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0017 #include <VecCore/VecCore>
0018
0019 #include <cstdio>
0020
0021 namespace vecgeom {
0022
0023 VECGEOM_DEVICE_FORWARD_DECLARE(struct ParallelepipedImplementation;);
0024 VECGEOM_DEVICE_DECLARE_CONV(struct, ParallelepipedImplementation);
0025
0026 inline namespace VECGEOM_IMPL_NAMESPACE {
0027
0028 class PlacedParallelepiped;
0029 template <typename T>
0030 struct ParallelepipedStruct;
0031 class UnplacedParallelepiped;
0032
0033 struct ParallelepipedImplementation {
0034
0035 using PlacedShape_t = PlacedParallelepiped;
0036 using UnplacedStruct_t = ParallelepipedStruct<Precision>;
0037 using UnplacedVolume_t = UnplacedParallelepiped;
0038
0039 template <typename Real_v>
0040 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Transform(UnplacedStruct_t const &unplaced,
0041 Vector3D<Real_v> &point)
0042 {
0043 point.y() -= unplaced.fTanThetaSinPhi * point.z();
0044 point.x() -= unplaced.fTanThetaCosPhi * point.z() + unplaced.fTanAlpha * point.y();
0045 }
0046
0047 template <typename Real_v>
0048 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyVector(UnplacedStruct_t const &unplaced,
0049 Vector3D<Real_v> const &localPoint,
0050 Vector3D<Real_v> &safety)
0051 {
0052 safety = localPoint.Abs() - Vector3D<Real_v>(unplaced.fDimensions);
0053 safety.x() *= unplaced.fCtx;
0054 safety.y() *= unplaced.fCty;
0055 }
0056
0057 template <typename Real_v, typename Bool_v>
0058 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Contains(UnplacedStruct_t const &unplaced,
0059 Vector3D<Real_v> const &point, Bool_v &inside)
0060 {
0061 Vector3D<Real_v> localPoint(point);
0062 Vector3D<Real_v> safetyVector;
0063 Transform<Real_v>(unplaced, localPoint);
0064 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0065
0066 inside = safetyVector.Max() < Real_v(0.0);
0067 }
0068
0069 template <typename Real_v, typename Inside_v>
0070 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Inside(UnplacedStruct_t const &unplaced,
0071 Vector3D<Real_v> const &point, Inside_v &inside)
0072 {
0073 Vector3D<Real_v> localPoint(point);
0074 Vector3D<Real_v> safetyVector;
0075 Transform<Real_v>(unplaced, localPoint);
0076 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0077
0078 Real_v safety = safetyVector.Max();
0079 inside = vecCore::Blend(safety < Real_v(0.0), Inside_v(kInside), Inside_v(kOutside));
0080 vecCore__MaskedAssignFunc(inside, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Inside_v(kSurface));
0081 }
0082
0083 template <typename Real_v>
0084 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToIn(UnplacedStruct_t const &unplaced,
0085 Vector3D<Real_v> const &point, Real_v &safety)
0086 {
0087 Vector3D<Real_v> localPoint(point);
0088 Vector3D<Real_v> safetyVector;
0089 Transform<Real_v>(unplaced, localPoint);
0090 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0091
0092 safety = safetyVector.Max();
0093 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Real_v(0.0));
0094 }
0095
0096 template <typename Real_v>
0097 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToOut(UnplacedStruct_t const &unplaced,
0098 Vector3D<Real_v> const &point, Real_v &safety)
0099 {
0100 Vector3D<Real_v> localPoint(point);
0101 Vector3D<Real_v> safetyVector;
0102 Transform<Real_v>(unplaced, localPoint);
0103 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0104
0105 safety = -safetyVector.Max();
0106 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Real_v(0.0));
0107 }
0108
0109 template <typename Real_v>
0110 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToIn(UnplacedStruct_t const &unplaced,
0111 Vector3D<Real_v> const &point,
0112 Vector3D<Real_v> const &direction,
0113 Real_v const &stepMax, Real_v &distance)
0114 {
0115
0116
0117 Vector3D<Real_v> p(point);
0118 Vector3D<Real_v> v(direction);
0119
0120 Transform<Real_v>(unplaced, p);
0121 Transform<Real_v>(unplaced, v);
0122
0123 BoxImplementation::DistanceToIn(BoxStruct<Precision>(unplaced.fDimensions), p, v, stepMax, distance);
0124 }
0125
0126 template <typename Real_v>
0127 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToOut(UnplacedStruct_t const &unplaced,
0128 Vector3D<Real_v> const &point,
0129 Vector3D<Real_v> const &direction,
0130 Real_v const &stepMax, Real_v &distance)
0131 {
0132
0133
0134 Vector3D<Real_v> p(point);
0135 Vector3D<Real_v> v(direction);
0136
0137 Transform<Real_v>(unplaced, p);
0138 Transform<Real_v>(unplaced, v);
0139
0140 BoxImplementation::DistanceToOut(BoxStruct<Precision>(unplaced.fDimensions), p, v, stepMax, distance);
0141 }
0142
0143 template <typename Real_v>
0144 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Real_v> NormalKernel(
0145 UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, typename vecCore::Mask_v<Real_v> &valid)
0146 {
0147
0148
0149
0150
0151 Vector3D<Real_v> normal(0.);
0152 valid = true;
0153
0154
0155 Vector3D<Real_v> p(point);
0156 Vector3D<Real_v> safetyVector;
0157 Transform<Real_v>(unplaced, p);
0158 SafetyVector<Real_v>(unplaced, p, safetyVector);
0159
0160
0161 const Vector3D<Real_v> signs(Sign(p.x()), Sign(p.y()), Sign(p.z()));
0162 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.z()) <= kHalfTolerance, Vector3D<Real_v>(0., 0., signs.z()));
0163 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.y()) <= kHalfTolerance,
0164 normal + signs.y() * unplaced.fNormals[1]);
0165 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.x()) <= kHalfTolerance,
0166 normal + signs.x() * unplaced.fNormals[0]);
0167
0168 Real_v mag2 = normal.Mag2();
0169 vecCore__MaskedAssignFunc(normal, mag2 > 1., normal.Unit());
0170 if (vecCore::MaskFull(mag2 > Real_v(0.))) return normal;
0171
0172
0173
0174 vecCore__MaskedAssignFunc(valid, mag2 == Real_v(0.), false);
0175 Real_v safety = safetyVector.Max();
0176 normal = signs.x() * unplaced.fNormals[0];
0177 vecCore__MaskedAssignFunc(normal, safetyVector.y() == safety, signs.y() * unplaced.fNormals[1]);
0178 vecCore__MaskedAssignFunc(normal, safetyVector.z() == safety, signs.z() * unplaced.fNormals[2]);
0179 return normal;
0180 }
0181 };
0182 }
0183 }
0184
0185 #endif