Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:11:39

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/SurfacePhysicsData.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/cont/EnumArray.hh"
0011 #include "corecel/data/Collection.hh"
0012 #include "celeritas/optical/Types.hh"
0013 #include "celeritas/phys/SurfacePhysicsMapData.hh"
0014 
0015 namespace celeritas
0016 {
0017 namespace optical
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Storage for physics data of a geometric surface.
0022  *
0023  * See \c SurfacePhysicsView for documentation.
0024  *
0025  * - \c interstitial_mats indexes into \c SurfacePhysicsParamsData::opt_mat_ids
0026  * - \c local_surface_ids give \c PhysSurfaceId for models
0027  * - physical surfaces map to models is done by \c model_maps
0028  */
0029 struct SurfacePhysicsRecord
0030 {
0031     //! Indirection to a stored optical mat ID (interstitial 0 = LPId{1})
0032     ItemRange<OptMatId> interstitial_mat_ids;
0033     //! Physics surface ID from the forward-oriented local surface ID
0034     ItemMap<LocalSurfaceId, PhysSurfaceId> local_surface_ids;
0035 
0036     //! Whether data is assigned
0037     explicit CELER_FUNCTION operator bool() const
0038     {
0039         return interstitial_mat_ids.size() + 1 == local_surface_ids.size();
0040     }
0041 };
0042 
0043 //---------------------------------------------------------------------------//
0044 /*!
0045  * Scalar quantities used by optical surface physics.
0046  */
0047 struct SurfacePhysicsParamsScalars
0048 {
0049     //! ID of the default surface
0050     SurfaceId default_surface{};
0051 
0052     //! Action ID of the init-boundary action
0053     ActionId init_boundary_action{};
0054 
0055     //! Action ID of the surface stepping loop action
0056     ActionId surface_stepping_action{};
0057 
0058     //! Action ID of the post-boundary action
0059     ActionId post_boundary_action{};
0060 
0061     //! Whether data is assigned and valid
0062     explicit CELER_FUNCTION operator bool() const
0063     {
0064         return default_surface && post_boundary_action
0065                && surface_stepping_action < post_boundary_action
0066                && init_boundary_action < surface_stepping_action;
0067     }
0068 };
0069 
0070 //---------------------------------------------------------------------------//
0071 /*!
0072  * Persistent shared optical surface data
0073  */
0074 template<Ownership W, MemSpace M>
0075 struct SurfacePhysicsParamsData
0076 {
0077     //!@{
0078     //! \name Type aliases
0079     template<class T>
0080     using GeoSurfaceItems = Collection<T, W, M, SurfaceId>;
0081 
0082     using SurfaceStepModelMaps
0083         = EnumArray<SurfacePhysicsOrder, SurfacePhysicsMapData<W, M>>;
0084 
0085     template<class T>
0086     using Items = Collection<T, W, M>;
0087     //!@}
0088 
0089     //! Non-templated data
0090     SurfacePhysicsParamsScalars scalars;
0091 
0092     //! Optical surface model data
0093     GeoSurfaceItems<SurfacePhysicsRecord> surfaces;
0094     SurfaceStepModelMaps model_maps;
0095 
0096     //// BACKEND STORAGE ////
0097 
0098     Items<OptMatId> opt_mat_ids;
0099 
0100     //! Whether data is assigned
0101     explicit CELER_FUNCTION operator bool() const
0102     {
0103         return scalars && !surfaces.empty();
0104     }
0105 
0106     //! Assign from another set of data
0107     template<Ownership W2, MemSpace M2>
0108     SurfacePhysicsParamsData<W, M>& operator=(
0109         SurfacePhysicsParamsData<W2, M2> const& other)
0110     {
0111         CELER_EXPECT(other);
0112         scalars = other.scalars;
0113         surfaces = other.surfaces;
0114         opt_mat_ids = other.opt_mat_ids;
0115         for (auto step : range(SurfacePhysicsOrder::size_))
0116         {
0117             model_maps[step] = other.model_maps[step];
0118         }
0119         return *this;
0120     }
0121 };
0122 
0123 //---------------------------------------------------------------------------//
0124 /*!
0125  * Dynamic optical surface physics state data.
0126  */
0127 template<Ownership W, MemSpace M>
0128 struct SurfacePhysicsStateData
0129 {
0130     //!@{
0131     //! \name Type aliases
0132     template<class T>
0133     using StateItems = StateCollection<T, W, M>;
0134     //!@}
0135 
0136     //!@{
0137     //! \name Constant state for a single boundary crossing
0138     StateItems<SurfaceId> surface;
0139     StateItems<LocalDirection> surface_orientation;
0140     StateItems<Real3> global_normal;
0141     StateItems<OptMatId> pre_volume_material;
0142     StateItems<OptMatId> post_volume_material;
0143     //!@}
0144 
0145     //!@{
0146     //! \name Mutable state for a single boundary crossing
0147     StateItems<LocalPositionId> local_position;
0148     StateItems<LocalDirection> local_direction;
0149     StateItems<Real3> facet_normal;
0150     StateItems<ReflectivityAction> reflectivity_action;
0151     //!@}
0152 
0153     //! Whether data is assigned
0154     explicit CELER_FUNCTION operator bool() const
0155     {
0156         return !surface.empty() && surface.size() == surface_orientation.size()
0157                && surface.size() == local_position.size()
0158                && surface.size() == local_direction.size()
0159                && surface.size() == pre_volume_material.size()
0160                && surface.size() == post_volume_material.size()
0161                && surface.size() == global_normal.size()
0162                && surface.size() == facet_normal.size()
0163                && surface.size() == reflectivity_action.size();
0164     }
0165 
0166     //! State size
0167     CELER_FUNCTION size_type size() const { return surface.size(); }
0168 
0169     //! Assign from another set of data
0170     template<Ownership W2, MemSpace M2>
0171     SurfacePhysicsStateData<W, M>& operator=(
0172         SurfacePhysicsStateData<W2, M2>& other)
0173     {
0174         CELER_EXPECT(other);
0175         surface = other.surface;
0176         surface_orientation = other.surface_orientation;
0177         global_normal = other.global_normal;
0178         local_position = other.local_position;
0179         local_direction = other.local_direction;
0180         pre_volume_material = other.pre_volume_material;
0181         post_volume_material = other.post_volume_material;
0182         facet_normal = other.facet_normal;
0183         reflectivity_action = other.reflectivity_action;
0184         return *this;
0185     }
0186 };
0187 
0188 //---------------------------------------------------------------------------//
0189 /*!
0190  * Resize the state in host code.
0191  */
0192 template<MemSpace M>
0193 inline void resize(SurfacePhysicsStateData<Ownership::value, M>* state,
0194                    size_type size)
0195 {
0196     CELER_EXPECT(state);
0197     CELER_EXPECT(size > 0);
0198 
0199     resize(&state->surface, size);
0200     resize(&state->surface_orientation, size);
0201     resize(&state->global_normal, size);
0202     resize(&state->local_position, size);
0203     resize(&state->local_direction, size);
0204     resize(&state->pre_volume_material, size);
0205     resize(&state->post_volume_material, size);
0206     resize(&state->facet_normal, size);
0207     resize(&state->reflectivity_action, size);
0208 
0209     CELER_ENSURE(*state);
0210     CELER_ENSURE(state->size() == size);
0211 }
0212 
0213 //---------------------------------------------------------------------------//
0214 }  // namespace optical
0215 }  // namespace celeritas