Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:14:14

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() { UnplacedAssembly::Extent(fLowerCorner, fUpperCorner); ComputeBBox(); }
0048   friend class LogicalVolume;
0049 
0050 public:
0051   VECCORE_ATT_HOST_DEVICE
0052   UnplacedAssembly(); // the constructor
0053 
0054   VECCORE_ATT_HOST_DEVICE
0055   virtual ~UnplacedAssembly();
0056 
0057   LogicalVolume const *GetLogicalVolume() const { return fLogicalVolume; }
0058 
0059   // add content
0060   void AddVolume(VPlacedVolume *const);
0061 
0062   // get number of volumes
0063   size_t GetNVolumes() const { return fLogicalVolume->GetDaughters().size(); }
0064 
0065   // the extent function
0066   VECCORE_ATT_HOST_DEVICE
0067   void Extent(Vector3D<Precision> &, Vector3D<Precision> &) const override;
0068 
0069   // Getter to cached bounding box
0070   VECCORE_ATT_HOST_DEVICE
0071   Vector3D<Precision> GetLowerCorner() const { return fLowerCorner; }
0072 
0073   VECCORE_ATT_HOST_DEVICE
0074   Vector3D<Precision> GetUpperCorner() const { return fUpperCorner; }
0075 
0076   // the ordinary assembly function
0077   VECCORE_ATT_HOST_DEVICE
0078   bool Contains(Vector3D<Precision> const &point) const override
0079   {
0080     assert(fLogicalVolume);
0081     // check bound box first
0082     bool inBoundingBox;
0083     ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
0084     if (!inBoundingBox) return false;
0085 
0086     Vector3D<Precision> daughterlocalpoint;
0087     VPlacedVolume const *nextv;
0088     return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, nextv, daughterlocalpoint);
0089   }
0090 
0091   VECCORE_ATT_HOST_DEVICE
0092   EnumInside Inside(Vector3D<Precision> const & /*point*/) const override
0093   {
0094 #ifndef VECCORE_CUDA
0095     throw std::runtime_error("Assembly inside to be implemented");
0096 #endif
0097     return static_cast<EnumInside>(EInside::kOutside);
0098   }
0099 
0100   // an extended contains function needed for navigation
0101   // if this function returns true it modifies the navigation state to point to the first non-assembly volume
0102   // the point is contained in
0103   // this function is not part of the generic UnplacedVolume interface but we could consider doing so
0104   VECCORE_ATT_HOST_DEVICE
0105   bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &daughterlocalpoint, NavigationState &state) const
0106   {
0107     assert(fLogicalVolume);
0108     // check bound box first
0109     bool inBoundingBox;
0110     ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
0111     if (!inBoundingBox) return false;
0112 
0113     return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, state, daughterlocalpoint);
0114   }
0115 
0116   using VUnplacedVolume::DistanceToOut;
0117   // DistanceToOut does not make sense -- throw exeption
0118   VECCORE_ATT_HOST_DEVICE
0119   Precision DistanceToOut(Vector3D<Precision> const & /*p*/, Vector3D<Precision> const & /*d*/,
0120                           Precision /*step_max*/ = kInfLength) const override
0121   {
0122 #ifndef VECCORE_CUDA
0123     throw std::runtime_error("Forbidden DistanceToOut in Assembly called");
0124 #endif
0125     return -1.;
0126   }
0127 
0128   // DistanceToOut does not make sense -- throw exeption
0129   VECCORE_ATT_HOST_DEVICE
0130   Real_v DistanceToOutVec(Vector3D<Real_v> const & /*p*/, Vector3D<Real_v> const & /*d*/,
0131                           Real_v const & /*step_max*/) const override
0132   {
0133 #ifndef VECCORE_CUDA
0134     throw std::runtime_error("Forbidden DistanceToOut in Assembly called");
0135 #endif
0136     return Real_v(-1.);
0137   }
0138 
0139   using VUnplacedVolume::SafetyToOut;
0140   VECCORE_ATT_HOST_DEVICE
0141   Precision SafetyToOut(Vector3D<Precision> const &) const override
0142   {
0143 #ifndef VECCORE_CUDA
0144     throw std::runtime_error("Forbidden SafetyToOut in Assembly called");
0145 #endif
0146     return -1.;
0147   }
0148 
0149   // an explicit SIMD interface
0150   VECCORE_ATT_HOST_DEVICE
0151   Real_v SafetyToOutVec(Vector3D<Real_v> const &) const override
0152   {
0153 #ifndef VECCORE_CUDA
0154     throw std::runtime_error("Forbidden SafetyToOut in Assembly called");
0155 #endif
0156     return Real_v(-1.);
0157   }
0158 
0159   // ---------------- SafetyToIn functions -------------------------------------------------------
0160   VECCORE_ATT_HOST_DEVICE
0161   virtual Precision SafetyToIn(Vector3D<Precision> const &p) const override
0162   {
0163     return fLogicalVolume->GetSafetyEstimator()->ComputeSafetyToDaughtersForLocalPoint(p, fLogicalVolume);
0164   }
0165 
0166   // explicit SIMD interface
0167   VECCORE_ATT_HOST_DEVICE
0168   virtual Real_v SafetyToInVec(Vector3D<Real_v> const &) const override
0169   {
0170 #ifndef VECCORE_CUDA
0171     throw std::runtime_error("SafetyToInVec in Assembly not yet implemented");
0172 #endif
0173     return Real_v(-1.);
0174   }
0175 
0176   // ---------------- DistanceToIn functions -----------------------------------------------------
0177 
0178   VECCORE_ATT_HOST_DEVICE
0179   virtual Precision DistanceToIn(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0180                                  const Precision /*step_max*/ = kInfLength) const override
0181   {
0182     if (!BoxImplementation::Intersect(&fLowerCorner, p, d, 0, kInfLength)) return kInfLength;
0183 
0184     Precision step(kInfLength);
0185     VPlacedVolume const *pv;
0186     fLogicalVolume->GetNavigator()->CheckDaughterIntersections(fLogicalVolume, p, d, nullptr, nullptr, step, pv);
0187     return step;
0188   }
0189 
0190   VECCORE_ATT_HOST_DEVICE
0191   virtual Real_v DistanceToInVec(Vector3D<Real_v> const & /*p*/, Vector3D<Real_v> const & /*d*/,
0192                                  const Real_v & /*step_max*/ = Real_v(kInfLength)) const override
0193   {
0194 #ifndef VECCORE_CUDA
0195     throw std::runtime_error("DistanceToInVec in Assembly not yet implemented");
0196 #endif
0197     return Real_v(-1.);
0198   }
0199 
0200   Vector3D<Precision> SamplePointOnSurface() const override;
0201   Precision Capacity() const override;
0202   Precision SurfaceArea() const override;
0203 
0204   // some dummy impl for virtual functions
0205   VECCORE_ATT_HOST_DEVICE
0206   virtual void Print() const override;
0207   virtual void Print(std::ostream &os) const override;
0208   virtual int MemorySize() const override { return sizeof(*this); }
0209 
0210 #ifdef VECGEOM_CUDA_INTERFACE
0211   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedAssembly>::SizeOf(); }
0212   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0213   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0214 #endif
0215 
0216 #ifndef VECCORE_CUDA
0217   virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0218                                            Transformation3D const *const transformation,
0219                                            const TranslationCode trans_code, const RotationCode rot_code,
0220                                            VPlacedVolume *const placement = NULL) const override;
0221 #else
0222   VECCORE_ATT_DEVICE VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0223                                                       Transformation3D const *const transformation,
0224                                                       const TranslationCode trans_code, const RotationCode rot_code,
0225                                                       const int id, const int copy_no, const int child_id,
0226                                                       VPlacedVolume *const placement) const override;
0227 #endif
0228 };
0229 } // namespace VECGEOM_IMPL_NAMESPACE
0230 } // namespace vecgeom
0231 
0232 #endif // VECGEOM_UNPLACEDASSEMBLY_H