File indexing completed on 2026-10-04 09:28:16
0001
0002
0003
0004 #ifndef VECGEOM_VOLUMES_UNPLACEDPOLYHEDRON_H_
0005 #define VECGEOM_VOLUMES_UNPLACEDPOLYHEDRON_H_
0006
0007 #include "VecGeom/base/Cuda.h"
0008 #include "VecGeom/base/Global.h"
0009 #include "VecGeom/base/AlignedBase.h"
0010 #include "VecGeom/volumes/UnplacedVolume.h"
0011 #include "VecGeom/volumes/PolyhedronStruct.h"
0012 #include "VecGeom/volumes/kernel/PolyhedronImplementation.h"
0013 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0014
0015 namespace vecgeom {
0016
0017 VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedPolyhedron;);
0018 VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedPolyhedron);
0019
0020 template <typename Stream>
0021 Stream &operator<<(Stream &st, EInnerRadii a)
0022 {
0023 if (a == EInnerRadii::kFalse) st << "EInnerRadii::kFalse";
0024 if (a == EInnerRadii::kGeneric) st << "EInnerRadii::kGeneric";
0025 if (a == EInnerRadii::kTrue) st << "EInnerRadii::kTrue";
0026 return st;
0027 }
0028
0029 template <typename Stream>
0030 Stream &operator<<(Stream &st, EPhiCutout a)
0031 {
0032 if (a == EPhiCutout::kFalse) st << "EPhiCutout::kFalse";
0033 if (a == EPhiCutout::kGeneric) st << "EPhiCutout::kGeneric";
0034 if (a == EPhiCutout::kTrue) st << "EPhiCutout::kTrue";
0035 if (a == EPhiCutout::kLarge) st << "EPhiCutout::kLarge";
0036 return st;
0037 }
0038
0039 inline namespace VECGEOM_IMPL_NAMESPACE {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 class UnplacedPolyhedron
0083 : public UnplacedVolumeImplHelper<
0084 PolyhedronImplementation<Polyhedron::EInnerRadii::kGeneric, Polyhedron::EPhiCutout::kGeneric>>,
0085 public AlignedBase {
0086
0087 private:
0088 PolyhedronStruct<Precision> *fPoly{nullptr};
0089 bool fAllocated{false};
0090 const void *fBuffer{nullptr};
0091
0092 public:
0093 UnplacedPolyhedron() = default;
0094
0095
0096
0097
0098
0099
0100
0101
0102 UnplacedPolyhedron(const int sideCount, const int zPlaneCount, Precision const zPlanes[], Precision const rMin[],
0103 Precision const rMax[]);
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 VECCORE_ATT_HOST_DEVICE
0121 UnplacedPolyhedron(Precision phiStart, Precision phiDelta, const int sideCount, const int zPlaneCount,
0122 Precision const zPlanes[], Precision const rMin[], Precision const rMax[]);
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 VECCORE_ATT_HOST_DEVICE
0143 UnplacedPolyhedron(Precision phiStart, Precision phiDelta, const int sideCount, const int zPlaneCount,
0144 Precision const zPlanes[], Precision const rMin[], Precision const rMax[], size_t const buff_size,
0145 void const *buffer);
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 UnplacedPolyhedron(Precision phiStart, Precision phiDelta, const int sideCount, const int verticesCount,
0164 Precision const r[], Precision const z[]);
0165
0166 VECCORE_ATT_HOST_DEVICE
0167 virtual ~UnplacedPolyhedron()
0168 {
0169 if (fAllocated) delete[] (char *)fBuffer;
0170 }
0171
0172 VECCORE_ATT_HOST_DEVICE
0173 VECGEOM_FORCE_INLINE
0174 virtual ESolidType GetType() const override { return ESolidType::polyhedron; }
0175
0176 VECCORE_ATT_HOST_DEVICE
0177 PolyhedronStruct<Precision> const &GetStruct() const { return *fPoly; }
0178
0179 VECCORE_ATT_HOST_DEVICE
0180 VECGEOM_FORCE_INLINE
0181 int GetSideCount() const { return fPoly->fSideCount; }
0182
0183 VECCORE_ATT_HOST_DEVICE
0184 VECGEOM_FORCE_INLINE
0185 int GetZSegmentCount() const { return fPoly->fZSegments.size(); }
0186
0187 VECCORE_ATT_HOST_DEVICE
0188 VECGEOM_FORCE_INLINE
0189 bool HasInnerRadii() const { return fPoly->fHasInnerRadii; }
0190
0191 VECCORE_ATT_HOST_DEVICE
0192 VECGEOM_FORCE_INLINE
0193 bool HasPhiCutout() const { return fPoly->fHasPhiCutout; }
0194
0195 VECCORE_ATT_HOST_DEVICE
0196 VECGEOM_FORCE_INLINE
0197 bool HasLargePhiCutout() const { return fPoly->fHasLargePhiCutout; }
0198
0199 VECCORE_ATT_HOST_DEVICE
0200 VECGEOM_FORCE_INLINE
0201 ZSegment const &GetZSegment(int i) const { return fPoly->fZSegments[i]; }
0202
0203 VECCORE_ATT_HOST_DEVICE
0204 VECGEOM_FORCE_INLINE
0205 Array<ZSegment> const &GetZSegments() const { return fPoly->fZSegments; }
0206
0207 VECCORE_ATT_HOST_DEVICE
0208 VECGEOM_FORCE_INLINE
0209 Precision GetZPlane(int i) const { return fPoly->fZPlanes[i]; }
0210
0211 VECCORE_ATT_HOST_DEVICE
0212 VECGEOM_FORCE_INLINE
0213 Array<Precision> const &GetZPlanes() const { return fPoly->fZPlanes; }
0214
0215 VECCORE_ATT_HOST_DEVICE
0216 VECGEOM_FORCE_INLINE
0217 Array<Precision> const &GetRMin() const { return fPoly->fRMin; }
0218
0219 VECCORE_ATT_HOST_DEVICE
0220 VECGEOM_FORCE_INLINE
0221 Array<Precision> const &GetRMax() const { return fPoly->fRMax; }
0222
0223 VECCORE_ATT_HOST_DEVICE
0224 VECGEOM_FORCE_INLINE
0225 Vector3D<Precision> GetPhiSection(int i) const { return fPoly->fPhiSections[i]; }
0226
0227 VECCORE_ATT_HOST_DEVICE
0228 VECGEOM_FORCE_INLINE
0229 SOA3D<Precision> const &GetPhiSections() const { return fPoly->fPhiSections; }
0230
0231 VECCORE_ATT_HOST_DEVICE
0232 VECGEOM_FORCE_INLINE
0233 evolution::Wedge const &GetPhiWedge() const { return fPoly->fPhiWedge; }
0234
0235 VECCORE_ATT_HOST_DEVICE
0236 VECGEOM_FORCE_INLINE
0237 TubeStruct<Precision> const &GetBoundingTube() const { return fPoly->fBoundingTube; }
0238
0239 VECCORE_ATT_HOST_DEVICE
0240 VECGEOM_FORCE_INLINE
0241 Precision GetBoundingTubeOffset() const { return fPoly->fBoundingTubeOffset; }
0242
0243 VECCORE_ATT_HOST_DEVICE
0244 bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0245
0246
0247
0248
0249 VECCORE_ATT_HOST_DEVICE
0250 Precision GetTriangleArea(Vector3D<Precision> const &v1, Vector3D<Precision> const &v2,
0251 Vector3D<Precision> const &v3) const;
0252
0253 Precision Capacity() const override;
0254
0255 Precision SurfaceArea() const override;
0256
0257 VECCORE_ATT_HOST_DEVICE
0258 void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0259
0260 #ifndef VECCORE_CUDA
0261 Precision DistanceSquarePointToSegment(Vector3D<Precision> &v1, Vector3D<Precision> &v2,
0262 const Vector3D<Precision> &p) const;
0263 bool InsideTriangle(Vector3D<Precision> &v1, Vector3D<Precision> &v2, Vector3D<Precision> &v3,
0264 const Vector3D<Precision> &p) const;
0265
0266
0267
0268
0269 Vector3D<Precision> GetPointOnTriangle(Vector3D<Precision> const &v1, Vector3D<Precision> const &v2,
0270 Vector3D<Precision> const &v3) const;
0271
0272 Vector3D<Precision> SamplePointOnSurface() const override;
0273
0274 std::string GetEntityType() const { return "Polyhedron"; }
0275 #endif
0276
0277
0278
0279 VECCORE_ATT_HOST_DEVICE
0280 VECGEOM_FORCE_INLINE
0281 Precision GetPhiStart() const { return fPoly->fPhiStart; }
0282
0283
0284
0285 VECCORE_ATT_HOST_DEVICE
0286 VECGEOM_FORCE_INLINE
0287 Precision GetPhiEnd() const { return fPoly->fPhiStart + fPoly->fPhiDelta; }
0288
0289
0290
0291 VECCORE_ATT_HOST_DEVICE
0292 VECGEOM_FORCE_INLINE
0293 Precision GetPhiDelta() const { return fPoly->fPhiDelta; }
0294
0295
0296
0297 VECCORE_ATT_HOST_DEVICE
0298 int GetNQuadrilaterals() const;
0299
0300
0301 template <typename PushableContainer>
0302 void ReconstructSectionArrays(PushableContainer &zplanes, PushableContainer &rmin, PushableContainer &rmax) const
0303 {
0304
0305
0306
0307
0308
0309
0310
0311 AOS3D<Precision> const *innercorners;
0312 AOS3D<Precision> const *outercorners;
0313
0314
0315 auto getradius = [](Vector3D<Precision> const &a, Vector3D<Precision> const &b) {
0316 return std::sqrt(a.Perp2() - (a - b).Mag2() / 4.);
0317 };
0318
0319 Array<ZSegment>::const_iterator s;
0320 Array<ZSegment>::const_iterator end = fPoly->fZSegments.cend();
0321
0322 for (s = fPoly->fZSegments.cbegin(); s != end; ++s) {
0323 outercorners = (*s).outer.GetCorners();
0324 Vector3D<Precision> a = outercorners[0][0];
0325 Vector3D<Precision> b = outercorners[1][0];
0326 rmax.push_back(getradius(a, b));
0327 zplanes.push_back(a.z());
0328
0329 if (fPoly->fHasInnerRadii) {
0330 innercorners = (*s).inner.GetCorners();
0331 a = innercorners[0][0];
0332 b = innercorners[1][0];
0333 rmin.push_back(getradius(a, b));
0334 } else {
0335 rmin.push_back(0.);
0336 }
0337 }
0338
0339
0340 Vector3D<Precision> a = outercorners[2][0];
0341 Vector3D<Precision> b = outercorners[3][0];
0342 rmax.push_back(getradius(a, b));
0343 zplanes.push_back(a.z());
0344
0345 if (fPoly->fHasInnerRadii) {
0346 a = innercorners[2][0];
0347 b = innercorners[3][0];
0348 rmin.push_back(getradius(a, b));
0349 } else {
0350 rmin.push_back(0.);
0351 }
0352 }
0353
0354 VECCORE_ATT_HOST_DEVICE
0355 void DetectConvexity();
0356
0357 VECCORE_ATT_HOST_DEVICE
0358 virtual void Print() const final;
0359
0360 VECCORE_ATT_HOST_DEVICE
0361 void PrintSegments() const;
0362
0363 virtual void Print(std::ostream &os) const final;
0364
0365 #ifndef VECCORE_CUDA
0366 virtual SolidMesh *CreateMesh3D(Transformation3D const &trans, size_t nSegments) const override;
0367 #endif
0368
0369 VECCORE_ATT_DEVICE
0370 static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0371 #ifdef VECCORE_CUDA
0372 const int id, const int copy_no, const int child_id,
0373 #endif
0374 VPlacedVolume *const placement = NULL);
0375
0376 VECCORE_ATT_DEVICE
0377 virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0378 Transformation3D const *const transformation,
0379 #ifdef VECCORE_CUDA
0380 const int id, const int copy_no, const int child_id,
0381 #endif
0382 VPlacedVolume *const placement = NULL) const final;
0383 VECGEOM_FORCE_INLINE
0384 virtual int MemorySize() const final { return sizeof(*this); }
0385
0386 #ifdef VECGEOM_CUDA_INTERFACE
0387 virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedPolyhedron>::SizeOf(); }
0388 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0389 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0390 static void CopyToGpu(std::vector<VUnplacedVolume const *> const &volumes,
0391 std::vector<DevicePtr<cuda::VUnplacedVolume>> const &devPtrs);
0392 #endif
0393
0394 private:
0395
0396
0397 VECCORE_ATT_HOST_DEVICE
0398 void Initialize(Precision phiStart, Precision phiDelta, const int sideCount, const int zPlaneCount,
0399 Precision const zPlanes[], Precision const rMin[], Precision const rMax[]);
0400
0401 };
0402
0403 }
0404
0405 }
0406
0407 #endif