File indexing completed on 2025-09-15 08:55:05
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/data/Collection.hh"
0010
0011 #include "FindInterp.hh"
0012 #include "NonuniformGrid.hh"
0013 #include "TwodGridData.hh"
0014
0015 namespace celeritas
0016 {
0017
0018
0019
0020
0021
0022
0023
0024 class TwodSubgridCalculator
0025 {
0026 public:
0027
0028
0029 using Values
0030 = Collection<real_type, Ownership::const_reference, MemSpace::native>;
0031 using InterpT = FindInterp<real_type>;
0032
0033
0034 public:
0035
0036 inline CELER_FUNCTION TwodSubgridCalculator(TwodGridData const& grid,
0037 Values const& storage,
0038 InterpT x_loc);
0039
0040
0041 inline CELER_FUNCTION real_type operator()(real_type y) const;
0042
0043
0044 inline CELER_FUNCTION real_type operator[](size_type i) const;
0045
0046
0047 CELER_FORCEINLINE_FUNCTION size_type x_index() const
0048 {
0049 return x_loc_.index;
0050 }
0051
0052
0053 CELER_FORCEINLINE_FUNCTION real_type x_fraction() const
0054 {
0055 return x_loc_.fraction;
0056 }
0057
0058 private:
0059 TwodGridData const& grids_;
0060 Values const& storage_;
0061 InterpT const x_loc_;
0062
0063 inline CELER_FUNCTION real_type at(size_type x_idx, size_type y_idx) const;
0064 };
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 CELER_FUNCTION
0077 TwodSubgridCalculator::TwodSubgridCalculator(TwodGridData const& grids,
0078 Values const& storage,
0079 InterpT x_loc)
0080 : grids_{grids}, storage_(storage), x_loc_(x_loc)
0081 {
0082 CELER_EXPECT(grids);
0083 CELER_EXPECT(grids.values.back() < storage.size());
0084 CELER_EXPECT(x_loc.index + 1 < grids.x.size());
0085 CELER_EXPECT(x_loc.fraction >= 0 && x_loc_.fraction < 1);
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095 CELER_FUNCTION real_type TwodSubgridCalculator::operator()(real_type y) const
0096 {
0097 NonuniformGrid<real_type> const y_grid{grids_.y, storage_};
0098 CELER_EXPECT(y >= y_grid.front() && y < y_grid.back());
0099
0100 InterpT const y_loc = find_interp(y_grid, y);
0101 auto at_corner = [this, y_loc](size_type xo, size_type yo) -> real_type {
0102 return this->at(x_loc_.index + xo, y_loc.index + yo);
0103 };
0104
0105 return (1 - x_loc_.fraction)
0106 * ((1 - y_loc.fraction) * at_corner(0, 0)
0107 + (y_loc.fraction) * at_corner(0, 1))
0108 + (x_loc_.fraction)
0109 * ((1 - y_loc.fraction) * at_corner(1, 0)
0110 + (y_loc.fraction) * at_corner(1, 1));
0111 }
0112
0113
0114
0115
0116
0117 CELER_FUNCTION real_type TwodSubgridCalculator::operator[](size_type i) const
0118 {
0119 CELER_EXPECT(i < grids_.y.size());
0120 return (1 - x_loc_.fraction) * this->at(x_loc_.index, i)
0121 + x_loc_.fraction * this->at(x_loc_.index + 1, i);
0122 }
0123
0124
0125
0126
0127
0128
0129
0130 CELER_FUNCTION real_type TwodSubgridCalculator::at(size_type x_idx,
0131 size_type y_idx) const
0132 {
0133 return storage_[grids_.at(x_idx, y_idx)];
0134 }
0135
0136
0137 }