File indexing completed on 2025-01-18 10:13:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef NAVIGATION_SIMPLELEVELLOCATOR_H_
0009 #define NAVIGATION_SIMPLELEVELLOCATOR_H_
0010
0011 #include "VecGeom/navigation/VLevelLocator.h"
0012 #include "VecGeom/volumes/LogicalVolume.h"
0013 #include "VecGeom/navigation/NavigationState.h"
0014 #include "VecGeom/volumes/PlacedAssembly.h"
0015
0016 namespace vecgeom {
0017 inline namespace VECGEOM_IMPL_NAMESPACE {
0018
0019
0020
0021 template <bool IsAssemblyAware, bool ModifyState>
0022 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0023 static bool CheckCandidateVol(VPlacedVolume const *nextvolume,
0024 Vector3D<Precision> const &localpoint,
0025 NavigationState *state, VPlacedVolume const *&pvol,
0026 Vector3D<Precision> &daughterlocalpoint)
0027 {
0028 if (IsAssemblyAware && ModifyState) {
0029 if (nextvolume->GetUnplacedVolume()->IsAssembly()) {
0030
0031
0032 assert(ModifyState == true);
0033 if (((PlacedAssembly *)nextvolume)->Contains(localpoint, daughterlocalpoint, *state)) {
0034 return true;
0035 }
0036 } else {
0037 if (nextvolume->Contains(localpoint, daughterlocalpoint)) {
0038 state->Push(nextvolume);
0039 return true;
0040 }
0041 }
0042 } else {
0043 if (nextvolume->Contains(localpoint, daughterlocalpoint)) {
0044 if (ModifyState) {
0045 state->Push(nextvolume);
0046 } else {
0047 pvol = nextvolume;
0048 }
0049 return true;
0050 }
0051 }
0052 return false;
0053 }
0054
0055
0056
0057 template <bool IsAssemblyAware, bool ModifyState>
0058 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0059 static bool CheckCandidateVolWithDirection(
0060 VPlacedVolume const *nextvolume, Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdirection,
0061 NavigationState *state, VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint)
0062 {
0063 if (IsAssemblyAware && ModifyState) {
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 assert(false && "not implemented yet");
0078 } else {
0079
0080 const auto transf = nextvolume->GetTransformation();
0081 const auto testdaughterlocal = transf->Transform(localpoint);
0082 const auto inside = nextvolume->GetUnplacedVolume()->Inside(testdaughterlocal);
0083
0084 auto CheckEntering = [&transf, &testdaughterlocal, &localdirection, &nextvolume]() {
0085 const auto unpl = nextvolume->GetUnplacedVolume();
0086 Vector3D<Precision> normal;
0087 unpl->Normal(testdaughterlocal, normal);
0088 const auto directiondaughterlocal = transf->TransformDirection(localdirection);
0089 const auto dot = normal.Dot(directiondaughterlocal);
0090 if (dot >= 0) {
0091 return false;
0092 }
0093 return true;
0094 };
0095
0096 if (inside == kInside || ((inside == kSurface) && CheckEntering())) {
0097 if (ModifyState) {
0098 state->Push(nextvolume);
0099 daughterlocalpoint = testdaughterlocal;
0100 } else {
0101 pvol = nextvolume;
0102 daughterlocalpoint = testdaughterlocal;
0103 }
0104 return true;
0105 }
0106 }
0107 return false;
0108 }
0109
0110
0111 template <bool IsAssemblyAware = false>
0112 class TSimpleLevelLocator : public VLevelLocator {
0113
0114 public:
0115 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0116 TSimpleLevelLocator() {}
0117
0118 private:
0119
0120
0121
0122 template <bool ExclV, bool ModifyState>
0123 VECGEOM_FORCE_INLINE
0124 VECCORE_ATT_HOST_DEVICE
0125 bool LevelLocateKernel(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0126 Vector3D<Precision> const &localpoint, NavigationState *state,
0127 VPlacedVolume const *&pvol,
0128 Vector3D<Precision> &daughterlocalpoint) const
0129 {
0130 auto daughters = lvol->GetDaughtersp();
0131 for (size_t i = 0; i < daughters->size(); ++i) {
0132 VPlacedVolume const *nextvolume = (*daughters)[i];
0133 if (ExclV) {
0134 if (exclvol == nextvolume) continue;
0135 }
0136 if (CheckCandidateVol<IsAssemblyAware, ModifyState>(nextvolume, localpoint, state, pvol, daughterlocalpoint)) {
0137 return true;
0138 }
0139 }
0140 return false;
0141 }
0142
0143
0144
0145
0146 template <bool ExclV, bool ModifyState>
0147 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0148 bool LevelLocateKernelWithDirection(LogicalVolume const *lvol,
0149 VPlacedVolume const *exclvol,
0150 Vector3D<Precision> const &localpoint,
0151 Vector3D<Precision> const &localdir,
0152 NavigationState *state, VPlacedVolume const *&pvol,
0153 Vector3D<Precision> &daughterlocalpoint) const
0154 {
0155 auto daughters = lvol->GetDaughtersp();
0156 for (size_t i = 0; i < daughters->size(); ++i) {
0157 VPlacedVolume const *nextvolume = (*daughters)[i];
0158 if (ExclV) {
0159 if (exclvol == nextvolume) continue;
0160 }
0161 if (CheckCandidateVolWithDirection<IsAssemblyAware, ModifyState>(nextvolume, localpoint, localdir, state, pvol,
0162 daughterlocalpoint)) {
0163 return true;
0164 }
0165 }
0166 return false;
0167 }
0168
0169 public:
0170 VECCORE_ATT_HOST_DEVICE
0171 virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0172 Vector3D<Precision> &daughterlocalpoint) const override
0173 {
0174 return LevelLocateKernel<false, false>(lvol, nullptr, localpoint, nullptr, pvol, daughterlocalpoint);
0175 }
0176
0177 VECCORE_ATT_HOST_DEVICE
0178 virtual bool LevelLocate(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint, NavigationState &state,
0179 Vector3D<Precision> &daughterlocalpoint) const override
0180 {
0181 VPlacedVolume const *pvol = nullptr;
0182 return LevelLocateKernel<false, true>(lvol, nullptr, localpoint, &state, pvol, daughterlocalpoint);
0183 }
0184
0185 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0186 virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0187 Vector3D<Precision> const &localpoint, VPlacedVolume const *&pvol,
0188 Vector3D<Precision> &daughterlocalpoint) const override
0189 {
0190 return LevelLocateKernel<true, false>(lvol, exclvol, localpoint, nullptr, pvol, daughterlocalpoint);
0191 }
0192
0193 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0194 virtual bool LevelLocateExclVol(LogicalVolume const *lvol, VPlacedVolume const *exclvol,
0195 Vector3D<Precision> const &localpoint, Vector3D<Precision> const &localdirection,
0196 VPlacedVolume const *&pvol, Vector3D<Precision> &daughterlocalpoint) const override
0197 {
0198 return LevelLocateKernelWithDirection<true, false>(lvol, exclvol, localpoint, localdirection, nullptr, pvol,
0199 daughterlocalpoint);
0200 }
0201
0202 static std::string GetClassName() { return "SimpleLevelLocator"; }
0203 virtual std::string GetName() const override { return GetClassName(); }
0204
0205 #ifndef VECCORE_CUDA
0206 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE
0207 static VLevelLocator const *GetInstance()
0208 {
0209 static TSimpleLevelLocator instance;
0210 return &instance;
0211 }
0212 #endif
0213
0214 };
0215
0216 using SimpleLevelLocator = TSimpleLevelLocator<>;
0217
0218 template <>
0219 inline std::string TSimpleLevelLocator<true>::GetClassName()
0220 {
0221 return "SimpleAssemblyLevelLocator";
0222 }
0223 using SimpleAssemblyLevelLocator = TSimpleLevelLocator<true>;
0224 }
0225 }
0226
0227 #endif