File indexing completed on 2025-01-18 10:14:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef VECGEOM_VOLUMES_KERNEL_GENTRAPIMPLEMENTATION_H_
0011 #define VECGEOM_VOLUMES_KERNEL_GENTRAPIMPLEMENTATION_H_
0012
0013 #include "VecGeom/base/Global.h"
0014
0015 #include "VecGeom/volumes/kernel/GenericKernels.h"
0016 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0017 #include "VecGeom/volumes/UnplacedGenTrap.h"
0018
0019 #include <iostream>
0020
0021 namespace vecgeom {
0022
0023 VECGEOM_DEVICE_FORWARD_DECLARE(struct GenTrapImplementation;);
0024 VECGEOM_DEVICE_DECLARE_CONV(struct, GenTrapImplementation);
0025
0026 inline namespace VECGEOM_IMPL_NAMESPACE {
0027
0028 class PlacedGenTrap;
0029 class UnplacedGenTrap;
0030
0031 template <typename T>
0032 struct GenTrapStruct;
0033
0034 struct GenTrapImplementation {
0035
0036 using Vertex_t = Vector3D<Precision>;
0037 using PlacedShape_t = PlacedGenTrap;
0038 using UnplacedStruct_t = GenTrapStruct<Precision>;
0039 using UnplacedVolume_t = UnplacedGenTrap;
0040
0041 VECCORE_ATT_HOST_DEVICE
0042 static void PrintType()
0043 {
0044
0045 }
0046
0047 template <typename Stream>
0048 static void PrintType(Stream &s, int transCodeT = translation::kGeneric, int rotCodeT = rotation::kGeneric)
0049 {
0050 s << "SpecializedGenTrap<" << transCodeT << "," << rotCodeT << ">";
0051 }
0052
0053 template <typename Stream>
0054 static void PrintImplementationType(Stream & )
0055 {
0056
0057 }
0058
0059 template <typename Stream>
0060 static void PrintUnplacedType(Stream & )
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 &unplaced, Vector3D<Real_v> const &point, Bool_v &inside);
0069
0070 template <typename Real_v, typename Bool_v>
0071 VECGEOM_FORCE_INLINE
0072 VECCORE_ATT_HOST_DEVICE
0073 static void ContainsGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Bool_v &inside);
0074
0075 template <typename Real_v, typename Inside_t>
0076 VECGEOM_FORCE_INLINE
0077 VECCORE_ATT_HOST_DEVICE
0078 static void Inside(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Inside_t &inside);
0079
0080 template <typename Real_v, typename Inside_t>
0081 VECGEOM_FORCE_INLINE
0082 VECCORE_ATT_HOST_DEVICE
0083 static void InsideGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Inside_t &inside);
0084
0085 template <typename Real_v, bool ForInside>
0086 VECGEOM_FORCE_INLINE
0087 VECCORE_ATT_HOST_DEVICE
0088 static void GenericKernelForContainsAndInside(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0089 vecCore::Mask_v<Real_v> &completelyinside,
0090 vecCore::Mask_v<Real_v> &completelyoutside);
0091
0092 template <typename Real_v>
0093 VECGEOM_FORCE_INLINE
0094 VECCORE_ATT_HOST_DEVICE
0095 static void DistanceToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0096 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance);
0097
0098 template <typename Real_v>
0099 VECGEOM_FORCE_INLINE
0100 VECCORE_ATT_HOST_DEVICE
0101 static void DistanceToInGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0102 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance);
0103
0104 template <typename Real_v>
0105 VECGEOM_FORCE_INLINE
0106 VECCORE_ATT_HOST_DEVICE
0107 static void DistanceToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0108 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance);
0109
0110 template <typename Real_v>
0111 VECGEOM_FORCE_INLINE
0112 VECCORE_ATT_HOST_DEVICE
0113 static void DistanceToOutGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0114 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance);
0115
0116 template <typename Real_v>
0117 VECGEOM_FORCE_INLINE
0118 VECCORE_ATT_HOST_DEVICE
0119 static void SafetyToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety);
0120
0121 template <typename Real_v>
0122 VECGEOM_FORCE_INLINE
0123 VECCORE_ATT_HOST_DEVICE
0124 static void SafetyToInGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety);
0125
0126 template <typename Real_v>
0127 VECGEOM_FORCE_INLINE
0128 VECCORE_ATT_HOST_DEVICE
0129 static void SafetyToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety);
0130
0131 template <typename Real_v>
0132 VECGEOM_FORCE_INLINE
0133 VECCORE_ATT_HOST_DEVICE
0134 static void SafetyToOutGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety);
0135
0136 template <typename Real_v, typename Bool_v>
0137 VECGEOM_FORCE_INLINE
0138 VECCORE_ATT_HOST_DEVICE
0139 static void NormalKernel(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Vector3D<Real_v> &normal,
0140 Bool_v &valid);
0141
0142 template <class Real_v>
0143 VECCORE_ATT_HOST_DEVICE
0144 static void GetClosestEdge(Vector3D<Real_v> const &point, Real_v vertexX[4], Real_v vertexY[4], Real_v &iseg,
0145 Real_v &fraction);
0146
0147 template <typename Real_v>
0148 VECGEOM_FORCE_INLINE
0149 VECCORE_ATT_HOST_DEVICE
0150 static vecCore::Mask_v<Real_v> IsInTopOrBottomPolygon(UnplacedStruct_t const &unplaced, Real_v const &pointx,
0151 Real_v const &pointy, vecCore::Mask_v<Real_v> top);
0152 };
0153
0154
0155
0156
0157
0158 template <typename Real_v>
0159 struct FillPlaneDataHelper {
0160 VECCORE_ATT_HOST_DEVICE
0161 VECGEOM_FORCE_INLINE
0162 static void FillPlaneData(GenTrapStruct<Precision> const &unplaced, Real_v &cornerx, Real_v &cornery, Real_v &deltax,
0163 Real_v &deltay, vecCore::Mask_v<Real_v> const &top, int edgeindex)
0164 {
0165
0166
0167
0168
0169 for (size_t i = 0; i < vecCore::VectorSize<Real_v>(); ++i) {
0170 int index = edgeindex + top[i] * 4;
0171 deltax[i] = unplaced.fDeltaX[index];
0172 deltay[i] = unplaced.fDeltaY[index];
0173 cornerx[i] = unplaced.fVerticesX[index];
0174 cornery[i] = unplaced.fVerticesY[index];
0175 }
0176 }
0177 };
0178
0179
0180
0181 template <>
0182 struct FillPlaneDataHelper<Precision> {
0183 VECCORE_ATT_HOST_DEVICE
0184 VECGEOM_FORCE_INLINE
0185 static void FillPlaneData(GenTrapStruct<Precision> const &unplaced, Precision &cornerx, Precision &cornery,
0186 Precision &deltax, Precision &deltay, bool const &top, int edgeindex)
0187 {
0188 int index = edgeindex + top * 4;
0189 deltax = unplaced.fDeltaX[index];
0190 deltay = unplaced.fDeltaY[index];
0191 cornerx = unplaced.fVerticesX[index];
0192 cornery = unplaced.fVerticesY[index];
0193 }
0194 };
0195
0196
0197 template <typename Real_v>
0198 VECGEOM_FORCE_INLINE
0199 VECCORE_ATT_HOST_DEVICE
0200 vecCore::Mask_v<Real_v> GenTrapImplementation::IsInTopOrBottomPolygon(UnplacedStruct_t const &unplaced,
0201 Real_v const &pointx, Real_v const &pointy,
0202 vecCore::Mask_v<Real_v> top)
0203 {
0204
0205
0206
0207
0208
0209
0210
0211
0212 using Bool_v = vecCore::Mask_v<Real_v>;
0213 Bool_v completelyoutside = Bool_v(false);
0214 Bool_v degenerate = Bool_v(true);
0215 for (int i = 0; i < 4; ++i) {
0216 Real_v deltaX;
0217 Real_v deltaY;
0218 Real_v cornerX;
0219 Real_v cornerY;
0220
0221
0222
0223 FillPlaneDataHelper<Real_v>::FillPlaneData(unplaced, cornerX, cornerY, deltaX, deltaY, top, i);
0224
0225
0226
0227 Real_v cross = (pointx - cornerX) * deltaY;
0228 cross -= (pointy - cornerY) * deltaX;
0229 degenerate =
0230 degenerate && (deltaX < Real_v(MakePlusTolerant<true>(0.))) && (deltaY < Real_v(MakePlusTolerant<true>(0.)));
0231 completelyoutside = completelyoutside || (cross < Real_v(MakeMinusTolerantCrossProduct<true,Real_v>(0., Abs(deltaX) + Abs(deltaY))));
0232
0233 if (vecCore::MaskFull(completelyoutside)) {
0234 return Bool_v(false);
0235 }
0236
0237 }
0238 completelyoutside = completelyoutside || degenerate;
0239 return (!completelyoutside);
0240 }
0241
0242
0243 template <typename Real_v, bool ForInside>
0244 VECGEOM_FORCE_INLINE
0245 VECCORE_ATT_HOST_DEVICE
0246 void GenTrapImplementation::GenericKernelForContainsAndInside(UnplacedStruct_t const &unplaced,
0247 Vector3D<Real_v> const &point,
0248 vecCore::Mask_v<Real_v> &completelyinside,
0249 vecCore::Mask_v<Real_v> &completelyoutside)
0250 {
0251
0252 using Bool_v = vecCore::Mask_v<Real_v>;
0253 VECGEOM_CONST Precision tolerancesq = 10000. * kTolerance * kTolerance;
0254
0255 Vector3D<Real_v> halfsize(unplaced.fBBdimensions[0], unplaced.fBBdimensions[1], unplaced.fBBdimensions[2]);
0256 BoxImplementation::GenericKernelForContainsAndInside<Real_v, ForInside>(halfsize, point - unplaced.fBBorigin,
0257 completelyinside, completelyoutside);
0258
0259 if (vecCore::MaskFull(completelyoutside)) {
0260 return;
0261 }
0262
0263
0264
0265 Real_v cf = unplaced.fHalfInverseDz * (unplaced.fDz - point.z());
0266
0267
0268
0269 Real_v vertexX[4];
0270 Real_v vertexY[4];
0271
0272 for (int i = 0; i < 4; i++) {
0273
0274 vertexX[i] = unplaced.fVerticesX[i + 4] + cf * unplaced.fConnectingComponentsX[i];
0275 vertexY[i] = unplaced.fVerticesY[i + 4] + cf * unplaced.fConnectingComponentsY[i];
0276 }
0277
0278 for (int i = 0; i < 4; i++) {
0279
0280
0281
0282
0283
0284
0285
0286
0287 if (unplaced.fDegenerated[i]) continue;
0288 int j = (i + 1) % 4;
0289 Real_v DeltaX = vertexX[j] - vertexX[i];
0290 Real_v DeltaY = vertexY[j] - vertexY[i];
0291 Real_v cross = (point.x() - vertexX[i]) * DeltaY - (point.y() - vertexY[i]) * DeltaX;
0292 if (ForInside) {
0293 Bool_v onsurf = (cross * cross < tolerancesq * (DeltaX * DeltaX + DeltaY * DeltaY));
0294 completelyoutside = completelyoutside || (((cross < Real_v(MakeMinusTolerant<ForInside>(0.))) && (!onsurf)));
0295 completelyinside = completelyinside && (cross > Real_v(MakePlusTolerant<ForInside>(0.))) && (!onsurf);
0296 } else {
0297 completelyoutside = completelyoutside || (cross < Real_v(MakeMinusTolerant<ForInside>(0.)));
0298 }
0299
0300
0301 if (vecCore::MaskFull(completelyoutside)) {
0302 return;
0303 }
0304
0305 }
0306 }
0307
0308
0309 template <typename Real_v, typename Bool_v>
0310 VECGEOM_FORCE_INLINE
0311 VECCORE_ATT_HOST_DEVICE
0312 void GenTrapImplementation::ContainsGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0313 Bool_v &inside)
0314 {
0315
0316 Bool_v unused;
0317 Bool_v outside;
0318 GenericKernelForContainsAndInside<Real_v, false>(unplaced, point, unused, outside);
0319 inside = !outside;
0320 }
0321
0322
0323 template <typename Real_v, typename Bool_v>
0324 VECGEOM_FORCE_INLINE
0325 VECCORE_ATT_HOST_DEVICE
0326 void GenTrapImplementation::Contains(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Bool_v &inside)
0327 {
0328 GenTrapImplementation::ContainsGeneric<Real_v, Bool_v>(unplaced, point, inside);
0329 }
0330
0331
0332 template <>
0333 VECGEOM_FORCE_INLINE
0334 VECCORE_ATT_HOST_DEVICE
0335 void GenTrapImplementation::Contains<Precision, bool>(UnplacedStruct_t const &unplaced,
0336 Vector3D<Precision> const &point, bool &inside)
0337 {
0338
0339 #ifndef VECCORE_CUDA
0340
0341 if (unplaced.fTslHelper) {
0342
0343 inside = false;
0344 if (vecCore::math::Abs(point.z()) > unplaced.fDz) return;
0345 inside = unplaced.fTslHelper->Contains(point);
0346 return;
0347 }
0348 #endif
0349 GenTrapImplementation::ContainsGeneric<Precision, bool>(unplaced, point, inside);
0350 }
0351
0352
0353 template <typename Real_v, typename Inside_t>
0354 VECGEOM_FORCE_INLINE
0355 VECCORE_ATT_HOST_DEVICE
0356 void GenTrapImplementation::InsideGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0357 Inside_t &inside)
0358 {
0359
0360 using Bool_v = vecCore::Mask_v<Real_v>;
0361 using InsideBool_v = vecCore::Mask_v<Inside_t>;
0362 Bool_v completelyinside;
0363 Bool_v completelyoutside;
0364 GenericKernelForContainsAndInside<Real_v, true>(unplaced, point, completelyinside, completelyoutside);
0365
0366 inside = Inside_t(EInside::kSurface);
0367 vecCore::MaskedAssign(inside, (InsideBool_v)completelyoutside, Inside_t(EInside::kOutside));
0368 vecCore::MaskedAssign(inside, (InsideBool_v)completelyinside, Inside_t(EInside::kInside));
0369 }
0370
0371
0372 template <typename Real_v, typename Inside_t>
0373 VECGEOM_FORCE_INLINE
0374 VECCORE_ATT_HOST_DEVICE
0375 void GenTrapImplementation::Inside(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Inside_t &inside)
0376 {
0377
0378 GenTrapImplementation::InsideGeneric<Real_v, Inside_t>(unplaced, point, inside);
0379 }
0380
0381
0382 template <>
0383 VECGEOM_FORCE_INLINE
0384 VECCORE_ATT_HOST_DEVICE
0385 void GenTrapImplementation::Inside<Precision, Inside_t>(UnplacedStruct_t const &unplaced,
0386 Vector3D<Precision> const &point, Inside_t &inside)
0387 {
0388
0389 #ifndef VECCORE_CUDA
0390 if (unplaced.fTslHelper) {
0391 inside = EInside::kOutside;
0392 Precision safZ = vecCore::math::Abs(point.z()) - unplaced.fDz;
0393 if (safZ > kTolerance) return;
0394 bool insideZ = safZ < -kTolerance;
0395 inside = unplaced.fTslHelper->Inside(point);
0396 if (insideZ || inside == EInside::kOutside) return;
0397 inside = EInside::kSurface;
0398 return;
0399 }
0400 #endif
0401 GenTrapImplementation::InsideGeneric<Precision, Inside_t>(unplaced, point, inside);
0402 }
0403
0404
0405 template <typename Real_v>
0406 VECGEOM_FORCE_INLINE
0407 VECCORE_ATT_HOST_DEVICE
0408 void GenTrapImplementation::DistanceToInGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0409 Vector3D<Real_v> const &direction, Real_v const &stepMax,
0410 Real_v &distance)
0411 {
0412
0413 using Bool_v = vecCore::Mask_v<Real_v>;
0414
0415
0416
0417
0418
0419 Real_v bbdistance = Real_v(kInfLength);
0420 BoxImplementation::DistanceToIn(BoxStruct<Precision>(unplaced.fBBdimensions), point - unplaced.fBBorigin, direction,
0421 stepMax, bbdistance);
0422
0423 distance = InfinityLength<Real_v>();
0424
0425
0426
0427 Bool_v done = bbdistance >= InfinityLength<Real_v>();
0428 if (vecCore::MaskFull(done)) return;
0429
0430
0431 Real_v zsafety = Abs(point.z()) - unplaced.fDz;
0432 Bool_v canhitz = zsafety > Real_v(MakeMinusTolerant<true>(0.));
0433 canhitz = canhitz && (point.z() * direction.z() < 0);
0434 canhitz = canhitz && (!done);
0435
0436 if (!vecCore::MaskEmpty(canhitz)) {
0437
0438
0439
0440 Real_v next = zsafety / NonZeroAbs(direction.z());
0441
0442 Real_v coord1 = point.x() + next * direction.x();
0443 Real_v coord2 = point.y() + next * direction.y();
0444 Bool_v top = direction.z() < 0;
0445 Bool_v hits = IsInTopOrBottomPolygon<Real_v>(unplaced, coord1, coord2, top);
0446 hits = hits && canhitz;
0447 vecCore::MaskedAssign(distance, hits, bbdistance);
0448 done = done || hits;
0449 if (vecCore::MaskFull(done)) return;
0450 }
0451
0452
0453 Real_v disttoplanes = unplaced.fSurfaceShell.DistanceToIn<Real_v>(point, direction, done);
0454 vecCore__MaskedAssignFunc(distance, !done, Min(disttoplanes, distance));
0455 }
0456
0457
0458 template <typename Real_v>
0459 VECGEOM_FORCE_INLINE
0460 VECCORE_ATT_HOST_DEVICE
0461 void GenTrapImplementation::DistanceToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0462 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance)
0463 {
0464 GenTrapImplementation::DistanceToInGeneric<Real_v>(unplaced, point, direction, stepMax, distance);
0465 }
0466
0467
0468 template <>
0469 VECGEOM_FORCE_INLINE
0470 VECCORE_ATT_HOST_DEVICE
0471 void GenTrapImplementation::DistanceToIn(UnplacedStruct_t const &unplaced, Vector3D<Precision> const &point,
0472 Vector3D<Precision> const &direction, Precision const &stepMax,
0473 Precision &distance)
0474 {
0475
0476 #ifndef VECCORE_CUDA
0477 if (unplaced.fTslHelper) {
0478 Precision invdirz = 1. / NonZero(direction.z());
0479 distance = unplaced.fTslHelper->DistanceToIn<false>(point, direction, invdirz, stepMax);
0480 return;
0481 }
0482 #endif
0483 GenTrapImplementation::DistanceToInGeneric<Precision>(unplaced, point, direction, stepMax, distance);
0484 }
0485
0486
0487 template <typename Real_v>
0488 VECGEOM_FORCE_INLINE
0489 VECCORE_ATT_HOST_DEVICE
0490 void GenTrapImplementation::DistanceToOutGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0491 Vector3D<Real_v> const &direction, Real_v const & ,
0492 Real_v &distance)
0493 {
0494
0495 using Bool_v = vecCore::Mask_v<Real_v>;
0496
0497
0498
0499
0500
0501 Bool_v negDirMask = direction.z() < 0;
0502 Real_v sign(1.0);
0503 vecCore__MaskedAssignFunc(sign, negDirMask, Real_v(-1.));
0504
0505
0506 Real_v distmin = (sign * unplaced.fDz - point.z()) / NonZero(direction.z());
0507
0508 Real_v distplane = unplaced.fSurfaceShell.DistanceToOut<Real_v>(point, direction);
0509 distance = Min(distmin, distplane);
0510 }
0511
0512 template <typename Real_v>
0513 VECGEOM_FORCE_INLINE
0514 VECCORE_ATT_HOST_DEVICE
0515 void GenTrapImplementation::DistanceToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0516 Vector3D<Real_v> const &direction, Real_v const &stepMax, Real_v &distance)
0517 {
0518 GenTrapImplementation::DistanceToOutGeneric<Real_v>(unplaced, point, direction, stepMax, distance);
0519 }
0520
0521
0522 template <>
0523 VECGEOM_FORCE_INLINE
0524 VECCORE_ATT_HOST_DEVICE
0525 void GenTrapImplementation::DistanceToOut(UnplacedStruct_t const &unplaced, Vector3D<Precision> const &point,
0526 Vector3D<Precision> const &direction, Precision const &stepMax,
0527 Precision &distance)
0528
0529 {
0530 #ifndef VECCORE_CUDA
0531 if (unplaced.fTslHelper) {
0532 distance = unplaced.fTslHelper->DistanceToOut(point, direction);
0533 return;
0534 }
0535 #endif
0536 GenTrapImplementation::DistanceToOutGeneric<Precision>(unplaced, point, direction, stepMax, distance);
0537 }
0538
0539
0540 template <typename Real_v>
0541 VECGEOM_FORCE_INLINE
0542 VECCORE_ATT_HOST_DEVICE
0543 void GenTrapImplementation::SafetyToInGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0544 Real_v &safety)
0545 {
0546
0547 using Bool_v = vecCore::Mask_v<Real_v>;
0548
0549 Bool_v inside;
0550
0551 BoxImplementation::Contains(BoxStruct<Precision>(unplaced.fBBdimensions), point - unplaced.fBBorigin, inside);
0552 if (vecCore::MaskEmpty(inside)) {
0553
0554
0555 BoxImplementation::SafetyToIn(BoxStruct<Precision>(unplaced.fBBdimensions), point - unplaced.fBBorigin, safety);
0556 return;
0557 }
0558
0559
0560 safety = Abs(point[2]) - unplaced.fDz;
0561 safety = unplaced.fSurfaceShell.SafetyToIn<Real_v>(point, safety);
0562 }
0563
0564
0565 template <typename Real_v>
0566 VECGEOM_FORCE_INLINE
0567 VECCORE_ATT_HOST_DEVICE
0568 void GenTrapImplementation::SafetyToIn(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0569 {
0570
0571 GenTrapImplementation::SafetyToInGeneric<Real_v>(unplaced, point, safety);
0572 }
0573
0574
0575 template <>
0576 VECGEOM_FORCE_INLINE
0577 VECCORE_ATT_HOST_DEVICE
0578 void GenTrapImplementation::SafetyToIn(UnplacedStruct_t const &unplaced, Vector3D<Precision> const &point,
0579 Precision &safety)
0580 {
0581
0582 #ifndef VECCORE_CUDA
0583 if (unplaced.fTslHelper) {
0584 safety = unplaced.fTslHelper->SafetyToIn(point);
0585 return;
0586 }
0587 #endif
0588 GenTrapImplementation::SafetyToInGeneric<Precision>(unplaced, point, safety);
0589 }
0590
0591
0592 template <typename Real_v>
0593 VECCORE_ATT_HOST_DEVICE
0594 void GenTrapImplementation::SafetyToOutGeneric(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0595 Real_v &safety)
0596 {
0597
0598
0599 safety = unplaced.fDz - Abs(point[2]);
0600 safety = unplaced.fSurfaceShell.SafetyToOut<Real_v>(point, safety);
0601 }
0602
0603
0604 template <typename Real_v>
0605 VECCORE_ATT_HOST_DEVICE
0606 void GenTrapImplementation::SafetyToOut(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point, Real_v &safety)
0607 {
0608
0609 GenTrapImplementation::SafetyToOutGeneric<Real_v>(unplaced, point, safety);
0610 }
0611
0612
0613 template <>
0614 VECGEOM_FORCE_INLINE
0615 VECCORE_ATT_HOST_DEVICE
0616 void GenTrapImplementation::SafetyToOut(UnplacedStruct_t const &unplaced, Vector3D<Precision> const &point,
0617 Precision &safety)
0618 {
0619
0620 #ifndef VECCORE_CUDA
0621 if (unplaced.fTslHelper) {
0622 safety = unplaced.fTslHelper->SafetyToOut(point);
0623 return;
0624 }
0625 #endif
0626 GenTrapImplementation::SafetyToOutGeneric<Precision>(unplaced, point, safety);
0627 }
0628
0629
0630 template <typename Real_v, typename Bool_v>
0631 VECCORE_ATT_HOST_DEVICE
0632 void GenTrapImplementation::NormalKernel(UnplacedStruct_t const &unplaced, Vector3D<Real_v> const &point,
0633 Vector3D<Real_v> &normal, Bool_v &valid)
0634 {
0635
0636
0637
0638
0639
0640 using Index_v = vecCore::Index_v<Real_v>;
0641
0642 valid = Bool_v(true);
0643 normal.Set(0., 0., 0.);
0644
0645 Real_v safz = Abs(unplaced.fDz - Abs(point.z()));
0646 Bool_v onZ = (safz < 10. * kTolerance);
0647 vecCore__MaskedAssignFunc(normal[2], onZ && (point.z() > Real_v(0.)), Real_v(1.));
0648 vecCore__MaskedAssignFunc(normal[2], onZ && (point.z() < Real_v(0.)), Real_v(-1.));
0649
0650
0651 if (vecCore::MaskFull(onZ)) {
0652 return;
0653 }
0654
0655
0656
0657 Real_v cf = unplaced.fHalfInverseDz * (unplaced.fDz - point.z());
0658 Real_v vertexX[4];
0659 Real_v vertexY[4];
0660 for (int i = 0; i < 4; i++) {
0661
0662 vertexX[i] = unplaced.fVerticesX[i + 4] + cf * unplaced.fConnectingComponentsX[i];
0663 vertexY[i] = unplaced.fVerticesY[i + 4] + cf * unplaced.fConnectingComponentsY[i];
0664 }
0665 Real_v seg;
0666 Real_v frac;
0667 GetClosestEdge<Real_v>(point, vertexX, vertexY, seg, frac);
0668 vecCore__MaskedAssignFunc(frac, frac < Real_v(0.), Real_v(0.));
0669 Index_v iseg = (Index_v)seg;
0670 if (unplaced.IsPlanar()) {
0671
0672 Vertex_t const *normals = unplaced.fSurfaceShell.GetNormals();
0673 normal = normals[iseg];
0674 return;
0675 }
0676 Index_v jseg = (iseg + 1) % 4;
0677 Real_v x0 = vertexX[iseg];
0678 Real_v y0 = vertexY[iseg];
0679 Real_v x2 = vertexX[jseg];
0680 Real_v y2 = vertexY[jseg];
0681 x0 += frac * (x2 - x0);
0682 y0 += frac * (y2 - y0);
0683 Real_v x1 = unplaced.fVerticesX[iseg + 4];
0684 Real_v y1 = unplaced.fVerticesY[iseg + 4];
0685 x1 += frac * (unplaced.fVerticesX[jseg + 4] - x1);
0686 y1 += frac * (unplaced.fVerticesY[jseg + 4] - y1);
0687 Real_v ax = x1 - x0;
0688 Real_v ay = y1 - y0;
0689 Real_v az = unplaced.fDz - point.z();
0690 Real_v bx = x2 - x0;
0691 Real_v by = y2 - y0;
0692 Real_v bz = Real_v(0.);
0693
0694
0695
0696 normal.Set(ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx);
0697 normal.Normalize();
0698 }
0699
0700
0701 template <typename Real_v>
0702 VECCORE_ATT_HOST_DEVICE
0703 void GenTrapImplementation::GetClosestEdge(Vector3D<Real_v> const &point, Real_v vertexX[4], Real_v vertexY[4],
0704 Real_v &iseg, Real_v &fraction)
0705 {
0706
0707
0708
0709
0710 using Bool_v = vecCore::Mask_v<Real_v>;
0711
0712 iseg = Real_v(0.);
0713
0714 Real_v lsq, dx, dy, dpx, dpy, u;
0715 fraction = Real_v(-1.);
0716 Real_v safe = InfinityLength<Real_v>();
0717 Real_v ssq = InfinityLength<Real_v>();
0718 for (int i = 0; i < 4; ++i) {
0719 int j = (i + 1) % 4;
0720 dx = vertexX[j] - vertexX[i];
0721 dy = vertexY[j] - vertexY[i];
0722 dpx = point.x() - vertexX[i];
0723 dpy = point.y() - vertexY[i];
0724 lsq = dx * dx + dy * dy;
0725
0726 Bool_v collapsed = lsq < kTolerance;
0727 if (!vecCore::MaskEmpty(collapsed)) {
0728 vecCore__MaskedAssignFunc(ssq, lsq < kTolerance, dpx * dpx + dpy * dpy);
0729
0730 vecCore::MaskedAssign(iseg, ssq < safe, (Precision)i);
0731 vecCore__MaskedAssignFunc(fraction, ssq < safe, Real_v(-1.));
0732 vecCore::MaskedAssign(safe, ssq < safe, ssq);
0733 if (vecCore::MaskFull(collapsed)) continue;
0734 }
0735
0736 u = (dpx * dx + dpy * dy) / NonZero(lsq);
0737 vecCore__MaskedAssignFunc(dpx, u > 1 && !collapsed, point.x() - vertexX[j]);
0738 vecCore__MaskedAssignFunc(dpy, u > 1 && !collapsed, point.y() - vertexY[j]);
0739 vecCore__MaskedAssignFunc(dpx, u >= 0 && u <= 1 && !collapsed, dpx - u * dx);
0740 vecCore__MaskedAssignFunc(dpy, u >= 0 && u <= 1 && !collapsed, dpy - u * dy);
0741 vecCore__MaskedAssignFunc(u, (u > 1 || u < 0) && !collapsed, Real_v(-1.));
0742 ssq = dpx * dpx + dpy * dpy;
0743 vecCore::MaskedAssign(iseg, ssq < safe, (Precision)i);
0744 vecCore::MaskedAssign(fraction, ssq < safe, u);
0745 vecCore::MaskedAssign(safe, ssq < safe, ssq);
0746 }
0747 }
0748
0749
0750
0751
0752 }
0753 }
0754
0755 #endif