Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-01 08:42:00

0001 // LICENSING INFORMATION TBD
0002 
0003 #ifndef VECGEOM_UNPLACEDASSEMBLY_H
0004 #define VECGEOM_UNPLACEDASSEMBLY_H
0005 
0006 #include "VecGeom/base/Cuda.h"
0007 #include "VecGeom/base/Global.h"
0008 #include "VecGeom/base/Vector.h"
0009 #include "VecGeom/navigation/VNavigator.h"
0010 #include "VecGeom/navigation/NavigationState.h"
0011 #include "VecGeom/base/Vector3D.h"
0012 #include "VecGeom/volumes/UnplacedVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0015 #include "VecGeom/navigation/NavStateFwd.h"
0016 
0017 namespace vecgeom {
0018 
0019 VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedAssembly;);
0020 VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedAssembly);
0021 
0022 inline namespace VECGEOM_IMPL_NAMESPACE {
0023 
0024 // An assembly volume offering navigation interfaces (Contains/Distances/...) in a loose/logical group of volumes
0025 // An UnplacedAssembly is always strongly coupled to a logical volume because the later naturally manages the actual
0026 // group of volumes that define the assembly
0027 
0028 // The following construct marks a logical volume as an assembly:
0029 
0030 // UnplacedAssembly *ass = new UnplacedAssembly
0031 // LogicalVolume *lv = new LogicalVolume("assembly", ass); // this will implicitely couple ass to lv
0032 // lv->PlacedDaughter(...)
0033 
0034 class UnplacedAssembly : public VUnplacedVolume, public AlignedBase {
0035 
0036 private:
0037   // back-reference to the logical volume
0038   // this get automacially set upon instantiation of a logical volume with an UnplacedAssembly
0039   LogicalVolume *fLogicalVolume;
0040 
0041   // caching the extent (bounding box)
0042   // these members are automatically updated whenever a new volume is added to the assembly
0043   Vector3D<Precision> fLowerCorner;
0044   Vector3D<Precision> fUpperCorner;
0045 
0046   void SetLogicalVolume(LogicalVolume *lv) { fLogicalVolume = lv; }
0047   void UpdateExtent()
0048   {
0049     UnplacedAssembly::Extent(fLowerCorner, fUpperCorner);
0050     ComputeBBox();
0051   }
0052   friend class LogicalVolume;
0053 
0054 public:
0055   VECCORE_ATT_HOST_DEVICE
0056   UnplacedAssembly(); // the constructor
0057 
0058   VECCORE_ATT_HOST_DEVICE
0059   virtual ~UnplacedAssembly();
0060 
0061   LogicalVolume const *GetLogicalVolume() const { return fLogicalVolume; }
0062 
0063   // add content
0064   void AddVolume(VPlacedVolume *const);
0065 
0066   // get number of volumes
0067   size_t GetNVolumes() const { return fLogicalVolume->GetDaughters().size(); }
0068 
0069   // the extent function
0070   VECCORE_ATT_HOST_DEVICE
0071   void Extent(Vector3D<Precision> &, Vector3D<Precision> &) const override;
0072 
0073   // Getter to cached bounding box
0074   VECCORE_ATT_HOST_DEVICE
0075   Vector3D<Precision> GetLowerCorner() const { return fLowerCorner; }
0076 
0077   VECCORE_ATT_HOST_DEVICE
0078   Vector3D<Precision> GetUpperCorner() const { return fUpperCorner; }
0079 
0080   // the ordinary assembly function
0081   VECCORE_ATT_HOST_DEVICE
0082   bool Contains(Vector3D<Precision> const &point) const override
0083   {
0084     VECGEOM_ASSERT(fLogicalVolume);
0085     // check bound box first
0086     bool inBoundingBox;
0087     ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
0088     if (!inBoundingBox) return false;
0089 
0090     Vector3D<Precision> daughterlocalpoint;
0091     VPlacedVolume const *nextv;
0092     return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, nextv, daughterlocalpoint);
0093   }
0094 
0095   VECCORE_ATT_HOST_DEVICE
0096   EnumInside Inside(Vector3D<Precision> const & /*point*/) const override
0097   {
0098 #ifndef VECCORE_CUDA
0099     throw std::runtime_error("Assembly inside to be implemented");
0100 #endif
0101     return static_cast<EnumInside>(EInside::kOutside);
0102   }
0103 
0104   // an extended contains function needed for navigation
0105   // if this function returns true it modifies the navigation state to point to the first non-assembly volume
0106   // the point is contained in
0107   // this function is not part of the generic UnplacedVolume interface but we could consider doing so
0108   VECCORE_ATT_HOST_DEVICE
0109   bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &daughterlocalpoint, NavigationState &state) const
0110   {
0111     VECGEOM_ASSERT(fLogicalVolume);
0112     // check bound box first
0113     bool inBoundingBox;
0114     ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
0115     if (!inBoundingBox) return false;
0116 
0117     return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, state, daughterlocalpoint);
0118   }
0119 
0120   using VUnplacedVolume::DistanceToOut;
0121   // DistanceToOut does not make sense -- throw exeption
0122   VECCORE_ATT_HOST_DEVICE
0123   Precision DistanceToOut(Vector3D<Precision> const & /*p*/, Vector3D<Precision> const & /*d*/,
0124                           Precision /*step_max*/ = kInfLength) const override
0125   {
0126 #ifndef VECCORE_CUDA
0127     throw std::runtime_error("Forbidden DistanceToOut in Assembly called");
0128 #endif
0129     return -1.;
0130   }
0131 
0132   using VUnplacedVolume::SafetyToOut;
0133   VECCORE_ATT_HOST_DEVICE
0134   Precision SafetyToOut(Vector3D<Precision> const &) const override
0135   {
0136 #ifndef VECCORE_CUDA
0137     throw std::runtime_error("Forbidden SafetyToOut in Assembly called");
0138 #endif
0139     return -1.;
0140   }
0141 
0142   // ---------------- SafetyToIn functions -------------------------------------------------------
0143   VECCORE_ATT_HOST_DEVICE
0144   virtual Precision SafetyToIn(Vector3D<Precision> const &p) const override
0145   {
0146     return fLogicalVolume->GetSafetyEstimator()->ComputeSafetyToDaughtersForLocalPoint(p, fLogicalVolume);
0147   }
0148 
0149   // ---------------- DistanceToIn functions -----------------------------------------------------
0150 
0151   VECCORE_ATT_HOST_DEVICE
0152   virtual Precision DistanceToIn(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0153                                  const Precision /*step_max*/ = kInfLength) const override
0154   {
0155     if (!BoxImplementation::Intersect(&fLowerCorner, p, d, 0, kInfLength)) return kInfLength;
0156 
0157     Precision step(kInfLength);
0158     VPlacedVolume const *pv;
0159     fLogicalVolume->GetNavigator()->CheckDaughterIntersections(fLogicalVolume, p, d, nullptr, nullptr, step, pv);
0160     return step;
0161   }
0162 
0163   VECCORE_ATT_HOST_DEVICE
0164   bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &norm) const override { return false; }
0165 
0166   Vector3D<Precision> SamplePointOnSurface() const override;
0167   Precision Capacity() const override;
0168   Precision SurfaceArea() const override;
0169 
0170   // some dummy impl for virtual functions
0171   VECCORE_ATT_HOST_DEVICE
0172   virtual void Print() const override;
0173   virtual void Print(std::ostream &os) const override;
0174   virtual int MemorySize() const override { return sizeof(*this); }
0175 
0176 #ifdef VECGEOM_CUDA_INTERFACE
0177   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedAssembly>::SizeOf(); }
0178   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0179   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0180 #endif
0181 
0182 #ifndef VECCORE_CUDA
0183   virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0184                                            Transformation3D const *const transformation,
0185                                            VPlacedVolume *const placement = NULL) const override;
0186 #else
0187   VECCORE_ATT_DEVICE VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0188                                                       Transformation3D const *const transformation, const int id,
0189                                                       const int copy_no, const int child_id,
0190                                                       VPlacedVolume *const placement) const override;
0191 #endif
0192 };
0193 } // namespace VECGEOM_IMPL_NAMESPACE
0194 } // namespace vecgeom
0195 
0196 #endif // VECGEOM_UNPLACEDASSEMBLY_H