Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-30 09:16:12

0001 /// @file UnplacedScaledShape.h
0002 /// @author Mihaela Gheata (mihaela.gheata@cern.ch)
0003 
0004 #ifndef VECGEOM_VOLUMES_UNPLACEDSCALEDSHAPE_H_
0005 #define VECGEOM_VOLUMES_UNPLACEDSCALEDSHAPE_H_
0006 
0007 #include "VecGeom/base/Cuda.h"
0008 #include "VecGeom/base/Global.h"
0009 #include "VecGeom/base/AlignedBase.h"
0010 #include "VecGeom/base/Vector3D.h"
0011 #include "VecGeom/base/Scale3D.h"
0012 #include "ScaledShapeStruct.h"
0013 #include "VecGeom/volumes/UnplacedVolume.h"
0014 #include "VecGeom/volumes/PlacedVolume.h"
0015 #include "VecGeom/volumes/LogicalVolume.h"
0016 #include "VecGeom/volumes/kernel/ScaledShapeImplementation.h"
0017 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0018 
0019 namespace vecgeom {
0020 
0021 VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedScaledShape;);
0022 VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedScaledShape);
0023 
0024 inline namespace VECGEOM_IMPL_NAMESPACE {
0025 
0026 #ifdef GOT_AROUND_TO_SPECIALIZE_SCALED_SHAPE
0027 template <typename Specialized_t>
0028 class SUnplacedScaledShape {};
0029 
0030 return ScaledShape::MakeInstance<BaseShape_t>(scale, Argtypes... args);
0031 
0032 template <typename Shape_t>
0033 Scale(Shape_t vol, ... Scale)
0034 {
0035   return SUnplacedScaleShabe<Shape_t>(scale, vol);
0036 }
0037 
0038 UnplacedScaledScale(UnplacedTube, scale) { if (dynamic_cast<...>()) }
0039 
0040 template <typename BaseShape_t, Argtypes... Args>
0041 static UnplacedScaledShape *MakeScaledInstance(Scale3D scale, Argtypes... args)
0042 {
0043   auto svol = BaseShape_t::MakeInstance(args...);
0044   return Scale(svol, scale);
0045 }
0046 #endif
0047 
0048 /**
0049  * The unplaced scaled shape class.
0050  */
0051 class UnplacedScaledShape : public UnplacedVolumeImplHelper<ScaledShapeImplementation>, public AlignedBase {
0052 
0053 public:
0054   ScaledShapeStruct<Precision> fScaled; /* The scaled shape structure */
0055 
0056 public:
0057   /// Dummy ctor
0058   VECCORE_ATT_HOST_DEVICE
0059   UnplacedScaledShape() : fScaled()
0060   {
0061     fGlobalConvexity = fScaled.fPlaced->GetUnplacedVolume()->IsConvex();
0062     ComputeBBox();
0063   }
0064 
0065   /// Constructor based on placed volume
0066   VECCORE_ATT_HOST_DEVICE
0067   UnplacedScaledShape(VPlacedVolume const *placed, Precision sx, Precision sy, Precision sz)
0068       : fScaled(placed, sx, sy, sz)
0069   {
0070     fGlobalConvexity = fScaled.fPlaced->GetUnplacedVolume()->IsConvex();
0071     ComputeBBox();
0072   }
0073 
0074 #if defined(VECCORE_CUDA)
0075   /// Constructor based on placed volume
0076   VECCORE_ATT_HOST_DEVICE
0077   UnplacedScaledShape(VPlacedVolume const *placed, Precision sx, Precision sy, Precision sz, bool globalConvexity)
0078       : fScaled(placed, sx, sy, sz)
0079   {
0080     /* VECGEOM_ASSERT(placed->GetTransformation()->IsIdentity());*/
0081     fGlobalConvexity = globalConvexity;
0082     /* We must have
0083          VECGEOM_ASSERT(globalConvexity == fPlaced->GetUnplacedVolume()->IsConvex())
0084        However due to the order we create the geometry on the GPU (i.e. all Unplaced *then* all
0085        Placed volume, we can not use this information (i.e. 'placed' points to uninitialized memory
0086        at time this constructor is callled.
0087     */
0088   }
0089 #endif
0090 
0091 /// Constructor based on unplaced volume
0092 #if !defined(VECCORE_CUDA)
0093   UnplacedScaledShape(VUnplacedVolume const *shape, Precision sx, Precision sy, Precision sz)
0094       : fScaled(nullptr, sx, sy, sz)
0095   {
0096     // We need to create a placement with identity transformation from the unplaced version
0097     // Hopefully we don't need to create a logical volume
0098     LogicalVolume *lvol = new LogicalVolume("", shape);
0099     fScaled.fPlaced     = lvol->Place();
0100     fGlobalConvexity    = fScaled.fPlaced->GetUnplacedVolume()->IsConvex();
0101     ComputeBBox();
0102   }
0103 #endif
0104 
0105   /// Copy constructor
0106   //  VECCORE_ATT_HOST_DEVICE
0107   UnplacedScaledShape(UnplacedScaledShape const &other) : fScaled()
0108   {
0109     fScaled.fPlaced  = other.fScaled.fPlaced->GetLogicalVolume()->Place();
0110     fScaled.fScale   = other.fScaled.fScale;
0111     fGlobalConvexity = other.fGlobalConvexity;
0112     ComputeBBox();
0113   }
0114 
0115   /// Assignment operator
0116   //  VECCORE_ATT_HOST_DEVICE
0117   UnplacedScaledShape &operator=(UnplacedScaledShape const &other)
0118   {
0119     if (&other != this) {
0120       fScaled.fPlaced  = other.fScaled.fPlaced->GetLogicalVolume()->Place();
0121       fScaled.fScale   = other.fScaled.fScale;
0122       fGlobalConvexity = other.fGlobalConvexity;
0123     }
0124     return *this;
0125   }
0126 
0127   /// Destructor
0128   VECCORE_ATT_HOST_DEVICE
0129   virtual ~UnplacedScaledShape()
0130   {
0131     // The fPlaced was owned by the class, but now it gets deleted before
0132     // the destructor by GeoManager. The class will be restructured to use
0133     // the VUnplaceVolume new navigation interfaces after migration of all
0134     // shapes to VecCore, so this data member will dissapear.
0135 
0136     // delete fScaled.fPlaced;
0137   }
0138 
0139   VECCORE_ATT_HOST_DEVICE
0140   VECGEOM_FORCE_INLINE
0141   virtual ESolidType GetType() const override { return ESolidType::scaled; }
0142 
0143   /// Getter for the generic scaled shape structure
0144   VECCORE_ATT_HOST_DEVICE
0145   ScaledShapeStruct<Precision> const &GetStruct() const { return fScaled; }
0146 
0147   virtual int MemorySize() const final { return (sizeof(*this) + fScaled.fPlaced->MemorySize()); }
0148 
0149 #ifdef VECGEOM_CUDA_INTERFACE
0150   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedScaledShape>::SizeOf(); }
0151   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0152   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0153 #endif
0154 
0155   VECGEOM_FORCE_INLINE
0156   const VUnplacedVolume *UnscaledShape() const { return fScaled.fPlaced->GetLogicalVolume()->GetUnplacedVolume(); }
0157 
0158   VECGEOM_FORCE_INLINE
0159   VPlacedVolume const *GetPlaced() const { return fScaled.fPlaced; }
0160 
0161   VECGEOM_FORCE_INLINE
0162   Scale3D const &GetScale() const { return fScaled.fScale; }
0163 
0164   Precision Volume() const
0165   {
0166     Precision capacity             = ((VPlacedVolume *)fScaled.fPlaced)->Capacity();
0167     const Vector3D<Precision> &scl = fScaled.fScale.Scale();
0168     capacity *= scl[0] * scl[1] * scl[2];
0169     return capacity;
0170   }
0171 
0172   Precision Capacity() const override { return Volume(); }
0173 
0174   // VECGEOM_FORCE_INLINE
0175   Precision SurfaceArea() const override
0176   {
0177     /// Not so easy as for the capacity...
0178     Precision area = VUnplacedVolume::EstimateSurfaceArea(1000000);
0179     return area;
0180   }
0181 
0182   VECCORE_ATT_HOST_DEVICE
0183   bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0184 
0185   VECCORE_ATT_HOST_DEVICE
0186   void Extent(Vector3D<Precision> &min, Vector3D<Precision> &max) const override;
0187 
0188   Vector3D<Precision> SamplePointOnSurface() const override;
0189 
0190   virtual std::string GetEntityType() const { return "ScaledShape"; }
0191 
0192   VECCORE_ATT_HOST_DEVICE
0193   virtual void Print() const final;
0194 
0195   virtual void Print(std::ostream &os) const final;
0196 
0197   VECCORE_ATT_DEVICE
0198   static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0199 #ifdef VECCORE_CUDA
0200                                const int id, const int copy_no, const int child_id,
0201 #endif // !VECCORE_CUDA
0202                                VPlacedVolume *const placement = NULL);
0203 
0204   VECCORE_ATT_DEVICE
0205   static VPlacedVolume *CreateSpecializedVolume(LogicalVolume const *const volume,
0206                                                 Transformation3D const *const transformation,
0207 #ifdef VECCORE_CUDA
0208                                                 const int id, const int copy_no, const int child_id,
0209 #endif // !VECCORE_CUDA
0210                                                 VPlacedVolume *const placement = NULL);
0211 
0212 private:
0213   VECCORE_ATT_DEVICE
0214   virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0215                                            Transformation3D const *const transformation,
0216 #ifdef VECCORE_CUDA
0217                                            const int id, const int copy_no, const int child_id,
0218 #endif
0219                                            VPlacedVolume *const placement = NULL) const final
0220   {
0221     return CreateSpecializedVolume(volume, transformation,
0222 #ifdef VECCORE_CUDA
0223                                    id, copy_no, child_id,
0224 #endif
0225                                    placement);
0226   }
0227   void SetPlaced(VPlacedVolume const *pvol) { fScaled.fPlaced = pvol; }
0228   void SetScale(Scale3D const &scale) { fScaled.fScale = scale; }
0229 
0230   friend class vecgeom::GeoManager;
0231 };
0232 } // namespace VECGEOM_IMPL_NAMESPACE
0233 } // namespace vecgeom
0234 
0235 #endif // VECGEOM_VOLUMES_UNPLACESCALEDSHAPE_H_