File indexing completed on 2025-10-31 09:19:07
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 #ifndef NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_
0009 #define NAVIGATION_SIMPLEABBOXLEVELLOCATOR_H_
0010 
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/management/ABBoxManager.h"
0015 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0016 
0017 #include "VecGeom/navigation/SimpleLevelLocator.h"
0018 
0019 #include <exception>
0020 #include <stdexcept>
0021 
0022 namespace vecgeom {
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 
0025 
0026 template <bool IsAssemblyAware = false>
0027 class TSimpleABBoxLevelLocator : public VLevelLocator {
0028 
0029 private:
0030   ABBoxManager &fAccelerationStructure;
0031   TSimpleABBoxLevelLocator() : fAccelerationStructure(ABBoxManager::Instance()) {}
0032 
0033   
0034   
0035   
0036   template <bool ExclV, bool ModifyState>
0037   __attribute__((always_inline)) bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0038                                                         Vector3D<Precision> const &localpoint, NavigationState *state,
0039                                                         VPlacedVolume const *&pvol,
0040                                                         Vector3D<Precision> &daughterlocalpoint) const
0041   {
0042     int size;
0043     ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
0044 
0045     auto daughters = lvol->GetDaughtersp();
0046     
0047     
0048     for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
0049       using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
0050       Bool_v inBox;
0051       ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
0052                                                localpoint, inBox);
0053       if (!vecCore::MaskEmpty(inBox)) {
0054         constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
0055         
0056         for (size_t ii = 0; ii < kVS; ++ii) {
0057           auto daughterid = boxgroupid * kVS + ii;
0058           if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
0059 
0060             VPlacedVolume const *daughter = (*daughters)[daughterid];
0061             if (ExclV) {
0062               if (daughter == exclvol) continue;
0063             }
0064             
0065             if (CheckCandidateVol<IsAssemblyAware, ModifyState>(daughter, localpoint, state, pvol, daughterlocalpoint))
0066               return true;
0067           }
0068         }
0069       }
0070     }
0071     return false;
0072   }
0073 
0074   template <bool ExclV, bool ModifyState>
0075   __attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0076                                                                      VPlacedVolume const *exclvol,
0077                                                                      Vector3D<Precision> const &localpoint,
0078                                                                      Vector3D<Precision> const &localdir,
0079                                                                      NavigationState *state, VPlacedVolume const *&pvol,
0080                                                                      Vector3D<Precision> &daughterlocalpoint) const
0081   {
0082 
0083     int size;
0084     ABBoxManager::ABBoxContainer_v alignedbboxes = fAccelerationStructure.GetABBoxes_v(lvol, size);
0085 
0086     auto daughters = lvol->GetDaughtersp();
0087     
0088     
0089     for (int boxgroupid = 0; boxgroupid < size; ++boxgroupid) {
0090       using Bool_v = vecCore::Mask_v<ABBoxManager::Float_v>;
0091       Bool_v inBox;
0092       ABBoxImplementation::ABBoxContainsKernel(alignedbboxes[2 * boxgroupid], alignedbboxes[2 * boxgroupid + 1],
0093                                                localpoint, inBox);
0094       if (!vecCore::MaskEmpty(inBox)) {
0095         constexpr auto kVS = vecCore::VectorSize<ABBoxManager::Float_v>();
0096         
0097         for (size_t ii = 0; ii < kVS; ++ii) {
0098           auto daughterid = boxgroupid * kVS + ii;
0099           if (daughterid < daughters->size() && vecCore::MaskLaneAt(inBox, ii)) {
0100 
0101             VPlacedVolume const *nextvolume = (*daughters)[daughterid];
0102             if (ExclV) {
0103               if (exclvol == nextvolume) continue;
0104             }
0105             if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(nextvolume, localpoint, localdir, state,
0106                                                                              pvol, daughterlocalpoint)) {
0107               return true;
0108             }
0109           }
0110         }
0111       }
0112     }
0113     return false;
0114   }
0115 
0116 public:
0117   VECCORE_ATT_HOST_DEVICE
0118   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0119                            Vector3D<Precision> &daughterlocalpoint) const override
0120   {
0121     return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0122   } 
0123 
0124   
0125   VECCORE_ATT_HOST_DEVICE
0126   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &outstate,
0127                            Vector3D<Precision> &daughterlocalpoint) const override
0128   {
0129     VPlacedVolume const *pvol;
0130     return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &outstate, pvol, daughterlocalpoint);
0131   }
0132 
0133   VECCORE_ATT_HOST_DEVICE
0134   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0135                                   Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0136                                   Vector3D<Precision> &daughterlocalpoint) const override
0137   {
0138     return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0139   } 
0140 
0141   VECCORE_ATT_HOST_DEVICE
0142   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0143                                   Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
0144                                   VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0145   {
0146     return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
0147                                                        daughterlocalpoint);
0148   }
0149 
0150   static std::string GetClassName() { return "SimpleABBoxLevelLocator"; }
0151   virtual std::string GetName() const override { return GetClassName(); }
0152 
0153   static VLevelLocator const *GetInstance()
0154   {
0155     static TSimpleABBoxLevelLocator instance;
0156     return &instance;
0157   }
0158 
0159 }; 
0160 
0161 using SimpleABBoxLevelLocator              = TSimpleABBoxLevelLocator<>;
0162 using SimpleAssemblyAwareABBoxLevelLocator = TSimpleABBoxLevelLocator<true>;
0163 
0164 
0165 
0166 
0167 
0168 
0169 
0170 
0171 
0172 
0173 
0174 
0175 
0176 
0177 
0178 
0179 
0180 
0181 
0182 
0183 
0184 
0185 
0186 
0187 
0188 
0189 
0190 
0191 
0192 
0193 
0194 
0195 
0196 
0197 
0198 
0199 
0200 
0201 template <>
0202 inline std::string TSimpleABBoxLevelLocator<true>::GetClassName()
0203 {
0204   return "SimpleAssemblyAwareABBoxLevelLocator";
0205 }
0206 } 
0207 } 
0208 
0209 #endif