Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:58

0001 /*
0002  * SimpleLevelLocator.h
0003  *
0004  *  Created on: Aug 27, 2015
0005  *      Author: swenzel
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 // shared kernel for many locators
0020 // treats the actual final check (depending on which interface to serve)
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       // in this case we call a special version of Contains
0031       // offered by the assembly
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 // shared kernel for many locators
0056 // treats the actual final check (depending on which interface to serve)
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     /* if (nextvolume->GetUnplacedVolume()->IsAssembly()) { */
0065     /*   // in this case we call a special version of Contains */
0066     /*   // offered by the assembly */
0067     /*   assert(ModifyState == true); */
0068     /*   if (((PlacedAssembly *)nextvolume)->Inside(localpoint, daughterlocalpoint, *state)) { */
0069     /*     return true; */
0070     /*   } */
0071     /* } else { */
0072     /*   if (nextvolume->Inside(localpoint, daughterlocalpoint)) { */
0073     /*     state->Push(nextvolume); */
0074     /*     return true; */
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 // a simple version of a LevelLocator offering a generic brute force algorithm
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   // the actual implementation kernel
0120   // the template "ifs" should be optimized away
0121   // arguments are pointers to allow for nullptr
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   // the actual implementation kernel
0144   // the template "ifs" should be optimized away
0145   // arguments are pointers to allow for nullptr
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 }; // end class declaration
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 } // namespace VECGEOM_IMPL_NAMESPACE
0225 } // namespace vecgeom
0226 
0227 #endif /* NAVIGATION_SIMPLELEVELLOCATOR_H_ */