Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-24 09:27:58

0001 // This file is part of VecGeom and is distributed under the
0002 // conditions in the file LICENSE.txt in the top directory.
0003 // For the full list of authors see CONTRIBUTORS.txt and `git log`.
0004 
0005 /// \file PlacedVolume.h
0006 /// \author created by Johannes de Fine Licht, Sandro Wenzel (CERN)
0007 
0008 #ifndef VECGEOM_VOLUMES_PLACEDVOLUME_H_
0009 #define VECGEOM_VOLUMES_PLACEDVOLUME_H_
0010 
0011 #include "VecGeom/base/Cuda.h"
0012 #include "VecGeom/base/Assert.h"
0013 #include "VecGeom/base/Global.h"
0014 #include "VecGeom/volumes/LogicalVolume.h"
0015 #include <string>
0016 
0017 #ifdef VECGEOM_GEANT4
0018 #include <G4VSolid.hh>
0019 #endif
0020 
0021 namespace vecgeom {
0022 
0023 VECGEOM_DEVICE_FORWARD_DECLARE(class VPlacedVolume;);
0024 VECGEOM_DEVICE_DECLARE_CONV(class, VPlacedVolume);
0025 #ifndef VECCORE_CUDA
0026 template <>
0027 struct kCudaType<const cxx::VPlacedVolume *> {
0028   using type_t = const cuda::VPlacedVolume *;
0029 };
0030 #endif
0031 class GeoManager;
0032 
0033 inline namespace VECGEOM_IMPL_NAMESPACE {
0034 
0035 class PlacedBox;
0036 
0037 /*!
0038  * \brief A placed volume is a positioned logical volume.
0039  *
0040  * Special features of VecGeom are that:
0041  *
0042  *   1. Placed volumes offer
0043  *      similar geometry interfaces (distance, etc) as unplaced volumes for user convenience.
0044  *   2. We can have sub-types of placed volumes, specialized according
0045  *      to underlying unplaced volume type as well as per categories
0046  *      of placing transformations.
0047  *
0048  * Given a logical volume and a transformation, factory methods
0049  * will generate the most suitable sub-type of a placed volume so that
0050  * geometry APIs, such as VPlacedVolume::DistanceToIn(position, direction)
0051  * are optimized as much as possible. Some CMake flags allow to select how
0052  * far this is done or not.
0053  */
0054 class VPlacedVolume {
0055   friend class vecgeom::GeoManager;
0056 
0057 private:
0058   unsigned int id_;  ///< Integer id
0059   int copy_no_ = 0;  ///< Copy number for the physical volume, used by transport
0060   int ichild_  = -1; ///< Index in the mother volume list;
0061 
0062   // Use a pointer so the string won't be constructed on the GPU
0063   std::string *label_;            ///< Label/name of placed volume
0064   static unsigned int g_id_count; ///< Static instance counter
0065 
0066 protected:
0067   LogicalVolume const *logical_volume_; ///< Pointer to positioned logical volume
0068 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0069   Transformation3D fTransformation; ///< The positioning transformation
0070 #else
0071   Transformation3D const *fTransformation; ///< The positioning transformation
0072 #endif
0073 
0074 #ifndef VECCORE_CUDA
0075 
0076   /** Constructor
0077    * \param label Name of logical volume.
0078    * \param logical_vol The logical volume to be positioned.
0079    * \param transform The positioning transformation.
0080    */
0081   VPlacedVolume(char const *const label, LogicalVolume const *const logical_vol,
0082                 Transformation3D const *const transform);
0083 
0084   /** Constructor
0085    * \param logical_vol The logical volume to be positioned.
0086    * \param transform The positioning transformation.
0087    */
0088   VPlacedVolume(LogicalVolume const *const logical_vol, Transformation3D const *const transform)
0089       : VPlacedVolume("", logical_vol, transform)
0090   {
0091   }
0092 
0093 #else
0094   /// CUDA version of constructor
0095   VECCORE_ATT_DEVICE VPlacedVolume(LogicalVolume const *const logical_vol, Transformation3D const *const transformation,
0096                                    unsigned int id, int copy_no, int ichild)
0097 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0098       : logical_volume_(logical_vol), fTransformation(*transformation), id_(id), copy_no_(copy_no), ichild_(ichild),
0099         label_(NULL)
0100   {
0101   }
0102 #else
0103       : logical_volume_(logical_vol), fTransformation(transformation), id_(id), copy_no_(copy_no), ichild_(ichild),
0104         label_(NULL)
0105   {
0106   }
0107 #endif
0108 #endif
0109 
0110   VECGEOM_FORCE_INLINE
0111   void SetChildId(int index) { ichild_ = index; }
0112 
0113 public:
0114   VECCORE_ATT_HOST_DEVICE
0115   VPlacedVolume(VPlacedVolume const &);
0116   VECCORE_ATT_HOST_DEVICE
0117   VPlacedVolume *operator=(VPlacedVolume const &);
0118 
0119   VECCORE_ATT_HOST_DEVICE
0120   virtual ~VPlacedVolume();
0121 
0122   /// Returns integer index associated to this volume.
0123   VECCORE_ATT_HOST_DEVICE
0124   VECGEOM_FORCE_INLINE
0125   unsigned int id() const { return id_; }
0126 
0127   /// Returns id of this placed volume in the mother volume list of daughters.
0128   VECCORE_ATT_HOST_DEVICE
0129   VECGEOM_FORCE_INLINE
0130   int GetChildId() const { return ichild_; }
0131 
0132   /// LogicalVolume::PlaceDaughters is a friend that can set the child index
0133   friend void LogicalVolume::PlaceDaughter(VPlacedVolume *const placed);
0134 
0135   /// Returns copy number.
0136   VECCORE_ATT_HOST_DEVICE
0137   VECGEOM_FORCE_INLINE
0138   int GetCopyNo() const { return copy_no_; }
0139 
0140   /// Returns value of static instance counter
0141   static unsigned int GetIdCount() { return g_id_count; }
0142 
0143   /// Returns name/label.
0144   std::string const &GetLabel() const { return *label_; }
0145 
0146   /// Returns underlying logical volume.
0147   VECCORE_ATT_HOST_DEVICE
0148   VECGEOM_FORCE_INLINE
0149   LogicalVolume const *GetLogicalVolume() const { return logical_volume_; }
0150 
0151   /// Returns daughter container of logical volume.
0152   VECCORE_ATT_HOST_DEVICE
0153   VECGEOM_FORCE_INLINE
0154   Vector<Daughter> const &GetDaughters() const { return logical_volume_->GetDaughters(); }
0155 
0156   /// Finds the index of a given daughter having its pointer (linear complexity)
0157   VECCORE_ATT_HOST_DEVICE
0158   VECGEOM_FORCE_INLINE
0159   int IndexOf(Daughter daughter) const
0160   {
0161     int id = 0;
0162     for (auto d : logical_volume_->GetDaughters()) {
0163       if (d == daughter) return id;
0164       id++;
0165     }
0166     return -1;
0167   }
0168 
0169   /// Returns name/label.
0170   VECCORE_ATT_HOST
0171   VECGEOM_FORCE_INLINE
0172   const char *GetName() const { return (*label_).c_str(); }
0173 
0174   /// Returns unplaced volume encapsulated in the logical volume.
0175   VECCORE_ATT_HOST_DEVICE
0176   VECGEOM_FORCE_INLINE
0177   VUnplacedVolume const *GetUnplacedVolume() const { return logical_volume_->GetUnplacedVolume(); }
0178 
0179   /// Returns if underlying unplaced volume is an assembly.
0180   VECCORE_ATT_HOST_DEVICE
0181   bool IsAssembly() const { return GetUnplacedVolume()->IsAssembly(); }
0182 
0183   /// Returns underlying transformation.
0184   VECCORE_ATT_HOST_DEVICE
0185   VECGEOM_FORCE_INLINE
0186   Transformation3D const *GetTransformation() const
0187   {
0188 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0189     return &fTransformation;
0190 #else
0191     return fTransformation;
0192 #endif
0193   }
0194 #ifndef VECCORE_CUDA
0195   SolidMesh *CreateMesh3D(size_t nFaces) const
0196   {
0197     return GetUnplacedVolume()->CreateMesh3D(*this->GetTransformation(), nFaces);
0198   }
0199 #endif
0200   /// Sets logical volume.
0201   VECCORE_ATT_HOST_DEVICE
0202   void SetLogicalVolume(LogicalVolume const *const logical_vol) { logical_volume_ = logical_vol; }
0203 
0204   /// Sets transformation.
0205   VECCORE_ATT_HOST_DEVICE
0206   void SetTransformation(Transformation3D const *const transform)
0207   {
0208 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0209     fTransformation = *transform;
0210 #else
0211     fTransformation = transform;
0212 #endif
0213   }
0214 
0215   /// Sets name/label.
0216   void set_label(char const *label)
0217   {
0218     if (label_) delete label_;
0219     label_ = new std::string(label);
0220   }
0221 
0222   /// Sets copy number.
0223   VECCORE_ATT_HOST_DEVICE
0224   VECGEOM_FORCE_INLINE
0225   void SetCopyNo(int copy_no) { copy_no_ = copy_no; }
0226 
0227   friend std::ostream &operator<<(std::ostream &os, VPlacedVolume const &vol);
0228 
0229   /// Returns in-memory size in bytes of deriving objects (used to copy to GPU).
0230   virtual int MemorySize() const = 0;
0231 
0232   /// Print info about placed volume.
0233   VECCORE_ATT_HOST_DEVICE
0234   virtual void Print(const int indent = 0) const;
0235 
0236   /// Print info about placed volume.
0237   VECCORE_ATT_HOST_DEVICE
0238   virtual void PrintType() const = 0;
0239 
0240   // some functions allowing for some very basic "introspection"
0241 
0242   /// Print the actual volume type to an outstream
0243   virtual void PrintType(std::ostream &os) const = 0;
0244 
0245   /// Recursively prints contained volumes to standard output.
0246   VECCORE_ATT_HOST_DEVICE
0247   void PrintContent(const int depth = 0) const;
0248 
0249   // Geometry functionality like in unplaced volume but taking the placement
0250   // into account.
0251 
0252   /*!
0253    * Returns whether a space point is contained or not in the placed volume.
0254    * This is similar to the functionality in VUnplacedVolume but taking into account
0255    * the positioning of the shape due to the placement.
0256    */
0257   VECCORE_ATT_HOST_DEVICE
0258   virtual bool Contains(Vector3D<Precision> const &point) const = 0;
0259 
0260   /*!
0261    * Returns whether a space point is contained or not in the placed volume.
0262    * Also returns the transformed position.
0263    *
0264    * \param point A given space point.
0265    * \param localPoint The point in the natural reference frame of the shape.
0266    *
0267    * This is similar to the functionality in VUnplacedVolume but taking into account
0268    * the positioning of the shape due to the placement.
0269    */
0270   VECCORE_ATT_HOST_DEVICE
0271   virtual bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &localPoint) const = 0;
0272 
0273   /// Direct dispatch to Contains of underlying unplaced volume without coordinate/placement transformation.
0274   VECCORE_ATT_HOST_DEVICE
0275   virtual bool UnplacedContains(Vector3D<Precision> const &localPoint) const = 0;
0276 
0277   /**
0278    * Like similar function in VUnplacedVolume but taking into account
0279    * the positioning of the shape due to the placement.
0280    */
0281   VECCORE_ATT_HOST_DEVICE
0282   virtual EnumInside Inside(Vector3D<Precision> const &point) const = 0;
0283 
0284   /**
0285    * Like similar function in VUnplacedVolume but taking into account
0286    * the positioning of the shape due to the placement.
0287    */
0288   VECCORE_ATT_HOST_DEVICE
0289   virtual Precision DistanceToIn(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0290                                  const Precision step_max = kInfLength) const = 0;
0291 
0292   /**
0293    * Like similar function in VUnplacedVolume. Here position and direction are supposed to be
0294    * in the frame of the placed volume!
0295    */
0296   VECCORE_ATT_HOST_DEVICE
0297   virtual Precision DistanceToOut(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0298                                   Precision const step_max = kInfLength) const = 0;
0299 
0300   /** A "placed" version of the DistanceToOut function; here
0301    * the point and direction are first of all transformed into the reference frame of the
0302    * shape. So given a position and direction in the reference frame in which the placed volume
0303    * is positioned, we transform everything into the coordinate system of the placed volume and
0304    * calculate DistanceToOut from there.
0305    */
0306   VECCORE_ATT_HOST_DEVICE
0307   virtual Precision PlacedDistanceToOut(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0308                                         Precision const step_max = kInfLength) const = 0;
0309 
0310   /**
0311    * Like similar function in VUnplacedVolume but taking into account
0312    * the positioning of the shape due to the placement.
0313    */
0314   VECCORE_ATT_HOST_DEVICE
0315   virtual Precision SafetyToIn(Vector3D<Precision> const &position) const = 0;
0316 
0317   /**
0318    * Like similar function in VUnplacedVolume. Here position is supposed to be
0319    * in the frame of the placed volume.
0320    */
0321   VECCORE_ATT_HOST_DEVICE
0322   virtual Precision SafetyToOut(Vector3D<Precision> const &position) const = 0;
0323 
0324   /// Simple forward to capacity on VUnplacedVolume
0325   virtual Precision Capacity();
0326 
0327   /// Get Extent of VUnplacedVolume, then apply transformation and recalculate
0328   VECCORE_ATT_HOST_DEVICE
0329   virtual void Extent(Vector3D<Precision> & /* min */, Vector3D<Precision> & /* max */) const;
0330 
0331   /// Get Normal of VUnplacedVolume, then apply transformation
0332   VECCORE_ATT_HOST_DEVICE
0333   virtual bool Normal(Vector3D<Precision> const & /*point*/, Vector3D<Precision> & /*normal*/) const;
0334 
0335   /// Like SurfaceArea on VUnplacedVolume
0336   virtual Precision SurfaceArea() const = 0;
0337 
0338 public:
0339 #ifdef VECGEOM_CUDA_INTERFACE
0340   virtual size_t DeviceSizeOf() const                                                                       = 0;
0341   virtual DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0342                                                    DevicePtr<cuda::Transformation3D> const transform,
0343                                                    DevicePtr<cuda::VPlacedVolume> const gpu_ptr) const      = 0;
0344   virtual DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0345                                                    DevicePtr<cuda::Transformation3D> const transform) const = 0;
0346   /**
0347    * Copy many instances of this class to the GPU.
0348    * \param host_volumes Host volumes to be copied. These should all be of the same type as the class that this function is called with.
0349    * \param logical_volumes GPU addresses of the logical volumes corresponding to the placed volumes.
0350    * \param transforms GPU addresses of the transformations corresponding to the placed volumes.
0351    * \param in_gpu_ptrs GPU addresses where the GPU instances of the host volumes should be placed.
0352    * \note This requires an explicit template instantiation of ConstructManyOnGpu<ThisClass_t>().
0353    * \see VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL
0354    */
0355   virtual void CopyManyToGpu(std::vector<VPlacedVolume const *> const &host_volumes,
0356                              std::vector<DevicePtr<cuda::LogicalVolume>> const &logical_volumes,
0357                              std::vector<DevicePtr<cuda::Transformation3D>> const &transforms,
0358                              std::vector<DevicePtr<cuda::VPlacedVolume>> const &in_gpu_ptrs) const = 0;
0359 
0360   template <typename Derived>
0361   DevicePtr<cuda::VPlacedVolume> CopyToGpuImpl(DevicePtr<cuda::LogicalVolume> const logical_volume,
0362                                                DevicePtr<cuda::Transformation3D> const transform,
0363                                                DevicePtr<cuda::VPlacedVolume> const in_gpu_ptr) const
0364   {
0365     DevicePtr<CudaType_t<Derived>> gpu_ptr(in_gpu_ptr);
0366     gpu_ptr.Construct(logical_volume, transform, nullptr, this->id(), this->GetCopyNo(), this->GetChildId());
0367     VECGEOM_DEVICE_API_CALL(GetLastError());
0368     // Need to go via the void* because the regular c++ compilation
0369     // does not actually see the declaration for the cuda version
0370     // (and thus can not determine the inheritance).
0371     return DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr);
0372   }
0373   template <typename Derived>
0374   DevicePtr<cuda::VPlacedVolume> CopyToGpuImpl(DevicePtr<cuda::LogicalVolume> const logical_volume,
0375                                                DevicePtr<cuda::Transformation3D> const transform) const
0376   {
0377     DevicePtr<CudaType_t<Derived>> gpu_ptr;
0378     gpu_ptr.Allocate();
0379     return this->CopyToGpuImpl<Derived>(logical_volume, transform, DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr));
0380   }
0381 
0382 #endif
0383 
0384 #ifndef VECCORE_CUDA
0385   /// A conversion function creating a generic unspecialized instance of the placed volume
0386   virtual VPlacedVolume const *ConvertToUnspecialized() const = 0;
0387 #ifdef VECGEOM_ROOT
0388   /// A conversion function to a TGeoShape (when TGeo support is available)
0389   virtual TGeoShape const *ConvertToRoot() const = 0;
0390 #endif
0391 #ifdef VECGEOM_GEANT4
0392   /// A conversion function to a Geant4 G4VSolid (when G4 support is available)
0393   virtual G4VSolid const *ConvertToGeant4() const
0394   {
0395     throw std::runtime_error("ConvertToGeant4() not implemented for this shape type.");
0396   }
0397 #endif
0398 #endif // VECCORE_CUDA
0399 };
0400 } // namespace VECGEOM_IMPL_NAMESPACE
0401 } // namespace vecgeom
0402 
0403 #ifdef VECCORE_CUDA
0404 
0405 /**
0406  * Trigger template instantiations of DevicePtr<Type>::SizeOf() and DevicePtr<Type>::Construct.
0407  */
0408 #define VECGEOM_DEVICE_INST_PLACED_VOLUME(PlacedVol)                                                       \
0409   namespace cxx {                                                                                          \
0410   template size_t DevicePtr<cuda::PlacedVol>::SizeOf();                                                    \
0411   template void DevicePtr<cuda::PlacedVol>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0412                                                       DevicePtr<cuda::Transformation3D> const transform,   \
0413                                                       const unsigned int id, const int copy_no,            \
0414                                                       const int child_id) const;                           \
0415   template void ConstructManyOnGpu<cuda::PlacedVol>(                                                       \
0416       std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs,                                \
0417       DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo,       \
0418       decltype(std::declval<VPlacedVolume>().id()) const *ids,                                             \
0419       decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos,                                  \
0420       decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds);                               \
0421   }
0422 
0423 /**
0424  * Trigger template instantiations of DevicePtr<Type>::SizeOf() and DevicePtr<Type>::Construct.
0425  */
0426 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol, Extra)                                                  \
0427   namespace cxx {                                                                                                 \
0428   template size_t DevicePtr<cuda::PlacedVol, Extra>::SizeOf();                                                    \
0429   template void DevicePtr<cuda::PlacedVol, Extra>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0430                                                              DevicePtr<cuda::Transformation3D> const transform,   \
0431                                                              const unsigned int id, const int copy_no,            \
0432                                                              const int child_id) const;                           \
0433   template void ConstructManyOnGpu<cuda::PlacedVol, Extra>(                                                       \
0434       std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs,                                       \
0435       DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo,              \
0436       decltype(std::declval<VPlacedVolume>().id()) const *ids,                                                    \
0437       decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos,                                         \
0438       decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds);                                      \
0439   }
0440 
0441 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC(PlacedVol) VECGEOM_DEVICE_INST_PLACED_VOLUME(PlacedVol)
0442 
0443 #if defined(VECGEOM_NO_SPECIALIZATION) || !defined(VECGEOM_CUDA_VOLUME_SPECIALIZATION)
0444 
0445 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, radii) \
0446   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kGeneric>)
0447 
0448 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALLSPEC(PlacedVol) \
0449   VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kGeneric)
0450 
0451 #else // VECGEOM_NO_SPECIALIZATION
0452 
0453 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, radii)                   \
0454   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kGeneric>) \
0455   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kFalse>)   \
0456   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kTrue>)    \
0457   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kLarge>)
0458 
0459 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALLSPEC(PlacedVol)                                 \
0460   VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kGeneric) \
0461   VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kFalse)   \
0462   VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kTrue)
0463 
0464 #endif // VECGEOM_NO_SPECIALIZATION
0465 
0466 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_3(PlacedVol, Type)                                                      \
0467   namespace cxx {                                                                                                      \
0468   template size_t DevicePtr<cuda::PlacedVol<cuda::Type>>::SizeOf();                                                    \
0469   template void DevicePtr<cuda::PlacedVol<cuda::Type>>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0470                                                                   DevicePtr<cuda::Transformation3D> const transform,   \
0471                                                                   const unsigned int id, const int copy_no,            \
0472                                                                   const int child_id) const;                           \
0473   template void ConstructManyOnGpu<cuda::PlacedVol<cuda::Type>>(                                                       \
0474       std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs,                                            \
0475       DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo,                   \
0476       decltype(std::declval<VPlacedVolume>().id()) const *ids,                                                         \
0477       decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos,                                              \
0478       decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds);                                           \
0479   }
0480 
0481 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_3(PlacedVol, Type) \
0482   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_3(PlacedVol, Type)
0483 
0484 // This serves only the polyhedron specializations
0485 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, radii, phi)                                                \
0486   namespace cxx {                                                                                                      \
0487   template size_t DevicePtr<cuda::PlacedVol<radii, phi>>::SizeOf();                                                    \
0488   template void DevicePtr<cuda::PlacedVol<radii, phi>>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0489                                                                   DevicePtr<cuda::Transformation3D> const transform,   \
0490                                                                   const unsigned int id, const int copy_no,            \
0491                                                                   const int child_id) const;                           \
0492   template void ConstructManyOnGpu<cuda::PlacedVol<radii, phi>>(                                                       \
0493       std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs,                                            \
0494       DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo,                   \
0495       decltype(std::declval<VPlacedVolume>().id()) const *ids,                                                         \
0496       decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos,                                              \
0497       decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds);                                           \
0498   }
0499 
0500 #if defined(VECGEOM_NO_SPECIALIZATION) || !defined(VECGEOM_CUDA_VOLUME_SPECIALIZATION)
0501 
0502 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_4(PlacedVol)                           \
0503   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kGeneric, \
0504                                            Polyhedron::EPhiCutout::kGeneric)
0505 
0506 #else
0507 
0508 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, phi)                         \
0509   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kFalse, phi)   \
0510   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kGeneric, phi) \
0511   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kTrue, phi)
0512 
0513 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_4(PlacedVol)                               \
0514   VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kFalse)   \
0515   VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kGeneric) \
0516   VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kTrue)    \
0517   VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kLarge)
0518 
0519 #endif
0520 
0521 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_BOOLEAN(PlacedVol)                                          \
0522   namespace cxx {                                                                                          \
0523   template size_t DevicePtr<cuda::PlacedVol>::SizeOf();                                                    \
0524   template void DevicePtr<cuda::PlacedVol>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0525                                                       DevicePtr<cuda::Transformation3D> const transform,   \
0526                                                       const unsigned int id, const int copy_no,            \
0527                                                       const int child_id) const;                           \
0528   template void ConstructManyOnGpu<cuda::PlacedVol>(                                                       \
0529       std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs,                                \
0530       DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo,       \
0531       decltype(std::declval<VPlacedVolume>().id()) const *ids,                                             \
0532       decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos,                                  \
0533       decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds);                               \
0534   }
0535 
0536 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_BOOLEAN(PlacedVol, Op) \
0537   VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_BOOLEAN(PlacedVol<Op>)
0538 
0539 #endif
0540 
0541 #endif // VECGEOM_VOLUMES_PLACEDVOLUME_H_