Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:07:50

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 orange/surf/LocalSurfaceVisitor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/math/Algorithms.hh"
0010 #include "orange/OrangeData.hh"
0011 
0012 #include "SurfaceTypeTraits.hh"
0013 
0014 #include "detail/AllSurfaces.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Apply a functor to a type-deleted local surface.
0021  *
0022  * An instance of this class is like \c std::visit but accepting a
0023  * \c LocalSurfaceId rather than a \c std::variant .
0024  *
0025  * Example: \code
0026  LocalSurfaceVisitor visit_surface{params_};
0027  auto sense = visit_surface(
0028     [&pos](auto const& s) { return s.calc_sense(pos); },
0029     surface_id);
0030  \endcode
0031  */
0032 class LocalSurfaceVisitor
0033 {
0034   public:
0035     //!@{
0036     //! \name Type aliases
0037     using ParamsRef = NativeCRef<OrangeParamsData>;
0038     //!@}
0039 
0040   public:
0041     // Construct from ORANGE params and surfaces redord
0042     inline CELER_FUNCTION
0043     LocalSurfaceVisitor(ParamsRef const& params,
0044                         SurfacesRecord const& local_surfaces);
0045 
0046     // Construct from ORANGE params and simple unit ID
0047     inline CELER_FUNCTION
0048     LocalSurfaceVisitor(ParamsRef const& params, SimpleUnitId unit);
0049 
0050     // Apply the function to the surface specified by the given ID
0051     template<class F>
0052     inline CELER_FUNCTION decltype(auto)
0053     operator()(F&& typed_visitor, LocalSurfaceId t);
0054 
0055   private:
0056     //// TYPES ////
0057 
0058     template<class T>
0059     using Items = Collection<T, Ownership::const_reference, MemSpace::native>;
0060 
0061     //// DATA ////
0062 
0063     ParamsRef const& params_;
0064     SurfacesRecord const& surfaces_;
0065 
0066     //// HELPER FUNCTIONS ////
0067 
0068     // Construct a surface from a data offset
0069     template<class T>
0070     inline CELER_FUNCTION T make_surface(LocalSurfaceId data_offset) const;
0071 
0072     // TODO: change surfaces record to use ItemMap, move this to Collection.hh
0073     template<class T, class U>
0074     static inline CELER_FUNCTION T get_item(Items<T> const& items,
0075                                             ItemRange<T> const& range,
0076                                             ItemId<U> item);
0077 };
0078 
0079 //---------------------------------------------------------------------------//
0080 // INLINE DEFINITIONS
0081 //---------------------------------------------------------------------------//
0082 /*!
0083  * Construct from ORANGE data ans local surfaces.
0084  *
0085  * This is meant to be called from inside a simple unit tracker.
0086  */
0087 CELER_FORCEINLINE_FUNCTION
0088 LocalSurfaceVisitor::LocalSurfaceVisitor(ParamsRef const& params,
0089                                          SurfacesRecord const& local_surfaces)
0090     : params_{params}, surfaces_{local_surfaces}
0091 {
0092 }
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Construct from ORANGE data with surfaces from a simple unit.
0097  */
0098 CELER_FORCEINLINE_FUNCTION
0099 LocalSurfaceVisitor::LocalSurfaceVisitor(ParamsRef const& params,
0100                                          SimpleUnitId unit)
0101     : LocalSurfaceVisitor{params, params.simple_units[unit].surfaces}
0102 {
0103 }
0104 
0105 #if !defined(__DOXYGEN__) || __DOXYGEN__ > 0x010908
0106 //---------------------------------------------------------------------------//
0107 /*!
0108  * Apply the function to the surface specified by the given ID.
0109  */
0110 template<class F>
0111 CELER_FUNCTION decltype(auto)
0112 LocalSurfaceVisitor::operator()(F&& func, LocalSurfaceId id)
0113 {
0114     CELER_EXPECT(id < surfaces_.size());
0115 
0116     // Apply type-deleted functor based on type
0117     return visit_surface_type(
0118         [this, &func, id](auto s_traits) {
0119             // Call the user-provided action using the reconstructed surface
0120             using S = typename decltype(s_traits)::type;
0121             return func(this->make_surface<S>(id));
0122         },
0123         this->get_item(params_.surface_types, surfaces_.types, id));
0124 }
0125 #endif
0126 
0127 //---------------------------------------------------------------------------//
0128 // PRIVATE HELPER FUNCTIONS
0129 //---------------------------------------------------------------------------//
0130 /*!
0131  * Construct a surface of a given type using the data at a specific ID.
0132  */
0133 template<class T>
0134 CELER_FUNCTION T LocalSurfaceVisitor::make_surface(LocalSurfaceId id) const
0135 {
0136     using Reals = decltype(params_.reals);
0137     using ItemIdT = typename Reals::ItemIdT;
0138     using ItemRangeT = typename Reals::ItemRangeT;
0139     ItemIdT offset
0140         = this->get_item(params_.real_ids, surfaces_.data_offsets, id);
0141     constexpr size_type size{T::StorageSpan::extent};
0142     CELER_ASSERT(offset + size <= params_.reals.size());
0143     auto storage_span = params_.reals[ItemRangeT{offset, offset + size}];
0144     // Convert to a statically sized span using the first() member template
0145     // function, then construct a surface, for LdgSpan to work correctly.
0146     return T{storage_span.template first<size>()};
0147 }
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * Get a pointer to the item offset using the given range in a given
0152  * collection.
0153  */
0154 template<class T, class U>
0155 CELER_FORCEINLINE_FUNCTION T LocalSurfaceVisitor::get_item(
0156     Items<T> const& items, ItemRange<T> const& offsets, ItemId<U> item)
0157 {
0158     CELER_EXPECT(*offsets.end() <= items.size());
0159     CELER_EXPECT(item < offsets.size());
0160     return items[offsets][item.unchecked_get()];
0161 }
0162 
0163 //---------------------------------------------------------------------------//
0164 }  // namespace celeritas