File indexing completed on 2025-01-18 10:14:02
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 <VecCore/VecCore>
0017
0018 #include <cstdio>
0019
0020 namespace vecgeom {
0021
0022 VECGEOM_DEVICE_FORWARD_DECLARE(struct ParallelepipedImplementation;);
0023 VECGEOM_DEVICE_DECLARE_CONV(struct, ParallelepipedImplementation);
0024
0025 inline namespace VECGEOM_IMPL_NAMESPACE {
0026
0027 class PlacedParallelepiped;
0028 template <typename T>
0029 struct ParallelepipedStruct;
0030 class UnplacedParallelepiped;
0031
0032 struct ParallelepipedImplementation {
0033
0034 using PlacedShape_t = PlacedParallelepiped;
0035 using UnplacedStruct_t = ParallelepipedStruct<Precision>;
0036 using UnplacedVolume_t = UnplacedParallelepiped;
0037
0038 VECCORE_ATT_HOST_DEVICE
0039 static void PrintType()
0040 {
0041
0042 }
0043
0044 template <typename Stream>
0045 static void PrintType(Stream &s, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0046 {
0047 s << "SpecializedParallelepiped<" << transCodeT << "," << rotCodeT << ">";
0048 }
0049
0050 template <typename Stream>
0051 static void PrintImplementationType(Stream & )
0052 {
0053
0054 }
0055
0056 template <typename Stream>
0057 static void PrintUnplacedType(Stream & )
0058 {
0059
0060 }
0061
0062 template <typename Real_v>
0063 VECGEOM_FORCE_INLINE
0064 VECCORE_ATT_HOST_DEVICE
0065 static void Transform(UnplacedStruct_t const &unplaced, Vector3D<Real_v> &point)
0066 {
0067 point.y() -= unplaced.fTanThetaSinPhi * point.z();
0068 point.x() -= unplaced.fTanThetaCosPhi * point.z() + unplaced.fTanAlpha * point.y();
0069 }
0070
0071 template <typename Real_v>
0072 VECGEOM_FORCE_INLINE
0073 VECCORE_ATT_HOST_DEVICE
0074 static void SafetyVector(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &localPoint,
0075 Vector3D<Real_v> &safety)
0076 {
0077 safety = localPoint.Abs() - Vector3D<Real_v>(unplaced.fDimensions);
0078 safety.x() *= unplaced.fCtx;
0079 safety.y() *= unplaced.fCty;
0080 }
0081
0082 template <typename Real_v, typename Bool_v>
0083 VECGEOM_FORCE_INLINE
0084 VECCORE_ATT_HOST_DEVICE
0085 static void Contains(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Bool_v &inside)
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 inside = safetyVector.Max() < Real_v(0.0);
0093 }
0094
0095 template <typename Real_v, typename Inside_v>
0096 VECGEOM_FORCE_INLINE
0097 VECCORE_ATT_HOST_DEVICE
0098 static void Inside(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Inside_v &inside)
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 Real_v safety = safetyVector.Max();
0106 inside = vecCore::Blend(safety < Real_v(0.0), Inside_v(kInside), Inside_v(kOutside));
0107 vecCore__MaskedAssignFunc(inside, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Inside_v(kSurface));
0108 }
0109
0110 template <typename Real_v>
0111 VECGEOM_FORCE_INLINE
0112 VECCORE_ATT_HOST_DEVICE
0113 static void SafetyToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0114 {
0115 Vector3D<Real_v> localPoint(point);
0116 Vector3D<Real_v> safetyVector;
0117 Transform<Real_v>(unplaced, localPoint);
0118 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0119
0120 safety = safetyVector.Max();
0121 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Real_v(0.0));
0122 }
0123
0124 template <typename Real_v>
0125 VECGEOM_FORCE_INLINE
0126 VECCORE_ATT_HOST_DEVICE
0127 static void SafetyToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0128 {
0129 Vector3D<Real_v> localPoint(point);
0130 Vector3D<Real_v> safetyVector;
0131 Transform<Real_v>(unplaced, localPoint);
0132 SafetyVector<Real_v>(unplaced, localPoint, safetyVector);
0133
0134 safety = -safetyVector.Max();
0135 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) < Real_v(kHalfTolerance), Real_v(0.0));
0136 }
0137
0138 template <typename Real_v>
0139 VECGEOM_FORCE_INLINE
0140 VECCORE_ATT_HOST_DEVICE
0141 static void DistanceToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0142 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0143 {
0144 using Bool_v = vecCore::Mask_v<Real_v>;
0145
0146
0147
0148 Vector3D<Real_v> p(point);
0149 Vector3D<Real_v> v(direction);
0150 Vector3D<Real_v> safetyVector;
0151
0152 Transform<Real_v>(unplaced, p);
0153 Transform<Real_v>(unplaced, v);
0154 SafetyVector<Real_v>(unplaced, p, safetyVector);
0155
0156
0157 Bool_v leaving(false);
0158 leaving |= (safetyVector.x() >= -kHalfTolerance && p.x() * v.x() >= Real_v(0.));
0159 leaving |= (safetyVector.y() >= -kHalfTolerance && p.y() * v.y() >= Real_v(0.));
0160 leaving |= (safetyVector.z() >= -kHalfTolerance && p.z() * v.z() >= Real_v(0.));
0161
0162
0163 const Vector3D<Real_v> invDir(Real_v(1.) / NonZero(v.x()), Real_v(1.) / NonZero(v.y()),
0164 Real_v(1.) / NonZero(v.z()));
0165 const Vector3D<Real_v> signDir(Sign(invDir.x()), Sign(invDir.y()), Sign(invDir.z()));
0166 const Vector3D<Real_v> temp = signDir * unplaced.fDimensions;
0167 const Real_v distIn = ((-temp - p) * invDir).Max();
0168 const Real_v distOut = ((temp - p) * invDir).Min();
0169
0170
0171 distance = Real_v(kInfLength);
0172 vecCore__MaskedAssignFunc(distance, !leaving && distOut > distIn + kHalfTolerance, distIn);
0173 }
0174
0175 template <typename Real_v>
0176 VECGEOM_FORCE_INLINE
0177 VECCORE_ATT_HOST_DEVICE
0178 static void DistanceToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0179 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0180 {
0181
0182
0183 Vector3D<Real_v> p(point);
0184 Vector3D<Real_v> v(direction);
0185 Vector3D<Real_v> safetyVector;
0186
0187 Transform<Real_v>(unplaced, p);
0188 Transform<Real_v>(unplaced, v);
0189 SafetyVector<Real_v>(unplaced, p, safetyVector);
0190
0191
0192 const Vector3D<Real_v> dir(NonZero(v.x()), NonZero(v.y()), NonZero(v.z()));
0193 const Vector3D<Real_v> signDir(Sign(dir.x()), Sign(dir.y()), Sign(dir.z()));
0194 distance = ((signDir * unplaced.fDimensions - p) / dir).Min();
0195
0196
0197 vecCore__MaskedAssignFunc(distance, safetyVector.Max() > kHalfTolerance, Real_v(-1.0));
0198 }
0199
0200 template <typename Real_v>
0201 VECGEOM_FORCE_INLINE
0202 VECCORE_ATT_HOST_DEVICE
0203 static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0204 typename vecCore::Mask_v<Real_v> &valid)
0205 {
0206
0207
0208
0209
0210 Vector3D<Real_v> normal(0.);
0211 valid = true;
0212
0213
0214 Vector3D<Real_v> p(point);
0215 Vector3D<Real_v> safetyVector;
0216 Transform<Real_v>(unplaced, p);
0217 SafetyVector<Real_v>(unplaced, p, safetyVector);
0218
0219
0220 const Vector3D<Real_v> signs(Sign(p.x()), Sign(p.y()), Sign(p.z()));
0221 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.z()) <= kHalfTolerance, Vector3D<Real_v>(0., 0., signs.z()));
0222 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.y()) <= kHalfTolerance,
0223 normal + signs.y() * unplaced.fNormals[1]);
0224 vecCore__MaskedAssignFunc(normal, Abs(safetyVector.x()) <= kHalfTolerance,
0225 normal + signs.x() * unplaced.fNormals[0]);
0226
0227 Real_v mag2 = normal.Mag2();
0228 vecCore__MaskedAssignFunc(normal, mag2 > 1., normal.Unit());
0229 if (vecCore::MaskFull(mag2 > Real_v(0.))) return normal;
0230
0231
0232
0233 vecCore__MaskedAssignFunc(valid, mag2 == Real_v(0.), false);
0234 Real_v safety = safetyVector.Max();
0235 normal = signs.x() * unplaced.fNormals[0];
0236 vecCore__MaskedAssignFunc(normal, safetyVector.y() == safety, signs.y() * unplaced.fNormals[1]);
0237 vecCore__MaskedAssignFunc(normal, safetyVector.z() == safety, signs.z() * unplaced.fNormals[2]);
0238 return normal;
0239 }
0240 };
0241 }
0242 }
0243
0244 #endif