Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:26:26

0001 //@author: initial implementation Sandro Wenzel (July 2018)
0002 #ifndef VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_
0003 #define VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_
0004 
0005 #include "VecGeom/base/Global.h"
0006 #include "VecGeom/volumes/UnplacedVolume.h"
0007 #include "VecGeom/management/VolumeFactory.h"
0008 #include "VecGeom/volumes/PlacedVolImplHelper.h"
0009 #include "VecGeom/volumes/SpecializedPlacedVolImplHelper.h"
0010 #include "VecGeom/volumes/kernel/ImplAsImplementation.h"
0011 #include <cassert>
0012 #include <type_traits>
0013 
0014 namespace vecgeom {
0015 
0016 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2t(class, SUnplacedImplAs, typename, typename);
0017 
0018 inline namespace VECGEOM_IMPL_NAMESPACE {
0019 
0020 // A wrapper class which generically implements a specialization of UnplacedBase
0021 // implemented in terms of another **existing** implementing volume ImplementingUnplaced.
0022 template <typename UnplacedBase, typename ImplementingUnplaced>
0023 class SUnplacedImplAs : public UnplacedBase {
0024   // static assert(make sure UnplacedBase is an UnplacedVolume
0025 
0026 public:
0027   using UnplacedStruct_t = typename ImplementingUnplaced::UnplacedStruct_t;
0028 
0029   template <typename... Args>
0030   SUnplacedImplAs(Args... args) : UnplacedBase(args...)
0031   {
0032     fImplPtr = new ImplementingUnplaced(args...);
0033   }
0034 
0035   // implement the important unplaced volume interfaces
0036   VECCORE_ATT_HOST_DEVICE
0037   bool Contains(Vector3D<Precision> const &p) const override { return fImplPtr->ImplementingUnplaced::Contains(p); }
0038 
0039   VECCORE_ATT_HOST_DEVICE
0040   EnumInside Inside(Vector3D<Precision> const &p) const override { return fImplPtr->ImplementingUnplaced::Inside(p); }
0041 
0042   // DistanceToOut
0043   VECCORE_ATT_HOST_DEVICE
0044   Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
0045                           Precision step_max = kInfLength) const override
0046   {
0047     return fImplPtr->ImplementingUnplaced::DistanceToOut(p, d, step_max);
0048   }
0049 
0050   VECCORE_ATT_HOST_DEVICE
0051   Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d, Vector3D<Precision> &normal,
0052                           bool &convex, Precision step_max = kInfLength) const override
0053   {
0054     return fImplPtr->ImplementingUnplaced::DistanceToOut(p, d, normal, convex, step_max);
0055   }
0056 
0057   VECCORE_ATT_HOST_DEVICE
0058   Real_v DistanceToOutVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d, Real_v const &step_max) const override
0059   {
0060     return fImplPtr->ImplementingUnplaced::DistanceToOutVec(p, d, step_max);
0061   }
0062 
0063   // the container/basket interface (possibly to be deprecated)
0064   void DistanceToOut(SOA3D<Precision> const &points, SOA3D<Precision> const &directions,
0065                      Precision const *const step_max, Precision *const output) const override
0066   {
0067     return fImplPtr->ImplementingUnplaced::DistanceToOut(points, directions, step_max, output);
0068   }
0069 
0070   // SafetyToOut
0071   VECCORE_ATT_HOST_DEVICE
0072   Precision SafetyToOut(Vector3D<Precision> const &p) const override
0073   {
0074     return fImplPtr->ImplementingUnplaced::SafetyToOut(p);
0075   }
0076 
0077   VECCORE_ATT_HOST_DEVICE
0078   Real_v SafetyToOutVec(Vector3D<Real_v> const &p) const override
0079   {
0080     return fImplPtr->ImplementingUnplaced::SafetyToOutVec(p);
0081   }
0082 
0083   void SafetyToOut(SOA3D<Precision> const &points, Precision *const output) const override
0084   {
0085     return fImplPtr->ImplementingUnplaced::SafetyToOut(points, output);
0086   }
0087 
0088   // NOTE: This does not work yet (for whatever reason) since the trampoline dispatch is confused
0089   // in UnplacedVolume.h
0090   // DistanceToIn
0091   //  VECCORE_ATT_HOST_DEVICE
0092   //  Precision DistanceToIn(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0093   //                         const Precision step_max) const override
0094   //  {
0095   //    return fImplPtr->ImplementingUnplaced::DistanceToIn(position, direction, step_max);
0096   //  }
0097 
0098   //  VECCORE_ATT_HOST_DEVICE
0099   //  Real_v DistanceToInVec(Vector3D<Real_v> const &position, Vector3D<Real_v> const &direction,
0100   //                         const Real_v &step_max) const override
0101   //  {
0102   //    return fImplPtr->ImplementingUnplaced::DistanceToInVec(position, direction, step_max);
0103   //  }
0104 
0105   VECCORE_ATT_HOST_DEVICE
0106   Precision SafetyToIn(Vector3D<Precision> const &position) const override
0107   {
0108     return fImplPtr->ImplementingUnplaced::SafetyToIn(position);
0109   }
0110 
0111   VECCORE_ATT_HOST_DEVICE
0112   Real_v SafetyToInVec(Vector3D<Real_v> const &p) const override
0113   {
0114     return fImplPtr->ImplementingUnplaced::SafetyToInVec(p);
0115   }
0116 
0117   // ---------------- SamplePointOnSurface ----------------------------------------------------------
0118   Vector3D<Precision> SamplePointOnSurface() const override
0119   {
0120     return fImplPtr->ImplementingUnplaced::SamplePointOnSurface();
0121   }
0122 
0123   // ----------------- Extent --------------------------------------------------------------------
0124   VECCORE_ATT_HOST_DEVICE
0125   void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override
0126   {
0127     fImplPtr->ImplementingUnplaced::Extent(aMin, aMax);
0128   }
0129 
0130   using StructType = decltype(std::declval<ImplementingUnplaced>().GetStruct());
0131   VECCORE_ATT_HOST_DEVICE
0132   StructType GetStruct() const { return fImplPtr->ImplementingUnplaced::GetStruct(); }
0133 
0134 private:
0135   // select target specialization helpers with SFINAE
0136   template <typename IUnplaced, typename ImplementingKernel>
0137   VPlacedVolume *changeTypeKeepTransformation(
0138       VPlacedVolume const *p, typename std::enable_if<IUnplaced::SIMDHELPER, IUnplaced>::type * = nullptr) const
0139   {
0140     // if the implementing helper supports SIMD
0141     auto c = VolumeFactory::ChangeTypeKeepTransformation<SIMDSpecializedVolImplHelper, ImplementingKernel>(p);
0142     return c;
0143   }
0144 
0145   template <typename IUnplaced, typename ImplementingKernel>
0146   VPlacedVolume *changeTypeKeepTransformation(
0147       VPlacedVolume const *p, typename std::enable_if<!IUnplaced::SIMDHELPER, IUnplaced>::type * = nullptr) const
0148   {
0149     // if the implementing helper does not support SIMD
0150     auto c = VolumeFactory::ChangeTypeKeepTransformation<LoopSpecializedVolImplHelper, ImplementingKernel>(p);
0151     return c;
0152   }
0153 
0154   VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume, Transformation3D const *const transformation,
0155                                    const TranslationCode trans_code, const RotationCode rot_code,
0156                                    VPlacedVolume *const placement = NULL) const override
0157   {
0158     auto p = fImplPtr->ImplementingUnplaced::SpecializedVolume(volume, transformation, trans_code, rot_code, placement);
0159 
0160     using ImplementingKernel = IndirectImplementation<SUnplacedImplAs<UnplacedBase, ImplementingUnplaced>,
0161                                                       typename ImplementingUnplaced::Kernel>;
0162 
0163     // the right function to use will be selected with SFINAE and enable_if
0164     return changeTypeKeepTransformation<ImplementingUnplaced, ImplementingKernel>(p);
0165     // TODO: original p is no longer needed in principle: delete and deregister from GeoManager
0166     // delete p;
0167   }
0168 
0169   ImplementingUnplaced *fImplPtr;
0170 };
0171 } // namespace VECGEOM_IMPL_NAMESPACE
0172 } // namespace vecgeom
0173 
0174 #endif /* VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_ */