Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:06:27

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 corecel/data/HyperslabIndexer.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/cont/Array.hh"
0013 
0014 #include "detail/HyperslabIndexerImpl.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Class for indexing into flattened N-dimensional data (N-D coords to index)
0021  *
0022  * Indexing is in standard C iteration order, such that final dimension
0023  * "changes fastest". For example, when indexing into a 3D grid (N=3) with
0024  * coords (i=0, j=0, k=1) the resulting index will be 1.
0025  */
0026 template<size_type N>
0027 class HyperslabIndexer
0028 {
0029   public:
0030     //!@{
0031     //! \name Type aliases
0032     using Coords = Array<size_type, N>;
0033     //!@}
0034 
0035   public:
0036     // Construct with an array denoting the size of each dimension
0037     explicit inline CELER_FUNCTION
0038     HyperslabIndexer(Array<size_type, N> const& dims);
0039 
0040     //// METHODS ////
0041 
0042     //! Convert N-dimensional coordinates to an index
0043     inline CELER_FUNCTION size_type operator()(Coords const& coords) const;
0044 
0045   private:
0046     //// DATA ////
0047 
0048     Array<size_type, N> const& dims_;
0049 };
0050 
0051 //---------------------------------------------------------------------------//
0052 /*!
0053  * Class for indexing into flattened N-dimensional data (index to N-D coords)
0054  *
0055  * Indexing is in standard C iteration order, such that final dimension
0056  * "changes fastest". For example, when indexing into a 3D grid (N=3), index 1
0057  * will result in coords (i=0, j=0, k=1).
0058  */
0059 template<size_type N>
0060 class HyperslabInverseIndexer
0061 {
0062   public:
0063     //!@{
0064     //! \name Type aliases
0065     using Coords = Array<size_type, N>;
0066     //!@}
0067 
0068   public:
0069     // Construct with an array denoting the size of each dimension
0070     explicit inline CELER_FUNCTION
0071     HyperslabInverseIndexer(Array<size_type, N> const& dims);
0072 
0073     //// METHODS ////
0074 
0075     //! Convert an index to N-dimensional coordinates
0076     inline CELER_FUNCTION Coords operator()(size_type index) const;
0077 
0078   private:
0079     //// DATA ////
0080 
0081     Array<size_type, N> const& dims_;
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 // INLINE DEFINITIONS
0086 //---------------------------------------------------------------------------//
0087 /*!
0088  * Construct from array denoting the sizes of each dimension.
0089  */
0090 template<size_type N>
0091 CELER_FUNCTION HyperslabIndexer<N>::HyperslabIndexer(Coords const& dims)
0092     : dims_(dims)
0093 {
0094     for (auto dim : dims_)
0095     {
0096         CELER_EXPECT(dim > 0);
0097     }
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Convert N-dimensional coordinates to an index.
0103  */
0104 template<size_type N>
0105 CELER_FUNCTION size_type HyperslabIndexer<N>::operator()(Coords const& coords) const
0106 {
0107     CELER_EXPECT(coords[0] < dims_[0]);
0108     size_type result = coords[0];
0109 
0110     for (size_type i = 1; i < N; ++i)
0111     {
0112         CELER_EXPECT(coords[i] < dims_[i]);
0113         result = dims_[i] * result + coords[i];
0114     }
0115     return result;
0116 }
0117 
0118 //---------------------------------------------------------------------------//
0119 /*!
0120  * Construct from array denoting the sizes of each dimension.
0121  */
0122 template<size_type N>
0123 CELER_FUNCTION HyperslabInverseIndexer<N>::HyperslabInverseIndexer(
0124     Array<size_type, N> const& dims)
0125     : dims_(dims)
0126 {
0127     for (auto dim : dims_)
0128     {
0129         CELER_EXPECT(dim > 0);
0130     }
0131 }
0132 
0133 //---------------------------------------------------------------------------//
0134 /*!
0135  * Convert an index into N-dimensional coordinates.
0136  */
0137 template<size_type N>
0138 CELER_FUNCTION typename HyperslabInverseIndexer<N>::Coords
0139 HyperslabInverseIndexer<N>::operator()(size_type index) const
0140 {
0141     CELER_EXPECT(index <= detail::hyperslab_size(dims_));
0142     Coords coords;
0143 
0144     for (size_type i = dims_.size() - 1; i > 0; i--)
0145     {
0146         coords[i] = index % dims_[i];
0147         index = (index - coords[i]) / dims_[i];
0148     }
0149 
0150     coords[0] = index;
0151 
0152     return coords;
0153 }
0154 
0155 //---------------------------------------------------------------------------//
0156 }  // namespace celeritas