File indexing completed on 2025-01-18 10:14:15
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 LoopUnplacedVolumeImplHelper<
0084 PolyhedronImplementation<Polyhedron::EInnerRadii::kGeneric, Polyhedron::EPhiCutout::kGeneric>>,
0085 public AlignedBase {
0086
0087 private:
0088 PolyhedronStruct<Precision> fPoly;
0089
0090 public:
0091 UnplacedPolyhedron() : fPoly() { ComputeBBox(); }
0092
0093
0094
0095
0096
0097
0098
0099
0100 UnplacedPolyhedron(const int sideCount, const int zPlaneCount, Precision const zPlanes[], Precision const rMin[],
0101 Precision const rMax[]);
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 VECCORE_ATT_HOST_DEVICE
0119 UnplacedPolyhedron(Precision phiStart, Precision phiDelta, const int sideCount, const int zPlaneCount,
0120 Precision const zPlanes[], Precision const rMin[], Precision const rMax[]);
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 UnplacedPolyhedron(Precision phiStart, Precision phiDelta, const int sideCount, const int verticesCount,
0139 Precision const r[], Precision const z[]);
0140
0141 VECCORE_ATT_HOST_DEVICE
0142 virtual ~UnplacedPolyhedron() {}
0143
0144 VECCORE_ATT_HOST_DEVICE
0145 PolyhedronStruct<Precision> const &GetStruct() const { return fPoly; }
0146
0147 VECCORE_ATT_HOST_DEVICE
0148 VECGEOM_FORCE_INLINE
0149 int GetSideCount() const { return fPoly.fSideCount; }
0150
0151 VECCORE_ATT_HOST_DEVICE
0152 VECGEOM_FORCE_INLINE
0153 int GetZSegmentCount() const { return fPoly.fZSegments.size(); }
0154
0155 VECCORE_ATT_HOST_DEVICE
0156 VECGEOM_FORCE_INLINE
0157 bool HasInnerRadii() const { return fPoly.fHasInnerRadii; }
0158
0159 VECCORE_ATT_HOST_DEVICE
0160 VECGEOM_FORCE_INLINE
0161 bool HasPhiCutout() const { return fPoly.fHasPhiCutout; }
0162
0163 VECCORE_ATT_HOST_DEVICE
0164 VECGEOM_FORCE_INLINE
0165 bool HasLargePhiCutout() const { return fPoly.fHasLargePhiCutout; }
0166
0167 VECCORE_ATT_HOST_DEVICE
0168 VECGEOM_FORCE_INLINE
0169 ZSegment const &GetZSegment(int i) const { return fPoly.fZSegments[i]; }
0170
0171 VECCORE_ATT_HOST_DEVICE
0172 VECGEOM_FORCE_INLINE
0173 Array<ZSegment> const &GetZSegments() const { return fPoly.fZSegments; }
0174
0175 VECCORE_ATT_HOST_DEVICE
0176 VECGEOM_FORCE_INLINE
0177 Precision GetZPlane(int i) const { return fPoly.fZPlanes[i]; }
0178
0179 VECCORE_ATT_HOST_DEVICE
0180 VECGEOM_FORCE_INLINE
0181 Array<Precision> const &GetZPlanes() const { return fPoly.fZPlanes; }
0182
0183 VECCORE_ATT_HOST_DEVICE
0184 VECGEOM_FORCE_INLINE
0185 Array<Precision> const &GetRMin() const { return fPoly.fRMin; }
0186
0187 VECCORE_ATT_HOST_DEVICE
0188 VECGEOM_FORCE_INLINE
0189 Array<Precision> const &GetRMax() const { return fPoly.fRMax; }
0190
0191 VECCORE_ATT_HOST_DEVICE
0192 VECGEOM_FORCE_INLINE
0193 Vector3D<Precision> GetPhiSection(int i) const { return fPoly.fPhiSections[i]; }
0194
0195 VECCORE_ATT_HOST_DEVICE
0196 VECGEOM_FORCE_INLINE
0197 SOA3D<Precision> const &GetPhiSections() const { return fPoly.fPhiSections; }
0198
0199 VECCORE_ATT_HOST_DEVICE
0200 VECGEOM_FORCE_INLINE
0201 evolution::Wedge const &GetPhiWedge() const { return fPoly.fPhiWedge; }
0202
0203 VECCORE_ATT_HOST_DEVICE
0204 VECGEOM_FORCE_INLINE
0205 TubeStruct<Precision> const &GetBoundingTube() const { return fPoly.fBoundingTube; }
0206
0207 VECCORE_ATT_HOST_DEVICE
0208 VECGEOM_FORCE_INLINE
0209 Precision GetBoundingTubeOffset() const { return fPoly.fBoundingTubeOffset; }
0210
0211 #ifndef VECCORE_CUDA
0212 VECCORE_ATT_HOST_DEVICE
0213 bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0214 #endif
0215
0216
0217
0218
0219 VECCORE_ATT_HOST_DEVICE
0220 Precision GetTriangleArea(Vector3D<Precision> const &v1, Vector3D<Precision> const &v2,
0221 Vector3D<Precision> const &v3) const;
0222
0223 Precision Capacity() const override;
0224
0225 Precision SurfaceArea() const override;
0226 #ifndef VECCORE_CUDA
0227 Precision DistanceSquarePointToSegment(Vector3D<Precision> &v1, Vector3D<Precision> &v2,
0228 const Vector3D<Precision> &p) const;
0229 bool InsideTriangle(Vector3D<Precision> &v1, Vector3D<Precision> &v2, Vector3D<Precision> &v3,
0230 const Vector3D<Precision> &p) const;
0231
0232
0233
0234
0235 Vector3D<Precision> GetPointOnTriangle(Vector3D<Precision> const &v1, Vector3D<Precision> const &v2,
0236 Vector3D<Precision> const &v3) const;
0237
0238 void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0239
0240 Vector3D<Precision> SamplePointOnSurface() const override;
0241
0242 std::string GetEntityType() const { return "Polyhedron"; }
0243 #endif
0244
0245
0246
0247 VECCORE_ATT_HOST_DEVICE
0248 VECGEOM_FORCE_INLINE
0249 Precision GetPhiStart() const { return fPoly.fPhiStart; }
0250
0251
0252
0253 VECCORE_ATT_HOST_DEVICE
0254 VECGEOM_FORCE_INLINE
0255 Precision GetPhiEnd() const { return fPoly.fPhiStart + fPoly.fPhiDelta; }
0256
0257
0258
0259 VECCORE_ATT_HOST_DEVICE
0260 VECGEOM_FORCE_INLINE
0261 Precision GetPhiDelta() const { return fPoly.fPhiDelta; }
0262
0263
0264
0265 VECCORE_ATT_HOST_DEVICE
0266 int GetNQuadrilaterals() const;
0267
0268
0269 template <typename PushableContainer>
0270 void ReconstructSectionArrays(PushableContainer &zplanes, PushableContainer &rmin, PushableContainer &rmax) const
0271 {
0272
0273
0274
0275
0276
0277
0278
0279 AOS3D<Precision> const *innercorners;
0280 AOS3D<Precision> const *outercorners;
0281
0282
0283 auto getradius = [](Vector3D<Precision> const &a, Vector3D<Precision> const &b) {
0284 return std::sqrt(a.Perp2() - (a - b).Mag2() / 4.);
0285 };
0286
0287 Array<ZSegment>::const_iterator s;
0288 Array<ZSegment>::const_iterator end = fPoly.fZSegments.cend();
0289
0290 for (s = fPoly.fZSegments.cbegin(); s != end; ++s) {
0291 outercorners = (*s).outer.GetCorners();
0292 Vector3D<Precision> a = outercorners[0][0];
0293 Vector3D<Precision> b = outercorners[1][0];
0294 rmax.push_back(getradius(a, b));
0295 zplanes.push_back(a.z());
0296
0297 if (fPoly.fHasInnerRadii) {
0298 innercorners = (*s).inner.GetCorners();
0299 a = innercorners[0][0];
0300 b = innercorners[1][0];
0301 rmin.push_back(getradius(a, b));
0302 } else {
0303 rmin.push_back(0.);
0304 }
0305 }
0306
0307
0308 Vector3D<Precision> a = outercorners[2][0];
0309 Vector3D<Precision> b = outercorners[3][0];
0310 rmax.push_back(getradius(a, b));
0311 zplanes.push_back(a.z());
0312
0313 if (fPoly.fHasInnerRadii) {
0314 a = innercorners[2][0];
0315 b = innercorners[3][0];
0316 rmin.push_back(getradius(a, b));
0317 } else {
0318 rmin.push_back(0.);
0319 }
0320 }
0321
0322 VECCORE_ATT_HOST_DEVICE
0323 void DetectConvexity();
0324
0325 VECCORE_ATT_HOST_DEVICE
0326 virtual void Print() const final;
0327
0328 VECCORE_ATT_HOST_DEVICE
0329 void PrintSegments() const;
0330
0331 virtual void Print(std::ostream &os) const final;
0332
0333 #ifndef VECCORE_CUDA
0334 virtual SolidMesh *CreateMesh3D(Transformation3D const &trans, size_t nSegments) const override;
0335 #endif
0336
0337 template <TranslationCode transCodeT, RotationCode rotCodeT>
0338 VECCORE_ATT_DEVICE
0339 static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0340 #ifdef VECCORE_CUDA
0341 const int id, const int copy_no, const int child_id,
0342 #endif
0343 VPlacedVolume *const placement = NULL);
0344
0345 VECCORE_ATT_DEVICE
0346 virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0347 Transformation3D const *const transformation,
0348 const TranslationCode trans_code, const RotationCode rot_code,
0349 #ifdef VECCORE_CUDA
0350 const int id, const int copy_no, const int child_id,
0351 #endif
0352 VPlacedVolume *const placement = NULL) const final;
0353 VECGEOM_FORCE_INLINE
0354 virtual int MemorySize() const final { return sizeof(*this); }
0355
0356 #ifdef VECGEOM_CUDA_INTERFACE
0357 virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedPolyhedron>::SizeOf(); }
0358 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0359 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0360 static void CopyToGpu(std::vector<VUnplacedVolume const *> const & volumes, std::vector<DevicePtr<cuda::VUnplacedVolume>> const & devPtrs);
0361 #endif
0362
0363 private:
0364
0365
0366 VECCORE_ATT_HOST_DEVICE
0367 void Initialize(Precision phiStart, Precision phiDelta, const int sideCount, const int zPlaneCount,
0368 Precision const zPlanes[], Precision const rMin[], Precision const rMax[]);
0369
0370 };
0371
0372 }
0373
0374 }
0375
0376 #endif