File indexing completed on 2026-09-18 09:33:05
0001 #pragma once
0002
0003 #include "VecGeom/base/Cuda.h"
0004 #include "VecGeom/base/Global.h"
0005 #include "VecGeom/base/SOA3D.h"
0006
0007 #include <algorithm>
0008 #include "VecGeom/base/Assert.h"
0009
0010 #ifdef VECGEOM_DISTANCE_DEBUG
0011 #include "VecGeom/volumes/utilities/ResultComparator.h"
0012 #endif
0013
0014 namespace vecgeom {
0015
0016
0017 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, SpecializedVolImplHelper, typename);
0018
0019
0020
0021 inline namespace VECGEOM_IMPL_NAMESPACE {
0022
0023 template <class Specialization>
0024 class SpecializedVolImplHelper : public Specialization::PlacedShape_t {
0025
0026 using PlacedShape_t = typename Specialization::PlacedShape_t;
0027 using UnplacedVolume_t = typename Specialization::UnplacedVolume_t;
0028
0029 public:
0030 #ifndef VECCORE_CUDA
0031 SpecializedVolImplHelper(VPlacedVolume const *other)
0032 : PlacedShape_t(other->GetName(), other->GetLogicalVolume(), other->GetTransformation())
0033 {
0034 }
0035
0036 SpecializedVolImplHelper(char const *const label, LogicalVolume const *const logical_volume,
0037 Transformation3D const *const transformation)
0038 : PlacedShape_t(label, logical_volume, transformation)
0039 {
0040 }
0041
0042 SpecializedVolImplHelper(char const *const label, LogicalVolume *const logical_volume,
0043 Transformation3D const *const transformation)
0044 : PlacedShape_t(label, logical_volume, transformation)
0045 {
0046 }
0047
0048 SpecializedVolImplHelper(LogicalVolume const *const logical_volume, Transformation3D const *const transformation)
0049 : SpecializedVolImplHelper("", logical_volume, transformation)
0050 {
0051 }
0052
0053
0054
0055 template <typename... ArgTypes>
0056 SpecializedVolImplHelper(char const *const label, ArgTypes... params)
0057 : SpecializedVolImplHelper(label, new LogicalVolume(new UnplacedVolume_t(params...)),
0058 &Transformation3D::kIdentity)
0059 {
0060 }
0061
0062 #else
0063 VECCORE_ATT_DEVICE SpecializedVolImplHelper(LogicalVolume const *const logical_volume,
0064 Transformation3D const *const transformation, const unsigned int id,
0065 const int copy_no, const int child_id)
0066 : PlacedShape_t(logical_volume, transformation, id, copy_no, child_id)
0067 {
0068 }
0069 #endif
0070 using PlacedShape_t::Contains;
0071 using PlacedShape_t::DistanceToIn;
0072 using PlacedShape_t::DistanceToOut;
0073 using PlacedShape_t::Inside;
0074 using PlacedShape_t::PlacedShape_t;
0075 using PlacedShape_t::SafetyToIn;
0076 using PlacedShape_t::SafetyToOut;
0077 using PlacedShape_t::UnplacedContains;
0078
0079 virtual int MemorySize() const override { return sizeof(*this); }
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 virtual EnumInside Inside(Vector3D<Precision> const &point) const override
0083 {
0084 Inside_t output;
0085 Transformation3D const *tr = this->GetTransformation();
0086 Specialization::Inside(*this->GetUnplacedStruct(), tr->Transform<Precision>(point), output);
0087 return (EnumInside)output;
0088 }
0089
0090 VECCORE_ATT_HOST_DEVICE
0091 virtual bool Contains(Vector3D<Precision> const &point) const override
0092 {
0093 bool output(false);
0094 Transformation3D const *tr = this->GetTransformation();
0095 Vector3D<Precision> lp = tr->Transform<Precision>(point);
0096 Specialization::Contains(*this->GetUnplacedStruct(), lp, output);
0097 return output;
0098 }
0099
0100 VECCORE_ATT_HOST_DEVICE
0101 virtual bool Contains(Vector3D<Precision> const &point, Vector3D<Precision> &localPoint) const override
0102 {
0103 bool output(false);
0104 Transformation3D const *tr = this->GetTransformation();
0105 localPoint = tr->Transform<Precision>(point);
0106 Specialization::Contains(*this->GetUnplacedStruct(), localPoint, output);
0107 #ifdef VECGEOM_DISTANCE_DEBUG
0108 DistanceComparator::CompareUnplacedContains(this, output, localPoint);
0109 #endif
0110 return output;
0111 }
0112
0113 VECCORE_ATT_HOST_DEVICE
0114 virtual Precision DistanceToIn(Vector3D<Precision> const &point, Vector3D<Precision> const &direction,
0115 const Precision stepMax = kInfLength) const override
0116 {
0117 VECGEOM_ASSERT(direction.IsNormalized() && " direction not normalized in call to DistanceToIn ");
0118 Precision output(kInfLength);
0119 Transformation3D const *tr = this->GetTransformation();
0120 Specialization::DistanceToIn(*this->GetUnplacedStruct(), tr->Transform(point), tr->TransformDirection(direction),
0121 stepMax, output);
0122 #ifdef VECGEOM_DISTANCE_DEBUG
0123 DistanceComparator::CompareDistanceToIn(this, output, point, direction, stepMax);
0124 #endif
0125 return output;
0126 }
0127
0128 VECCORE_ATT_HOST_DEVICE
0129 virtual Precision PlacedDistanceToOut(Vector3D<Precision> const &point, Vector3D<Precision> const &direction,
0130 const Precision stepMax = kInfLength) const override
0131 {
0132 VECGEOM_ASSERT(direction.IsNormalized() && " direction not normalized in call to PlacedDistanceToOut ");
0133 Transformation3D const *tr = this->GetTransformation();
0134 Precision output(-1.);
0135 Specialization::template DistanceToOut<>(*this->GetUnplacedStruct(), tr->Transform(point),
0136 tr->TransformDirection(direction), stepMax, output);
0137
0138 #ifdef VECGEOM_DISTANCE_DEBUG
0139 DistanceComparator::CompareDistanceToOut(this, output, this->GetTransformation()->Transform(point),
0140 this->GetTransformation()->TransformDirection(direction), stepMax);
0141 #endif
0142 return output;
0143 }
0144
0145 VECCORE_ATT_HOST_DEVICE
0146 virtual Precision SafetyToIn(Vector3D<Precision> const &point) const override
0147 {
0148 Precision output(kInfLength);
0149 Transformation3D const *tr = this->GetTransformation();
0150 Specialization::SafetyToIn(*this->GetUnplacedStruct(), tr->Transform(point), output);
0151 return output;
0152 }
0153
0154 #ifdef VECGEOM_CUDA_INTERFACE
0155 using ThisClass_t = SpecializedVolImplHelper<Specialization>;
0156 virtual size_t DeviceSizeOf() const override { return DevicePtr<CudaType_t<ThisClass_t>>::SizeOf(); }
0157
0158 DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0159 DevicePtr<cuda::Transformation3D> const transform,
0160 DevicePtr<cuda::VPlacedVolume> const in_gpu_ptr) const override
0161 {
0162 DevicePtr<CudaType_t<ThisClass_t>> gpu_ptr(in_gpu_ptr);
0163 gpu_ptr.Construct(logical_volume, transform, this->id(), this->GetCopyNo(), this->GetChildId());
0164 VECGEOM_DEVICE_API_CALL(GetLastError());
0165
0166
0167
0168 return DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr);
0169 }
0170
0171 DevicePtr<cuda::VPlacedVolume> CopyToGpu(DevicePtr<cuda::LogicalVolume> const logical_volume,
0172 DevicePtr<cuda::Transformation3D> const transform) const override
0173 {
0174 DevicePtr<CudaType_t<ThisClass_t>> gpu_ptr;
0175 gpu_ptr.Allocate();
0176 return CopyToGpu(logical_volume, transform, DevicePtr<cuda::VPlacedVolume>((void *)gpu_ptr));
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 void CopyManyToGpu(std::vector<VPlacedVolume const *> const &host_volumes,
0189 std::vector<DevicePtr<cuda::LogicalVolume>> const &logical_volumes,
0190 std::vector<DevicePtr<cuda::Transformation3D>> const &transforms,
0191 std::vector<DevicePtr<cuda::VPlacedVolume>> const &in_gpu_ptrs) const override
0192 {
0193 VECGEOM_ASSERT(host_volumes.size() == logical_volumes.size());
0194 VECGEOM_ASSERT(host_volumes.size() == transforms.size());
0195 VECGEOM_ASSERT(host_volumes.size() == in_gpu_ptrs.size());
0196
0197 std::vector<decltype(std::declval<ThisClass_t>().id())> ids;
0198 std::vector<decltype(std::declval<ThisClass_t>().GetCopyNo())> copyNos;
0199 std::vector<decltype(std::declval<ThisClass_t>().GetChildId())> childIds;
0200 for (auto placedVol : host_volumes) {
0201 ids.push_back(placedVol->id());
0202 copyNos.push_back(placedVol->GetCopyNo());
0203 childIds.push_back(placedVol->GetChildId());
0204 }
0205
0206 ConstructManyOnGpu<CudaType_t<ThisClass_t>>(in_gpu_ptrs.size(), in_gpu_ptrs.data(), logical_volumes.data(),
0207 transforms.data(), ids.data(), copyNos.data(), childIds.data());
0208 }
0209
0210 #endif
0211
0212 };
0213
0214 }
0215 }