File indexing completed on 2025-01-18 09:54:47
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Macros.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/data/Collection.hh"
0014 #include "corecel/math/Algorithms.hh"
0015
0016 namespace celeritas
0017 {
0018
0019
0020
0021
0022
0023
0024
0025 template<class T>
0026 class NonuniformGrid
0027 {
0028 public:
0029
0030
0031 using value_type = T;
0032 using Storage
0033 = Collection<value_type, Ownership::const_reference, MemSpace::native>;
0034 using ItemRangeT = ItemRange<value_type>;
0035
0036
0037 public:
0038
0039 inline CELER_FUNCTION
0040 NonuniformGrid(ItemRangeT const& values, Storage const& storage);
0041
0042
0043 CELER_FORCEINLINE_FUNCTION size_type size() const
0044 {
0045 return offset_.size();
0046 }
0047
0048
0049 CELER_FORCEINLINE_FUNCTION value_type front() const
0050 {
0051 return storage_[*offset_.begin()];
0052 }
0053
0054
0055 CELER_FORCEINLINE_FUNCTION value_type back() const
0056 {
0057 return storage_[*(offset_.end() - 1)];
0058 }
0059
0060
0061 inline CELER_FUNCTION value_type operator[](size_type i) const;
0062
0063
0064 inline CELER_FUNCTION size_type find(value_type value) const;
0065
0066
0067 CELER_FORCEINLINE_FUNCTION ItemRangeT offset() const { return offset_; }
0068
0069 private:
0070 Storage const& storage_;
0071 ItemRangeT offset_;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080 template<class T>
0081 CELER_FUNCTION NonuniformGrid<T>::NonuniformGrid(ItemRangeT const& values,
0082 Storage const& storage)
0083 : storage_{storage}, offset_{values}
0084 {
0085 CELER_EXPECT(offset_.size() >= 2);
0086 CELER_EXPECT(*offset_.end() <= storage.size());
0087 CELER_EXPECT(this->front() <= this->back());
0088 }
0089
0090
0091
0092
0093
0094 template<class T>
0095 CELER_FUNCTION auto
0096 NonuniformGrid<T>::operator[](size_type i) const -> value_type
0097 {
0098 CELER_EXPECT(i < offset_.size());
0099 return storage_[offset_[i]];
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 template<class T>
0112 CELER_FUNCTION size_type NonuniformGrid<T>::find(value_type value) const
0113 {
0114 CELER_EXPECT(value >= this->front() && value < this->back());
0115
0116 using ItemIdT = ItemId<T>;
0117 auto iter = celeritas::lower_bound(
0118 offset_.begin(),
0119 offset_.end(),
0120 value,
0121 [&v = storage_](ItemIdT i, T value) { return v[i] < value; });
0122 CELER_ASSERT(iter != offset_.end());
0123
0124 if (value != storage_[*iter])
0125 {
0126
0127
0128 --iter;
0129 }
0130
0131 return iter - offset_.begin();
0132 }
0133
0134
0135 }