Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef UNPLACEDBOOLEANVOLUME_H_
0002 #define UNPLACEDBOOLEANVOLUME_H_
0003 
0004 #include "VecGeom/base/Cuda.h"
0005 #include "VecGeom/base/Global.h"
0006 #include "VecGeom/base/AlignedBase.h"
0007 #include "VecGeom/base/Vector3D.h"
0008 #include "VecGeom/volumes/UnplacedVolume.h"
0009 #include "VecGeom/volumes/PlacedVolume.h"
0010 #include "VecGeom/volumes/BooleanStruct.h"
0011 #include "VecGeom/volumes/kernel/BooleanImplementation.h"
0012 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0013 #ifndef VECCORE_CUDA
0014 #include "VecGeom/volumes/UnplacedMultiUnion.h"
0015 #endif
0016 
0017 #include <string>
0018 
0019 namespace vecgeom {
0020 
0021 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(class, UnplacedBooleanVolume, BooleanOperation, Arg1);
0022 
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 
0025 #ifndef VECCORE_CUDA
0026 namespace BooleanHelper {
0027 
0028 VECCORE_ATT_HOST_DEVICE
0029 BooleanStruct const *GetBooleanStruct(VUnplacedVolume const *unplaced);
0030 
0031 VECCORE_ATT_HOST_DEVICE
0032 size_t CountBooleanNodes(VUnplacedVolume const *unplaced, size_t &nunion, size_t &nintersection, size_t &nsubtraction);
0033 
0034 UnplacedMultiUnion *Flatten(VUnplacedVolume const *unplaced, size_t min_unions = 3,
0035                             Transformation3D const *trbase = nullptr, UnplacedMultiUnion *munion = nullptr);
0036 } // namespace BooleanHelper
0037 #endif
0038 
0039 /**
0040  * A class representing a simple UNPLACED boolean volume A-B
0041  * It takes two template arguments:
0042  * 1.: the mother (or left) volume A in unplaced form
0043  * 2.: the (or right) volume B in placed form, acting on A with a boolean operation;
0044  * the placement is with respect to the left volume
0045  *
0046  *
0047  *
0048  * will be a boolean solid where two boxes are subtracted
0049  * and B is only translated (not rotated) with respect to A
0050  *
0051  */
0052 template <BooleanOperation Op>
0053 class UnplacedBooleanVolume : public LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>, public AlignedBase {
0054 
0055 public:
0056   BooleanStruct fBoolean;
0057   using LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>::fGlobalConvexity;
0058 
0059   // the constructor
0060   VECCORE_ATT_HOST_DEVICE
0061   UnplacedBooleanVolume(BooleanOperation op, VPlacedVolume const *left, VPlacedVolume const *right)
0062       : fBoolean(op, left, right)
0063   {
0064     fGlobalConvexity = false;
0065     VUnplacedVolume::ComputeBBox();
0066 #ifndef VECCORE_CUDA
0067     if (fBoolean.fLeftVolume->IsAssembly() || fBoolean.fRightVolume->IsAssembly()) {
0068       throw std::runtime_error("Trying to make boolean out of assembly which is not supported\n");
0069     }
0070 #endif
0071   }
0072 
0073   virtual int MemorySize() const override { return sizeof(*this); }
0074 
0075 #ifdef VECGEOM_CUDA_INTERFACE
0076   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedBooleanVolume<Op>>::SizeOf(); }
0077   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0078   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0079 #endif
0080 
0081   VECCORE_ATT_HOST_DEVICE
0082   VECGEOM_FORCE_INLINE
0083   BooleanOperation GetOp() const { return fBoolean.fOp; }
0084 
0085   VECCORE_ATT_HOST_DEVICE
0086   BooleanStruct const &GetStruct() const { return fBoolean; }
0087 
0088   VECCORE_ATT_HOST_DEVICE
0089   bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0090 
0091   Precision Capacity() const override
0092   {
0093     if (fBoolean.fCapacity < 0.) {
0094       fBoolean.fCapacity = VUnplacedVolume::EstimateCapacity(1000000);
0095     }
0096     return fBoolean.fCapacity;
0097   }
0098 
0099   Precision SurfaceArea() const override
0100   {
0101     if (fBoolean.fSurfaceArea < 0.) {
0102       fBoolean.fSurfaceArea = VUnplacedVolume::EstimateSurfaceArea(1000000);
0103     }
0104     return fBoolean.fSurfaceArea;
0105   }
0106 
0107   VECCORE_ATT_HOST_DEVICE
0108   void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0109 
0110   Vector3D<Precision> SamplePointOnSurface() const override;
0111 
0112   std::string GetEntityType() const { return "BooleanVolume"; }
0113 
0114   VECCORE_ATT_HOST_DEVICE
0115   virtual void Print() const override {
0116 #ifndef VECCORE_CUDA
0117       auto op = this->GetOp();
0118       const char* opname = (op == kUnion ? "Union"
0119              : (op == kIntersection ? "Intersection" : "Subtraction"));
0120       printf("UnplacedBooleanVol<%s>{fLeft=[%i]<%s>, fRight=[%i]<%s>}", opname,
0121           this->GetLeft()->id(), this->GetLeft()->GetName(),
0122           this->GetRight()->id(), this->GetRight()->GetName());
0123 #else
0124       printf("UnplacedBooleanVol<%i>{fLeft=[%i], fRight=[%i]}",
0125           this->GetOp(), this->GetLeft()->id(), this->GetRight()->id());
0126 #endif
0127       printf("\nfLeft:  [%i] ", this->GetLeft()->id());
0128       this->GetLeft()->GetUnplacedVolume()->Print();
0129       printf("\nfRight: [%i] ", this->GetRight()->id());
0130       this->GetRight()->GetUnplacedVolume()->Print();
0131       printf("\n");
0132   }
0133 
0134   virtual void Print(std::ostream& os) const override {
0135 #ifndef VECCORE_CUDA
0136       auto op = this->GetOp();
0137       os << "UnplacedBooleanVol<"<< (op == kUnion ? "Union" 
0138                          : (op == kIntersection ? "Intersection" : "Subtraction"))
0139          <<">{fLeft=<"<< this->GetLeft()->id()
0140          << ">, fRight=<"<< this->GetRight()->id() <<">}\n";
0141 #endif
0142       os << "fLeft:  [" << this->GetLeft()->id() <<"] ";
0143       this->GetLeft()->GetUnplacedVolume()->Print(os);
0144       os << "fRight: [" << this->GetRight()->id() <<"] ";
0145       this->GetRight()->GetUnplacedVolume()->Print(os);
0146       os <<"\n";
0147   }
0148 
0149   template <TranslationCode transCodeT, RotationCode rotCodeT>
0150   VECCORE_ATT_DEVICE
0151   static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0152 #ifdef VECCORE_CUDA
0153                                const int id, const int copy_no, const int child_id,
0154 #endif
0155                                VPlacedVolume *const placement = NULL);
0156 
0157   VECCORE_ATT_HOST_DEVICE
0158   VPlacedVolume const *GetLeft() const { return fBoolean.fLeftVolume; }
0159   VECCORE_ATT_HOST_DEVICE
0160   VPlacedVolume const *GetRight() const { return fBoolean.fRightVolume; }
0161 
0162 #ifndef VECCORE_CUDA
0163   /** @brief Count number of Boolean nodes of different types under this Boolean volume */
0164   VECCORE_ATT_HOST_DEVICE
0165   size_t CountNodes(size_t &nunion, size_t &nintersection, size_t &nsubtraction) const
0166   {
0167     return BooleanHelper::CountBooleanNodes(this, nunion, nintersection, nsubtraction);
0168   }
0169 
0170   /** @brief Flatten the Boolean node structure and create multiple union volumes if possible */
0171   UnplacedMultiUnion *Flatten(size_t min_unions = 1, Transformation3D const *trbase = nullptr,
0172                               UnplacedMultiUnion *munion = nullptr)
0173   {
0174     return BooleanHelper::Flatten(this, min_unions, trbase, munion);
0175   }
0176 #endif
0177 
0178 private:
0179   VECCORE_ATT_DEVICE
0180   virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0181                                            Transformation3D const *const transformation,
0182                                            const TranslationCode trans_code, const RotationCode rot_code,
0183 #ifdef VECCORE_CUDA
0184                                            const int id, const int copy_no, const int child_id,
0185 #endif
0186                                            VPlacedVolume *const placement = NULL) const override;
0187 
0188   void SetLeft(VPlacedVolume const *pvol) { fBoolean.fLeftVolume = pvol; }
0189   void SetRight(VPlacedVolume const *pvol) { fBoolean.fRightVolume = pvol; }
0190 
0191   friend class GeoManager;
0192 }; // End class
0193 
0194 } // namespace VECGEOM_IMPL_NAMESPACE
0195 
0196 } // namespace vecgeom
0197 
0198 #endif /* UNPLACEDBOOLEANVOLUME_H_ */