Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:08

0001 /// \file BVHNavigatorV.h
0002 /// \brief IndexedBVH-accelerated navigator behind the virtual VNavigator interface.
0003 
0004 #ifndef VECGEOM_NAVIGATION_BVHNAVIGATORV_H_
0005 #define VECGEOM_NAVIGATION_BVHNAVIGATORV_H_
0006 
0007 #include "VecGeom/base/IndexedBVH.h"
0008 #include "VecGeom/management/BVHManager.h"
0009 #include "VecGeom/navigation/BVHNavigator.h"
0010 #include "VecGeom/navigation/BVHSafetyEstimator.h"
0011 #include "VecGeom/navigation/VNavigator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 
0015 namespace vecgeom {
0016 inline namespace VECGEOM_IMPL_NAMESPACE {
0017 
0018 /**
0019  * @brief IndexedBVH navigator behind the virtual VNavigator interface.
0020  *
0021  * The VNavigator counterpart of the standalone BVHNavigator, for consumers that assign a
0022  * navigator per logical volume. Pair it with BVHLevelLocator and BVHSafetyEstimator.
0023  * Only the daughter query is implemented here; VNavigatorHelper provides the rest.
0024  * BVHManager::Init() must have run after GeoManager::CloseGeometry(), or the hierarchies do not exist.
0025  */
0026 template <bool MotherIsConvex = false>
0027 class BVHNavigatorV : public VNavigatorHelper<BVHNavigatorV<MotherIsConvex>, MotherIsConvex> {
0028 
0029 private:
0030   /** Constructor. Private since this is a singleton class accessed only via Instance(). */
0031   BVHNavigatorV() : VNavigatorHelper<BVHNavigatorV<MotherIsConvex>, MotherIsConvex>(BVHSafetyEstimator::Instance()) {}
0032 
0033 public:
0034   using Base = VNavigatorHelper<BVHNavigatorV<MotherIsConvex>, MotherIsConvex>;
0035   using Base::PrepareOutState;
0036 
0037   /// Safety from the same hierarchy.
0038   typedef BVHSafetyEstimator SafetyEstimator_t;
0039 
0040   static constexpr const char *gClassNameString = "BVHNavigatorV";
0041 
0042   /** Returns the instance of this singleton class. */
0043   static VNavigator *Instance()
0044   {
0045     static BVHNavigatorV instance;
0046     return &instance;
0047   }
0048 
0049   /**
0050    * Nearest daughter of @p lvol hit within @p step. The volume last exited in @p in_state is refused only at a
0051    * non-positive distance, so a non-convex daughter the ray leaves can be re-entered further on.
0052    * @returns Always false: the outgoing state is not modified.
0053    */
0054   VECCORE_ATT_HOST_DEVICE
0055   bool CheckDaughterIntersections(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint,
0056                                   Vector3D<Precision> const &localdir, NavigationState const *in_state,
0057                                   NavigationState * /* out_state */, Precision &step,
0058                                   VPlacedVolume const *&hitcandidate) const final
0059   {
0060     auto const *bvh = BVHManager::GetBVH(lvol->id());
0061     if (bvh == nullptr) return false;
0062 
0063     // A placed-volume id is unsigned; -1 as a long is the "no exclusion" marker.
0064     long last_exited_id          = -1;
0065     VPlacedVolume const *lastvol = in_state ? in_state->GetLastExited() : nullptr;
0066     if (lastvol != nullptr) last_exited_id = lastvol->id();
0067 
0068     long hitcandidate_index = -1;
0069     BVHNavigator::CheckDaughterIntersectionsBlocked<BVHNavigator>(*bvh, localpoint, localdir, step, last_exited_id,
0070                                                                   hitcandidate_index);
0071     if (hitcandidate_index >= 0) hitcandidate = (*lvol->GetDaughtersp())[hitcandidate_index];
0072 
0073     return false; /* return value indicates whether out_state has been modified */
0074   }
0075 
0076   /**
0077    * Nearest daughter of @p lvol hit within @p step. At a non-positive distance it refuses @p blocked and any
0078    * daughter the ray is leaving, as SimpleABBoxNavigator does. This is the query of Geant4 glue.
0079    * @returns Always false: no outgoing state is modified.
0080    */
0081   VECCORE_ATT_HOST_DEVICE
0082   bool CheckDaughterIntersections(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint,
0083                                   Vector3D<Precision> const &localdir, VPlacedVolume const *blocked, Precision &step,
0084                                   VPlacedVolume const *&hitcandidate) const override
0085   {
0086     auto const *bvh = BVHManager::GetBVH(lvol->id());
0087     if (bvh == nullptr) return false;
0088 
0089     // A placed-volume id is unsigned; -1 as a long is the "no exclusion" marker.
0090     long last_exited_id = (blocked != nullptr) ? static_cast<long>(blocked->id()) : -1;
0091 
0092     long hitcandidate_index = -1;
0093     BVHNavigator::CheckDaughterIntersectionsBlocked<BVHNavigator>(*bvh, localpoint, localdir, step, last_exited_id,
0094                                                                   hitcandidate_index);
0095     if (hitcandidate_index >= 0) hitcandidate = (*lvol->GetDaughtersp())[hitcandidate_index];
0096 
0097     return false; /* return value indicates whether out_state has been modified */
0098   }
0099 }; // end class declaration
0100 
0101 } // namespace VECGEOM_IMPL_NAMESPACE
0102 } // namespace vecgeom
0103 
0104 #endif // VECGEOM_NAVIGATION_BVHNAVIGATORV_H_