File indexing completed on 2025-01-18 10:13:53
0001
0002
0003
0004
0005 #ifndef VECGEOM_BASE_SIDEPLANES_H_
0006 #define VECGEOM_BASE_SIDEPLANES_H_
0007
0008 #include "VecGeom/base/Global.h"
0009 #include "VecGeom/volumes/kernel/GenericKernels.h"
0010
0011
0012 #include <VecCore/VecCore>
0013
0014 namespace vecgeom {
0015 inline namespace VECGEOM_IMPL_NAMESPACE {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 template <int N, typename Type>
0032 struct PlaneShell {
0033
0034
0035 Precision fA[N];
0036 Precision fB[N];
0037 Precision fC[N];
0038 Precision fD[N];
0039
0040 public:
0041
0042
0043
0044 VECCORE_ATT_HOST_DEVICE
0045 PlaneShell(Precision *const a, Precision *const b, Precision *const c, Precision *const d)
0046 {
0047 memcpy(&(this->fA), a, N * sizeof(Type));
0048 memcpy(&(this->fB), b, N * sizeof(Type));
0049 memcpy(&(this->fC), c, N * sizeof(Type));
0050 memcpy(&(this->fD), d, N * sizeof(Type));
0051 }
0052
0053
0054
0055
0056
0057 VECCORE_ATT_HOST_DEVICE
0058 PlaneShell()
0059 {
0060 memset(&(this->fA), 0, N * sizeof(Type));
0061 memset(&(this->fB), 0, N * sizeof(Type));
0062 memset(&(this->fC), 0, N * sizeof(Type));
0063 memset(&(this->fD), 0, N * sizeof(Type));
0064 }
0065
0066
0067
0068
0069 VECCORE_ATT_HOST_DEVICE
0070 PlaneShell(PlaneShell const &other)
0071 {
0072 memcpy(&(this->fA), &(other.fA), N * sizeof(Type));
0073 memcpy(&(this->fB), &(other.fB), N * sizeof(Type));
0074 memcpy(&(this->fC), &(other.fC), N * sizeof(Type));
0075 memcpy(&(this->fD), &(other.fD), N * sizeof(Type));
0076 }
0077
0078
0079
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 PlaneShell &operator=(PlaneShell const &other)
0083 {
0084 memcpy(this->fA, other.fA, N * sizeof(Type));
0085 memcpy(this->fB, other.fB, N * sizeof(Type));
0086 memcpy(this->fC, other.fC, N * sizeof(Type));
0087 memcpy(this->fD, other.fD, N * sizeof(Type));
0088 return *this;
0089 }
0090
0091 VECCORE_ATT_HOST_DEVICE
0092 void Set(int i, Precision a, Precision b, Precision c, Precision d)
0093 {
0094 fA[i] = a;
0095 fB[i] = b;
0096 fC[i] = c;
0097 fD[i] = d;
0098 }
0099
0100 VECCORE_ATT_HOST_DEVICE
0101 unsigned int size() { return N; }
0102
0103 VECCORE_ATT_HOST_DEVICE
0104 ~PlaneShell() {}
0105
0106
0107
0108 template <typename Type2>
0109 VECGEOM_FORCE_INLINE
0110 VECCORE_ATT_HOST_DEVICE
0111 void DistanceToPoint(Vector3D<Type2> const &point, Type2 *distances) const
0112 {
0113 for (int i = 0; i < N; ++i) {
0114 distances[i] = this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i];
0115 }
0116 }
0117
0118
0119
0120 template <typename Type2>
0121 VECGEOM_FORCE_INLINE
0122 VECCORE_ATT_HOST_DEVICE
0123 void ProjectionToNormal(Vector3D<Type2> const &dir, Type2 *projection) const
0124 {
0125 for (int i = 0; i < N; ++i) {
0126 projection[i] = this->fA[i] * dir.x() + this->fB[i] * dir.y() + this->fC[i] * dir.z();
0127 }
0128 }
0129
0130 template <typename Real_v, bool ForInside>
0131 VECGEOM_FORCE_INLINE
0132 VECCORE_ATT_HOST_DEVICE
0133 void GenericKernelForContainsAndInside(Vector3D<Real_v> const &point, vecCore::Mask_v<Real_v> &completelyInside,
0134 vecCore::Mask_v<Real_v> &completelyOutside) const
0135 {
0136
0137 Real_v dist[N];
0138 for (unsigned int i = 0; i < N; ++i) {
0139 dist[i] = this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i];
0140 }
0141
0142
0143 for (unsigned int i = 0; i < N; ++i) {
0144
0145 completelyOutside = completelyOutside || (dist[i] > Real_v(MakePlusTolerant<ForInside>(0.)));
0146 if (ForInside) {
0147 completelyInside = completelyInside && (dist[i] < Real_v(MakeMinusTolerant<ForInside>(0.)));
0148 }
0149
0150 }
0151 }
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 template <typename Real_v>
0162 VECGEOM_FORCE_INLINE
0163 VECCORE_ATT_HOST_DEVICE
0164 Real_v DistanceToIn(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir, Real_v &smin, Real_v &smax) const
0165 {
0166 using Bool_v = vecCore::Mask_v<Real_v>;
0167 Bool_v done(false);
0168 Real_v distIn(kInfLength);
0169
0170
0171 Real_v pdist[N];
0172 Real_v proj[N];
0173 Real_v vdist[N];
0174
0175 for (int i = 0; i < N; ++i) {
0176 pdist[i] = this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i];
0177 proj[i] = this->fA[i] * dir.x() + this->fB[i] * dir.y() + this->fC[i] * dir.z();
0178
0179
0180 vdist[i] = -pdist[i] / NonZero(proj[i]);
0181 }
0182
0183
0184 for (int i = 0; i < N; ++i) {
0185 done = done || (pdist[i] > Real_v(MakePlusTolerant<true>(0.)) && proj[i] >= Real_v(0.));
0186 done = done || (pdist[i] > Real_v(MakeMinusTolerant<true>(0.)) && proj[i] > Real_v(0.));
0187 }
0188 if (vecCore::EarlyReturnMaxLength(done, 1) && vecCore::MaskFull(done)) return distIn;
0189
0190
0191 for (int i = 0; i < N; ++i) {
0192
0193 Bool_v posPoint = pdist[i] > Real_v(MakeMinusTolerant<true>(0.));
0194 Bool_v posDir = proj[i] > 0;
0195
0196
0197 Bool_v interceptFromInside = (!posPoint && posDir);
0198 done = done || (interceptFromInside && vdist[i] < smin);
0199
0200 Bool_v interceptFromOutside = (posPoint && !posDir);
0201 done = done || (interceptFromOutside && vdist[i] > smax);
0202 if (vecCore::EarlyReturnMaxLength(done, 1) && vecCore::MaskFull(done)) return distIn;
0203
0204
0205 vecCore__MaskedAssignFunc(smin, interceptFromOutside && vdist[i] > smin, vdist[i]);
0206 vecCore__MaskedAssignFunc(smax, interceptFromInside && vdist[i] < smax, vdist[i]);
0207 }
0208
0209
0210
0211 vecCore::MaskedAssign(distIn, !done && smin <= smax, smin);
0212 return distIn;
0213 }
0214
0215
0216
0217
0218
0219 template <typename Real_v>
0220 VECGEOM_FORCE_INLINE
0221 VECCORE_ATT_HOST_DEVICE
0222 Real_v DistanceToOut(Vector3D<Real_v> const &point, Vector3D<Real_v> const &dir) const
0223 {
0224
0225
0226 Real_v distOut(kInfLength);
0227
0228
0229
0230
0231
0232 Real_v pdist[N];
0233 Real_v proj[N];
0234 Real_v vdist[N];
0235 for (int i = 0; i < N; ++i) {
0236 pdist[i] = this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i];
0237 proj[i] = this->fA[i] * dir.x() + this->fB[i] * dir.y() + this->fC[i] * dir.z();
0238 vdist[i] = -pdist[i] / NonZero(proj[i]);
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 for (int i = 0; i < N; ++i) {
0250 vecCore__MaskedAssignFunc(distOut, pdist[i] > kHalfTolerance, Real_v(-1.));
0251 vecCore__MaskedAssignFunc(distOut, proj[i] > Real_v(0.) && vdist[i] < distOut, vdist[i]);
0252
0253
0254 }
0255
0256 return distOut;
0257 }
0258
0259
0260 template <typename Real_v>
0261 VECGEOM_FORCE_INLINE
0262 VECCORE_ATT_HOST_DEVICE
0263 void SafetyToIn(Vector3D<Real_v> const &point, Real_v &safety) const
0264 {
0265
0266 Real_v dist[N];
0267 for (int i = 0; i < N; ++i) {
0268 dist[i] = this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i];
0269 }
0270
0271
0272 for (int i = 0; i < N; ++i) {
0273 vecCore__MaskedAssignFunc(safety, dist[i] > safety, dist[i]);
0274 }
0275 }
0276
0277
0278 template <typename Real_v>
0279 VECGEOM_FORCE_INLINE
0280 VECCORE_ATT_HOST_DEVICE
0281 void SafetyToOut(Vector3D<Real_v> const &point, Real_v &safety) const
0282 {
0283
0284 Real_v dist[N];
0285 for (int i = 0; i < N; ++i) {
0286 dist[i] = -(this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i]);
0287 }
0288
0289
0290 for (int i = 0; i < N; ++i) {
0291 vecCore__MaskedAssignFunc(safety, dist[i] < safety, dist[i]);
0292 }
0293 }
0294
0295 template <typename Real_v>
0296 VECGEOM_FORCE_INLINE
0297 VECCORE_ATT_HOST_DEVICE
0298 size_t ClosestFace(Vector3D<Real_v> const &point, Real_v &safety) const
0299 {
0300
0301 Real_v dist[N];
0302 for (int i = 0; i < N; ++i) {
0303 dist[i] = Abs(this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i]);
0304 }
0305
0306
0307 using Bool_v = vecCore::Mask_v<Real_v>;
0308 using Index_v = vecCore::Index<Real_v>;
0309 Index_v closest = static_cast<Index_v>(-1);
0310 for (size_t i = 0; i < N; ++i) {
0311 Bool_v closer = dist[i] < safety;
0312 vecCore__MaskedAssignFunc(safety, closer, dist[i]);
0313 vecCore::MaskedAssign(closest, closer, i);
0314 }
0315
0316 return closest;
0317 }
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 template <typename Real_v>
0328 VECGEOM_FORCE_INLINE
0329 VECCORE_ATT_HOST_DEVICE
0330 Real_v NormalKernel(Vector3D<Real_v> const &point, Vector3D<Real_v> &normal) const
0331 {
0332 Real_v safety = -InfinityLength<Real_v>();
0333
0334
0335 Real_v dist[N];
0336 for (int i = 0; i < N; ++i) {
0337 dist[i] = (this->fA[i] * point.x() + this->fB[i] * point.y() + this->fC[i] * point.z() + this->fD[i]);
0338 }
0339
0340
0341 for (int i = 0; i < 4; ++i) {
0342 Real_v saf_i = dist[i] - safety;
0343
0344
0345 vecCore__MaskedAssignFunc(normal, Abs(saf_i) < kHalfTolerance && dist[i] >= -kHalfTolerance,
0346 normal + Vector3D<Real_v>(this->fA[i], this->fB[i], this->fC[i]));
0347
0348
0349 vecCore__MaskedAssignFunc(normal, saf_i > Real_v(0.), Vector3D<Real_v>(this->fA[i], this->fB[i], this->fC[i]));
0350 vecCore__MaskedAssignFunc(safety, saf_i > Real_v(0.), dist[i]);
0351
0352
0353 }
0354
0355
0356
0357 return safety;
0358 }
0359 };
0360
0361 }
0362 }
0363
0364 #endif