Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:48

0001 // This file is part of VecGeom and is distributed under the
0002 // conditions in the file LICENSE.txt in the top directory.
0003 // For the full list of authors see CONTRIBUTORS.txt and `git log`.
0004 
0005 /// \brief Volume tree and hierarchical elements data structures
0006 /// \file VolumeTree.h
0007 /// \author Andrei Gheata (CERN)
0008 
0009 #ifndef VECGEOM_VOLUMES_VOLUMETREE_H_
0010 #define VECGEOM_VOLUMES_VOLUMETREE_H_
0011 
0012 #include "VecGeom/management/DeviceGlobals.h"
0013 
0014 namespace vecgeom {
0015 
0016 struct PlacedId;
0017 
0018 /// @brief Structure representing a logical volume
0019 struct LogicalId {
0020   int fId{-1};                                ///< Logical volume id
0021   int fNplaced{0};                            ///< Number of children placed volumes
0022   ESolidType fSolidType{ESolidType::nosolid}; ///< Solid type (see Global.h)
0023   PlacedId *fChildren{nullptr};               ///< Array of children placed volumes
0024 
0025   LogicalId() = default;
0026   LogicalId(int ivol, ESolidType type, int nchildren, PlacedId *nodes) { Set(ivol, type, nchildren, nodes); }
0027 
0028   bool operator==(LogicalId const &other) const
0029   {
0030     if (fId != other.fId) return false;
0031     if (fNplaced != other.fNplaced) return false;
0032     if (fChildren != other.fChildren) return false;
0033     return true;
0034   }
0035 
0036   bool operator!=(LogicalId const &other) const { return !operator==(other); }
0037 
0038   void Set(int ivol, ESolidType type, int nchildren, PlacedId *nodes)
0039   {
0040     fId        = ivol;
0041     fNplaced   = nchildren;
0042     fSolidType = type;
0043     fChildren  = nodes;
0044   }
0045 
0046   VECGEOM_FORCE_INLINE
0047   PlacedId const &GetPlacedId(int ichild);
0048 };
0049 
0050 /// @brief Structure representing a placed volume
0051 struct PlacedId {
0052   int fId{-1};       ///< Placed volume id
0053   int fCopyNo{-1};   ///< Copy number
0054   int fChildId{-1};  ///< Index in the parent volume list
0055   LogicalId fVolume; ///< Logical volume
0056 
0057   PlacedId() = default;
0058   PlacedId(int id, int icopy, int ichild, LogicalId const &lvol) { Set(id, icopy, ichild, lvol); }
0059   void Set(int id, int icopy, int ichild, LogicalId const &lvol)
0060   {
0061     fId      = id;
0062     fCopyNo  = icopy;
0063     fChildId = ichild;
0064     fVolume  = lvol;
0065   }
0066 
0067   bool operator==(PlacedId const &other) const
0068   {
0069     if (fId != other.fId) return false;
0070     if (fCopyNo != other.fCopyNo) return false;
0071     if (fChildId != other.fChildId) return false;
0072     if (fVolume != other.fVolume) return false;
0073     return true;
0074   }
0075 
0076   bool operator!=(PlacedId const &other) const { return !operator==(other); }
0077 
0078   void Place(LogicalId &parent)
0079   {
0080     VECGEOM_VALIDATE(parent.fChildren, << "Parent volume has no children space allocated");
0081     parent.fChildren[parent.fNplaced++] = *this;
0082   }
0083 
0084   VECCORE_ATT_HOST_DEVICE
0085   void Print()
0086   {
0087     printf("PlacedId %d: copyNo = %d  childId = %d  volumeId = %d  nchildren = %d\n   children: ", fId, fCopyNo,
0088            fChildId, fVolume.fId, fVolume.fNplaced);
0089     for (auto i = 0; i < fVolume.fNplaced; ++i)
0090       printf("%d  ", fVolume.fChildren[i].fId);
0091     printf("\n");
0092   }
0093 };
0094 
0095 VECGEOM_FORCE_INLINE
0096 PlacedId const &LogicalId::GetPlacedId(int ichild) { return fChildren[ichild]; }
0097 
0098 struct VolumeTree {
0099   PlacedId fWorld;
0100   int fNlogical{0};             ///< Number of registered logical volumes
0101   int fNplaced{0};              ///< Number of registered placed volumes
0102   int fNplacedC{0};             ///< Number of placed children
0103   LogicalId *fLogical{nullptr}; ///< List of logical volumes
0104   PlacedId *fPlaced{nullptr};   ///< List of placed volumes
0105   PlacedId *fChildren{nullptr}; ///< List of placed volumes
0106   bool fValid{false};           ///< Validity
0107 
0108   VolumeTree() = default;
0109   ~VolumeTree()
0110   {
0111 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0112     // Only delete arrays on host. On device, one needs to delete globaldevicegeomdata::gVolumeTree
0113     delete[] fLogical;
0114     delete[] fPlaced;
0115     delete[] fChildren;
0116     fLogical  = nullptr;
0117     fPlaced   = nullptr;
0118     fChildren = nullptr;
0119 #endif
0120   }
0121 
0122   size_t GetSize() const
0123   {
0124     size_t sizeInBytes = sizeof(VolumeTree) + fNlogical * sizeof(LogicalId) + (fNplaced + fNplacedC) * sizeof(PlacedId);
0125     return sizeInBytes;
0126   }
0127 
0128   /// @brief Allocate the volume tree in a contiguous buffer
0129   /// @param nlogical
0130   /// @param nplaced
0131   void Allocate(int nlogical, int nplaced, int nplaced_children)
0132   {
0133     fNlogical = nlogical;
0134     fNplaced  = nplaced;
0135     fNplacedC = nplaced_children;
0136     fLogical  = new LogicalId[nlogical];
0137     fPlaced   = new PlacedId[nplaced];
0138     fChildren = new PlacedId[nplaced_children];
0139   }
0140 
0141   /// @brief Relocate the internal data
0142   /// @param shift_bytes shift of placed id children array
0143   VECCORE_ATT_HOST_DEVICE
0144   void Relocate(long shift_bytes)
0145   {
0146     auto moveAddress = [shift_bytes](PlacedId *address) {
0147       return reinterpret_cast<PlacedId *>((char *)address + shift_bytes);
0148     };
0149     if (fWorld.fVolume.fChildren) fWorld.fVolume.fChildren = moveAddress(fWorld.fVolume.fChildren);
0150     for (auto i = 0; i < fNlogical; ++i)
0151       if (fLogical[i].fChildren) fLogical[i].fChildren = moveAddress(fLogical[i].fChildren);
0152     for (auto i = 0; i < fNplaced; ++i)
0153       if (fPlaced[i].fVolume.fChildren) fPlaced[i].fVolume.fChildren = moveAddress(fPlaced[i].fVolume.fChildren);
0154     // Debug only
0155     // for (auto i = 0; i < fNplaced; ++i)
0156     //   fPlaced[i].Print();
0157   }
0158 
0159   VECCORE_ATT_HOST_DEVICE
0160   VECGEOM_FORCE_INLINE
0161   static VolumeTree &Instance()
0162   {
0163 #ifdef VECCORE_CUDA_DEVICE_COMPILATION
0164     return *globaldevicegeomdata::gVolumeTree;
0165 #else
0166     static VolumeTree gVolumeTree;
0167     return gVolumeTree;
0168 #endif
0169   }
0170 };
0171 
0172 } // namespace vecgeom
0173 #endif