Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:26:08

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 navigation/VoxelLevelLocator.h
0006 /// \author Sandro Wenzel (CERN)
0007 
0008 #ifndef NAVIGATION_VOXELLEVELLOCATOR_H_
0009 #define NAVIGATION_VOXELLEVELLOCATOR_H_
0010 
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/management/FlatVoxelManager.h"
0015 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0016 #include "VecGeom/navigation/SimpleLevelLocator.h"
0017 #include "VecGeom/management/ABBoxManager.h"
0018 
0019 namespace vecgeom {
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021 
0022 //! A LevelLocator using voxel hash-maps containing candidate volume ids to quickly
0023 //! decide in which volume a point is.
0024 template <bool IsAssemblyAware = false>
0025 class TVoxelLevelLocator : public VLevelLocator {
0026 
0027 private:
0028   FlatVoxelManager &fAccelerationStructure;
0029 
0030   TVoxelLevelLocator() : fAccelerationStructure(FlatVoxelManager::Instance()) {}
0031 
0032   // the actual implementation kernel
0033   // the template "ifs" should be optimized away
0034   // arguments are pointers to allow for nullptr
0035   template <bool ExclV, bool ModifyState>
0036   __attribute__((always_inline)) bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0037                                                         Vector3D<Precision> const &localpoint, NavigationState *state,
0038                                                         VPlacedVolume const *&pvol,
0039                                                         Vector3D<Precision> &daughterlocalpoint) const
0040   {
0041     const auto accstructure = fAccelerationStructure.GetStructure(lvol);
0042     // fetch the right voxels
0043     const auto locatevoxels = accstructure->fVoxelToLocateCandidates;
0044     // fetch the list of candidates to check (as id)
0045     Vector3D<float> floatlocalpoint(localpoint.x(), localpoint.y(), localpoint.z());
0046 
0047     int numbercandidates{0};
0048     const auto candidateidsptr = locatevoxels->getProperties(floatlocalpoint, numbercandidates);
0049 
0050     if (numbercandidates > 0) {
0051       // here we have something to do
0052       int numberboxes{0};
0053       const auto boxes = ABBoxManager::Instance().GetABBoxes(lvol, numberboxes);
0054 
0055       for (int i = 0; i < numbercandidates; ++i) {
0056         const int daughterid = candidateidsptr[i];
0057 
0058         // discard blocked volume
0059         VPlacedVolume const *candidate = lvol->GetDaughters()[daughterid];
0060         if (ExclV) {
0061           if (candidate == exclvol) continue;
0062         }
0063 
0064         // quick aligned bounding box check (could be done in SIMD fashion if multiple candidates)
0065         const auto &lower = boxes[2 * daughterid];
0066         const auto &upper = boxes[2 * daughterid + 1];
0067         bool boxcontains{false};
0068         ABBoxImplementation::ABBoxContainsKernel(lower, upper, localpoint, boxcontains);
0069         if (!boxcontains) {
0070           continue;
0071         }
0072 
0073         // final candidate check
0074         if (CheckCandidateVol<IsAssemblyAware, ModifyState>(candidate, localpoint, state, pvol, daughterlocalpoint)) {
0075           return true;
0076         }
0077       }
0078     }
0079     return false;
0080   }
0081 
0082   // the actual implementation kernel
0083   // the template "ifs" should be optimized away
0084   // arguments are pointers to allow for nullptr
0085   template <bool ExclV, bool ModifyState>
0086   __attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0087                                                                      VPlacedVolume const *exclvol,
0088                                                                      Vector3D<Precision> const &localpoint,
0089                                                                      Vector3D<Precision> const &localdir,
0090                                                                      NavigationState *state, VPlacedVolume const *&pvol,
0091                                                                      Vector3D<Precision> &daughterlocalpoint) const
0092   {
0093     const auto accstructure = fAccelerationStructure.GetStructure(lvol);
0094     // fetch the right voxels
0095     const auto locatevoxels = accstructure->fVoxelToLocateCandidates;
0096     // fetch the list of candidates to check (as id)
0097     Vector3D<float> floatlocalpoint(localpoint.x(), localpoint.y(), localpoint.z());
0098 
0099     int numbercandidates{0};
0100     const auto candidateidsptr = locatevoxels->getProperties(floatlocalpoint, numbercandidates);
0101 
0102     if (numbercandidates > 0) {
0103       // here we have something to do
0104       int numberboxes{0};
0105       const auto boxes = ABBoxManager::Instance().GetABBoxes(lvol, numberboxes);
0106 
0107       for (int i = 0; i < numbercandidates; ++i) {
0108         const int daughterid = candidateidsptr[i];
0109 
0110         // discard blocked volume
0111         VPlacedVolume const *candidate = lvol->GetDaughters()[daughterid];
0112         if (ExclV) {
0113           if (candidate == exclvol) continue;
0114         }
0115 
0116         // quick aligned bounding box check (could be done in SIMD fashion if multiple candidates)
0117         const auto &lower = boxes[2 * daughterid];
0118         const auto &upper = boxes[2 * daughterid + 1];
0119         bool boxcontains{false};
0120         ABBoxImplementation::ABBoxContainsKernel(lower, upper, localpoint, boxcontains);
0121         if (!boxcontains) {
0122           continue;
0123         }
0124 
0125         // final candidate check
0126         if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(candidate, localpoint, localdir, state, pvol,
0127                                                                          daughterlocalpoint)) {
0128           return true;
0129         }
0130       }
0131     }
0132     return false;
0133   }
0134 
0135 public:
0136   static std::string GetClassName() { return "VoxelLevelLocator"; }
0137   std::string GetName() const override { return GetClassName(); }
0138 
0139   bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0140                    Vector3D<Precision> &daughterlocalpoint) const override
0141   {
0142     return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0143   }
0144 
0145   bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &state,
0146                    Vector3D<Precision> &daughterlocalpoint) const override
0147   {
0148     VPlacedVolume const *pvol;
0149     return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &state, pvol, daughterlocalpoint);
0150   }
0151 
0152   bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0153                           Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0154                           Vector3D<Precision> &daughterlocalpoint) const override
0155   {
0156     return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0157   }
0158 
0159   bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0160                           Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
0161                           VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0162   {
0163     return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
0164                                                        daughterlocalpoint);
0165   }
0166 
0167   static VLevelLocator const *GetInstance()
0168   {
0169     static TVoxelLevelLocator instance;
0170     return &instance;
0171   }
0172 
0173 }; // end class declaration
0174 
0175 template <>
0176 inline std::string TVoxelLevelLocator<true>::GetClassName()
0177 {
0178   return "AssemblyAwareVoxelLevelLocator";
0179 }
0180 } // namespace VECGEOM_IMPL_NAMESPACE
0181 } // namespace vecgeom
0182 
0183 #endif /* NAVIGATION_VOXELLEVELLOCATOR_H_ */