Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:57

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