File indexing completed on 2025-01-30 10:26:21
0001
0002
0003
0004
0005
0006 #ifndef VECGEOM_SECONDORDERSURFACESHELL_H_
0007 #define VECGEOM_SECONDORDERSURFACESHELL_H_
0008
0009 #include "VecGeom/base/Vector3D.h"
0010 #include "VecGeom/volumes/kernel/GenericKernels.h"
0011
0012 namespace vecgeom {
0013
0014
0015
0016
0017 VECGEOM_DEVICE_FORWARD_DECLARE(class SecondOrderSurfaceShell;);
0018
0019 inline namespace VECGEOM_IMPL_NAMESPACE {
0020
0021 template <int N>
0022 class SecondOrderSurfaceShell {
0023
0024 using Vertex_t = Vector3D<Precision>;
0025
0026 private:
0027
0028 Precision fxa[N], fya[N], fxb[N], fyb[N], fxc[N], fyc[N], fxd[N], fyd[N];
0029 Precision ftx1[N], fty1[N], ftx2[N], fty2[N];
0030 Precision ft1crosst2[N];
0031 Precision fDeltatx[N];
0032 Precision fDeltaty[N];
0033
0034 Precision fDz;
0035 Precision fDz2;
0036 Precision fiscurved[N];
0037 bool fisplanar;
0038 bool fdegenerated[N];
0039
0040 Vertex_t fNormals[N];
0041
0042
0043 Vertex_t fViCrossHi0[N];
0044 Vertex_t fViCrossVj[N];
0045 Vertex_t fHi1CrossHi0[N];
0046
0047 public:
0048
0049 VECCORE_ATT_HOST_DEVICE
0050 SecondOrderSurfaceShell() : fDz(0), fDz2(0) {}
0051
0052
0053
0054
0055
0056
0057 VECCORE_ATT_HOST_DEVICE
0058 SecondOrderSurfaceShell(const Precision *verticesx, const Precision *verticesy, Precision dz) : fDz(0.), fDz2(0.)
0059 {
0060
0061 Initialize(verticesx, verticesy, dz);
0062 }
0063
0064 VECCORE_ATT_HOST_DEVICE
0065 void Initialize(const Precision *verticesx, const Precision *verticesy, Precision dz)
0066 {
0067 #ifndef VECCORE_CUDA
0068 if (dz <= 0.) throw std::runtime_error("Half-length of generic trapezoid must be positive");
0069 #endif
0070 fDz = dz;
0071 fDz2 = 0.5 / dz;
0072
0073 Vertex_t va, vb, vc, vd;
0074 for (int i = 0; i < N; ++i) {
0075 int j = (i + 1) % N;
0076 va.Set(verticesx[i], verticesy[i], -dz);
0077 fxa[i] = verticesx[i];
0078 fya[i] = verticesy[i];
0079 vb.Set(verticesx[i + N], verticesy[i + N], dz);
0080 fxb[i] = verticesx[i + N];
0081 fyb[i] = verticesy[i + N];
0082 vc.Set(verticesx[j], verticesy[j], -dz);
0083 fxc[i] = verticesx[j];
0084 fyc[i] = verticesy[j];
0085 vd.Set(verticesx[j + N], verticesy[j + N], dz);
0086 fxd[i] = verticesx[N + j];
0087 fyd[i] = verticesy[N + j];
0088 fdegenerated[i] = (Abs(fxa[i] - fxc[i]) < kTolerance) && (Abs(fya[i] - fyc[i]) < kTolerance) &&
0089 (Abs(fxb[i] - fxd[i]) < kTolerance) && (Abs(fyb[i] - fyd[i]) < kTolerance);
0090 ftx1[i] = fDz2 * (fxb[i] - fxa[i]);
0091 fty1[i] = fDz2 * (fyb[i] - fya[i]);
0092 ftx2[i] = fDz2 * (fxd[i] - fxc[i]);
0093 fty2[i] = fDz2 * (fyd[i] - fyc[i]);
0094
0095 ft1crosst2[i] = ftx1[i] * fty2[i] - ftx2[i] * fty1[i];
0096 fDeltatx[i] = ftx2[i] - ftx1[i];
0097 fDeltaty[i] = fty2[i] - fty1[i];
0098 fNormals[i] = Vertex_t::Cross(vb - va, vc - va);
0099
0100 if (fNormals[i].Mag2() < kTolerance) {
0101
0102 fNormals[i] = Vertex_t::Cross(vb - va, vd - vb);
0103 if (fNormals[i].Mag2() < kTolerance) fNormals[i].Set(0., 0., 1.);
0104 }
0105 fNormals[i].Normalize();
0106
0107 fViCrossHi0[i] = Vertex_t::Cross(vb - va, vc - va);
0108 fViCrossVj[i] = Vertex_t::Cross(vb - va, vd - vc);
0109 fHi1CrossHi0[i] = Vertex_t::Cross(vd - vb, vc - va);
0110 }
0111
0112
0113 fisplanar = true;
0114 for (int i = 0; i < N; ++i) {
0115 fiscurved[i] = (((Abs(fxc[i] - fxa[i]) < kTolerance) && (Abs(fyc[i] - fya[i]) < kTolerance)) ||
0116 ((Abs(fxd[i] - fxb[i]) < kTolerance) && (Abs(fyd[i] - fyb[i]) < kTolerance)) ||
0117 (Abs((fxc[i] - fxa[i]) * (fyd[i] - fyb[i]) - (fxd[i] - fxb[i]) * (fyc[i] - fya[i])) < kTolerance))
0118 ? 0
0119 : 1;
0120 if (fiscurved[i]) fisplanar = false;
0121 }
0122 }
0123
0124
0125 template <typename Real_v>
0126 VECGEOM_FORCE_INLINE
0127 VECCORE_ATT_HOST_DEVICE
0128
0129
0130
0131
0132
0133
0134 void CheckInside(Vector3D<Real_v> const &point, vecCore::Mask_v<Real_v> &completelyinside,
0135 vecCore::Mask_v<Real_v> &completelyoutside, vecCore::Mask_v<Real_v> &onsurf) const
0136 {
0137
0138 using Bool_v = vecCore::Mask_v<Real_v>;
0139 VECGEOM_CONST Precision tolerancesq = 10000. * kTolerance * kTolerance;
0140
0141 onsurf = Bool_v(false);
0142 completelyinside = (Abs(point.z()) < Real_v(MakeMinusTolerant<true>(fDz)));
0143 completelyoutside = (Abs(point.z()) > Real_v(MakePlusTolerant<true>(fDz)));
0144
0145 if (vecCore::MaskFull(completelyoutside)) return;
0146
0147
0148 Real_v cross;
0149 Real_v vertexX[N];
0150 Real_v vertexY[N];
0151 Real_v dzp = fDz + point[2];
0152
0153 for (int i = 0; i < N; i++) {
0154
0155 vertexX[i] = fxa[i] + ftx1[i] * dzp;
0156 vertexY[i] = fya[i] + fty1[i] * dzp;
0157 }
0158 Bool_v degenerated = Bool_v(true);
0159 for (int i = 0; i < N; i++) {
0160
0161
0162 int j = (i + 1) % 4;
0163 Real_v DeltaX = vertexX[j] - vertexX[i];
0164 Real_v DeltaY = vertexY[j] - vertexY[i];
0165 Real_v deltasq = DeltaX * DeltaX + DeltaY * DeltaY;
0166
0167 Bool_v samevertex = deltasq < Real_v(MakePlusTolerant<true>(0.));
0168 degenerated = degenerated && samevertex;
0169
0170
0171 cross = (point.x() - vertexX[i]) * DeltaY - (point.y() - vertexY[i]) * DeltaX;
0172
0173 onsurf = (cross * cross < tolerancesq * deltasq) && (!samevertex);
0174 completelyoutside = completelyoutside || (((cross < Real_v(MakeMinusTolerant<true>(0.))) && (!onsurf)));
0175 completelyinside =
0176 completelyinside && (samevertex || ((cross > Real_v(MakePlusTolerant<true>(0.))) && (!onsurf)));
0177 }
0178 onsurf = (!completelyoutside) && (!completelyinside);
0179
0180 completelyoutside = completelyoutside || degenerated;
0181 }
0182
0183
0184 template <typename Real_v>
0185 VECGEOM_FORCE_INLINE
0186 VECCORE_ATT_HOST_DEVICE
0187
0188
0189
0190
0191 Real_v DistanceToOut(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir) const
0192 {
0193
0194 using Bool_v = vecCore::Mask_v<Real_v>;
0195
0196
0197 if (fisplanar) return DistanceToOutPlanar<Real_v>(point, dir);
0198
0199
0200 const Real_v tolerance(100. * kTolerance);
0201
0202 Real_v dist(InfinityLength<Real_v>());
0203 Real_v smin[N], smax[N];
0204 Vector3D<Real_v> unorm;
0205 Real_v r(-1.0);
0206 Real_v rz;
0207 Bool_v completelyinside, completelyoutside, onsurf;
0208 CheckInside<Real_v>(point, completelyinside, completelyoutside, onsurf);
0209
0210
0211 Real_v wrongsidedist(-1.0);
0212 vecCore::MaskedAssign(dist, completelyoutside, wrongsidedist);
0213 if (vecCore::MaskFull(completelyoutside)) return dist;
0214
0215
0216 ComputeSminSmax<Real_v>(point, dir, smin, smax);
0217 for (int i = 0; i < N; ++i) {
0218
0219 Bool_v crtbound = (Abs(smin[i]) < tolerance || Abs(smax[i]) < tolerance);
0220 if (!vecCore::MaskEmpty(crtbound)) {
0221 if (fiscurved[i])
0222 UNormal<Real_v>(point, i, unorm, rz, r);
0223 else
0224 unorm = fNormals[i];
0225 }
0226
0227
0228 vecCore__MaskedAssignFunc(smin[i], !completelyoutside && Abs(smin[i]) < tolerance && dir.Dot(unorm) < 0,
0229 InfinityLength<Real_v>());
0230 vecCore__MaskedAssignFunc(smax[i], !completelyoutside && Abs(smax[i]) < tolerance && dir.Dot(unorm) < 0,
0231 InfinityLength<Real_v>());
0232
0233 vecCore__MaskedAssignFunc(dist, !completelyoutside && (smin[i] > -tolerance) && (smin[i] < dist),
0234 Max(smin[i], Real_v(0.)));
0235 vecCore__MaskedAssignFunc(dist, !completelyoutside && (smax[i] > -tolerance) && (smax[i] < dist),
0236 Max(smax[i], Real_v(0.)));
0237 }
0238 vecCore__MaskedAssignFunc(dist, dist < tolerance && onsurf, Real_v(0.));
0239 return (dist);
0240 }
0241
0242
0243
0244
0245
0246
0247 template <typename Real_v>
0248 VECGEOM_FORCE_INLINE
0249 VECCORE_ATT_HOST_DEVICE
0250 Real_v DistanceToOutPlanar(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir) const
0251 {
0252
0253 using Bool_v = vecCore::Mask_v<Real_v>;
0254
0255
0256 Vertex_t va;
0257 Vector3D<Real_v> pa;
0258 Real_v distance = InfinityLength<Real_v>();
0259
0260
0261 Bool_v outside = (Abs(point.z()) > MakePlusTolerant<true>(fDz));
0262 for (int i = 0; i < N && (!vecCore::MaskFull(outside)); ++i) {
0263 if (fdegenerated[i]) continue;
0264
0265 pa.Set(Real_v(fxa[i]), Real_v(fya[i]), Real_v(-fDz));
0266 Vector3D<Real_v> vecAP = point - pa;
0267
0268 Real_v dotAPNorm = vecAP.Dot(fNormals[i]);
0269 Bool_v otherside = (dotAPNorm > Real_v(10.) * kTolerance);
0270
0271 Real_v dotDirNorm = dir.Dot(fNormals[i]);
0272 Bool_v outgoing = (dotDirNorm > Real_v(0.));
0273
0274 outside = outside || otherside;
0275 Bool_v valid = outgoing && (!otherside);
0276 if (vecCore::MaskEmpty(valid)) continue;
0277 Real_v snext = -dotAPNorm / NonZero(dotDirNorm);
0278 vecCore__MaskedAssignFunc(distance, valid && snext < distance, Max(snext, Real_v(0.)));
0279 }
0280
0281 vecCore__MaskedAssignFunc(distance, distance < kTolerance, Real_v(0.));
0282 vecCore__MaskedAssignFunc(distance, outside, Real_v(-1.));
0283 return distance;
0284 }
0285
0286
0287
0288
0289
0290
0291 template <typename Real_v>
0292 VECGEOM_FORCE_INLINE
0293 VECCORE_ATT_HOST_DEVICE
0294 Real_v DistanceToInPlanar(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir,
0295 vecCore::Mask_v<Real_v> &done) const
0296 {
0297
0298
0299 using Bool_v = vecCore::Mask_v<Real_v>;
0300 Vertex_t va;
0301 Vector3D<Real_v> pa;
0302 Real_v distance = InfinityLength<Real_v>();
0303
0304
0305 Bool_v inside = (Abs(point.z()) < MakeMinusTolerant<true>(fDz));
0306 for (int i = 0; i < N; ++i) {
0307 if (fdegenerated[i]) continue;
0308
0309 pa.Set(Real_v(fxa[i]), Real_v(fya[i]), Real_v(-fDz));
0310 Vector3D<Real_v> vecAP = point - pa;
0311
0312 Real_v dotAPNorm = vecAP.Dot(fNormals[i]);
0313 Bool_v otherside = (dotAPNorm < Real_v(-10.) * kTolerance);
0314
0315 Real_v dotDirNorm = dir.Dot(fNormals[i]);
0316 Bool_v ingoing = (dotDirNorm < Real_v(0.));
0317
0318 inside = inside && otherside;
0319 Bool_v valid = ingoing && (!otherside);
0320 if (vecCore::MaskEmpty(valid)) continue;
0321 Real_v snext = -dotAPNorm / NonZero(dotDirNorm);
0322
0323 Vector3D<Real_v> psurf = point + snext * dir;
0324 valid = valid && InSurfLimits<Real_v>(psurf, i);
0325 vecCore__MaskedAssignFunc(distance, (!done) && valid && snext < distance, Max(snext, Real_v(0.)));
0326 }
0327
0328 vecCore__MaskedAssignFunc(distance, (!done) && (distance < kTolerance), Real_v(0.));
0329 vecCore__MaskedAssignFunc(distance, (!done) && inside, Real_v(-1.));
0330 return distance;
0331 }
0332
0333
0334 template <typename Real_v>
0335 VECGEOM_FORCE_INLINE
0336 VECCORE_ATT_HOST_DEVICE
0337
0338
0339
0340
0341
0342
0343
0344
0345 Real_v DistanceToIn(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir, vecCore::Mask_v<Real_v> &done) const
0346 {
0347
0348 using Bool_v = vecCore::Mask_v<Real_v>;
0349 if (fisplanar) return DistanceToInPlanar<Real_v>(point, dir, done);
0350 Real_v crtdist;
0351 Vector3D<Real_v> hit;
0352 Real_v distance = InfinityLength<Real_v>();
0353 Real_v tolerance(100. * kTolerance);
0354 Vector3D<Real_v> unorm;
0355 Real_v r(-1.0);
0356 Real_v rz;
0357 Bool_v completelyinside, completelyoutside, onsurf;
0358 CheckInside<Real_v>(point, completelyinside, completelyoutside, onsurf);
0359
0360 Real_v wrongsidedist(-1.0);
0361 vecCore::MaskedAssign(distance, Bool_v(completelyinside && (!done)), wrongsidedist);
0362 Bool_v checked = completelyinside || done;
0363 if (vecCore::MaskFull(checked)) return (distance);
0364
0365 Real_v smin[N], smax[N];
0366 ComputeSminSmax<Real_v>(point, dir, smin, smax);
0367
0368
0369
0370 for (int i = 0; i < N; ++i) {
0371 crtdist = smin[i];
0372
0373 hit = point + crtdist * dir;
0374 Bool_v crossing = (crtdist > -tolerance) && (Abs(hit.z()) < fDz + kTolerance);
0375
0376 if (!vecCore::MaskEmpty(Bool_v(crossing && (!checked)))) {
0377
0378 UNormal<Real_v>(hit, i, unorm, rz, r);
0379
0380 crossing = crossing && dir.Dot(unorm) < Real_v(0.);
0381
0382 crossing = crossing && (r >= Real_v(0.)) && (r <= Real_v(1.));
0383 vecCore__MaskedAssignFunc(distance, crossing && (!checked) && crtdist < distance, Max(crtdist, Real_v(0.)));
0384 }
0385
0386 if (!vecCore::MaskFull(Bool_v(crossing || checked))) {
0387
0388 crossing = !crossing;
0389 crtdist = smax[i];
0390 hit = point + crtdist * dir;
0391 crossing = crossing && (crtdist > -tolerance) && (Abs(hit.z()) < fDz + kTolerance);
0392 if (vecCore::MaskEmpty(crossing)) continue;
0393 if (fiscurved[i])
0394 UNormal<Real_v>(hit, i, unorm, rz, r);
0395 else
0396 unorm = fNormals[i];
0397 crossing = crossing && (dir.Dot(unorm) < Real_v(0.));
0398 crossing = crossing && (r >= Real_v(0.)) && (r <= Real_v(1.));
0399 vecCore__MaskedAssignFunc(distance, crossing && (!checked) && crtdist < distance, Max(crtdist, Real_v(0.)));
0400 }
0401 }
0402 vecCore__MaskedAssignFunc(distance, distance < tolerance && onsurf, Real_v(0.));
0403 return (distance);
0404
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414 template <typename Real_v>
0415 VECGEOM_FORCE_INLINE
0416 VECCORE_ATT_HOST_DEVICE
0417 Real_v SafetyToOut(Vector3D<Real_v> const &point, Real_v const &safmax) const
0418 {
0419
0420 using Bool_v = vecCore::Mask_v<Real_v>;
0421 VECGEOM_CONST Precision eps = 100. * kTolerance;
0422
0423 Real_v safety = safmax;
0424 Bool_v done = (Abs(safety) < eps);
0425 if (vecCore::MaskFull(done)) return (safety);
0426 Real_v safetyface = InfinityLength<Real_v>();
0427
0428
0429
0430 Vertex_t va;
0431 Vector3D<Real_v> pa;
0432 if (fisplanar) {
0433 for (int i = 0; i < N; ++i) {
0434 if (fdegenerated[i]) continue;
0435 va.Set(fxa[i], fya[i], -fDz);
0436 pa = va;
0437 safetyface = (pa - point).Dot(fNormals[i]);
0438 vecCore::MaskedAssign(safety, (safetyface < safety) && (!done), safetyface);
0439 }
0440 vecCore__MaskedAssignFunc(safety, Abs(safety) < eps, Real_v(0.));
0441 return safety;
0442 }
0443
0444
0445 safetyface = SafetyCurved<Real_v>(point, Bool_v(true));
0446
0447 vecCore::MaskedAssign(safety, (safetyface < safety) && (!done), safetyface);
0448
0449 vecCore__MaskedAssignFunc(safety, safety > Real_v(0.) && safety < eps, Real_v(0.));
0450 return safety;
0451
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461 template <typename Real_v>
0462 VECGEOM_FORCE_INLINE
0463 VECCORE_ATT_HOST_DEVICE
0464 Real_v SafetyToIn(Vector3D<Real_v> const &point, Real_v const &safmax) const
0465 {
0466
0467 using Bool_v = vecCore::Mask_v<Real_v>;
0468 VECGEOM_CONST Precision eps = 100. * kTolerance;
0469
0470 Real_v safety = safmax;
0471 Bool_v done = (Abs(safety) < eps);
0472 if (vecCore::MaskFull(done)) return (safety);
0473 Real_v safetyface = InfinityLength<Real_v>();
0474
0475
0476
0477 Vertex_t va;
0478 Vector3D<Real_v> pa;
0479 if (fisplanar) {
0480 for (int i = 0; i < N; ++i) {
0481 if (fdegenerated[i]) continue;
0482 va.Set(fxa[i], fya[i], -fDz);
0483 pa = va;
0484 safetyface = (point - pa).Dot(fNormals[i]);
0485 vecCore::MaskedAssign(safety, (safetyface > safety) && (!done), safetyface);
0486 }
0487 vecCore__MaskedAssignFunc(safety, Abs(safety) < eps, Real_v(0.));
0488 return safety;
0489 }
0490
0491
0492 safetyface = SafetyCurved<Real_v>(point, Bool_v(false));
0493
0494 vecCore::MaskedAssign(safety, (safetyface > safety) && (!done), safetyface);
0495
0496 vecCore__MaskedAssignFunc(safety, safety > Real_v(0.) && safety < eps, Real_v(0.));
0497 return (safety);
0498
0499 }
0500
0501
0502
0503
0504
0505
0506
0507
0508 template <typename Real_v>
0509 VECGEOM_FORCE_INLINE
0510 VECCORE_ATT_HOST_DEVICE
0511 Real_v SafetyCurved(Vector3D<Real_v> const &point, vecCore::Mask_v<Real_v> in) const
0512 {
0513 using Bool_v = vecCore::Mask_v<Real_v>;
0514 Real_v safety = InfinityLength<Real_v>();
0515 Real_v safplanar = InfinityLength<Real_v>();
0516 Real_v tolerance = Real_v(100 * kTolerance);
0517 vecCore__MaskedAssignFunc(tolerance, !in, -tolerance);
0518
0519
0520 Real_v dx, dy, dpx, dpy, lsq, u;
0521 Real_v dx1 = Real_v(0.);
0522 Real_v dx2 = Real_v(0.);
0523 Real_v dy1 = Real_v(0.);
0524 Real_v dy2 = Real_v(0.);
0525
0526 Bool_v completelyinside, completelyoutside, onsurf;
0527 CheckInside<Real_v>(point, completelyinside, completelyoutside, onsurf);
0528 if (vecCore::MaskFull(onsurf)) return (Real_v(0.));
0529
0530 Bool_v wrong = in && (completelyoutside);
0531 wrong = wrong || ((!in) && completelyinside);
0532 if (vecCore::MaskFull(wrong)) {
0533 return (Real_v(-1.));
0534 }
0535 Real_v vertexX[N];
0536 Real_v vertexY[N];
0537 Real_v dzp = fDz + point[2];
0538 for (int i = 0; i < N; i++) {
0539
0540 vertexX[i] = fxa[i] + ftx1[i] * dzp;
0541 vertexY[i] = fya[i] + fty1[i] * dzp;
0542 }
0543 Real_v umin = Real_v(0.);
0544 for (int i = 0; i < N; i++) {
0545 if (fiscurved[i] == 0) {
0546
0547 Vector3D<Real_v> pa;
0548 pa.Set(Real_v(fxa[i]), Real_v(fya[i]), Real_v(-fDz));
0549 Real_v sface = Abs((point - pa).Dot(fNormals[i]));
0550 vecCore::MaskedAssign(safplanar, sface < safplanar, sface);
0551 continue;
0552 }
0553 int j = (i + 1) % N;
0554 dx = vertexX[j] - vertexX[i];
0555 dy = vertexY[j] - vertexY[i];
0556 dpx = point[0] - vertexX[i];
0557 dpy = point[1] - vertexY[i];
0558 lsq = dx * dx + dy * dy;
0559 u = (dpx * dx + dpy * dy) / NonZero(lsq);
0560 vecCore__MaskedAssignFunc(dpx, u > 1, point[0] - vertexX[j]);
0561 vecCore__MaskedAssignFunc(dpy, u > 1, point[1] - vertexY[j]);
0562 vecCore__MaskedAssignFunc(dpx, u >= 0 && u <= 1, dpx - u * dx);
0563 vecCore__MaskedAssignFunc(dpy, u >= 0 && u <= 1, dpy - u * dy);
0564 Real_v ssq = dpx * dpx + dpy * dpy;
0565 vecCore__MaskedAssignFunc(dx1, ssq < safety, Real_v(fxc[i] - fxa[i]));
0566 vecCore__MaskedAssignFunc(dx2, ssq < safety, Real_v(fxd[i] - fxb[i]));
0567 vecCore__MaskedAssignFunc(dy1, ssq < safety, Real_v(fyc[i] - fya[i]));
0568 vecCore__MaskedAssignFunc(dy2, ssq < safety, Real_v(fyd[i] - fyb[i]));
0569 vecCore::MaskedAssign(umin, ssq < safety, u);
0570 vecCore::MaskedAssign(safety, ssq < safety, ssq);
0571 }
0572 vecCore__MaskedAssignFunc(umin, umin < 0 || umin > 1, Real_v(0.));
0573 dx = dx1 + umin * (dx2 - dx1);
0574 dy = dy1 + umin * (dy2 - dy1);
0575
0576 safety *= Real_v(1.) - Real_v(4.) * fDz * fDz / (dx * dx + dy * dy + Real_v(4.) * fDz * fDz);
0577 safety = Sqrt(safety);
0578 vecCore::MaskedAssign(safety, safplanar < safety, safplanar);
0579 vecCore__MaskedAssignFunc(safety, wrong, -safety);
0580 vecCore__MaskedAssignFunc(safety, onsurf, Real_v(0.));
0581 return safety;
0582 }
0583
0584 VECCORE_ATT_HOST_DEVICE
0585 VECGEOM_FORCE_INLINE
0586 Vertex_t const *GetNormals() const { return fNormals; }
0587
0588
0589
0590
0591
0592
0593
0594 template <typename Real_v>
0595 VECGEOM_FORCE_INLINE
0596 VECCORE_ATT_HOST_DEVICE
0597 vecCore::Mask_v<Real_v> InSurfLimits(Vector3D<Real_v> const &point, int isurf) const
0598 {
0599
0600 using Bool_v = vecCore::Mask_v<Real_v>;
0601
0602 Real_v rz = fDz2 * (point.z() + fDz);
0603 Bool_v insurf = (rz > Real_v(MakeMinusTolerant<true>(0.))) && (rz < Real_v(MakePlusTolerant<true>(1.)));
0604 if (vecCore::MaskEmpty(insurf)) return insurf;
0605
0606 Real_v r = InfinityLength<Real_v>();
0607 Real_v num = (point.x() - fxa[isurf]) - rz * (fxb[isurf] - fxa[isurf]);
0608 Real_v denom = (fxc[isurf] - fxa[isurf]) + rz * (fxd[isurf] - fxc[isurf] - fxb[isurf] + fxa[isurf]);
0609 vecCore__MaskedAssignFunc(r, (Abs(denom) > Real_v(1.e-6)), num / NonZero(denom));
0610 num = (point.y() - fya[isurf]) - rz * (fyb[isurf] - fya[isurf]);
0611 denom = (fyc[isurf] - fya[isurf]) + rz * (fyd[isurf] - fyc[isurf] - fyb[isurf] + fya[isurf]);
0612 vecCore__MaskedAssignFunc(r, (Abs(denom) > Real_v(1.e-6)), num / NonZero(denom));
0613 insurf = insurf && (r > Real_v(MakeMinusTolerant<true>(0.))) && (r < Real_v(MakePlusTolerant<true>(1.)));
0614 return insurf;
0615 }
0616
0617
0618
0619 template <typename Real_v>
0620 VECGEOM_FORCE_INLINE
0621 VECCORE_ATT_HOST_DEVICE
0622 void UNormal(Vector3D<Real_v> const &point, int isurf, Vector3D<Real_v> &unorm, Real_v &rz, Real_v &r) const
0623 {
0624
0625
0626
0627
0628
0629
0630
0631
0632 rz = fDz2 * (point.z() + fDz);
0633
0634
0635
0636
0637
0638
0639 Real_v num = (point.x() - fxa[isurf]) - rz * (fxb[isurf] - fxa[isurf]);
0640 Real_v denom = (fxc[isurf] - fxa[isurf]) + rz * (fxd[isurf] - fxc[isurf] - fxb[isurf] + fxa[isurf]);
0641 vecCore__MaskedAssignFunc(r, Abs(denom) > Real_v(1.e-6), num / NonZero(denom));
0642 num = (point.y() - fya[isurf]) - rz * (fyb[isurf] - fya[isurf]);
0643 denom = (fyc[isurf] - fya[isurf]) + rz * (fyd[isurf] - fyc[isurf] - fyb[isurf] + fya[isurf]);
0644 vecCore__MaskedAssignFunc(r, Abs(denom) > Real_v(1.e-6), num / NonZero(denom));
0645
0646 unorm = (Vector3D<Real_v>)fViCrossHi0[isurf] + rz * (Vector3D<Real_v>)fViCrossVj[isurf] +
0647 r * (Vector3D<Real_v>)fHi1CrossHi0[isurf];
0648 }
0649
0650
0651
0652 template <typename Real_v>
0653 VECGEOM_FORCE_INLINE
0654 VECCORE_ATT_HOST_DEVICE
0655
0656
0657
0658 void ComputeSminSmax(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir, Real_v smin[N], Real_v smax[N]) const
0659 {
0660
0661 const Real_v big = InfinityLength<Real_v>();
0662
0663 Real_v dzp = fDz + point[2];
0664
0665 Real_v a[N], b[N], c[N], d[N];
0666 Real_v signa[N], inva[N];
0667
0668
0669 for (int i = 0; i < N; ++i) {
0670 Real_v xs1 = fxa[i] + ftx1[i] * dzp;
0671 Real_v ys1 = fya[i] + fty1[i] * dzp;
0672 Real_v xs2 = fxc[i] + ftx2[i] * dzp;
0673 Real_v ys2 = fyc[i] + fty2[i] * dzp;
0674 Real_v dxs = xs2 - xs1;
0675 Real_v dys = ys2 - ys1;
0676 a[i] = (fDeltatx[i] * dir[1] - fDeltaty[i] * dir[0] + ft1crosst2[i] * dir[2]) * dir[2];
0677 b[i] = dxs * dir[1] - dys * dir[0] +
0678 (fDeltatx[i] * point[1] - fDeltaty[i] * point[0] + fty2[i] * xs1 - fty1[i] * xs2 + ftx1[i] * ys2 -
0679 ftx2[i] * ys1) *
0680 dir[2];
0681 c[i] = dxs * point[1] - dys * point[0] + xs1 * ys2 - xs2 * ys1;
0682 d[i] = b[i] * b[i] - 4 * a[i] * c[i];
0683 }
0684
0685
0686 for (int i = 0; i < N; ++i) {
0687
0688 signa[i] = Real_v(0.);
0689 vecCore__MaskedAssignFunc(signa[i], a[i] < -kTolerance, Real_v(-1.));
0690 vecCore__MaskedAssignFunc(signa[i], a[i] > kTolerance, Real_v(1.));
0691 inva[i] = c[i] / NonZero(b[i] * b[i]);
0692 vecCore__MaskedAssignFunc(inva[i], Abs(a[i]) > kTolerance, Real_v(1.) / NonZero(Real_v(2.) * a[i]));
0693 }
0694
0695
0696 for (int i = 0; i < N; ++i) {
0697
0698 Real_v sqrtd = signa[i] * Sqrt(Abs(d[i]));
0699 vecCore::MaskedAssign(sqrtd, d[i] < Real_v(0.), big);
0700
0701 smin[i] = (-b[i] - sqrtd) * inva[i];
0702 smax[i] = (-b[i] + sqrtd) * inva[i];
0703 }
0704
0705
0706 for (int i = 0; i < N; ++i) {
0707 if (fiscurved[i]) continue;
0708 Vertex_t va;
0709 Vector3D<Real_v> pa;
0710
0711 pa.Set(Real_v(fxa[i]), Real_v(fya[i]), Real_v(-fDz));
0712 Vector3D<Real_v> vecAP = point - pa;
0713
0714 Real_v dotAPNorm = vecAP.Dot(fNormals[i]);
0715
0716 Real_v dotDirNorm = dir.Dot(fNormals[i]);
0717 smin[i] = -dotAPNorm / NonZero(dotDirNorm);
0718 smax[i] = InfinityLength<Real_v>();
0719 }
0720 }
0721
0722 };
0723
0724 }
0725
0726 }
0727
0728 #endif