File indexing completed on 2025-09-15 08:55:04
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Array.hh"
0012
0013 #include "detail/HyperslabIndexerImpl.hh"
0014
0015 namespace celeritas
0016 {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 template<size_type N>
0029 class HyperslabIndexer
0030 {
0031 public:
0032
0033
0034 using Coords = Array<size_type, N>;
0035
0036
0037 public:
0038
0039 explicit inline CELER_FUNCTION
0040 HyperslabIndexer(Array<size_type, N> const& dims);
0041
0042
0043
0044
0045 inline CELER_FUNCTION size_type operator()(Coords const& coords) const;
0046
0047
0048 template<typename... Args>
0049 inline CELER_FUNCTION size_type operator()(Args... args) const;
0050
0051 private:
0052
0053
0054 Array<size_type, N> const& dims_;
0055 };
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<size_type N>
0066 class HyperslabInverseIndexer
0067 {
0068 public:
0069
0070
0071 using Coords = Array<size_type, N>;
0072
0073
0074 public:
0075
0076 explicit inline CELER_FUNCTION
0077 HyperslabInverseIndexer(Array<size_type, N> const& dims);
0078
0079
0080
0081
0082 inline CELER_FUNCTION Coords operator()(size_type index) const;
0083
0084 private:
0085
0086
0087 Array<size_type, N> const& dims_;
0088 };
0089
0090
0091
0092
0093
0094
0095
0096 template<size_type N>
0097 CELER_FUNCTION HyperslabIndexer<N>::HyperslabIndexer(Coords const& dims)
0098 : dims_(dims)
0099 {
0100 for (auto dim : dims_)
0101 {
0102 CELER_EXPECT(dim > 0);
0103 }
0104 }
0105
0106
0107
0108
0109
0110 template<size_type N>
0111 CELER_FUNCTION size_type HyperslabIndexer<N>::operator()(Coords const& coords) const
0112 {
0113 CELER_EXPECT(coords[0] < dims_[0]);
0114 size_type result = coords[0];
0115
0116 for (size_type i = 1; i < N; ++i)
0117 {
0118 CELER_EXPECT(coords[i] < dims_[i]);
0119 result = dims_[i] * result + coords[i];
0120 }
0121 return result;
0122 }
0123
0124
0125
0126
0127
0128 template<size_type N>
0129 template<typename... Args>
0130 CELER_FUNCTION size_type HyperslabIndexer<N>::operator()(Args... args) const
0131 {
0132 static_assert(sizeof...(Args) == N,
0133 "Number of coordinates must match number of dimensions");
0134
0135 return this->operator()(Coords{static_cast<size_type>(args)...});
0136 }
0137
0138
0139
0140
0141
0142 template<size_type N>
0143 CELER_FUNCTION HyperslabInverseIndexer<N>::HyperslabInverseIndexer(
0144 Array<size_type, N> const& dims)
0145 : dims_(dims)
0146 {
0147 for (auto dim : dims_)
0148 {
0149 CELER_EXPECT(dim > 0);
0150 }
0151 }
0152
0153
0154
0155
0156
0157 template<size_type N>
0158 CELER_FUNCTION typename HyperslabInverseIndexer<N>::Coords
0159 HyperslabInverseIndexer<N>::operator()(size_type index) const
0160 {
0161 CELER_EXPECT(index <= detail::hyperslab_size(dims_));
0162 Coords coords;
0163
0164 for (size_type i = dims_.size() - 1; i > 0; i--)
0165 {
0166 coords[i] = index % dims_[i];
0167 index = (index - coords[i]) / dims_[i];
0168 }
0169
0170 coords[0] = index;
0171
0172 return coords;
0173 }
0174
0175
0176 }