File indexing completed on 2025-01-18 10:13:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef NAVIGATION_SIMPLESAFETYESTIMATOR_H_
0009 #define NAVIGATION_SIMPLESAFETYESTIMATOR_H_
0010
0011 #include "VecGeom/navigation/VSafetyEstimator.h"
0012
0013
0014 namespace vecgeom {
0015 inline namespace VECGEOM_IMPL_NAMESPACE {
0016
0017
0018 static void VectMin(unsigned int nelem, Precision *__restrict__ dest, const Precision *__restrict__ temp) {
0019 using vecCore::FromPtr;
0020 using Real_v = vecgeom::VectorBackend::Real_v;
0021
0022
0023 unsigned int i = 0;
0024 constexpr unsigned int nlanes = vecCore::VectorSize<Real_v>();
0025 const auto ilast = nelem - (nlanes-1);
0026 Real_v result;
0027 for ( ; i < ilast; i += nlanes) {
0028 result = vecCore::math::Min(FromPtr<Real_v>(dest + i), FromPtr<Real_v>(temp + i));
0029 vecCore::Store(result, &dest[i]);
0030 }
0031
0032
0033 for (; i < nelem; ++i) {
0034 if ( dest[i] > temp[i] ) dest[i] = temp[i];
0035 }
0036 }
0037
0038
0039 class SimpleSafetyEstimator : public VSafetyEstimatorHelper<SimpleSafetyEstimator> {
0040
0041 public:
0042 static constexpr const char *gClassNameString = "SimpleSafetyEstimator";
0043
0044
0045
0046 VECCORE_ATT_HOST_DEVICE
0047 virtual Precision ComputeSafetyToDaughtersForLocalPoint(Vector3D<Precision> const &localpoint,
0048 LogicalVolume const *lvol) const override
0049 {
0050
0051 double safety(kInfLength);
0052 auto daughters = lvol->GetDaughtersp();
0053 auto numberdaughters = daughters->size();
0054 for (decltype(numberdaughters) d = 0; d < numberdaughters; ++d) {
0055 VPlacedVolume const *daughter = daughters->operator[](d);
0056 double tmp = daughter->SafetyToIn(localpoint);
0057 safety = Min(safety, tmp);
0058 }
0059 return safety;
0060 }
0061
0062 VECGEOM_FORCE_INLINE
0063 VECCORE_ATT_HOST_DEVICE
0064 virtual Precision ComputeSafetyForLocalPoint(Vector3D<Precision> const &localpoint,
0065 VPlacedVolume const *pvol) const override
0066 {
0067
0068 double safety = pvol->SafetyToOut(localpoint);
0069
0070
0071 auto daughters = pvol->GetLogicalVolume()->GetDaughtersp();
0072 auto numberdaughters = daughters->size();
0073 for (decltype(numberdaughters) d = 0; d < numberdaughters; ++d) {
0074 VPlacedVolume const *daughter = daughters->operator[](d);
0075 double tmp = daughter->SafetyToIn(localpoint);
0076 safety = Min(safety, tmp);
0077 }
0078 return safety;
0079 }
0080
0081 VECGEOM_FORCE_INLINE
0082 VECCORE_ATT_HOST_DEVICE
0083 virtual Real_v ComputeSafetyForLocalPoint(Vector3D<Real_v> const &localpoint, VPlacedVolume const *pvol,
0084 Bool_v m) const override
0085 {
0086
0087 Real_v safety(0.);
0088 if (!vecCore::MaskEmpty(m)) {
0089 safety = pvol->SafetyToOut(localpoint);
0090
0091
0092 auto daughters = pvol->GetLogicalVolume()->GetDaughtersp();
0093 auto numberdaughters = daughters->size();
0094 for (decltype(numberdaughters) d = 0; d < numberdaughters; ++d) {
0095 VPlacedVolume const *daughter = daughters->operator[](d);
0096 auto tmp = daughter->SafetyToIn(localpoint);
0097 safety = Min(safety, tmp);
0098 }
0099 }
0100 return safety;
0101 }
0102
0103
0104 VECGEOM_FORCE_INLINE
0105 virtual void ComputeSafetyForLocalPoints(SOA3D<Precision> const &localpoints, VPlacedVolume const *pvol,
0106 Precision *safeties) const override
0107 {
0108 auto npoints = localpoints.size();
0109
0110
0111 char stackspace[npoints * sizeof(Precision)];
0112 Precision *tmpSafeties = reinterpret_cast<Precision *>(&stackspace);
0113
0114
0115
0116
0117
0118
0119 pvol->SafetyToOut(localpoints, safeties);
0120
0121
0122 Vector<Daughter> const *daughters = pvol->GetLogicalVolume()->GetDaughtersp();
0123 auto numberdaughters = daughters->size();
0124 for (decltype(numberdaughters) d = 0; d < numberdaughters; ++d) {
0125 VPlacedVolume const *daughter = daughters->operator[](d);
0126 daughter->SafetyToIn(localpoints, tmpSafeties);
0127
0128
0129 VectMin(npoints, safeties, tmpSafeties);
0130 }
0131
0132 }
0133
0134
0135 using VSafetyEstimatorHelper<SimpleSafetyEstimator>::ComputeVectorSafety;
0136
0137
0138 virtual void ComputeVectorSafety(SOA3D<Precision> const &globalpoints, NavStatePool &states,
0139 Precision *safeties) const override
0140 {
0141 VPlacedVolume const *pvol = states[0]->Top();
0142 auto npoints = globalpoints.size();
0143
0144 constexpr auto kVS = vecCore::VectorSize<Real_v>();
0145 for (decltype(npoints) i = 0; i < npoints; i += kVS) {
0146
0147 Vector3D<Real_v> local;
0148 for (size_t j = 0; j < kVS; ++j) {
0149 Transformation3D m;
0150 states[i + j]->TopMatrix(m);
0151 auto v = m.Transform(globalpoints[i + j]);
0152
0153 using vecCore::AssignLane;
0154 AssignLane(local.x(), j, v.x());
0155 AssignLane(local.y(), j, v.y());
0156 AssignLane(local.z(), j, v.z());
0157 }
0158
0159 auto safety = pvol->SafetyToOut(local);
0160 auto daughters = pvol->GetLogicalVolume()->GetDaughtersp();
0161 auto numberdaughters = daughters->size();
0162 for (decltype(numberdaughters) d = 0; d < numberdaughters; ++d) {
0163 VPlacedVolume const *daughter = daughters->operator[](d);
0164 safety = Min(safety, daughter->SafetyToIn(local));
0165 }
0166 vecCore::Store(safety, safeties + i);
0167 }
0168 }
0169
0170 #ifndef VECCORE_CUDA
0171 static VSafetyEstimator *Instance()
0172 {
0173 static SimpleSafetyEstimator instance;
0174 return &instance;
0175 }
0176 #else
0177 VECCORE_ATT_DEVICE
0178 static VSafetyEstimator *Instance();
0179 #endif
0180
0181 };
0182 }
0183 }
0184
0185 #endif