Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-29 09:13:52

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file geocel/detail/GeantVolumeInstanceMapper.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <unordered_map>
0010 #include <vector>
0011 
0012 #include "corecel/Config.hh"
0013 
0014 #include "geocel/Types.hh"
0015 
0016 class G4LogicalVolume;
0017 class G4VPhysicalVolume;
0018 
0019 namespace celeritas
0020 {
0021 namespace detail
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Map between Geant4 PV+copy and Celeritas VolumeInstanceId.
0026  *
0027  * This uses a Geant4 world to define a set of \c VolumeInstanceId values. The
0028  * world will always have \c VolumeInstanceId{0}, and further instance IDs are
0029  * ordered depth-first.
0030  *
0031  * The behavior of this class can be surprising for some Geant4 volume types
0032  * (replica and parameterised) which have internal thread-local state: their
0033  * "copy number" reflects transformations applied to them.
0034  * When querying G4PV*, the PV's state will be incorporated into the resulting
0035  * VI id. When converting a volume instance to a G4PV pointer, the G4PV will be
0036  * updated locally so that its transformation and copy number reflect the
0037  * requested volume instance.
0038  */
0039 class GeantVolumeInstanceMapper
0040 {
0041   public:
0042     //!@{
0043     //! \name Type aliases
0044     using G4LV = G4LogicalVolume;
0045     using G4PV = G4VPhysicalVolume;
0046     using size_type = VolumeInstanceId::size_type;
0047     //!@}
0048 
0049   public:
0050     //! Allow empty construction
0051     GeantVolumeInstanceMapper() = default;
0052 
0053     // Construct from world volume
0054     explicit GeantVolumeInstanceMapper(G4PV const& world);
0055 
0056     //! Number of volume instances
0057     size_type size() const { return g4pv_.size(); }
0058 
0059     // Get the volume instance using the pv and its current state
0060     VolumeInstanceId geant_to_id(G4PV const&) const;
0061 
0062     // Get the volume instance *without* checking replica state
0063     VolumeInstanceId geant_to_id(G4PV const&, int copy_no) const;
0064 
0065     // Return and (if replica) update the volume from an instance ID.
0066     G4PV const& id_to_geant(VolumeInstanceId) const;
0067 
0068     // Get the logical volume from an instance ID (no mutate required)
0069     G4LV const& logical_volume(VolumeInstanceId vi_id) const;
0070 
0071   private:
0072     //// DATA ////
0073 
0074     // Map volume (without copy number) to starting VolumeInstanceId
0075     std::unordered_map<G4PV const*, VolumeInstanceId> base_vi_;
0076     // Geant4 volumes for each VI ID
0077     std::vector<G4PV const*> g4pv_;
0078 
0079     //// HELPER FUNCTIONS ////
0080 
0081     void update_replica(G4PV&, VolumeInstanceId) const;
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 #if !CELERITAS_USE_GEANT4 && !defined(__DOXYGEN__)
0086 inline VolumeInstanceId GeantVolumeInstanceMapper::geant_to_id(
0087     G4PV const&) const
0088 {
0089     CELER_ASSERT_UNREACHABLE();
0090 }
0091 inline VolumeInstanceId GeantVolumeInstanceMapper::geant_to_id(G4PV const&,
0092                                                                int) const
0093 {
0094     CELER_ASSERT_UNREACHABLE();
0095 }
0096 inline auto GeantVolumeInstanceMapper::id_to_geant(VolumeInstanceId) const
0097     -> G4PV const&
0098 {
0099     CELER_ASSERT_UNREACHABLE();
0100 }
0101 inline auto GeantVolumeInstanceMapper::logical_volume(VolumeInstanceId) const
0102     -> G4LV const&
0103 {
0104     CELER_ASSERT_UNREACHABLE();
0105 }
0106 #endif
0107 
0108 //---------------------------------------------------------------------------//
0109 }  // namespace detail
0110 }  // namespace celeritas