Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*
0002  * HybridLevelLocator.h
0003  *
0004  *  Created on: Aug 27, 2015
0005  *      Author: Yang Zhang and Sandro Wenzel (sandro.wenzel@cern.ch)
0006  */
0007 
0008 #ifndef NAVIGATION_HYBRIDLEVELLOCATOR_H_
0009 #define NAVIGATION_HYBRIDLEVELLOCATOR_H_
0010 
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/volumes/PlacedVolume.h"
0014 #include "VecGeom/management/HybridManager2.h"
0015 #include "VecGeom/volumes/kernel/BoxImplementation.h"
0016 #include "VecGeom/navigation/SimpleLevelLocator.h"
0017 
0018 namespace vecgeom {
0019 inline namespace VECGEOM_IMPL_NAMESPACE {
0020 
0021 // a LevelLocator using a flat list of bounding boxes
0022 template <bool IsAssemblyAware = false>
0023 class THybridLevelLocator : public VLevelLocator {
0024 
0025 private:
0026   HybridManager2 &fAccelerationStructure;
0027 
0028   THybridLevelLocator() : fAccelerationStructure(HybridManager2::Instance()) {}
0029 
0030   // the actual implementation kernel
0031   // the template "ifs" should be optimized away
0032   // arguments are pointers to allow for nullptr
0033   template <bool ExclV, bool ModifyState>
0034   __attribute__((always_inline)) bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0035                                                         Vector3D<Precision> const &localpoint, NavigationState *state,
0036                                                         VPlacedVolume const *&pvol,
0037                                                         Vector3D<Precision> &daughterlocalpoint) const
0038   {
0039     auto accstructure = fAccelerationStructure.GetAccStructure(lvol);
0040     int halfvectorsize, numberOfNodes;
0041     auto boxes_v                = fAccelerationStructure.GetABBoxes_v(*accstructure, halfvectorsize, numberOfNodes);
0042     auto const *nodeToDaughters = accstructure->fNodeToDaughters;
0043     constexpr auto kVS          = vecCore::VectorSize<HybridManager2::Float_v>();
0044 
0045     for (int index = 0, nodeindex = 0; index < halfvectorsize * 2; index += 2 * (kVS + 1), nodeindex += kVS) {
0046       using Bool_v = vecCore::Mask_v<HybridManager2::Float_v>;
0047       Bool_v inChildNodes;
0048       ABBoxImplementation::ABBoxContainsKernel(boxes_v[index], boxes_v[index + 1], localpoint, inChildNodes);
0049       if (!vecCore::MaskEmpty(inChildNodes)) {
0050         for (size_t i = 0 /*inChildNodes.firstOne()*/; i < kVS; ++i) {
0051           if (vecCore::MaskLaneAt(inChildNodes, i)) {
0052             Bool_v inDaughterBox;
0053             ABBoxImplementation::ABBoxContainsKernel(boxes_v[index + 2 * i + 2], boxes_v[index + 2 * i + 3], localpoint,
0054                                                      inDaughterBox);
0055             if (!vecCore::MaskEmpty(inDaughterBox)) {
0056               for (size_t j = 0 /*inDaughterBox.firstOne()*/; j < kVS; ++j) { // leaf node
0057                 if (vecCore::MaskLaneAt(inDaughterBox, j)) {
0058 
0059                   // final candidate check
0060                   VPlacedVolume const *candidate = lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]];
0061                   if (ExclV)
0062                     if (candidate == exclvol) continue;
0063 
0064                   if (CheckCandidateVol<IsAssemblyAware, ModifyState>(candidate, localpoint, state, pvol,
0065                                                                       daughterlocalpoint)) {
0066                     return true;
0067                   }
0068                 }
0069               }
0070             }
0071           }
0072         }
0073       }
0074     }
0075     return false;
0076   }
0077 
0078   // the actual implementation kernel
0079   // the template "ifs" should be optimized away
0080   // arguments are pointers to allow for nullptr
0081   template <bool ExclV, bool ModifyState>
0082   __attribute__((always_inline)) bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0083                                                                      VPlacedVolume const *exclvol,
0084                                                                      Vector3D<Precision> const &localpoint,
0085                                                                      Vector3D<Precision> const &localdir,
0086                                                                      NavigationState *state, VPlacedVolume const *&pvol,
0087                                                                      Vector3D<Precision> &daughterlocalpoint) const
0088   {
0089     auto accstructure = fAccelerationStructure.GetAccStructure(lvol);
0090     int halfvectorsize, numberOfNodes;
0091     auto boxes_v                = fAccelerationStructure.GetABBoxes_v(*accstructure, halfvectorsize, numberOfNodes);
0092     auto const *nodeToDaughters = accstructure->fNodeToDaughters;
0093     constexpr auto kVS          = vecCore::VectorSize<HybridManager2::Float_v>();
0094 
0095     for (int index = 0, nodeindex = 0; index < halfvectorsize * 2; index += 2 * (kVS + 1), nodeindex += kVS) {
0096       using Bool_v = vecCore::Mask_v<HybridManager2::Float_v>;
0097       Bool_v inChildNodes;
0098       ABBoxImplementation::ABBoxContainsKernel(boxes_v[index], boxes_v[index + 1], localpoint, inChildNodes);
0099       if (!vecCore::MaskEmpty(inChildNodes)) {
0100         for (size_t i = 0 /*inChildNodes.firstOne()*/; i < kVS; ++i) {
0101           if (vecCore::MaskLaneAt(inChildNodes, i)) {
0102             Bool_v inDaughterBox;
0103             ABBoxImplementation::ABBoxContainsKernel(boxes_v[index + 2 * i + 2], boxes_v[index + 2 * i + 3], localpoint,
0104                                                      inDaughterBox);
0105             if (!vecCore::MaskEmpty(inDaughterBox)) {
0106               for (size_t j = 0 /*inDaughterBox.firstOne()*/; j < kVS; ++j) { // leaf node
0107                 if (vecCore::MaskLaneAt(inDaughterBox, j)) {
0108 
0109                   // final candidate check
0110                   VPlacedVolume const *candidate = lvol->GetDaughters()[nodeToDaughters[nodeindex + i][j]];
0111                   if (ExclV) {
0112                     if (candidate == exclvol) {
0113                       continue;
0114                     }
0115                   }
0116 
0117                   if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(candidate, localpoint, localdir,
0118                                                                                    state, pvol, daughterlocalpoint)) {
0119                     return true;
0120                   }
0121                 }
0122               }
0123             }
0124           }
0125         }
0126       }
0127     }
0128     return false;
0129   }
0130 
0131 public:
0132   static std::string GetClassName() { return "HybridLevelLocator"; }
0133   virtual std::string GetName() const override { return GetClassName(); }
0134 
0135   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0136                            Vector3D<Precision> &daughterlocalpoint) const override
0137   {
0138     return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0139   }
0140 
0141   virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &state,
0142                            Vector3D<Precision> &daughterlocalpoint) const override
0143   {
0144     VPlacedVolume const *pvol;
0145     return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &state, pvol, daughterlocalpoint);
0146   }
0147 
0148   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0149                                   Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0150                                   Vector3D<Precision> &daughterlocalpoint) const override
0151   {
0152     return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0153   }
0154 
0155   virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0156                                   Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdir,
0157                                   VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0158   {
0159     return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdir, nullptr, pvol,
0160                                                        daughterlocalpoint);
0161   }
0162 
0163   static VLevelLocator const *GetInstance()
0164   {
0165     static THybridLevelLocator instance;
0166     return &instance;
0167   }
0168 
0169 }; // end class declaration
0170 
0171 template <>
0172 inline std::string THybridLevelLocator<true>::GetClassName()
0173 {
0174   return "AssemblyAwareHybridLevelLocator";
0175 }
0176 } // namespace VECGEOM_IMPL_NAMESPACE
0177 } // namespace vecgeom
0178 
0179 #endif /* NAVIGATION_HYBRIDLEVELLOCATOR_H_ */