File indexing completed on 2025-02-22 10:31:15
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cmath>
0011
0012 #include "corecel/Macros.hh"
0013 #include "corecel/Types.hh"
0014 #include "corecel/math/Algorithms.hh"
0015 #include "celeritas/Constants.hh"
0016 #include "celeritas/Quantities.hh"
0017 #include "celeritas/phys/ParticleTrackView.hh"
0018 #include "celeritas/random/distribution/InverseSquareDistribution.hh"
0019 #include "celeritas/random/distribution/RejectionSampler.hh"
0020
0021 #include "detail/Utils.hh"
0022
0023 namespace celeritas
0024 {
0025
0026
0027
0028
0029
0030
0031
0032 class BraggICRU73QOEnergyDistribution
0033 {
0034 public:
0035
0036
0037 using Energy = units::MevEnergy;
0038 using Mass = units::MevMass;
0039
0040
0041 public:
0042
0043 inline CELER_FUNCTION
0044 BraggICRU73QOEnergyDistribution(ParticleTrackView const& particle,
0045 Energy electron_cutoff,
0046 Mass electron_mass);
0047
0048
0049 template<class Engine>
0050 inline CELER_FUNCTION Energy operator()(Engine& rng);
0051
0052
0053 CELER_FUNCTION Energy min_secondary_energy() const { return min_energy_; }
0054
0055
0056 CELER_FUNCTION Energy max_secondary_energy() const { return max_energy_; }
0057
0058 private:
0059
0060
0061
0062 real_type inc_mass_;
0063
0064 real_type beta_sq_;
0065
0066 Energy min_energy_;
0067
0068 Energy max_energy_;
0069
0070
0071
0072
0073 static CELER_CONSTEXPR_FUNCTION Energy bragg_lowest_kin_energy()
0074 {
0075 return units::MevEnergy{2.5e-4};
0076 }
0077
0078
0079 static CELER_CONSTEXPR_FUNCTION Energy icru73qo_lowest_kin_energy()
0080 {
0081 return units::MevEnergy{5e-3};
0082 }
0083 };
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 CELER_FUNCTION
0094 BraggICRU73QOEnergyDistribution::BraggICRU73QOEnergyDistribution(
0095 ParticleTrackView const& particle,
0096 Energy electron_cutoff,
0097 Mass electron_mass)
0098 : inc_mass_(value_as<Mass>(particle.mass()))
0099 , beta_sq_(particle.beta_sq())
0100 , min_energy_(
0101 min(electron_cutoff,
0102 Energy(value_as<Energy>(particle.charge() < zero_quantity()
0103 ? icru73qo_lowest_kin_energy()
0104 : bragg_lowest_kin_energy())
0105 * inc_mass_
0106 / native_value_to<Mass>(constants::proton_mass).value())))
0107 , max_energy_(detail::calc_max_secondary_energy(particle, electron_mass))
0108 {
0109 }
0110
0111
0112
0113
0114
0115 template<class Engine>
0116 CELER_FUNCTION auto
0117 BraggICRU73QOEnergyDistribution::operator()(Engine& rng) -> Energy
0118 {
0119 InverseSquareDistribution sample_energy(value_as<Energy>(min_energy_),
0120 value_as<Energy>(max_energy_));
0121 real_type energy;
0122 do
0123 {
0124
0125 energy = sample_energy(rng);
0126 } while (RejectionSampler<>(
0127 1 - (beta_sq_ / value_as<Energy>(max_energy_)) * energy)(rng));
0128
0129 CELER_ENSURE(energy > 0);
0130 return Energy{energy};
0131 }
0132
0133
0134 }