Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/orange/surf/LocalSurfaceVisitor.hh was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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/Types.hh"
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 LocalSurfaceVisitor(
0044         ParamsRef const& params, SurfacesRecord const& local_surfaces);
0045 
0046     // Construct from ORANGE params and simple unit ID
0047     inline CELER_FUNCTION LocalSurfaceVisitor(ParamsRef const& params,
0048                                               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) operator()(F&& typed_visitor,
0053                                                     LocalSurfaceId t);
0054 
0055   private:
0056     //// TYPES ////
0057 
0058     template<class T>
0059     using Items = Collection<T, Ownership::const_reference, MemSpace::native>;
0060     using Reals = Items<real_type>;
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 
0074 //---------------------------------------------------------------------------//
0075 // INLINE DEFINITIONS
0076 //---------------------------------------------------------------------------//
0077 /*!
0078  * Construct from ORANGE data and local surfaces.
0079  *
0080  * This is meant to be called from inside a simple unit tracker.
0081  */
0082 CELER_FORCEINLINE_FUNCTION LocalSurfaceVisitor::LocalSurfaceVisitor(
0083     ParamsRef const& params, SurfacesRecord const& local_surfaces)
0084     : params_{params}, surfaces_{local_surfaces}
0085 {
0086 }
0087 
0088 //---------------------------------------------------------------------------//
0089 /*!
0090  * Construct from ORANGE data with surfaces from a simple unit.
0091  */
0092 CELER_FORCEINLINE_FUNCTION LocalSurfaceVisitor::LocalSurfaceVisitor(
0093     ParamsRef const& params, SimpleUnitId unit)
0094     : LocalSurfaceVisitor{params, params.simple_units[unit].surfaces}
0095 {
0096 }
0097 
0098 #if !defined(__DOXYGEN__) || __DOXYGEN__ > 0x010908
0099 //---------------------------------------------------------------------------//
0100 /*!
0101  * Apply the function to the surface specified by the given ID.
0102  */
0103 template<class F>
0104 CELER_FUNCTION decltype(auto) LocalSurfaceVisitor::operator()(
0105     F&& func, LocalSurfaceId id)
0106 {
0107     CELER_EXPECT(id < surfaces_.size());
0108 
0109     // Apply type-deleted functor based on type
0110     return visit_surface_type(
0111         [this, &func, id](auto s_traits) {
0112             // Call the user-provided action using the reconstructed surface
0113             using S = typename decltype(s_traits)::type;
0114             return func(this->make_surface<S>(id));
0115         },
0116         params_.surface_types[surfaces_.types[id]]);
0117 }
0118 #endif
0119 
0120 //---------------------------------------------------------------------------//
0121 // PRIVATE HELPER FUNCTIONS
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Construct a surface of a given type using the data at a specific ID.
0125  */
0126 template<class T>
0127 CELER_FUNCTION T LocalSurfaceVisitor::make_surface(LocalSurfaceId id) const
0128 {
0129     using RealIdT = Reals::ItemIdT;
0130     using RealRangeT = Reals::ItemRangeT;
0131     RealIdT offset = params_.real_ids[surfaces_.data_offsets[id]];
0132     constexpr size_type size{T::StorageSpan::extent};
0133     CELER_ASSERT(offset + size <= params_.reals.size());
0134     auto storage_span = params_.reals[RealRangeT{offset, offset + size}];
0135     // Convert to a statically sized span using the first() member template
0136     // function, then construct a surface, for LdgSpan to work correctly.
0137     return T{storage_span.template first<size>()};
0138 }
0139 
0140 //---------------------------------------------------------------------------//
0141 }  // namespace celeritas