File indexing completed on 2025-01-18 10:14:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef VECGEOM_VOLUMES_KERNEL_ELLIPTICALTUBEIMPLEMENTATION_H_
0010 #define VECGEOM_VOLUMES_KERNEL_ELLIPTICALTUBEIMPLEMENTATION_H_
0011
0012 #include "VecGeom/base/Vector3D.h"
0013 #include "VecGeom/volumes/EllipticalTubeStruct.h"
0014 #include "VecGeom/volumes/kernel/GenericKernels.h"
0015 #include <VecCore/VecCore>
0016
0017 #include <cstdio>
0018
0019 namespace vecgeom {
0020
0021 VECGEOM_DEVICE_FORWARD_DECLARE(struct EllipticalTubeImplementation;);
0022 VECGEOM_DEVICE_DECLARE_CONV(struct, EllipticalTubeImplementation);
0023
0024 inline namespace VECGEOM_IMPL_NAMESPACE {
0025
0026 class PlacedEllipticalTube;
0027 template <typename T>
0028 struct EllipticalTubeStruct;
0029 class UnplacedEllipticalTube;
0030
0031 struct EllipticalTubeImplementation {
0032
0033 using PlacedShape_t = PlacedEllipticalTube;
0034 using UnplacedStruct_t = EllipticalTubeStruct<Precision>;
0035 using UnplacedVolume_t = UnplacedEllipticalTube;
0036
0037 VECCORE_ATT_HOST_DEVICE
0038 static void PrintType()
0039 {
0040
0041 }
0042
0043 template <typename Stream>
0044 static void PrintType(Stream &st, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0045 {
0046 st << "SpecializedEllipticalTube<" << transCodeT << "," << rotCodeT << ">";
0047 }
0048
0049 template <typename Stream>
0050 static void PrintImplementationType(Stream &st)
0051 {
0052 (void)st;
0053
0054 }
0055
0056 template <typename Stream>
0057 static void PrintUnplacedType(Stream &st)
0058 {
0059 (void)st;
0060
0061
0062 }
0063
0064 template <typename Real_v, typename Bool_v>
0065 VECGEOM_FORCE_INLINE
0066 VECCORE_ATT_HOST_DEVICE
0067 static void Contains(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point, Bool_v &inside)
0068 {
0069 Bool_v unused, outside;
0070 GenericKernelForContainsAndInside<Real_v, Bool_v, false>(ellipticaltube, point, unused, outside);
0071 inside = !outside;
0072 }
0073
0074
0075
0076 template <typename Real_v, typename Inside_t>
0077 VECGEOM_FORCE_INLINE
0078 VECCORE_ATT_HOST_DEVICE
0079 static void Inside(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point, Inside_t &inside)
0080 {
0081
0082 using Bool_v = vecCore::Mask_v<Real_v>;
0083 using InsideBool_v = vecCore::Mask_v<Inside_t>;
0084 Bool_v completelyinside, completelyoutside;
0085 GenericKernelForContainsAndInside<Real_v, Bool_v, true>(ellipticaltube, point, completelyinside, completelyoutside);
0086 inside = EInside::kSurface;
0087 vecCore::MaskedAssign(inside, (InsideBool_v)completelyoutside, Inside_t(EInside::kOutside));
0088 vecCore::MaskedAssign(inside, (InsideBool_v)completelyinside, Inside_t(EInside::kInside));
0089 }
0090
0091 template <typename Real_v, typename Bool_v, bool ForInside>
0092 VECGEOM_FORCE_INLINE
0093 VECCORE_ATT_HOST_DEVICE
0094 static void GenericKernelForContainsAndInside(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point,
0095 Bool_v &completelyinside, Bool_v &completelyoutside)
0096 {
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 Real_v x = point.x() * ellipticaltube.fSx;
0107 Real_v y = point.y() * ellipticaltube.fSy;
0108 Real_v distR = ellipticaltube.fQ1 * (x * x + y * y) - ellipticaltube.fQ2;
0109 Real_v distZ = vecCore::math::Abs(point.z()) - ellipticaltube.fDz;
0110 Real_v safety = vecCore::math::Max(distR, distZ);
0111
0112 completelyoutside = safety > kHalfTolerance;
0113 if (ForInside) completelyinside = safety <= -kHalfTolerance;
0114 return;
0115 }
0116
0117 template <typename Real_v>
0118 VECGEOM_FORCE_INLINE
0119 VECCORE_ATT_HOST_DEVICE
0120 static void DistanceToIn(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point,
0121 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0122 {
0123
0124 using Bool_v = vecCore::Mask_v<Real_v>;
0125 distance = kInfLength;
0126 Real_v offset(0.);
0127 Vector3D<Real_v> pcur(point);
0128
0129
0130 Real_v Rfar2(1024. * ellipticaltube.fRsph * ellipticaltube.fRsph);
0131 vecCore__MaskedAssignFunc(pcur, ((pcur.Mag2() > Rfar2) && (direction.Dot(point) < Real_v(0.))),
0132 pcur + (offset = pcur.Mag() - Real_v(2.) * ellipticaltube.fRsph) * direction);
0133
0134
0135 Real_v px = pcur.x() * ellipticaltube.fSx;
0136 Real_v py = pcur.y() * ellipticaltube.fSy;
0137 Real_v pz = pcur.z();
0138 Real_v vx = direction.x() * ellipticaltube.fSx;
0139 Real_v vy = direction.y() * ellipticaltube.fSy;
0140 Real_v vz = direction.z();
0141
0142
0143 Real_v invz = Real_v(-1.) / NonZero(vz);
0144 Real_v dz = vecCore::math::CopySign(Real_v(ellipticaltube.fDz), invz);
0145 Real_v tzmin = (pz - dz) * invz;
0146 Real_v tzmax = (pz + dz) * invz;
0147
0148
0149 Real_v rr = px * px + py * py;
0150 Real_v A = vx * vx + vy * vy;
0151 Real_v B = px * vx + py * vy;
0152 Real_v C = rr - ellipticaltube.fR * ellipticaltube.fR;
0153 Real_v D = B * B - A * C;
0154
0155
0156 Real_v distZ = vecCore::math::Abs(pz) - ellipticaltube.fDz;
0157 Real_v distR = ellipticaltube.fQ1 * rr - ellipticaltube.fQ2;
0158 Bool_v parallelToZ = (A < kEpsilon || vecCore::math::Abs(vz) >= Real_v(1.));
0159 Bool_v leaving = (distZ >= -kHalfTolerance && pz * vz >= Real_v(0.)) ||
0160 (distR >= -kHalfTolerance && (B >= Real_v(0.) || parallelToZ));
0161
0162
0163
0164
0165 vecCore__MaskedAssignFunc(distance, !leaving && parallelToZ, tzmin + offset);
0166 Bool_v done = (leaving || parallelToZ || D <= A * A * ellipticaltube.fScratch);
0167
0168
0169
0170
0171 Real_v tmp(0.), t1(0.), t2(0.);
0172 vecCore__MaskedAssignFunc(tmp, !done, -B - vecCore::math::CopySign(vecCore::math::Sqrt(D), B));
0173 vecCore__MaskedAssignFunc(t1, !done, tmp / A);
0174 vecCore__MaskedAssignFunc(t2, !done, C / tmp);
0175 Real_v trmin = vecCore::math::Min(t1, t2);
0176 Real_v trmax = vecCore::math::Max(t1, t2);
0177
0178
0179
0180 Real_v tin = vecCore::math::Max(tzmin, trmin);
0181 Real_v tout = vecCore::math::Min(tzmax, trmax);
0182 vecCore__MaskedAssignFunc(distance, !done && (tout - tin) >= kHalfTolerance, tin + offset);
0183 }
0184
0185 template <typename Real_v>
0186 VECGEOM_FORCE_INLINE
0187 VECCORE_ATT_HOST_DEVICE
0188 static void DistanceToOut(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point,
0189 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0190 {
0191
0192 using Bool_v = vecCore::Mask_v<Real_v>;
0193
0194
0195 Real_v px = point.x() * ellipticaltube.fSx;
0196 Real_v py = point.y() * ellipticaltube.fSy;
0197 Real_v pz = point.z();
0198 Real_v vx = direction.x() * ellipticaltube.fSx;
0199 Real_v vy = direction.y() * ellipticaltube.fSy;
0200 Real_v vz = direction.z();
0201
0202
0203 Real_v rr = px * px + py * py;
0204 Real_v distR = ellipticaltube.fQ1 * rr - ellipticaltube.fQ2;
0205 Real_v distZ = vecCore::math::Abs(pz) - ellipticaltube.fDz;
0206 Bool_v outside = vecCore::math::Max(distR, distZ) > kHalfTolerance;
0207 distance = Real_v(0.);
0208 vecCore__MaskedAssignFunc(distance, outside, Real_v(-1.));
0209
0210
0211 Real_v tzmax = kMaximum;
0212 vecCore__MaskedAssignFunc(tzmax, vz != Real_v(0.),
0213 (vecCore::math::CopySign(Real_v(ellipticaltube.fDz), vz) - pz) / vz);
0214
0215
0216 Real_v A = vx * vx + vy * vy;
0217 Real_v B = px * vx + py * vy;
0218 Real_v C = rr - ellipticaltube.fR * ellipticaltube.fR;
0219 Real_v D = B * B - A * C;
0220
0221
0222
0223
0224 Bool_v parallelToZ = (A < kEpsilon || vecCore::math::Abs(vz) >= Real_v(1.));
0225 vecCore__MaskedAssignFunc(distance, (!outside && parallelToZ), tzmax);
0226 Bool_v done = (outside || parallelToZ || D <= Real_v(0.));
0227
0228
0229
0230 vecCore__MaskedAssignFunc(distance, !done && B >= Real_v(0.),
0231 vecCore::math::Min(tzmax, -C / (vecCore::math::Sqrt(D) + B)));
0232 vecCore__MaskedAssignFunc(distance, !done && B < Real_v(0.),
0233 vecCore::math::Min(tzmax, (vecCore::math::Sqrt(D) - B) / A));
0234 }
0235
0236 template <typename Real_v>
0237 VECGEOM_FORCE_INLINE
0238 VECCORE_ATT_HOST_DEVICE
0239 static void SafetyToIn(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point, Real_v &safety)
0240 {
0241
0242 Real_v x = point.x() * ellipticaltube.fSx;
0243 Real_v y = point.y() * ellipticaltube.fSy;
0244 Real_v distR = vecCore::math::Sqrt(x * x + y * y) - ellipticaltube.fR;
0245 Real_v distZ = vecCore::math::Abs(point.z()) - ellipticaltube.fDz;
0246
0247 safety = vecCore::math::Max(distR, distZ);
0248 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) <= kHalfTolerance, Real_v(0.));
0249 }
0250
0251 template <typename Real_v>
0252 VECGEOM_FORCE_INLINE
0253 VECCORE_ATT_HOST_DEVICE
0254 static void SafetyToOut(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point, Real_v &safety)
0255 {
0256
0257 Real_v x = point.x() * ellipticaltube.fSx;
0258 Real_v y = point.y() * ellipticaltube.fSy;
0259 Real_v distR = ellipticaltube.fR - vecCore::math::Sqrt(x * x + y * y);
0260 Real_v distZ = ellipticaltube.fDz - vecCore::math::Abs(point.z());
0261
0262 safety = vecCore::math::Min(distR, distZ);
0263 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) <= kHalfTolerance, Real_v(0.));
0264 }
0265
0266 template <typename Real_v>
0267 VECGEOM_FORCE_INLINE
0268 VECCORE_ATT_HOST_DEVICE
0269 static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &ellipticaltube, Vector3D<Real_v> const &point,
0270 typename vecCore::Mask_v<Real_v> &valid)
0271 {
0272
0273
0274
0275
0276
0277 Vector3D<Real_v> normal(0.);
0278 valid = true;
0279
0280 Real_v x = point.x() * ellipticaltube.fSx;
0281 Real_v y = point.y() * ellipticaltube.fSy;
0282 Real_v distR = ellipticaltube.fQ1 * (x * x + y * y) - ellipticaltube.fQ2;
0283 vecCore__MaskedAssignFunc(
0284 normal, vecCore::math::Abs(distR) <= kHalfTolerance,
0285 Vector3D<Real_v>(point.x() * ellipticaltube.fDDy, point.y() * ellipticaltube.fDDx, 0.).Unit());
0286
0287 Real_v distZ = vecCore::math::Abs(point.z()) - ellipticaltube.fDz;
0288 vecCore__MaskedAssignFunc(normal[2], vecCore::math::Abs(distZ) <= kHalfTolerance, vecCore::math::Sign(point[2]));
0289 vecCore__MaskedAssignFunc(normal, normal.Mag2() > 1., normal.Unit());
0290
0291 vecCore::Mask_v<Real_v> done = normal.Mag2() > Real_v(0.);
0292 if (vecCore::MaskFull(done)) return normal;
0293
0294
0295
0296 vecCore__MaskedAssignFunc(valid, !done, false);
0297 vecCore__MaskedAssignFunc(normal[2], !done, vecCore::math::Sign(point[2]));
0298 vecCore__MaskedAssignFunc(distR, !done, vecCore::math::Sqrt(x * x + y * y) - ellipticaltube.fR);
0299 vecCore__MaskedAssignFunc(
0300 normal, !done && distR > distZ && (x * x + y * y) > Real_v(0.),
0301 Vector3D<Real_v>(point.x() * ellipticaltube.fDDy, point.y() * ellipticaltube.fDDx, 0.).Unit());
0302 return normal;
0303 }
0304 };
0305 }
0306 }
0307
0308 #endif