File indexing completed on 2025-12-16 10:11:35
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/math/Algorithms.hh"
0012 #include "celeritas/Types.hh"
0013
0014 namespace celeritas
0015 {
0016 namespace detail
0017 {
0018
0019
0020
0021
0022 class UrbanPositronCorrector
0023 {
0024 public:
0025
0026 explicit inline CELER_FUNCTION UrbanPositronCorrector(real_type zeff);
0027
0028
0029 inline CELER_FUNCTION real_type operator()(real_type y) const;
0030
0031 private:
0032 real_type a_, b_, c_, d_, mult_;
0033 };
0034
0035
0036
0037
0038
0039
0040
0041 CELER_FUNCTION UrbanPositronCorrector::UrbanPositronCorrector(real_type zeff)
0042 {
0043 CELER_EXPECT(zeff >= 1);
0044 using PolyLin = PolyEvaluator<real_type, 1>;
0045 using PolyQuad = PolyEvaluator<real_type, 2>;
0046
0047 a_ = PolyLin(0.994, -4.08e-3)(zeff);
0048 b_ = PolyQuad(7.16, 52.6, 365)(1 / zeff);
0049 c_ = PolyLin(1, -4.47e-3)(zeff);
0050 d_ = real_type(1.21e-3) * zeff;
0051 mult_ = PolyQuad(1.41125, -1.86427e-2, 1.84035e-4)(zeff);
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 CELER_FUNCTION real_type UrbanPositronCorrector::operator()(real_type y) const
0064 {
0065 CELER_EXPECT(y > 0);
0066 real_type corr = [this, y] {
0067 constexpr real_type xl = 0.6;
0068 constexpr real_type xh = 0.9;
0069 constexpr real_type e = 113;
0070
0071
0072 real_type x = std::sqrt(y * (y + 2) / ipow<2>(y + 1));
0073 if (x < xl)
0074 {
0075 return a_ * (1 - std::exp(-b_ * x));
0076 }
0077 if (x > xh)
0078 {
0079 return c_ + d_ * std::exp(e * (x - 1));
0080 }
0081 real_type yl = a_ * (1 - std::exp(-b_ * xl));
0082 real_type yh = c_ + d_ * std::exp(e * (xh - 1));
0083 real_type y0 = (yh - yl) / (xh - xl);
0084 real_type y1 = yl - y0 * xl;
0085 return y0 * x + y1;
0086 }();
0087
0088 return corr * mult_;
0089 }
0090
0091
0092 }
0093 }