Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:17:13

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/transform/TransformVisitor.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/math/Algorithms.hh"
0011 #include "orange/OrangeData.hh"
0012 
0013 #include "NoTransformation.hh"
0014 #include "TransformTypeTraits.hh"
0015 #include "Transformation.hh"
0016 #include "Translation.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Apply a functor to a type-deleted transform.
0023  *
0024  * An instance of this class is like \c std::visit but accepting a \c
0025  * TransformId rather than a \c std::variant .
0026  *
0027  * Example: \code
0028  TransformVisitor visit_transform{params_};
0029  auto new_pos = visit_transform(
0030     [&pos](auto&& t) { return t.transform_up(pos); },
0031     daughter.transform_id);
0032  \endcode
0033  */
0034 class TransformVisitor
0035 {
0036     template<class T>
0037     using Items = Collection<T, Ownership::const_reference, MemSpace::native>;
0038 
0039   public:
0040     //!@{
0041     //! \name Type aliases
0042     using ParamsRef = NativeCRef<OrangeParamsData>;
0043     using TransformRecords = Items<TransformRecord>;
0044     using Reals = Items<real_type>;
0045     //!@}
0046 
0047   public:
0048     // Construct manually from required data
0049     inline CELER_FUNCTION
0050     TransformVisitor(TransformRecords const& transforms, Reals const& reals);
0051 
0052     // Construct from ORANGE params
0053     explicit inline CELER_FUNCTION TransformVisitor(ParamsRef const& params);
0054 
0055     // Apply the function to the transform specified by the given ID
0056     template<class F>
0057     inline CELER_FUNCTION decltype(auto)
0058     operator()(F&& typed_visitor, TransformId t);
0059 
0060   private:
0061     TransformRecords const& transforms_;
0062     Reals const& reals_;
0063 
0064     // Construct a transform from a data offset
0065     template<class T>
0066     inline CELER_FUNCTION T make_transform(OpaqueId<real_type> data_offset) const;
0067 };
0068 
0069 //---------------------------------------------------------------------------//
0070 // INLINE DEFINITIONS
0071 //---------------------------------------------------------------------------//
0072 /*!
0073  * Construct manually from required data.
0074  */
0075 CELER_FUNCTION
0076 TransformVisitor::TransformVisitor(TransformRecords const& transforms,
0077                                    Reals const& reals)
0078     : transforms_{transforms}, reals_{reals}
0079 {
0080 }
0081 
0082 //---------------------------------------------------------------------------//
0083 /*!
0084  * Construct from ORANGE data.
0085  */
0086 CELER_FUNCTION TransformVisitor::TransformVisitor(ParamsRef const& params)
0087     : TransformVisitor{params.transforms, params.reals}
0088 {
0089 }
0090 
0091 #if !defined(__DOXYGEN__) || __DOXYGEN__ > 0x010908
0092 //---------------------------------------------------------------------------//
0093 /*!
0094  * Apply the function to the transform specified by the given ID.
0095  */
0096 template<class F>
0097 CELER_FUNCTION decltype(auto)
0098 TransformVisitor::operator()(F&& func, TransformId id)
0099 {
0100     CELER_EXPECT(id < transforms_.size());
0101 
0102     // Load transform record (type + data)
0103     TransformRecord const tr = transforms_[id];
0104     CELER_ASSERT(tr);
0105 
0106     // Apply type-deleted functor based on type
0107     return visit_transform_type(
0108         [&](auto tt_traits) {
0109             // Call the user-provided action using the reconstructed transform
0110             using TF = typename decltype(tt_traits)::type;
0111             return func(this->make_transform<TF>(tr.data_offset));
0112         },
0113         tr.type);
0114 }
0115 #endif
0116 
0117 //---------------------------------------------------------------------------//
0118 /*!
0119  * Apply the function to the transform specified by the given ID.
0120  */
0121 template<class T>
0122 CELER_FUNCTION T
0123 TransformVisitor::make_transform(OpaqueId<real_type> data_offset) const
0124 {
0125     CELER_EXPECT(data_offset <= reals_.size());
0126     constexpr size_type size{T::StorageSpan::extent};
0127     CELER_ASSERT(data_offset + size <= reals_.size());
0128 
0129     return T{reals_[Reals::ItemRangeT{data_offset, data_offset + size}]};
0130 }
0131 
0132 //---------------------------------------------------------------------------//
0133 }  // namespace celeritas