File: UnplacedImplAs.h

package info (click to toggle)
vecgeom 1.2.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 23,928 kB
  • sloc: cpp: 88,717; ansic: 6,894; python: 1,035; sh: 582; sql: 538; makefile: 29
file content (174 lines) | stat: -rw-r--r-- 7,001 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//@author: initial implementation Sandro Wenzel (July 2018)
#ifndef VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_
#define VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_

#include "VecGeom/base/Global.h"
#include "VecGeom/volumes/UnplacedVolume.h"
#include "VecGeom/management/VolumeFactory.h"
#include "VecGeom/volumes/PlacedVolImplHelper.h"
#include "VecGeom/volumes/SpecializedPlacedVolImplHelper.h"
#include "VecGeom/volumes/kernel/ImplAsImplementation.h"
#include <cassert>
#include <type_traits>

namespace vecgeom {

VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_2t(class, SUnplacedImplAs, typename, typename);

inline namespace VECGEOM_IMPL_NAMESPACE {

// A wrapper class which generically implements a specialization of UnplacedBase
// implemented in terms of another **existing** implementing volume ImplementingUnplaced.
template <typename UnplacedBase, typename ImplementingUnplaced>
class SUnplacedImplAs : public UnplacedBase {
  // static assert(make sure UnplacedBase is an UnplacedVolume

public:
  using UnplacedStruct_t = typename ImplementingUnplaced::UnplacedStruct_t;

  template <typename... Args>
  SUnplacedImplAs(Args... args) : UnplacedBase(args...)
  {
    fImplPtr = new ImplementingUnplaced(args...);
  }

  // implement the important unplaced volume interfaces
  VECCORE_ATT_HOST_DEVICE
  bool Contains(Vector3D<Precision> const &p) const override { return fImplPtr->ImplementingUnplaced::Contains(p); }

  VECCORE_ATT_HOST_DEVICE
  EnumInside Inside(Vector3D<Precision> const &p) const override { return fImplPtr->ImplementingUnplaced::Inside(p); }

  // DistanceToOut
  VECCORE_ATT_HOST_DEVICE
  Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
                          Precision step_max = kInfLength) const override
  {
    return fImplPtr->ImplementingUnplaced::DistanceToOut(p, d, step_max);
  }

  VECCORE_ATT_HOST_DEVICE
  Precision DistanceToOut(Vector3D<Precision> const &p, Vector3D<Precision> const &d, Vector3D<Precision> &normal,
                          bool &convex, Precision step_max = kInfLength) const override
  {
    return fImplPtr->ImplementingUnplaced::DistanceToOut(p, d, normal, convex, step_max);
  }

  VECCORE_ATT_HOST_DEVICE
  Real_v DistanceToOutVec(Vector3D<Real_v> const &p, Vector3D<Real_v> const &d, Real_v const &step_max) const override
  {
    return fImplPtr->ImplementingUnplaced::DistanceToOutVec(p, d, step_max);
  }

  // the container/basket interface (possibly to be deprecated)
  void DistanceToOut(SOA3D<Precision> const &points, SOA3D<Precision> const &directions,
                     Precision const *const step_max, Precision *const output) const override
  {
    return fImplPtr->ImplementingUnplaced::DistanceToOut(points, directions, step_max, output);
  }

  // SafetyToOut
  VECCORE_ATT_HOST_DEVICE
  Precision SafetyToOut(Vector3D<Precision> const &p) const override
  {
    return fImplPtr->ImplementingUnplaced::SafetyToOut(p);
  }

  VECCORE_ATT_HOST_DEVICE
  Real_v SafetyToOutVec(Vector3D<Real_v> const &p) const override
  {
    return fImplPtr->ImplementingUnplaced::SafetyToOutVec(p);
  }

  void SafetyToOut(SOA3D<Precision> const &points, Precision *const output) const override
  {
    return fImplPtr->ImplementingUnplaced::SafetyToOut(points, output);
  }

  // NOTE: This does not work yet (for whatever reason) since the trampoline dispatch is confused
  // in UnplacedVolume.h
  // DistanceToIn
  //  VECCORE_ATT_HOST_DEVICE
  //  Precision DistanceToIn(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
  //                         const Precision step_max) const override
  //  {
  //    return fImplPtr->ImplementingUnplaced::DistanceToIn(position, direction, step_max);
  //  }

  //  VECCORE_ATT_HOST_DEVICE
  //  Real_v DistanceToInVec(Vector3D<Real_v> const &position, Vector3D<Real_v> const &direction,
  //                         const Real_v &step_max) const override
  //  {
  //    return fImplPtr->ImplementingUnplaced::DistanceToInVec(position, direction, step_max);
  //  }

  VECCORE_ATT_HOST_DEVICE
  Precision SafetyToIn(Vector3D<Precision> const &position) const override
  {
    return fImplPtr->ImplementingUnplaced::SafetyToIn(position);
  }

  VECCORE_ATT_HOST_DEVICE
  Real_v SafetyToInVec(Vector3D<Real_v> const &p) const override
  {
    return fImplPtr->ImplementingUnplaced::SafetyToInVec(p);
  }

  // ---------------- SamplePointOnSurface ----------------------------------------------------------
  Vector3D<Precision> SamplePointOnSurface() const override
  {
    return fImplPtr->ImplementingUnplaced::SamplePointOnSurface();
  }

  // ----------------- Extent --------------------------------------------------------------------
  VECCORE_ATT_HOST_DEVICE
  void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override
  {
    fImplPtr->ImplementingUnplaced::Extent(aMin, aMax);
  }

  using StructType = decltype(std::declval<ImplementingUnplaced>().GetStruct());
  VECCORE_ATT_HOST_DEVICE
  StructType GetStruct() const { return fImplPtr->ImplementingUnplaced::GetStruct(); }

private:
  // select target specialization helpers with SFINAE
  template <typename IUnplaced, typename ImplementingKernel>
  VPlacedVolume *changeTypeKeepTransformation(
      VPlacedVolume const *p, typename std::enable_if<IUnplaced::SIMDHELPER, IUnplaced>::type * = nullptr) const
  {
    // if the implementing helper supports SIMD
    auto c = VolumeFactory::ChangeTypeKeepTransformation<SIMDSpecializedVolImplHelper, ImplementingKernel>(p);
    return c;
  }

  template <typename IUnplaced, typename ImplementingKernel>
  VPlacedVolume *changeTypeKeepTransformation(
      VPlacedVolume const *p, typename std::enable_if<!IUnplaced::SIMDHELPER, IUnplaced>::type * = nullptr) const
  {
    // if the implementing helper does not support SIMD
    auto c = VolumeFactory::ChangeTypeKeepTransformation<LoopSpecializedVolImplHelper, ImplementingKernel>(p);
    return c;
  }

  VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume, Transformation3D const *const transformation,
                                   const TranslationCode trans_code, const RotationCode rot_code,
                                   VPlacedVolume *const placement = NULL) const override
  {
    auto p = fImplPtr->ImplementingUnplaced::SpecializedVolume(volume, transformation, trans_code, rot_code, placement);

    using ImplementingKernel = IndirectImplementation<SUnplacedImplAs<UnplacedBase, ImplementingUnplaced>,
                                                      typename ImplementingUnplaced::Kernel>;

    // the right function to use will be selected with SFINAE and enable_if
    return changeTypeKeepTransformation<ImplementingUnplaced, ImplementingKernel>(p);
    // TODO: original p is no longer needed in principle: delete and deregister from GeoManager
    // delete p;
  }

  ImplementingUnplaced *fImplPtr;
};
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom

#endif /* VOLUMES_SUNPLACEDVOLUME_IMPLAS_H_ */