File: UnplacedAssembly.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 (232 lines) | stat: -rw-r--r-- 8,766 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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// LICENSING INFORMATION TBD

#ifndef VECGEOM_UNPLACEDASSEMBLY_H
#define VECGEOM_UNPLACEDASSEMBLY_H

#include "VecGeom/base/Cuda.h"
#include "VecGeom/base/Global.h"
#include "VecGeom/base/Vector.h"
#include "VecGeom/navigation/VNavigator.h"
#include "VecGeom/navigation/NavigationState.h"
#include "VecGeom/base/Vector3D.h"
#include "VecGeom/volumes/UnplacedVolume.h"
#include "VecGeom/volumes/PlacedVolume.h"
#include "VecGeom/volumes/kernel/BoxImplementation.h"
#include "VecGeom/navigation/NavStateFwd.h"

namespace vecgeom {

VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedAssembly;);
VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedAssembly);

inline namespace VECGEOM_IMPL_NAMESPACE {

// An assembly volume offering navigation interfaces (Contains/Distances/...) in a loose/logical group of volumes
// An UnplacedAssembly is always strongly coupled to a logical volume because the later naturally manages the actual
// group of volumes that define the assembly

// The following construct marks a logical volume as an assembly:

// UnplacedAssembly *ass = new UnplacedAssembly
// LogicalVolume *lv = new LogicalVolume("assembly", ass); // this will implicitely couple ass to lv
// lv->PlacedDaughter(...)

class UnplacedAssembly : public VUnplacedVolume, public AlignedBase {

private:
  // back-reference to the logical volume
  // this get automacially set upon instantiation of a logical volume with an UnplacedAssembly
  LogicalVolume *fLogicalVolume;

  // caching the extent (bounding box)
  // these members are automatically updated whenever a new volume is added to the assembly
  Vector3D<Precision> fLowerCorner;
  Vector3D<Precision> fUpperCorner;

  void SetLogicalVolume(LogicalVolume *lv) { fLogicalVolume = lv; }
  void UpdateExtent() { UnplacedAssembly::Extent(fLowerCorner, fUpperCorner); ComputeBBox(); }
  friend class LogicalVolume;

public:
  VECCORE_ATT_HOST_DEVICE
  UnplacedAssembly(); // the constructor

  VECCORE_ATT_HOST_DEVICE
  virtual ~UnplacedAssembly();

  LogicalVolume const *GetLogicalVolume() const { return fLogicalVolume; }

  // add content
  void AddVolume(VPlacedVolume *const);

  // get number of volumes
  size_t GetNVolumes() const { return fLogicalVolume->GetDaughters().size(); }

  // the extent function
  VECCORE_ATT_HOST_DEVICE
  void Extent(Vector3D<Precision> &, Vector3D<Precision> &) const override;

  // Getter to cached bounding box
  VECCORE_ATT_HOST_DEVICE
  Vector3D<Precision> GetLowerCorner() const { return fLowerCorner; }

  VECCORE_ATT_HOST_DEVICE
  Vector3D<Precision> GetUpperCorner() const { return fUpperCorner; }

  // the ordinary assembly function
  VECCORE_ATT_HOST_DEVICE
  bool Contains(Vector3D<Precision> const &point) const override
  {
    assert(fLogicalVolume);
    // check bound box first
    bool inBoundingBox;
    ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
    if (!inBoundingBox) return false;

    Vector3D<Precision> daughterlocalpoint;
    VPlacedVolume const *nextv;
    return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, nextv, daughterlocalpoint);
  }

  VECCORE_ATT_HOST_DEVICE
  EnumInside Inside(Vector3D<Precision> const & /*point*/) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("Assembly inside to be implemented");
#endif
    return static_cast<EnumInside>(EInside::kOutside);
  }

  // an extended contains function needed for navigation
  // if this function returns true it modifies the navigation state to point to the first non-assembly volume
  // the point is contained in
  // this function is not part of the generic UnplacedVolume interface but we could consider doing so
  VECCORE_ATT_HOST_DEVICE
  bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &daughterlocalpoint, NavigationState &state) const
  {
    assert(fLogicalVolume);
    // check bound box first
    bool inBoundingBox;
    ABBoxImplementation::ABBoxContainsKernel(fLowerCorner, fUpperCorner, point, inBoundingBox);
    if (!inBoundingBox) return false;

    return fLogicalVolume->GetLevelLocator()->LevelLocate(fLogicalVolume, point, state, daughterlocalpoint);
  }

  using VUnplacedVolume::DistanceToOut;
  // DistanceToOut does not make sense -- throw exeption
  VECCORE_ATT_HOST_DEVICE
  Precision DistanceToOut(Vector3D<Precision> const & /*p*/, Vector3D<Precision> const & /*d*/,
                          Precision /*step_max*/ = kInfLength) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("Forbidden DistanceToOut in Assembly called");
#endif
    return -1.;
  }

  // DistanceToOut does not make sense -- throw exeption
  VECCORE_ATT_HOST_DEVICE
  Real_v DistanceToOutVec(Vector3D<Real_v> const & /*p*/, Vector3D<Real_v> const & /*d*/,
                          Real_v const & /*step_max*/) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("Forbidden DistanceToOut in Assembly called");
#endif
    return Real_v(-1.);
  }

  using VUnplacedVolume::SafetyToOut;
  VECCORE_ATT_HOST_DEVICE
  Precision SafetyToOut(Vector3D<Precision> const &) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("Forbidden SafetyToOut in Assembly called");
#endif
    return -1.;
  }

  // an explicit SIMD interface
  VECCORE_ATT_HOST_DEVICE
  Real_v SafetyToOutVec(Vector3D<Real_v> const &) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("Forbidden SafetyToOut in Assembly called");
#endif
    return Real_v(-1.);
  }

  // ---------------- SafetyToIn functions -------------------------------------------------------
  VECCORE_ATT_HOST_DEVICE
  virtual Precision SafetyToIn(Vector3D<Precision> const &p) const override
  {
    return fLogicalVolume->GetSafetyEstimator()->ComputeSafetyToDaughtersForLocalPoint(p, fLogicalVolume);
  }

  // explicit SIMD interface
  VECCORE_ATT_HOST_DEVICE
  virtual Real_v SafetyToInVec(Vector3D<Real_v> const &) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("SafetyToInVec in Assembly not yet implemented");
#endif
    return Real_v(-1.);
  }

  // ---------------- DistanceToIn functions -----------------------------------------------------

  VECCORE_ATT_HOST_DEVICE
  virtual Precision DistanceToIn(Vector3D<Precision> const &p, Vector3D<Precision> const &d,
                                 const Precision /*step_max*/ = kInfLength) const override
  {
    if (!BoxImplementation::Intersect(&fLowerCorner, p, d, 0, kInfLength)) return kInfLength;

    Precision step(kInfLength);
    VPlacedVolume const *pv;
    fLogicalVolume->GetNavigator()->CheckDaughterIntersections(fLogicalVolume, p, d, nullptr, nullptr, step, pv);
    return step;
  }

  VECCORE_ATT_HOST_DEVICE
  virtual Real_v DistanceToInVec(Vector3D<Real_v> const & /*p*/, Vector3D<Real_v> const & /*d*/,
                                 const Real_v & /*step_max*/ = Real_v(kInfLength)) const override
  {
#ifndef VECCORE_CUDA
    throw std::runtime_error("DistanceToInVec in Assembly not yet implemented");
#endif
    return Real_v(-1.);
  }

  Vector3D<Precision> SamplePointOnSurface() const override;
  Precision Capacity() const override;
  Precision SurfaceArea() const override;

  // some dummy impl for virtual functions
  VECCORE_ATT_HOST_DEVICE
  virtual void Print() const override;
  virtual void Print(std::ostream &os) const override;
  virtual int MemorySize() const override { return sizeof(*this); }

#ifdef VECGEOM_CUDA_INTERFACE
  virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedAssembly>::SizeOf(); }
  virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
  virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
#endif

#ifndef VECCORE_CUDA
  virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
                                           Transformation3D const *const transformation,
                                           const TranslationCode trans_code, const RotationCode rot_code,
                                           VPlacedVolume *const placement = NULL) const override;
#else
  VECCORE_ATT_DEVICE VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
                                                      Transformation3D const *const transformation,
                                                      const TranslationCode trans_code, const RotationCode rot_code,
                                                      const int id, const int copy_no, const int child_id,
                                                      VPlacedVolume *const placement) const override;
#endif
};
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom

#endif // VECGEOM_UNPLACEDASSEMBLY_H