File indexing completed on 2025-01-18 10:13:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef NAVIGATION_NEWSIMPLENAVIGATOR_H_
0009 #define NAVIGATION_NEWSIMPLENAVIGATOR_H_
0010
0011 #include "VNavigator.h"
0012 #include "SimpleSafetyEstimator.h"
0013
0014 namespace vecgeom {
0015 inline namespace VECGEOM_IMPL_NAMESPACE {
0016
0017
0018 template <bool MotherIsConvex = false>
0019 class NewSimpleNavigator : public VNavigatorHelper<class NewSimpleNavigator<MotherIsConvex>, MotherIsConvex> {
0020
0021 private:
0022 VECCORE_ATT_DEVICE
0023 NewSimpleNavigator()
0024 : VNavigatorHelper<class NewSimpleNavigator<MotherIsConvex>, MotherIsConvex>(SimpleSafetyEstimator::Instance()) {
0025 } VECCORE_ATT_DEVICE virtual ~NewSimpleNavigator() {}
0026
0027 public:
0028 VECGEOM_FORCE_INLINE
0029 VECCORE_ATT_HOST_DEVICE
0030 virtual bool CheckDaughterIntersections(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint,
0031 Vector3D<Precision> const &localdir, NavigationState const *in_state,
0032 NavigationState * , Precision &step,
0033 VPlacedVolume const *&hitcandidate) const override
0034 {
0035
0036 auto *daughters = lvol->GetDaughtersp();
0037 auto ndaughters = daughters->size();
0038 for (decltype(ndaughters) d = 0; d < ndaughters; ++d) {
0039 auto daughter = daughters->operator[](d);
0040
0041
0042
0043
0044 #ifdef CHECKCONTAINS
0045 bool contains = daughter->Contains(localpoint);
0046 if (!contains) {
0047 #endif
0048 Precision ddistance = daughter->DistanceToIn(localpoint, localdir, step);
0049
0050
0051
0052 const bool valid = (ddistance < step && !IsInf(ddistance)) &&
0053 !((ddistance <= 0.) && in_state && in_state->GetLastExited() == daughter);
0054 hitcandidate = valid ? daughter : hitcandidate;
0055 step = valid ? ddistance : step;
0056 #ifdef CHECKCONTAINS
0057 } else {
0058 std::cerr << " INDA "
0059 << " contained in daughter " << daughter << " - inside = " << daughter->Inside(localpoint)
0060 << " , distToIn(p,v,s) = " << daughter->DistanceToIn(localpoint, localdir, step) << " \n";
0061
0062 std::cerr << " INDA ";
0063 step = -1.;
0064 hitcandidate = daughter;
0065 break;
0066 }
0067 #endif
0068 }
0069 return false;
0070 }
0071
0072 VECGEOM_FORCE_INLINE
0073 VECCORE_ATT_HOST_DEVICE
0074 virtual bool CheckDaughterIntersections(LogicalVolume const *lvol, Vector3D<Precision> const &localpoint,
0075 Vector3D<Precision> const &localdir, VPlacedVolume const *blocked,
0076 Precision &step, VPlacedVolume const *&hitcandidate) const override
0077 {
0078
0079 static const double kMinExitingCos = 1.e-3;
0080 VPlacedVolume const *excludedVol = nullptr;
0081 if (blocked) {
0082 Vector3D<Precision> normal;
0083 blocked->Normal(localpoint, normal);
0084 if (normal.Dot(localdir) >= kMinExitingCos) {
0085 excludedVol = blocked;
0086 }
0087 }
0088
0089
0090 auto *daughters = lvol->GetDaughtersp();
0091 auto ndaughters = daughters->size();
0092 for (decltype(ndaughters) d = 0; d < ndaughters; ++d) {
0093 auto daughter = daughters->operator[](d);
0094
0095
0096
0097
0098 #ifdef CHECKCONTAINS
0099 bool contains = daughter->Contains(localpoint);
0100 if (!contains) {
0101 #endif
0102 if (daughter != excludedVol) {
0103 Precision ddistance = daughter->DistanceToIn(localpoint, localdir, step);
0104
0105
0106
0107 const bool valid = (ddistance < step && !IsInf(ddistance));
0108 hitcandidate = valid ? daughter : hitcandidate;
0109 step = valid ? ddistance : step;
0110 }
0111 #ifdef CHECKCONTAINS
0112 } else {
0113 std::cerr << " INDA: contained in daughter " << daughter << " - inside = " << daughter->Inside(localpoint)
0114 << " , distToIn(p,v,s) = " << daughter->DistanceToIn(localpoint, localdir, step) << " \n";
0115 step = -1.;
0116 hitcandidate = daughter;
0117 break;
0118 }
0119 #endif
0120 }
0121
0122 return false;
0123 }
0124
0125
0126
0127 template <typename T, unsigned int ChunkSize>
0128 VECCORE_ATT_HOST_DEVICE
0129 static void DaughterIntersectionsLooper(VNavigator const * , LogicalVolume const *lvol,
0130 Vector3D<T> const &localpoint, Vector3D<T> const &localdir,
0131 NavigationState const* const* , NavigationState ** ,
0132 unsigned int from_index, Precision *out_steps,
0133 VPlacedVolume const *hitcandidates[ChunkSize])
0134 {
0135
0136
0137
0138
0139 T step(vecCore::FromPtr<T>(out_steps + from_index));
0140 const auto *daughters = lvol->GetDaughtersp();
0141 auto ndaughters = daughters->size();
0142 for (decltype(ndaughters) d = 0; d < ndaughters; ++d) {
0143 auto daughter = daughters->operator[](d);
0144
0145
0146
0147
0148
0149
0150
0151 const T ddistance = daughter->DistanceToIn(localpoint, localdir, step);
0152
0153
0154
0155 const auto valid = (ddistance < step && !IsInf(ddistance));
0156
0157
0158
0159 if (!vecCore::MaskEmpty(valid)) {
0160 for (unsigned int i = 0 ; i < ChunkSize; ++i) {
0161 hitcandidates[i] = vecCore::MaskLaneAt(valid, i) ? daughter : hitcandidates[i];
0162 }
0163
0164 vecCore::MaskedAssign(step, valid, ddistance);
0165
0166
0167
0168
0169
0170
0171
0172
0173 }
0174 }
0175 vecCore::Store(step, out_steps + from_index);
0176 }
0177
0178
0179
0180 template <typename T, unsigned int ChunkSize>
0181 VECCORE_ATT_HOST_DEVICE
0182 static void DaughterIntersectionsLooper(VNavigator const * , LogicalVolume const *lvol,
0183 Vector3D<T> const &localpoint, Vector3D<T> const &localdir,
0184 NavStatePool const &, NavStatePool &,
0185 unsigned int from_index, Precision *out_steps,
0186 VPlacedVolume const *hitcandidates[ChunkSize])
0187 {
0188
0189
0190
0191
0192 T step(vecCore::FromPtr<T>(out_steps + from_index));
0193 const auto *daughters = lvol->GetDaughtersp();
0194 auto ndaughters = daughters->size();
0195 for (decltype(ndaughters) d = 0; d < ndaughters; ++d) {
0196 auto daughter = daughters->operator[](d);
0197
0198
0199
0200
0201
0202
0203
0204 const T ddistance = daughter->DistanceToIn(localpoint, localdir, step);
0205
0206
0207
0208 const auto valid = (ddistance < step && !IsInf(ddistance));
0209
0210
0211
0212 if (!vecCore::MaskEmpty(valid)) {
0213 for (unsigned int i = 0 ; i < ChunkSize; ++i) {
0214 hitcandidates[i] = vecCore::MaskLaneAt(valid, i) ? daughter : hitcandidates[i];
0215 }
0216
0217 vecCore::MaskedAssign(step, valid, ddistance);
0218
0219
0220
0221
0222
0223
0224
0225
0226 }
0227 }
0228 vecCore::Store(step, out_steps + from_index);
0229 }
0230
0231 template <typename T, unsigned int ChunkSize>
0232 VECCORE_ATT_HOST_DEVICE
0233 static void DaughterIntersectionsLooper(VNavigator const *nav, LogicalVolume const *lvol,
0234 Vector3D<T> const &localpoint, Vector3D<T> const &localdir,
0235 NavigationState const *const *in_states, unsigned int from_index,
0236 Precision *out_steps, VPlacedVolume const *hitcandidates[ChunkSize])
0237 {
0238 NewSimpleNavigator<MotherIsConvex>::template DaughterIntersectionsLooper<T, ChunkSize>(
0239 nav, lvol, localpoint, localdir, in_states, nullptr, from_index, out_steps, hitcandidates);
0240 }
0241
0242 #ifndef VECCORE_CUDA
0243 static VNavigator *Instance()
0244 {
0245 static NewSimpleNavigator instance;
0246 return &instance;
0247 }
0248 #else
0249 VECCORE_ATT_DEVICE
0250 static VNavigator *Instance();
0251 #endif
0252
0253 static constexpr const char *gClassNameString = "NewSimpleNavigator";
0254 typedef SimpleSafetyEstimator SafetyEstimator_t;
0255 };
0256 }
0257 }
0258
0259 #endif