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