File indexing completed on 2025-01-18 10:14:01
0001
0002
0003
0004
0005
0006 #ifndef VECGEOM_VOLUMES_KERNEL_EXTRUDEDIMPLEMENTATION_H_
0007 #define VECGEOM_VOLUMES_KERNEL_EXTRUDEDIMPLEMENTATION_H_
0008
0009 #include <cstdio>
0010 #include <VecCore/VecCore>
0011 #include "VecGeom/base/Config.h"
0012 #include "VecGeom/volumes/kernel/GenericKernels.h"
0013 #include "VecGeom/base/Vector3D.h"
0014
0015 #include "TessellatedImplementation.h"
0016 #include "SExtruImplementation.h"
0017
0018 namespace vecgeom {
0019
0020 VECGEOM_DEVICE_FORWARD_DECLARE(struct ExtrudedImplementation;);
0021 VECGEOM_DEVICE_DECLARE_CONV(struct, ExtrudedImplementation);
0022
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024
0025 class PlacedExtruded;
0026 class ExtrudedStruct;
0027 class UnplacedExtruded;
0028
0029 struct ExtrudedImplementation {
0030
0031 using PlacedShape_t = PlacedExtruded;
0032 using UnplacedStruct_t = ExtrudedStruct;
0033 using UnplacedVolume_t = UnplacedExtruded;
0034
0035 VECCORE_ATT_HOST_DEVICE
0036 static void PrintType()
0037 {
0038
0039 }
0040
0041 template <typename Stream>
0042 static void PrintType(Stream &st, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0043 {
0044 st << "SpecializedExtruded<" << transCodeT << "," << rotCodeT << ">";
0045 }
0046
0047 template <typename Stream>
0048 static void PrintImplementationType(Stream &st)
0049 {
0050 (void)st;
0051 }
0052
0053 template <typename Stream>
0054 static void PrintUnplacedType(Stream &st)
0055 {
0056 (void)st;
0057 }
0058
0059 template <typename Real_v, typename Bool_v>
0060 VECGEOM_FORCE_INLINE
0061 VECCORE_ATT_HOST_DEVICE
0062 static void Contains(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point, Bool_v &inside)
0063 {
0064 inside = false;
0065 if (extruded.fIsSxtru) {
0066 SExtruImplementation::Contains<Real_v, Bool_v>(extruded.fSxtruHelper, point, inside);
0067 return;
0068 }
0069
0070 #ifndef VECGEOM_ENABLE_CUDA
0071 if (extruded.fUseTslSections) {
0072
0073 int zIndex = extruded.FindZSegment(point[2]);
0074 if ((zIndex < 0) || (zIndex >= (int)extruded.GetNSegments())) return;
0075 inside = extruded.fTslSections[zIndex]->Contains(point);
0076 return;
0077 }
0078 #endif
0079 TessellatedImplementation::Contains<Real_v, Bool_v>(extruded.fTslHelper, point, inside);
0080 }
0081
0082 template <typename Real_v, typename Inside_v>
0083 VECGEOM_FORCE_INLINE
0084 VECCORE_ATT_HOST_DEVICE
0085 static void Inside(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point, Inside_v &inside)
0086 {
0087 inside = EInside::kOutside;
0088
0089 if (extruded.fIsSxtru) {
0090 SExtruImplementation::Inside<Real_v, Inside_v>(extruded.fSxtruHelper, point, inside);
0091 return;
0092 }
0093
0094 #ifndef VECGEOM_ENABLE_CUDA
0095 if (extruded.fUseTslSections) {
0096 const int nseg = (int)extruded.GetNSegments();
0097 int zIndex = extruded.FindZSegment(point[2]);
0098 if ((zIndex < 0) || (zIndex > nseg)) return;
0099 inside = extruded.fTslSections[Min(zIndex, nseg - 1)]->Inside(point);
0100 if (inside == EInside::kOutside) return;
0101 if (inside == EInside::kInside) {
0102
0103 if (((zIndex == 0) || (zIndex == nseg)) &&
0104 vecCore::math::Abs(point[2] - extruded.fZPlanes[zIndex]) < kTolerance) {
0105 inside = EInside::kSurface;
0106 }
0107 } else {
0108 inside = EInside::kSurface;
0109 }
0110 return;
0111 }
0112 #endif
0113 TessellatedImplementation::Inside<Real_v, Inside_v>(extruded.fTslHelper, point, inside);
0114 }
0115
0116 template <typename Real_v>
0117 VECGEOM_FORCE_INLINE
0118 VECCORE_ATT_HOST_DEVICE
0119 static void DistanceToIn(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point,
0120 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance)
0121 {
0122
0123 #ifdef EFFICIENT_TSL_DISTANCETOIN
0124 if (extruded.fUseTslSections) {
0125
0126 const Vector3D<Real_v> invdir(Real_v(1.0) / NonZero(direction.x()), Real_v(1.0) / NonZero(direction.y()),
0127 Real_v(1.0) / NonZero(direction.z()));
0128 Vector3D<int> sign;
0129 sign[0] = invdir.x() < 0;
0130 sign[1] = invdir.y() < 0;
0131 sign[2] = invdir.z() < 0;
0132 distance = BoxImplementation::IntersectCachedKernel2<Real_v, Real_v>(&extruded.fTslHelper.fMinExtent, point,
0133 invdir, sign.x(), sign.y(), sign.z(),
0134 -kTolerance, InfinityLength<Real_v>());
0135 if (distance >= stepMax) return;
0136
0137
0138
0139
0140
0141
0142 int zIndex = extruded.FindZSegment(point[2]);
0143 const int zMax = extruded.GetNSegments();
0144
0145
0146 bool fromOutZ =
0147 (point[2] < extruded.fZPlanes[0] + kTolerance) || (point[2] > extruded.fZPlanes[zMax] - kTolerance);
0148 zIndex = zIndex < 0 ? 0 : (zIndex >= zMax ? zMax - 1 : zIndex);
0149
0150
0151 bool goingRight = direction[2] >= 0;
0152
0153 distance = InfinityLength<Real_v>();
0154 if (goingRight) {
0155 for (int zSegCount = zMax; zIndex < zSegCount; ++zIndex) {
0156 bool skipZ = fromOutZ && (zSegCount == 0);
0157 if (skipZ)
0158 distance = extruded.fTslSections[zIndex]->DistanceToIn<true>(point, direction, invdir.z(), stepMax);
0159 else
0160 distance = extruded.fTslSections[zIndex]->DistanceToIn<false>(point, direction, invdir.z(), stepMax);
0161
0162
0163 if (distance >= -kTolerance && distance < InfinityLength<Precision>()) break;
0164 }
0165 } else {
0166
0167 for (; zIndex >= 0; --zIndex) {
0168 bool skipZ = fromOutZ && (zIndex == zMax);
0169 if (skipZ)
0170 distance = extruded.fTslSections[zIndex]->DistanceToIn<true>(point, direction, invdir.z(), stepMax);
0171 else
0172 distance = extruded.fTslSections[zIndex]->DistanceToIn<false>(point, direction, invdir.z(), stepMax);
0173
0174
0175 if (distance >= -kTolerance && distance < InfinityLength<Precision>()) break;
0176 }
0177 }
0178 }
0179 #endif
0180 if (extruded.fIsSxtru)
0181 SExtruImplementation::DistanceToIn<Real_v>(extruded.fSxtruHelper, point, direction, stepMax, distance);
0182 else
0183 TessellatedImplementation::DistanceToIn<Real_v>(extruded.fTslHelper, point, direction, stepMax, distance);
0184 }
0185
0186 template <typename Real_v>
0187 VECGEOM_FORCE_INLINE
0188 VECCORE_ATT_HOST_DEVICE
0189 static void DistanceToOut(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point,
0190 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance)
0191 {
0192 if (extruded.fIsSxtru)
0193 SExtruImplementation::DistanceToOut<Real_v>(extruded.fSxtruHelper, point, direction, stepMax, distance);
0194 else
0195 TessellatedImplementation::DistanceToOut<Real_v>(extruded.fTslHelper, point, direction, stepMax, distance);
0196 }
0197
0198 template <typename Real_v>
0199 VECGEOM_FORCE_INLINE
0200 VECCORE_ATT_HOST_DEVICE
0201 static void SafetyToIn(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point, Real_v &safety)
0202 {
0203 if (extruded.fIsSxtru)
0204 SExtruImplementation::SafetyToIn<Real_v>(extruded.fSxtruHelper, point, safety);
0205 else
0206 TessellatedImplementation::SafetyToIn<Real_v>(extruded.fTslHelper, point, safety);
0207 }
0208
0209 template <typename Real_v>
0210 VECGEOM_FORCE_INLINE
0211 VECCORE_ATT_HOST_DEVICE
0212 static void SafetyToOut(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point, Real_v &safety)
0213 {
0214 if (extruded.fIsSxtru)
0215 SExtruImplementation::SafetyToOut<Real_v>(extruded.fSxtruHelper, point, safety);
0216 else
0217 TessellatedImplementation::SafetyToOut<Real_v>(extruded.fTslHelper, point, safety);
0218 }
0219
0220 template <typename Real_v>
0221 VECGEOM_FORCE_INLINE
0222 VECCORE_ATT_HOST_DEVICE
0223 static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &extruded, Vector3D<Real_v> const &point,
0224 typename vecCore::Mask_v<Real_v> &valid)
0225 {
0226
0227 if (extruded.fIsSxtru) return SExtruImplementation::NormalKernel<Real_v>(extruded.fSxtruHelper, point, valid);
0228 return TessellatedImplementation::NormalKernel<Real_v>(extruded.fTslHelper, point, valid);
0229 }
0230
0231 };
0232
0233 }
0234 }
0235
0236 #endif