File indexing completed on 2025-11-03 09:44:07
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 template<class T>
0025 class NonuniformGrid
0026 {
0027   public:
0028     
0029     
0030     using value_type = T;
0031     using Storage
0032         = Collection<value_type, Ownership::const_reference, MemSpace::native>;
0033     using ItemRangeT = ItemRange<value_type>;
0034     using SpanConstT = typename Storage::SpanConstT;
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     
0070     inline CELER_FUNCTION SpanConstT values() const;
0071 
0072   private:
0073     Storage const& storage_;
0074     ItemRangeT offset_;
0075 };
0076 
0077 
0078 
0079 
0080 
0081 
0082 
0083 template<class T>
0084 CELER_FUNCTION NonuniformGrid<T>::NonuniformGrid(ItemRangeT const& values,
0085                                                  Storage const& storage)
0086     : storage_{storage}, offset_{values}
0087 {
0088     CELER_EXPECT(offset_.size() >= 2);
0089     CELER_EXPECT(*offset_.end() <= storage.size());
0090     CELER_EXPECT(this->front() <= this->back());  
0091 }
0092 
0093 
0094 
0095 
0096 
0097 template<class T>
0098 CELER_FUNCTION auto
0099 NonuniformGrid<T>::operator[](size_type i) const -> value_type
0100 {
0101     CELER_EXPECT(i < offset_.size());
0102     return storage_[offset_[i]];
0103 }
0104 
0105 
0106 
0107 
0108 
0109 
0110 
0111 
0112 
0113 
0114 template<class T>
0115 CELER_FUNCTION size_type NonuniformGrid<T>::find(value_type value) const
0116 {
0117     CELER_EXPECT(value >= this->front() && value < this->back());
0118 
0119     using ItemIdT = ItemId<T>;
0120     auto iter = celeritas::lower_bound(
0121         offset_.begin(),
0122         offset_.end(),
0123         value,
0124         [&v = storage_](ItemIdT i, T value) { return v[i] < value; });
0125     CELER_ASSERT(iter != offset_.end());
0126 
0127     if (value != storage_[*iter])
0128     {
0129         
0130         
0131         --iter;
0132     }
0133 
0134     return iter - offset_.begin();
0135 }
0136 
0137 
0138 
0139 
0140 
0141 template<class T>
0142 CELER_FUNCTION auto NonuniformGrid<T>::values() const -> SpanConstT
0143 {
0144     return storage_[offset_];
0145 }
0146 
0147 
0148 }