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/data/Collection.hh"
0013 #include "corecel/grid/Interpolator.hh"
0014 #include "corecel/grid/UniformGrid.hh"
0015 #include "corecel/math/Quantity.hh"
0016
0017 #include "XsGridData.hh"
0018
0019 namespace celeritas
0020 {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 class RangeCalculator
0036 {
0037 public:
0038
0039
0040 using Energy = Quantity<XsGridData::EnergyUnits>;
0041 using Values
0042 = Collection<real_type, Ownership::const_reference, MemSpace::native>;
0043
0044
0045 public:
0046
0047 inline CELER_FUNCTION
0048 RangeCalculator(XsGridData const& grid, Values const& values);
0049
0050
0051 inline CELER_FUNCTION real_type operator()(Energy energy) const;
0052
0053 private:
0054 XsGridData const& data_;
0055 Values const& reals_;
0056
0057 CELER_FORCEINLINE_FUNCTION real_type get(size_type index) const;
0058 };
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 CELER_FUNCTION
0069 RangeCalculator::RangeCalculator(XsGridData const& grid, Values const& values)
0070 : data_(grid), reals_(values)
0071 {
0072 CELER_EXPECT(data_);
0073 CELER_EXPECT(data_.prime_index == XsGridData::no_scaling());
0074 }
0075
0076
0077
0078
0079
0080 CELER_FUNCTION real_type RangeCalculator::operator()(Energy energy) const
0081 {
0082 CELER_ASSERT(energy > zero_quantity());
0083 UniformGrid loge_grid(data_.log_energy);
0084 real_type const loge = std::log(energy.value());
0085
0086 if (loge <= loge_grid.front())
0087 {
0088 real_type result = this->get(0);
0089
0090 result *= std::exp(real_type(.5) * (loge - loge_grid.front()));
0091 return result;
0092 }
0093 else if (loge >= loge_grid.back())
0094 {
0095
0096 return this->get(loge_grid.size() - 1);
0097 }
0098
0099
0100 auto idx = loge_grid.find(loge);
0101 CELER_ASSERT(idx + 1 < loge_grid.size());
0102
0103
0104 LinearInterpolator<real_type> interpolate_xs(
0105 {std::exp(loge_grid[idx]), this->get(idx)},
0106 {std::exp(loge_grid[idx + 1]), this->get(idx + 1)});
0107 return interpolate_xs(energy.value());
0108 }
0109
0110
0111
0112
0113
0114 CELER_FUNCTION real_type RangeCalculator::get(size_type index) const
0115 {
0116 CELER_EXPECT(index < reals_.size());
0117 return reals_[data_.value[index]];
0118 }
0119
0120
0121 }