File indexing completed on 2025-01-18 10:13:57
0001
0002
0003
0004 #ifndef VECGEOM_NAVIGATION_BVHNAVIGATOR_H_
0005 #define VECGEOM_NAVIGATION_BVHNAVIGATOR_H_
0006
0007 #include "VecGeom/management/BVHManager.h"
0008 #include "VecGeom/navigation/BVHSafetyEstimator.h"
0009 #include "VecGeom/navigation/VNavigator.h"
0010 #include "VecGeom/volumes/LogicalVolume.h"
0011 #include "VecGeom/volumes/PlacedVolume.h"
0012
0013 namespace vecgeom {
0014 inline namespace VECGEOM_IMPL_NAMESPACE {
0015
0016
0017
0018
0019
0020 template <bool MotherIsConvex = false>
0021 class BVHNavigator : public VNavigatorHelper<BVHNavigator<MotherIsConvex>, MotherIsConvex> {
0022 private:
0023
0024 VECCORE_ATT_DEVICE
0025 BVHNavigator() : VNavigatorHelper<BVHNavigator<MotherIsConvex>, MotherIsConvex>(BVHSafetyEstimator::Instance()) {}
0026
0027 public:
0028 using SafetyEstimator_t = BVHSafetyEstimator;
0029 using Base = VNavigatorHelper<BVHNavigator<MotherIsConvex>, MotherIsConvex>;
0030 using Base::CheckDaughterIntersections;
0031
0032 static constexpr const char *gClassNameString = "BVHNavigator";
0033
0034 #ifndef VECCORE_CUDA
0035
0036 static VNavigator *Instance()
0037 {
0038 static BVHNavigator instance;
0039 return &instance;
0040 }
0041 #else
0042
0043
0044
0045 VECCORE_ATT_DEVICE
0046 static VNavigator *Instance();
0047 #endif
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 VECCORE_ATT_HOST_DEVICE
0062 bool CheckDaughterIntersections(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint,
0063 Vector3D<Precision> const &localdir, NavigationState const *in_state,
0064 NavigationState * , Precision &step,
0065 VPlacedVolume const *&hitcandidate) const final
0066 {
0067 if (auto bvh = BVHManager::GetBVH(lvol)) {
0068 VPlacedVolume const *last = in_state ? in_state->GetLastExited() : nullptr;
0069 bvh->CheckDaughterIntersections(localpoint, localdir, step, last, hitcandidate);
0070 }
0071 return false;
0072 }
0073
0074
0075
0076
0077
0078 VECCORE_ATT_HOST_DEVICE
0079 void Relocate(Vector3D<Precision> const &pointafterboundary, NavigationState const &__restrict__ in_state,
0080 NavigationState &__restrict__ out_state) const final
0081 {
0082
0083
0084 if (out_state.Top() == in_state.Top()) {
0085 RelocatePointFromPathForceDifferent(pointafterboundary, out_state);
0086 } else {
0087
0088 VPlacedVolume const *nextvol = out_state.Top();
0089 out_state.Pop();
0090 LocateGlobalPoint(nextvol, nextvol->GetTransformation()->Transform(pointafterboundary), out_state, false);
0091 return;
0092 }
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102 VECCORE_ATT_HOST_DEVICE
0103 VPlacedVolume const *LocateGlobalPoint(VPlacedVolume const *vol, Vector3D<Precision> const &point,
0104 NavigationState &path, bool top, VPlacedVolume const *exclude = nullptr) const
0105 {
0106 if (top) {
0107 assert(vol != nullptr);
0108 if (!vol->UnplacedContains(point)) return nullptr;
0109 }
0110
0111 path.Push(vol);
0112
0113 Vector3D<Precision> currentpoint(point);
0114 Vector3D<Precision> daughterlocalpoint;
0115
0116 for (auto v = vol; v->GetDaughters().size() > 0;) {
0117 auto bvh = vecgeom::BVHManager::GetBVH(v->GetLogicalVolume()->id());
0118
0119 if (!bvh->LevelLocate(exclude, currentpoint, v, daughterlocalpoint)) break;
0120
0121 currentpoint = daughterlocalpoint;
0122 path.Push(v);
0123
0124
0125 exclude = nullptr;
0126 }
0127
0128 return path.Top();
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 VECCORE_ATT_HOST_DEVICE
0140 VPlacedVolume const *LocateGlobalPointExclVolume(VPlacedVolume const *vol, VPlacedVolume const *exclvol,
0141 Vector3D<Precision> const &point, NavigationState &path,
0142 bool top) const
0143 {
0144 VPlacedVolume const *candvolume = vol;
0145 Vector3D<Precision> currentpoint(point);
0146 if (top) {
0147 assert(vol != nullptr);
0148 candvolume = (vol->UnplacedContains(point)) ? vol : nullptr;
0149 }
0150 if (candvolume) {
0151 path.Push(candvolume);
0152 LogicalVolume const *lvol = candvolume->GetLogicalVolume();
0153 Vector<Daughter> const *daughters = lvol->GetDaughtersp();
0154
0155 bool godeeper = true;
0156 while (daughters->size() > 0 && godeeper) {
0157
0158 Vector3D<Precision> transformedpoint;
0159 godeeper = BVHManager::GetBVH(lvol)->LevelLocate(exclvol, currentpoint, candvolume, transformedpoint);
0160 if (godeeper) {
0161 lvol = candvolume->GetLogicalVolume();
0162 daughters = lvol->GetDaughtersp();
0163 currentpoint = transformedpoint;
0164 path.Push(candvolume);
0165 }
0166 }
0167 }
0168 return candvolume;
0169 }
0170
0171
0172
0173
0174
0175 VECCORE_ATT_HOST_DEVICE
0176 VPlacedVolume const *RelocatePointFromPathForceDifferent(Vector3D<Precision> const &localpoint,
0177 NavigationState &path) const
0178 {
0179
0180
0181
0182
0183 VPlacedVolume const *currentmother = path.Top();
0184 VPlacedVolume const *entryvol = currentmother;
0185
0186 if (currentmother != nullptr) {
0187 Vector3D<Precision> tmp = localpoint;
0188 while (currentmother) {
0189 if (currentmother == entryvol || currentmother->GetLogicalVolume()->GetUnplacedVolume()->IsAssembly() ||
0190 !currentmother->UnplacedContains(tmp)) {
0191 path.Pop();
0192 Vector3D<Precision> pointhigherup = currentmother->GetTransformation()->InverseTransform(tmp);
0193 tmp = pointhigherup;
0194 currentmother = path.Top();
0195 } else {
0196 break;
0197 }
0198 }
0199
0200 if (currentmother) {
0201 path.Pop();
0202 return LocateGlobalPointExclVolume(currentmother, entryvol, tmp, path, false);
0203 }
0204 }
0205 return currentmother;
0206 }
0207 };
0208 }
0209 }
0210
0211 #endif