File indexing completed on 2025-01-18 10:14:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef VECGEOM_VOLUMES_KERNEL_ELLIPTICALCONEIMPLEMENTATION_H_
0010 #define VECGEOM_VOLUMES_KERNEL_ELLIPTICALCONEIMPLEMENTATION_H_
0011
0012 #include "VecGeom/base/Vector3D.h"
0013 #include "VecGeom/volumes/EllipticalConeStruct.h"
0014 #include "VecGeom/volumes/kernel/GenericKernels.h"
0015 #include <VecCore/VecCore>
0016
0017 #include <cstdio>
0018 #include <iomanip>
0019
0020 namespace vecgeom {
0021
0022 VECGEOM_DEVICE_FORWARD_DECLARE(struct EllipticalConeImplementation;);
0023 VECGEOM_DEVICE_DECLARE_CONV(struct, EllipticalConeImplementation);
0024
0025 inline namespace VECGEOM_IMPL_NAMESPACE {
0026
0027 class PlacedEllipticalCone;
0028 template <typename T>
0029 struct EllipticalConeStruct;
0030 class UnplacedEllipticalCone;
0031
0032 struct EllipticalConeImplementation {
0033
0034 using PlacedShape_t = PlacedEllipticalCone;
0035 using UnplacedStruct_t = EllipticalConeStruct<Precision>;
0036 using UnplacedVolume_t = UnplacedEllipticalCone;
0037
0038 VECCORE_ATT_HOST_DEVICE
0039 static void PrintType()
0040 {
0041
0042 }
0043
0044 template <typename Stream>
0045 static void PrintType(Stream &st, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0046 {
0047 st << "SpecializedEllipticalCone<" << transCodeT << "," << rotCodeT << ">";
0048 }
0049
0050 template <typename Stream>
0051 static void PrintImplementationType(Stream &st)
0052 {
0053 (void)st;
0054
0055 }
0056
0057 template <typename Stream>
0058 static void PrintUnplacedType(Stream &st)
0059 {
0060 (void)st;
0061
0062
0063 }
0064
0065 template <typename Real_v, typename Bool_v>
0066 VECGEOM_FORCE_INLINE
0067 VECCORE_ATT_HOST_DEVICE
0068 static void Contains(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point, Bool_v &inside)
0069 {
0070 Bool_v unused, outside;
0071 GenericKernelForContainsAndInside<Real_v, Bool_v, false>(ellipticalcone, point, unused, outside);
0072 inside = !outside;
0073 }
0074
0075
0076
0077 template <typename Real_v, typename Inside_t>
0078 VECGEOM_FORCE_INLINE
0079 VECCORE_ATT_HOST_DEVICE
0080 static void Inside(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point, Inside_t &inside)
0081 {
0082
0083 using Bool_v = vecCore::Mask_v<Real_v>;
0084 using InsideBool_v = vecCore::Mask_v<Inside_t>;
0085 Bool_v completelyinside, completelyoutside;
0086 GenericKernelForContainsAndInside<Real_v, Bool_v, true>(ellipticalcone, point, completelyinside, completelyoutside);
0087 inside = EInside::kSurface;
0088 vecCore::MaskedAssign(inside, (InsideBool_v)completelyoutside, Inside_t(EInside::kOutside));
0089 vecCore::MaskedAssign(inside, (InsideBool_v)completelyinside, Inside_t(EInside::kInside));
0090 }
0091
0092 template <typename Real_v, typename Bool_v, bool ForInside>
0093 VECGEOM_FORCE_INLINE
0094 VECCORE_ATT_HOST_DEVICE
0095 static void GenericKernelForContainsAndInside(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point,
0096 Bool_v &completelyinside, Bool_v &completelyoutside)
0097 {
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 Real_v px = point.x() * ellipticalcone.invDx;
0108 Real_v py = point.y() * ellipticalcone.invDy;
0109 Real_v pz = point.z();
0110 Real_v hp = vecCore::math::Sqrt(px * px + py * py) + pz;
0111 Real_v ds = (hp - ellipticalcone.fDz) * ellipticalcone.cosAxisMin;
0112 Real_v dz = vecCore::math::Abs(pz) - ellipticalcone.fZCut;
0113 Real_v safety = vecCore::math::Max(ds, dz);
0114
0115 completelyoutside = safety > kHalfTolerance;
0116 if (ForInside) completelyinside = safety <= -kHalfTolerance;
0117 return;
0118 }
0119
0120 template <typename Real_v>
0121 VECGEOM_FORCE_INLINE
0122 VECCORE_ATT_HOST_DEVICE
0123 static void DistanceToIn(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point,
0124 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0125 {
0126
0127 using Bool_v = vecCore::Mask_v<Real_v>;
0128 Real_v kTwoEpsilon = 2. * kEpsilon;
0129 distance = Real_v(kInfLength);
0130 Real_v offset(0.);
0131 Vector3D<Real_v> p(point);
0132
0133
0134 Real_v Rfar2(1024. * ellipticalcone.fRsph * ellipticalcone.fRsph);
0135 vecCore__MaskedAssignFunc(offset, ((p.Mag2() > Rfar2) && (direction.Dot(p) < Real_v(0.))),
0136 p.Mag() - Real_v(2.) * ellipticalcone.fRsph);
0137 p += offset * direction;
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 Real_v px = p.x() * ellipticalcone.invDx;
0148 Real_v py = p.y() * ellipticalcone.invDy;
0149 Real_v pz = p.z();
0150 Real_v pz0 = p.z() - ellipticalcone.fDz;
0151 Real_v vx = direction.x() * ellipticalcone.invDx;
0152 Real_v vy = direction.y() * ellipticalcone.invDy;
0153 Real_v vz = direction.z();
0154
0155
0156 Real_v Ar = vx * vx + vy * vy;
0157 Real_v Br = px * vx + py * vy;
0158 Real_v Cr = px * px + py * py;
0159
0160
0161
0162 Real_v vzvz = vz * vz;
0163 Bool_v tinyA = vecCore::math::Abs(Ar - vzvz) < kTwoEpsilon * vzvz;
0164 vecCore__MaskedAssignFunc(vz, tinyA, vz + vecCore::math::Abs(vz) * kTwoEpsilon);
0165
0166 Real_v Az = vz * vz;
0167 Real_v Bz = pz0 * vz;
0168 Real_v Cz = pz0 * pz0;
0169 Real_v A = Ar - Az;
0170 Real_v B = Br - Bz;
0171 Real_v B0 = Br - pz0 * direction.z();
0172 Real_v C = Cr - Cz;
0173 Real_v D = B * B - A * C;
0174
0175
0176 Real_v sfz = vecCore::math::Abs(pz) - ellipticalcone.fZCut;
0177 Real_v nz = vecCore::math::Sqrt(Cr);
0178 Real_v sfr = (nz + pz0) * ellipticalcone.cosAxisMin;
0179 vecCore::MaskedAssign(nz, (vecCore::math::Abs(p.x()) + vecCore::math::Abs(p.y()) < Real_v(0.1) * kHalfTolerance),
0180 Real_v(1.));
0181 Real_v pzA = pz0 + ellipticalcone.dApex;
0182 Bool_v done =
0183 (sfz >= -kHalfTolerance && pz * vz >= Real_v(0.)) || (sfr >= -kHalfTolerance && Br + nz * vz >= Real_v(0.)) ||
0184 (pz0 * ellipticalcone.cosAxisMin > -kHalfTolerance && (Cr - pzA * pzA) <= Real_v(0.) && A >= Real_v(0.));
0185
0186
0187
0188 vecCore__MaskedAssignFunc(D, (sfr <= Real_v(0.) && D < Real_v(0.)), Real_v(0.));
0189 done |= (D < Real_v(0.)) || ((D < kTwoEpsilon * B * B) && (A >= Real_v(0.)));
0190
0191
0192 Real_v invz = Real_v(-1.) / NonZero(vz);
0193 Real_v dz = vecCore::math::CopySign(Real_v(ellipticalcone.fZCut), invz);
0194 Real_v tzin = (pz - dz) * invz;
0195 Real_v tzout = (pz + dz) * invz;
0196
0197
0198 Real_v tmp(0.), t1(0.), t2(0.);
0199 vecCore__MaskedAssignFunc(tmp, !done, -B - vecCore::math::CopySign(vecCore::math::Sqrt(D), B));
0200 vecCore__MaskedAssignFunc(t1, !done, tmp / A);
0201 vecCore__MaskedAssignFunc(t2, !done && tmp != 0, C / tmp);
0202 vecCore__MaskedAssignFunc(t2, !done && tinyA && B != Real_v(0.), -C / (Real_v(2.) * B0));
0203 Real_v tmin = vecCore::math::Min(t1, t2);
0204 Real_v tmax = vecCore::math::Max(t1, t2);
0205
0206
0207 Real_v trin = tmin;
0208 Real_v trout = tmax;
0209
0210 done |= (A >= Real_v(0.) && pz0 + vz * tmin >= Real_v(0.));
0211
0212
0213 vecCore__MaskedAssignFunc(trin, (!done && A < Real_v(0.)), Real_v(-kInfLength));
0214 vecCore__MaskedAssignFunc(trout, (!done && A < Real_v(0.)), Real_v(kInfLength));
0215 vecCore__MaskedAssignFunc(trin, (!done && A < Real_v(0.) && vz < Real_v(0.)), tmax);
0216 vecCore__MaskedAssignFunc(trout, (!done && A < Real_v(0.) && vz > Real_v(0.)), tmin);
0217
0218
0219
0220 Real_v tin = vecCore::math::Max(tzin, trin);
0221 Real_v tout = vecCore::math::Min(tzout, trout);
0222 vecCore__MaskedAssignFunc(distance, !done && (tout - tin) >= kHalfTolerance, tin + offset);
0223 }
0224
0225 template <typename Real_v>
0226 VECGEOM_FORCE_INLINE
0227 VECCORE_ATT_HOST_DEVICE
0228 static void DistanceToOut(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point,
0229 Vector3D<Real_v> const &direction, Real_v const & , Real_v &distance)
0230 {
0231
0232 using Bool_v = vecCore::Mask_v<Real_v>;
0233 Real_v kTwoEpsilon = 2. * kEpsilon;
0234 distance = Real_v(0.);
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 Real_v px = point.x() * ellipticalcone.invDx;
0245 Real_v py = point.y() * ellipticalcone.invDy;
0246 Real_v pz = point.z();
0247 Real_v pz0 = pz - ellipticalcone.fDz;
0248 Real_v hp = vecCore::math::Sqrt(px * px + py * py) + pz;
0249 Real_v sfr = (hp - ellipticalcone.fDz) * ellipticalcone.cosAxisMin;
0250 Real_v sfz = vecCore::math::Abs(pz) - ellipticalcone.fZCut;
0251
0252
0253 Bool_v outside = vecCore::math::Max(sfr, sfz) > kHalfTolerance;
0254 vecCore__MaskedAssignFunc(distance, outside, Real_v(-1.));
0255 Bool_v done = outside;
0256
0257
0258 Real_v vx = direction.x() * ellipticalcone.invDx;
0259 Real_v vy = direction.y() * ellipticalcone.invDy;
0260 Real_v vz = direction.z();
0261 Real_v Ar = vx * vx + vy * vy;
0262 Real_v Br = px * vx + py * vy;
0263 Real_v Cr = px * px + py * py;
0264
0265
0266
0267 Bool_v tinyA = vecCore::math::Abs(Ar - vz * vz) < kTwoEpsilon * vz * vz;
0268 vecCore__MaskedAssignFunc(vz, tinyA, vz + vecCore::math::Abs(vz) * kTwoEpsilon);
0269
0270 Real_v Az = vz * vz;
0271 Real_v Bz = pz0 * vz;
0272 Real_v Cz = pz0 * pz0;
0273 Real_v A = Ar - Az;
0274 Real_v B = Br - Bz;
0275 Real_v B0 = Br - pz0 * direction.z();
0276 Real_v C = Cr - Cz;
0277 Real_v D = B * B - A * C;
0278 vecCore__MaskedAssignFunc(D, (sfr <= Real_v(0.) && D < Real_v(0.)), Real_v(0.));
0279
0280
0281
0282 done |= (D < Real_v(0.)) || (D < kTwoEpsilon * B * B && A >= Real_v(0.));
0283
0284
0285 Real_v tzout = kMaximum;
0286 vecCore__MaskedAssignFunc(tzout, vz != Real_v(0.),
0287 (vecCore::math::CopySign(Real_v(ellipticalcone.fZCut), vz) - pz) / direction.z());
0288
0289
0290 Real_v tmp(0.), t1(0.), t2(0.);
0291 vecCore__MaskedAssignFunc(tmp, !done, -B - vecCore::math::CopySign(vecCore::math::Sqrt(D), B));
0292 vecCore__MaskedAssignFunc(t1, !done, tmp / A);
0293 vecCore__MaskedAssignFunc(t2, !done && tmp != Real_v(0.), C / tmp);
0294 vecCore__MaskedAssignFunc(t2, !done && tinyA && B0 != Real_v(0.), -C / (Real_v(2.) * B0));
0295 Real_v tmin = vecCore::math::Min(t1, t2);
0296 Real_v tmax = vecCore::math::Max(t1, t2);
0297
0298
0299 Real_v trout = tmax;
0300
0301 done |= ((A >= Real_v(0.) && pz0 + vz * tmax >= Real_v(0.)) || (pz0 >= Real_v(0.) && vz >= Real_v(0.)));
0302
0303
0304 vecCore__MaskedAssignFunc(trout, (!done && A < Real_v(0.)), Real_v(kInfLength));
0305 vecCore__MaskedAssignFunc(trout, (!done && A < Real_v(0.) && vz > Real_v(0.)), tmin);
0306
0307
0308
0309 vecCore__MaskedAssignFunc(distance, !done, vecCore::math::Min(tzout, trout));
0310 }
0311
0312 template <typename Real_v>
0313 VECGEOM_FORCE_INLINE
0314 VECCORE_ATT_HOST_DEVICE
0315 static void SafetyToIn(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point, Real_v &safety)
0316 {
0317
0318 Real_v px = point.x() * ellipticalcone.invDx;
0319 Real_v py = point.y() * ellipticalcone.invDy;
0320 Real_v pz = point.z();
0321 Real_v hp = vecCore::math::Sqrt(px * px + py * py) + pz;
0322 Real_v ds = (hp - ellipticalcone.fDz) * ellipticalcone.cosAxisMin;
0323 Real_v dz = vecCore::math::Abs(pz) - ellipticalcone.fZCut;
0324 safety = vecCore::math::Max(ds, dz);
0325 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) <= kHalfTolerance, Real_v(0.));
0326 }
0327
0328 template <typename Real_v>
0329 VECGEOM_FORCE_INLINE
0330 VECCORE_ATT_HOST_DEVICE
0331 static void SafetyToOut(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point, Real_v &safety)
0332 {
0333
0334 Real_v px = point.x() * ellipticalcone.invDx;
0335 Real_v py = point.y() * ellipticalcone.invDy;
0336 Real_v pz = point.z();
0337 Real_v hp = vecCore::math::Sqrt(px * px + py * py) + pz;
0338 Real_v ds = (ellipticalcone.fDz - hp) * ellipticalcone.cosAxisMin;
0339 Real_v dz = ellipticalcone.fZCut - vecCore::math::Abs(pz);
0340 safety = vecCore::math::Min(ds, dz);
0341 vecCore::MaskedAssign(safety, vecCore::math::Abs(safety) <= kHalfTolerance, Real_v(0.));
0342 }
0343
0344 template <typename Real_v>
0345 VECGEOM_FORCE_INLINE
0346 VECCORE_ATT_HOST_DEVICE
0347 static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &ellipticalcone, Vector3D<Real_v> const &point,
0348 typename vecCore::Mask_v<Real_v> &valid)
0349 {
0350
0351
0352
0353
0354
0355 Vector3D<Real_v> normal(0., 0., 0.);
0356 valid = true;
0357
0358
0359 Real_v px = point.x();
0360 Real_v py = point.y();
0361 Real_v pz = point.z();
0362 Real_v dz = vecCore::math::Abs(pz) - ellipticalcone.fZCut;
0363 vecCore__MaskedAssignFunc(normal[2], vecCore::math::Abs(dz) <= kHalfTolerance, vecCore::math::Sign(pz));
0364
0365
0366 Real_v nx = px * ellipticalcone.invDx * ellipticalcone.invDx;
0367 Real_v ny = py * ellipticalcone.invDy * ellipticalcone.invDy;
0368 Real_v nz = vecCore::math::Sqrt(px * nx + py * ny);
0369 vecCore__MaskedAssignFunc(nz, (nx * nx + ny * ny) == Real_v(0.), Real_v(1.));
0370 Vector3D<Real_v> nside(nx, ny, nz);
0371 Real_v ds = (nz + pz - ellipticalcone.fDz) * ellipticalcone.cosAxisMin;
0372 vecCore__MaskedAssignFunc(normal, vecCore::math::Abs(ds) <= kHalfTolerance, (normal + nside.Unit()).Unit());
0373
0374
0375 vecCore::Mask_v<Real_v> done = normal.Mag2() > Real_v(0.);
0376 if (vecCore::MaskFull(done)) return normal;
0377
0378
0379
0380 vecCore__MaskedAssignFunc(valid, !done, false);
0381 vecCore__MaskedAssignFunc(normal[2], !done, vecCore::math::Sign(pz));
0382 vecCore__MaskedAssignFunc(normal, !done && ds > dz, nside.Unit());
0383 return normal;
0384 }
0385 };
0386 }
0387 }
0388
0389 #endif