File indexing completed on 2025-01-18 10:14:15
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef VECGEOM_VOLUMES_UNPLACEDHYPE_H_
0010 #define VECGEOM_VOLUMES_UNPLACEDHYPE_H_
0011
0012 #include "VecGeom/base/Cuda.h"
0013 #include "VecGeom/base/Global.h"
0014 #include "VecGeom/base/AlignedBase.h"
0015 #include "VecGeom/volumes/UnplacedVolume.h"
0016 #include "VecGeom/volumes/HypeStruct.h"
0017 #include "VecGeom/volumes/kernel/HypeImplementation.h"
0018 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0019
0020 namespace vecgeom {
0021
0022 VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedHype;);
0023 VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedHype);
0024 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, SUnplacedHype, typename);
0025
0026 inline namespace VECGEOM_IMPL_NAMESPACE {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 class UnplacedHype : public VUnplacedVolume {
0042
0043 private:
0044 HypeStruct<Precision> fHype;
0045
0046 public:
0047
0048
0049
0050
0051
0052
0053
0054
0055 VECCORE_ATT_HOST_DEVICE
0056 UnplacedHype(const Precision rMin, const Precision rMax, const Precision stIn, const Precision stOut,
0057 const Precision dz)
0058 : fHype(rMin, rMax, stIn, stOut, dz)
0059 {
0060 DetectConvexity();
0061 ComputeBBox();
0062 }
0063
0064
0065 VECCORE_ATT_HOST_DEVICE
0066 HypeStruct<Precision> const &GetStruct() const { return fHype; }
0067
0068
0069 VECCORE_ATT_HOST_DEVICE
0070 VECGEOM_FORCE_INLINE
0071 Precision GetZToleranceLevel() const { return fHype.zToleranceLevel; }
0072
0073
0074 VECCORE_ATT_HOST_DEVICE
0075 VECGEOM_FORCE_INLINE
0076 Precision GetInnerRadToleranceLevel() const { return fHype.innerRadToleranceLevel; }
0077
0078
0079 VECCORE_ATT_HOST_DEVICE
0080 VECGEOM_FORCE_INLINE
0081 Precision GetOuterRadToleranceLevel() const { return fHype.outerRadToleranceLevel; }
0082
0083
0084 VECCORE_ATT_HOST_DEVICE
0085 VECGEOM_FORCE_INLINE
0086 Precision GetRmin() const { return fHype.fRmin; }
0087
0088
0089 VECCORE_ATT_HOST_DEVICE
0090 VECGEOM_FORCE_INLINE
0091 Precision GetRmax() const { return fHype.fRmax; }
0092
0093
0094 VECCORE_ATT_HOST_DEVICE
0095 VECGEOM_FORCE_INLINE
0096 Precision GetRmin2() const { return fHype.fRmin2; }
0097
0098
0099 VECCORE_ATT_HOST_DEVICE
0100 VECGEOM_FORCE_INLINE
0101 Precision GetRmax2() const { return fHype.fRmax2; }
0102
0103
0104 VECCORE_ATT_HOST_DEVICE
0105 VECGEOM_FORCE_INLINE
0106 Precision GetStIn() const { return fHype.fStIn; }
0107
0108
0109 VECCORE_ATT_HOST_DEVICE
0110 VECGEOM_FORCE_INLINE
0111 Precision GetStOut() const { return fHype.fStOut; }
0112
0113
0114 VECCORE_ATT_HOST_DEVICE
0115 VECGEOM_FORCE_INLINE
0116 Precision GetTIn() const { return fHype.fTIn; }
0117
0118
0119 VECCORE_ATT_HOST_DEVICE
0120 VECGEOM_FORCE_INLINE
0121 Precision GetTOut() const { return fHype.fTOut; }
0122
0123
0124 VECCORE_ATT_HOST_DEVICE
0125 VECGEOM_FORCE_INLINE
0126 Precision GetTIn2() const { return fHype.fTIn2; }
0127
0128
0129 VECCORE_ATT_HOST_DEVICE
0130 VECGEOM_FORCE_INLINE
0131 Precision GetTOut2() const { return fHype.fTOut2; }
0132
0133
0134 VECCORE_ATT_HOST_DEVICE
0135 VECGEOM_FORCE_INLINE
0136 Precision GetTIn2Inv() const { return fHype.fTIn2Inv; }
0137
0138
0139 VECCORE_ATT_HOST_DEVICE
0140 VECGEOM_FORCE_INLINE
0141 Precision GetTOut2Inv() const { return fHype.fTOut2Inv; }
0142
0143
0144 VECCORE_ATT_HOST_DEVICE
0145 VECGEOM_FORCE_INLINE
0146 Precision GetDz() const { return fHype.fDz; }
0147
0148
0149 VECCORE_ATT_HOST_DEVICE
0150 VECGEOM_FORCE_INLINE
0151 Precision GetDz2() const { return fHype.fDz2; }
0152
0153
0154 VECCORE_ATT_HOST_DEVICE
0155 VECGEOM_FORCE_INLINE
0156 Precision GetEndInnerRadius() const { return fHype.fEndInnerRadius; }
0157
0158
0159 VECCORE_ATT_HOST_DEVICE
0160 VECGEOM_FORCE_INLINE
0161 Precision GetEndInnerRadius2() const { return fHype.fEndInnerRadius2; }
0162
0163
0164 VECCORE_ATT_HOST_DEVICE
0165 VECGEOM_FORCE_INLINE
0166 Precision GetEndOuterRadius() const { return fHype.fEndOuterRadius; }
0167
0168
0169 VECCORE_ATT_HOST_DEVICE
0170 VECGEOM_FORCE_INLINE
0171 Precision GetEndOuterRadius2() const { return fHype.fEndOuterRadius2; }
0172
0173
0174 VECCORE_ATT_HOST_DEVICE
0175 VECGEOM_FORCE_INLINE
0176 Precision GetInSqSide() const { return fHype.fInSqSide; }
0177
0178
0179
0180
0181
0182
0183
0184
0185 VECCORE_ATT_HOST_DEVICE
0186 VECGEOM_FORCE_INLINE
0187 void SetParameters(const Precision rMin, const Precision rMax, const Precision stIn, const Precision stOut,
0188 const Precision dz)
0189 {
0190 fHype.SetParameters(rMin, rMax, stIn, stOut, dz);
0191 DetectConvexity();
0192 }
0193
0194
0195
0196
0197
0198 VECCORE_ATT_HOST_DEVICE
0199 Precision Volume(bool outer);
0200
0201
0202
0203
0204
0205 VECCORE_ATT_HOST_DEVICE
0206 Precision Area(bool outer);
0207
0208
0209
0210 VECCORE_ATT_HOST_DEVICE
0211 Precision AreaEndCaps();
0212
0213
0214 VECCORE_ATT_HOST_DEVICE
0215 void CalcCapacity();
0216
0217
0218 VECCORE_ATT_HOST_DEVICE
0219 void CalcSurfaceArea();
0220
0221
0222 VECCORE_ATT_HOST_DEVICE
0223 void DetectConvexity();
0224
0225 VECCORE_ATT_HOST_DEVICE
0226 void Extent(Vector3D<Precision> &, Vector3D<Precision> &) const override;
0227
0228 Precision Capacity() const override { return fHype.fCubicVolume; }
0229
0230
0231 Precision SurfaceArea() const override { return fHype.fSurfaceArea; }
0232
0233
0234
0235
0236
0237
0238 template <bool ForInnerSurface>
0239 VECGEOM_FORCE_INLINE
0240 VECCORE_ATT_HOST_DEVICE
0241 Precision GetHypeRadius2(Precision dz) const
0242 {
0243 if (ForInnerSurface)
0244 return GetRmin2() + GetTIn2() * dz * dz;
0245 else
0246 return GetRmax2() + GetTOut2() * dz * dz;
0247 }
0248
0249
0250
0251
0252
0253 VECCORE_ATT_HOST_DEVICE
0254 VECGEOM_FORCE_INLINE
0255 bool PointOnZSurface(Vector3D<Precision> const &p) const
0256 {
0257 return (p.z() > (GetDz() - GetZToleranceLevel())) && (p.z() < (GetDz() + GetZToleranceLevel()));
0258 }
0259
0260
0261
0262
0263
0264 template <bool ForInnerSurface>
0265 VECGEOM_FORCE_INLINE
0266 VECCORE_ATT_HOST_DEVICE
0267 bool PointOnHyperbolicSurface(Vector3D<Precision> const &p) const
0268 {
0269 Precision hypeR2 = 0.;
0270 hypeR2 = GetHypeRadius2<ForInnerSurface>(p.z());
0271 Precision pointRad2 = p.Perp2();
0272 return ((pointRad2 > (hypeR2 - GetOuterRadToleranceLevel())) &&
0273 (pointRad2 < (hypeR2 + GetOuterRadToleranceLevel())));
0274 }
0275
0276 VECCORE_ATT_HOST_DEVICE
0277 bool Normal(Vector3D<Precision> const &p, Vector3D<Precision> &normal) const override
0278 {
0279
0280 bool valid = true;
0281
0282 Precision absZ(std::fabs(p.z()));
0283 Precision distZ(absZ - GetDz());
0284 Precision dist2Z(distZ * distZ);
0285
0286 Precision xR2 = p.Perp2();
0287 Precision dist2Outer(std::fabs(xR2 - GetHypeRadius2<false>(absZ)));
0288 Precision dist2Inner(std::fabs(xR2 - GetHypeRadius2<true>(absZ)));
0289
0290
0291 if (PointOnZSurface(p) || ((dist2Z < dist2Inner) && (dist2Z < dist2Outer)))
0292 normal = Vector3D<Precision>(0.0, 0.0, p.z() < 0 ? -1.0 : 1.0);
0293
0294
0295 if (PointOnHyperbolicSurface<false>(p) || ((dist2Outer < dist2Inner) && (dist2Outer < dist2Z)))
0296 normal = Vector3D<Precision>(p.x(), p.y(), -p.z() * GetTOut2()).Unit();
0297
0298
0299 if (PointOnHyperbolicSurface<true>(p) || ((dist2Inner < dist2Outer) && (dist2Inner < dist2Z)))
0300 normal = Vector3D<Precision>(-p.x(), -p.y(), p.z() * GetTIn2()).Unit();
0301
0302 return valid;
0303 }
0304
0305 Vector3D<Precision> SamplePointOnSurface() const override;
0306
0307
0308
0309 std::string GetEntityType() const;
0310
0311
0312
0313
0314
0315 VECCORE_ATT_HOST_DEVICE
0316 void GetParametersList(int aNumber, Precision *aArray) const;
0317
0318 VECCORE_ATT_HOST_DEVICE
0319 UnplacedHype *Clone() const;
0320
0321 std::ostream &StreamInfo(std::ostream &os) const;
0322
0323
0324
0325 VECCORE_ATT_HOST_DEVICE
0326 bool InnerSurfaceExists() const;
0327
0328 virtual int MemorySize() const override { return sizeof(*this); }
0329
0330 VECCORE_ATT_HOST_DEVICE
0331 virtual void Print() const override;
0332
0333 virtual void Print(std::ostream &os) const override;
0334
0335 #ifndef VECCORE_CUDA
0336 virtual SolidMesh *CreateMesh3D(Transformation3D const &trans, size_t nSegments) const override;
0337 #endif
0338
0339 #ifdef VECGEOM_CUDA_INTERFACE
0340 virtual size_t DeviceSizeOf() const override
0341 {
0342 return DevicePtr<cuda::SUnplacedHype<cuda::HypeTypes::UniversalHype>>::SizeOf();
0343 }
0344 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0345 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0346 #endif
0347
0348 #ifndef VECCORE_CUDA
0349 #ifdef VECGEOM_ROOT
0350 TGeoShape const *ConvertToRoot(char const *label) const;
0351 #endif
0352
0353 #ifdef VECGEOM_GEANT4
0354 G4VSolid const *ConvertToGeant4(char const *label) const;
0355 #endif
0356 #endif
0357 };
0358
0359 template <>
0360 struct Maker<UnplacedHype> {
0361 template <typename... ArgTypes>
0362 static UnplacedHype *MakeInstance(const Precision rMin, const Precision rMax, const Precision stIn,
0363 const Precision stOut, const Precision dz);
0364 };
0365
0366
0367 template <typename HypeType = HypeTypes::UniversalHype>
0368 class SUnplacedHype : public SIMDUnplacedVolumeImplHelper<HypeImplementation<HypeType>, UnplacedHype>,
0369 public AlignedBase {
0370 public:
0371 using BaseType_t = SIMDUnplacedVolumeImplHelper<HypeImplementation<HypeType>, UnplacedHype>;
0372 using BaseType_t::BaseType_t;
0373
0374 template <TranslationCode transCodeT, RotationCode rotCodeT>
0375 VECCORE_ATT_DEVICE
0376 static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0377 #ifdef VECCORE_CUDA
0378 const int id, const int copy_no, const int child_id,
0379 #endif
0380 VPlacedVolume *const placement = NULL);
0381
0382 private:
0383 #ifndef VECCORE_CUDA
0384 virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0385 Transformation3D const *const transformation,
0386 const TranslationCode trans_code, const RotationCode rot_code,
0387 VPlacedVolume *const placement = NULL) const override
0388 {
0389 return VolumeFactory::CreateByTransformation<SUnplacedHype<HypeType>>(volume, transformation, trans_code, rot_code,
0390 placement);
0391 }
0392
0393 #else
0394 VECCORE_ATT_DEVICE
0395 virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0396 Transformation3D const *const transformation,
0397 const TranslationCode trans_code, const RotationCode rot_code, const int id,
0398 const int copy_no, const int child_id,
0399 VPlacedVolume *const placement = NULL) const override
0400 {
0401 return VolumeFactory::CreateByTransformation<SUnplacedHype<HypeType>>(volume, transformation, trans_code, rot_code,
0402 id, copy_no, child_id, placement);
0403 }
0404 #endif
0405 };
0406
0407 using GenericUnplacedHype = SUnplacedHype<HypeTypes::UniversalHype>;
0408
0409 }
0410 }
0411
0412 #include "VecGeom/volumes/SpecializedHype.h"
0413
0414 #endif