File indexing completed on 2025-01-30 10:26:06
0001
0002
0003
0004
0005
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
0022 template <bool IsAssemblyAware = false>
0023 class THybridLevelLocator : public VLevelLocator {
0024
0025 private:
0026 HybridManager2 &fAccelerationStructure;
0027
0028 THybridLevelLocator() : fAccelerationStructure(HybridManager2::Instance()) {}
0029
0030
0031
0032
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 ; 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 ; j < kVS; ++j) {
0057 if (vecCore::MaskLaneAt(inDaughterBox, j)) {
0058
0059
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
0079
0080
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 ; 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 ; j < kVS; ++j) {
0107 if (vecCore::MaskLaneAt(inDaughterBox, j)) {
0108
0109
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 };
0170
0171 template <>
0172 inline std::string THybridLevelLocator<true>::GetClassName()
0173 {
0174 return "AssemblyAwareHybridLevelLocator";
0175 }
0176 }
0177 }
0178
0179 #endif