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