File indexing completed on 2026-09-24 09:27:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef VECGEOM_VOLUMES_PLACEDVOLUME_H_
0009 #define VECGEOM_VOLUMES_PLACEDVOLUME_H_
0010
0011 #include "VecGeom/base/Cuda.h"
0012 #include "VecGeom/base/Assert.h"
0013 #include "VecGeom/base/Global.h"
0014 #include "VecGeom/volumes/LogicalVolume.h"
0015 #include <string>
0016
0017 #ifdef VECGEOM_GEANT4
0018 #include <G4VSolid.hh>
0019 #endif
0020
0021 namespace vecgeom {
0022
0023 VECGEOM_DEVICE_FORWARD_DECLARE(class VPlacedVolume;);
0024 VECGEOM_DEVICE_DECLARE_CONV(class, VPlacedVolume);
0025 #ifndef VECCORE_CUDA
0026 template <>
0027 struct kCudaType<const cxx::VPlacedVolume *> {
0028 using type_t = const cuda::VPlacedVolume *;
0029 };
0030 #endif
0031 class GeoManager;
0032
0033 inline namespace VECGEOM_IMPL_NAMESPACE {
0034
0035 class PlacedBox;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 class VPlacedVolume {
0055 friend class vecgeom::GeoManager;
0056
0057 private:
0058 unsigned int id_;
0059 int copy_no_ = 0;
0060 int ichild_ = -1;
0061
0062
0063 std::string *label_;
0064 static unsigned int g_id_count;
0065
0066 protected:
0067 LogicalVolume const *logical_volume_;
0068 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0069 Transformation3D fTransformation;
0070 #else
0071 Transformation3D const *fTransformation;
0072 #endif
0073
0074 #ifndef VECCORE_CUDA
0075
0076
0077
0078
0079
0080
0081 VPlacedVolume(char const *const label, LogicalVolume const *const logical_vol,
0082 Transformation3D const *const transform);
0083
0084
0085
0086
0087
0088 VPlacedVolume(LogicalVolume const *const logical_vol, Transformation3D const *const transform)
0089 : VPlacedVolume("", logical_vol, transform)
0090 {
0091 }
0092
0093 #else
0094
0095 VECCORE_ATT_DEVICE VPlacedVolume(LogicalVolume const *const logical_vol, Transformation3D const *const transformation,
0096 unsigned int id, int copy_no, int ichild)
0097 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0098 : logical_volume_(logical_vol), fTransformation(*transformation), id_(id), copy_no_(copy_no), ichild_(ichild),
0099 label_(NULL)
0100 {
0101 }
0102 #else
0103 : logical_volume_(logical_vol), fTransformation(transformation), id_(id), copy_no_(copy_no), ichild_(ichild),
0104 label_(NULL)
0105 {
0106 }
0107 #endif
0108 #endif
0109
0110 VECGEOM_FORCE_INLINE
0111 void SetChildId(int index) { ichild_ = index; }
0112
0113 public:
0114 VECCORE_ATT_HOST_DEVICE
0115 VPlacedVolume(VPlacedVolume const &);
0116 VECCORE_ATT_HOST_DEVICE
0117 VPlacedVolume *operator=(VPlacedVolume const &);
0118
0119 VECCORE_ATT_HOST_DEVICE
0120 virtual ~VPlacedVolume();
0121
0122
0123 VECCORE_ATT_HOST_DEVICE
0124 VECGEOM_FORCE_INLINE
0125 unsigned int id() const { return id_; }
0126
0127
0128 VECCORE_ATT_HOST_DEVICE
0129 VECGEOM_FORCE_INLINE
0130 int GetChildId() const { return ichild_; }
0131
0132
0133 friend void LogicalVolume::PlaceDaughter(VPlacedVolume *const placed);
0134
0135
0136 VECCORE_ATT_HOST_DEVICE
0137 VECGEOM_FORCE_INLINE
0138 int GetCopyNo() const { return copy_no_; }
0139
0140
0141 static unsigned int GetIdCount() { return g_id_count; }
0142
0143
0144 std::string const &GetLabel() const { return *label_; }
0145
0146
0147 VECCORE_ATT_HOST_DEVICE
0148 VECGEOM_FORCE_INLINE
0149 LogicalVolume const *GetLogicalVolume() const { return logical_volume_; }
0150
0151
0152 VECCORE_ATT_HOST_DEVICE
0153 VECGEOM_FORCE_INLINE
0154 Vector<Daughter> const &GetDaughters() const { return logical_volume_->GetDaughters(); }
0155
0156
0157 VECCORE_ATT_HOST_DEVICE
0158 VECGEOM_FORCE_INLINE
0159 int IndexOf(Daughter daughter) const
0160 {
0161 int id = 0;
0162 for (auto d : logical_volume_->GetDaughters()) {
0163 if (d == daughter) return id;
0164 id++;
0165 }
0166 return -1;
0167 }
0168
0169
0170 VECCORE_ATT_HOST
0171 VECGEOM_FORCE_INLINE
0172 const char *GetName() const { return (*label_).c_str(); }
0173
0174
0175 VECCORE_ATT_HOST_DEVICE
0176 VECGEOM_FORCE_INLINE
0177 VUnplacedVolume const *GetUnplacedVolume() const { return logical_volume_->GetUnplacedVolume(); }
0178
0179
0180 VECCORE_ATT_HOST_DEVICE
0181 bool IsAssembly() const { return GetUnplacedVolume()->IsAssembly(); }
0182
0183
0184 VECCORE_ATT_HOST_DEVICE
0185 VECGEOM_FORCE_INLINE
0186 Transformation3D const *GetTransformation() const
0187 {
0188 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0189 return &fTransformation;
0190 #else
0191 return fTransformation;
0192 #endif
0193 }
0194 #ifndef VECCORE_CUDA
0195 SolidMesh *CreateMesh3D(size_t nFaces) const
0196 {
0197 return GetUnplacedVolume()->CreateMesh3D(*this->GetTransformation(), nFaces);
0198 }
0199 #endif
0200
0201 VECCORE_ATT_HOST_DEVICE
0202 void SetLogicalVolume(LogicalVolume const *const logical_vol) { logical_volume_ = logical_vol; }
0203
0204
0205 VECCORE_ATT_HOST_DEVICE
0206 void SetTransformation(Transformation3D const *const transform)
0207 {
0208 #ifdef VECGEOM_INPLACE_TRANSFORMATIONS
0209 fTransformation = *transform;
0210 #else
0211 fTransformation = transform;
0212 #endif
0213 }
0214
0215
0216 void set_label(char const *label)
0217 {
0218 if (label_) delete label_;
0219 label_ = new std::string(label);
0220 }
0221
0222
0223 VECCORE_ATT_HOST_DEVICE
0224 VECGEOM_FORCE_INLINE
0225 void SetCopyNo(int copy_no) { copy_no_ = copy_no; }
0226
0227 friend std::ostream &operator<<(std::ostream &os, VPlacedVolume const &vol);
0228
0229
0230 virtual int MemorySize() const = 0;
0231
0232
0233 VECCORE_ATT_HOST_DEVICE
0234 virtual void Print(const int indent = 0) const;
0235
0236
0237 VECCORE_ATT_HOST_DEVICE
0238 virtual void PrintType() const = 0;
0239
0240
0241
0242
0243 virtual void PrintType(std::ostream &os) const = 0;
0244
0245
0246 VECCORE_ATT_HOST_DEVICE
0247 void PrintContent(const int depth = 0) const;
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 VECCORE_ATT_HOST_DEVICE
0258 virtual bool Contains(Vector3D<Precision> const &point) const = 0;
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 VECCORE_ATT_HOST_DEVICE
0271 virtual bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &localPoint) const = 0;
0272
0273
0274 VECCORE_ATT_HOST_DEVICE
0275 virtual bool UnplacedContains(Vector3D<Precision> const &localPoint) const = 0;
0276
0277
0278
0279
0280
0281 VECCORE_ATT_HOST_DEVICE
0282 virtual EnumInside Inside(Vector3D<Precision> const &point) const = 0;
0283
0284
0285
0286
0287
0288 VECCORE_ATT_HOST_DEVICE
0289 virtual Precision DistanceToIn(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0290 const Precision step_max = kInfLength) const = 0;
0291
0292
0293
0294
0295
0296 VECCORE_ATT_HOST_DEVICE
0297 virtual Precision DistanceToOut(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0298 Precision const step_max = kInfLength) const = 0;
0299
0300
0301
0302
0303
0304
0305
0306 VECCORE_ATT_HOST_DEVICE
0307 virtual Precision PlacedDistanceToOut(Vector3D<Precision> const &position, Vector3D<Precision> const &direction,
0308 Precision const step_max = kInfLength) const = 0;
0309
0310
0311
0312
0313
0314 VECCORE_ATT_HOST_DEVICE
0315 virtual Precision SafetyToIn(Vector3D<Precision> const &position) const = 0;
0316
0317
0318
0319
0320
0321 VECCORE_ATT_HOST_DEVICE
0322 virtual Precision SafetyToOut(Vector3D<Precision> const &position) const = 0;
0323
0324
0325 virtual Precision Capacity();
0326
0327
0328 VECCORE_ATT_HOST_DEVICE
0329 virtual void Extent(Vector3D<Precision> & , Vector3D<Precision> & ) const;
0330
0331
0332 VECCORE_ATT_HOST_DEVICE
0333 virtual bool Normal(Vector3D<Precision> const & , Vector3D<Precision> & ) const;
0334
0335
0336 virtual Precision SurfaceArea() const = 0;
0337
0338 public:
0339 #ifdef VECGEOM_CUDA_INTERFACE
0340 virtual size_t DeviceSizeOf() const = 0;
0341 virtual DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0342 DevicePtr<cuda::Transformation3D> const transform,
0343 DevicePtr<cuda::VPlacedVolume> const gpu_ptr) const = 0;
0344 virtual DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0345 DevicePtr<cuda::Transformation3D> const transform) const = 0;
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355 virtual void CopyManyToGpu(std::vector<VPlacedVolume const *> const &host_volumes,
0356 std::vector<DevicePtr<cuda::LogicalVolume>> const &logical_volumes,
0357 std::vector<DevicePtr<cuda::Transformation3D>> const &transforms,
0358 std::vector<DevicePtr<cuda::VPlacedVolume>> const &in_gpu_ptrs) const = 0;
0359
0360 template <typename Derived>
0361 DevicePtr<cuda::VPlacedVolume> CopyToGpuImpl(DevicePtr<cuda::LogicalVolume> const logical_volume,
0362 DevicePtr<cuda::Transformation3D> const transform,
0363 DevicePtr<cuda::VPlacedVolume> const in_gpu_ptr) const
0364 {
0365 DevicePtr<CudaType_t<Derived>> gpu_ptr(in_gpu_ptr);
0366 gpu_ptr.Construct(logical_volume, transform, nullptr, this->id(), this->GetCopyNo(), this->GetChildId());
0367 VECGEOM_DEVICE_API_CALL(GetLastError());
0368
0369
0370
0371 return DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr);
0372 }
0373 template <typename Derived>
0374 DevicePtr<cuda::VPlacedVolume> CopyToGpuImpl(DevicePtr<cuda::LogicalVolume> const logical_volume,
0375 DevicePtr<cuda::Transformation3D> const transform) const
0376 {
0377 DevicePtr<CudaType_t<Derived>> gpu_ptr;
0378 gpu_ptr.Allocate();
0379 return this->CopyToGpuImpl<Derived>(logical_volume, transform, DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr));
0380 }
0381
0382 #endif
0383
0384 #ifndef VECCORE_CUDA
0385
0386 virtual VPlacedVolume const *ConvertToUnspecialized() const = 0;
0387 #ifdef VECGEOM_ROOT
0388
0389 virtual TGeoShape const *ConvertToRoot() const = 0;
0390 #endif
0391 #ifdef VECGEOM_GEANT4
0392
0393 virtual G4VSolid const *ConvertToGeant4() const
0394 {
0395 throw std::runtime_error("ConvertToGeant4() not implemented for this shape type.");
0396 }
0397 #endif
0398 #endif
0399 };
0400 }
0401 }
0402
0403 #ifdef VECCORE_CUDA
0404
0405
0406
0407
0408 #define VECGEOM_DEVICE_INST_PLACED_VOLUME(PlacedVol) \
0409 namespace cxx { \
0410 template size_t DevicePtr<cuda::PlacedVol>::SizeOf(); \
0411 template void DevicePtr<cuda::PlacedVol>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0412 DevicePtr<cuda::Transformation3D> const transform, \
0413 const unsigned int id, const int copy_no, \
0414 const int child_id) const; \
0415 template void ConstructManyOnGpu<cuda::PlacedVol>( \
0416 std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs, \
0417 DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo, \
0418 decltype(std::declval<VPlacedVolume>().id()) const *ids, \
0419 decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos, \
0420 decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds); \
0421 }
0422
0423
0424
0425
0426 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol, Extra) \
0427 namespace cxx { \
0428 template size_t DevicePtr<cuda::PlacedVol, Extra>::SizeOf(); \
0429 template void DevicePtr<cuda::PlacedVol, Extra>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0430 DevicePtr<cuda::Transformation3D> const transform, \
0431 const unsigned int id, const int copy_no, \
0432 const int child_id) const; \
0433 template void ConstructManyOnGpu<cuda::PlacedVol, Extra>( \
0434 std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs, \
0435 DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo, \
0436 decltype(std::declval<VPlacedVolume>().id()) const *ids, \
0437 decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos, \
0438 decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds); \
0439 }
0440
0441 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC(PlacedVol) VECGEOM_DEVICE_INST_PLACED_VOLUME(PlacedVol)
0442
0443 #if defined(VECGEOM_NO_SPECIALIZATION) || !defined(VECGEOM_CUDA_VOLUME_SPECIALIZATION)
0444
0445 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, radii) \
0446 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kGeneric>)
0447
0448 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALLSPEC(PlacedVol) \
0449 VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kGeneric)
0450
0451 #else
0452
0453 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, radii) \
0454 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kGeneric>) \
0455 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kFalse>) \
0456 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kTrue>) \
0457 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL(PlacedVol<radii, Polyhedron::EPhiCutout::kLarge>)
0458
0459 #define VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALLSPEC(PlacedVol) \
0460 VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kGeneric) \
0461 VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kFalse) \
0462 VECGEOM_DEVICE_INST_PLACED_POLYHEDRON_ALL_CUTOUT(PlacedVol, Polyhedron::EInnerRadii::kTrue)
0463
0464 #endif
0465
0466 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_3(PlacedVol, Type) \
0467 namespace cxx { \
0468 template size_t DevicePtr<cuda::PlacedVol<cuda::Type>>::SizeOf(); \
0469 template void DevicePtr<cuda::PlacedVol<cuda::Type>>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0470 DevicePtr<cuda::Transformation3D> const transform, \
0471 const unsigned int id, const int copy_no, \
0472 const int child_id) const; \
0473 template void ConstructManyOnGpu<cuda::PlacedVol<cuda::Type>>( \
0474 std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs, \
0475 DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo, \
0476 decltype(std::declval<VPlacedVolume>().id()) const *ids, \
0477 decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos, \
0478 decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds); \
0479 }
0480
0481 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_3(PlacedVol, Type) \
0482 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_3(PlacedVol, Type)
0483
0484
0485 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, radii, phi) \
0486 namespace cxx { \
0487 template size_t DevicePtr<cuda::PlacedVol<radii, phi>>::SizeOf(); \
0488 template void DevicePtr<cuda::PlacedVol<radii, phi>>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0489 DevicePtr<cuda::Transformation3D> const transform, \
0490 const unsigned int id, const int copy_no, \
0491 const int child_id) const; \
0492 template void ConstructManyOnGpu<cuda::PlacedVol<radii, phi>>( \
0493 std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs, \
0494 DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo, \
0495 decltype(std::declval<VPlacedVolume>().id()) const *ids, \
0496 decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos, \
0497 decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds); \
0498 }
0499
0500 #if defined(VECGEOM_NO_SPECIALIZATION) || !defined(VECGEOM_CUDA_VOLUME_SPECIALIZATION)
0501
0502 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_4(PlacedVol) \
0503 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kGeneric, \
0504 Polyhedron::EPhiCutout::kGeneric)
0505
0506 #else
0507
0508 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, phi) \
0509 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kFalse, phi) \
0510 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kGeneric, phi) \
0511 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_4(PlacedVol, Polyhedron::EInnerRadii::kTrue, phi)
0512
0513 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_4(PlacedVol) \
0514 VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kFalse) \
0515 VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kGeneric) \
0516 VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kTrue) \
0517 VECGEOM_DEVICE_INST_PLACED_VOLUME_ALL_RADII_4(PlacedVol, Polyhedron::EPhiCutout::kLarge)
0518
0519 #endif
0520
0521 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_BOOLEAN(PlacedVol) \
0522 namespace cxx { \
0523 template size_t DevicePtr<cuda::PlacedVol>::SizeOf(); \
0524 template void DevicePtr<cuda::PlacedVol>::Construct(DevicePtr<cuda::LogicalVolume> const logical_volume, \
0525 DevicePtr<cuda::Transformation3D> const transform, \
0526 const unsigned int id, const int copy_no, \
0527 const int child_id) const; \
0528 template void ConstructManyOnGpu<cuda::PlacedVol>( \
0529 std::size_t nElement, DevicePtr<cuda::VPlacedVolume> const *gpu_ptrs, \
0530 DevicePtr<cuda::LogicalVolume> const *logical, DevicePtr<cuda::Transformation3D> const *trafo, \
0531 decltype(std::declval<VPlacedVolume>().id()) const *ids, \
0532 decltype(std::declval<VPlacedVolume>().GetCopyNo()) const *copyNos, \
0533 decltype(std::declval<VPlacedVolume>().GetChildId()) const *childIds); \
0534 }
0535
0536 #define VECGEOM_DEVICE_INST_PLACED_VOLUME_ALLSPEC_BOOLEAN(PlacedVol, Op) \
0537 VECGEOM_DEVICE_INST_PLACED_VOLUME_IMPL_BOOLEAN(PlacedVol<Op>)
0538
0539 #endif
0540
0541 #endif