File indexing completed on 2025-01-18 10:13:58
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