Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-07 10:01:43

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 celeritas/optical/surface/VolumeSurfaceSelector.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "geocel/SurfaceData.hh"
0012 #include "geocel/VolumeSurfaceView.hh"
0013 #include "celeritas/geo/GeoTrackView.hh"
0014 
0015 namespace celeritas
0016 {
0017 namespace optical
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Retrieve the surface ID between two volume instances.
0022  *
0023  * Given (old, new) physical volumes P0, P1 corresponding to logical volumes
0024  * L0, L1
0025  * - Ordered (P0, P1) interface surface
0026  * - Boundary surface of L0
0027  * - Boundary surface of L1
0028  *
0029  * This behavior differs from Geant4's order of precedence, which considers
0030  * if there's a mother-daughter relation between L0 and L1 when both have
0031  * a boundary surface:
0032  * - Ordered (P0, P1) interface surface
0033  * - Boundary surface of L1 if it's the daughter of L0
0034  * - Boundary surface of L0
0035  * - Boundary surface of L1
0036  *
0037  * When multiple layers are implemented, this selector will be responsible
0038  * for determining the ordering of the layers between the volumes,
0039  * including both interface and boundary surfaces.
0040  */
0041 class VolumeSurfaceSelector
0042 {
0043   public:
0044     // Construct with pre-volume IDs
0045     inline CELER_FUNCTION
0046     VolumeSurfaceSelector(NativeCRef<SurfaceParamsData> const& params,
0047                           VolumeId pre_volume,
0048                           VolumeInstanceId pre_volume_inst);
0049 
0050     // Convenience constructor to use IDs from geometry
0051     inline CELER_FUNCTION
0052     VolumeSurfaceSelector(NativeCRef<SurfaceParamsData> const& params,
0053                           GeoTrackView const& geo);
0054 
0055     // Select surface based on post-volume IDs
0056     inline CELER_FUNCTION SurfaceId
0057     operator()(VolumeId post_volume, VolumeInstanceId post_volume_inst) const;
0058 
0059     // Convenience function to use IDs from geometry
0060     inline CELER_FUNCTION SurfaceId operator()(GeoTrackView const&) const;
0061 
0062   private:
0063     NativeCRef<SurfaceParamsData> const& params_;
0064     VolumeId pre_volume_;
0065     VolumeInstanceId pre_volume_inst_;
0066 };
0067 
0068 //---------------------------------------------------------------------------//
0069 // INLINE DEFINITIONS
0070 //---------------------------------------------------------------------------//
0071 /*!
0072  * Construct with pre-volume IDs.
0073  */
0074 CELER_FUNCTION VolumeSurfaceSelector::VolumeSurfaceSelector(
0075     NativeCRef<SurfaceParamsData> const& params,
0076     VolumeId pre_volume,
0077     VolumeInstanceId pre_volume_inst)
0078     : params_(params)
0079     , pre_volume_(pre_volume)
0080     , pre_volume_inst_(pre_volume_inst)
0081 {
0082     CELER_EXPECT(pre_volume_ < params_.volume_surfaces.size());
0083     CELER_EXPECT(pre_volume_inst_);
0084 }
0085 
0086 //---------------------------------------------------------------------------//
0087 /*!
0088  * Convenience constructor to use IDs from geometry.
0089  */
0090 CELER_FUNCTION VolumeSurfaceSelector::VolumeSurfaceSelector(
0091     NativeCRef<SurfaceParamsData> const& params, GeoTrackView const& geo)
0092     : VolumeSurfaceSelector(params, geo.volume_id(), geo.volume_instance_id())
0093 {
0094     CELER_EXPECT(!geo.is_outside());
0095 }
0096 
0097 //---------------------------------------------------------------------------//
0098 /*!
0099  * Select surface based on post-volume IDs.
0100  *
0101  * Returns an invalid \c SurfaceId if no surface data exists for the volumes.
0102  */
0103 CELER_FUNCTION SurfaceId VolumeSurfaceSelector::operator()(
0104     VolumeId post_volume, VolumeInstanceId post_volume_inst) const
0105 {
0106     VolumeSurfaceView pre_surface{params_, pre_volume_};
0107 
0108     if (auto surface_id
0109         = pre_surface.find_interface(pre_volume_inst_, post_volume_inst))
0110     {
0111         return surface_id;
0112     }
0113 
0114     if (auto surface_id = pre_surface.boundary_id())
0115     {
0116         return surface_id;
0117     }
0118 
0119     return VolumeSurfaceView{params_, post_volume}.boundary_id();
0120 }
0121 
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Convenience function to use IDs from geometry.
0125  */
0126 CELER_FUNCTION SurfaceId
0127 VolumeSurfaceSelector::operator()(GeoTrackView const& geo) const
0128 {
0129     if (geo.is_outside())
0130         return SurfaceId{};
0131 
0132     return (*this)(geo.volume_id(), geo.volume_instance_id());
0133 }
0134 
0135 //---------------------------------------------------------------------------//
0136 }  // namespace optical
0137 }  // namespace celeritas