File indexing completed on 2025-02-22 10:31:23
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cmath>
0011
0012 #include "corecel/grid/Interpolator.hh"
0013 #include "corecel/grid/UniformGrid.hh"
0014 #include "corecel/math/Quantity.hh"
0015
0016 #include "XsGridData.hh"
0017
0018 namespace celeritas
0019 {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class XsCalculator
0039 {
0040 public:
0041
0042
0043 using Energy = Quantity<XsGridData::EnergyUnits>;
0044 using Values
0045 = Collection<real_type, Ownership::const_reference, MemSpace::native>;
0046
0047
0048 public:
0049
0050 inline CELER_FUNCTION
0051 XsCalculator(XsGridData const& grid, Values const& values);
0052
0053
0054 inline CELER_FUNCTION real_type operator()(Energy energy) const;
0055
0056
0057 inline CELER_FUNCTION real_type operator[](size_type index) const;
0058
0059
0060 CELER_FUNCTION Energy energy_min() const
0061 {
0062 return Energy(std::exp(loge_grid_.front()));
0063 }
0064
0065
0066 CELER_FUNCTION Energy energy_max() const
0067 {
0068 return Energy(std::exp(loge_grid_.back()));
0069 }
0070
0071 private:
0072 XsGridData const& data_;
0073 Values const& reals_;
0074 UniformGrid loge_grid_;
0075
0076 CELER_FORCEINLINE_FUNCTION real_type get(size_type index) const;
0077 };
0078
0079
0080
0081
0082
0083
0084
0085 CELER_FUNCTION
0086 XsCalculator::XsCalculator(XsGridData const& grid, Values const& values)
0087 : data_(grid), reals_(values), loge_grid_(data_.log_energy)
0088 {
0089 CELER_EXPECT(data_);
0090 CELER_ASSERT(grid.value.size() == data_.log_energy.size);
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100 CELER_FUNCTION real_type XsCalculator::operator()(Energy energy) const
0101 {
0102 real_type const loge = std::log(energy.value());
0103
0104
0105 size_type lower_idx;
0106 real_type result;
0107 if (loge <= loge_grid_.front())
0108 {
0109 lower_idx = 0;
0110 result = this->get(lower_idx);
0111 }
0112 else if (loge >= loge_grid_.back())
0113 {
0114 lower_idx = loge_grid_.size() - 1;
0115 result = this->get(lower_idx);
0116 }
0117 else
0118 {
0119
0120 lower_idx = loge_grid_.find(loge);
0121 CELER_ASSERT(lower_idx + 1 < loge_grid_.size());
0122
0123 real_type const upper_energy = std::exp(loge_grid_[lower_idx + 1]);
0124 real_type upper_xs = this->get(lower_idx + 1);
0125 if (lower_idx + 1 == data_.prime_index)
0126 {
0127
0128
0129 upper_xs /= upper_energy;
0130 }
0131
0132
0133 LinearInterpolator<real_type> interpolate_xs(
0134 {std::exp(loge_grid_[lower_idx]), this->get(lower_idx)},
0135 {upper_energy, upper_xs});
0136 result = interpolate_xs(energy.value());
0137 }
0138
0139 if (lower_idx >= data_.prime_index)
0140 {
0141 result /= energy.value();
0142 }
0143 return result;
0144 }
0145
0146
0147
0148
0149
0150 CELER_FUNCTION real_type XsCalculator::operator[](size_type index) const
0151 {
0152 real_type energy = std::exp(loge_grid_[index]);
0153 real_type result = this->get(index);
0154
0155 if (index >= data_.prime_index)
0156 {
0157 result /= energy;
0158 }
0159 return result;
0160 }
0161
0162
0163
0164
0165
0166 CELER_FUNCTION real_type XsCalculator::get(size_type index) const
0167 {
0168 CELER_EXPECT(index < data_.value.size());
0169 return reals_[data_.value[index]];
0170 }
0171
0172
0173 }