File indexing completed on 2025-09-14 08:50:33
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <cmath>
0010
0011 #include "corecel/Macros.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/data/StackAllocator.hh"
0014 #include "corecel/math/Algorithms.hh"
0015 #include "corecel/math/ArrayUtils.hh"
0016 #include "celeritas/Constants.hh"
0017 #include "celeritas/Quantities.hh"
0018 #include "celeritas/em/data/MollerBhabhaData.hh"
0019 #include "celeritas/em/distribution/BhabhaEnergyDistribution.hh"
0020 #include "celeritas/em/distribution/MollerEnergyDistribution.hh"
0021 #include "celeritas/phys/CutoffView.hh"
0022 #include "celeritas/phys/Interaction.hh"
0023 #include "celeritas/phys/ParticleTrackView.hh"
0024 #include "celeritas/phys/Secondary.hh"
0025
0026 #include "detail/IoniFinalStateHelper.hh"
0027
0028 namespace celeritas
0029 {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 class MollerBhabhaInteractor
0042 {
0043 public:
0044
0045
0046 using Mass = units::MevMass;
0047 using Energy = units::MevEnergy;
0048 using Momentum = units::MevMomentum;
0049
0050
0051 public:
0052
0053 inline CELER_FUNCTION
0054 MollerBhabhaInteractor(MollerBhabhaData const& shared,
0055 ParticleTrackView const& particle,
0056 CutoffView const& cutoffs,
0057 Real3 const& inc_direction,
0058 StackAllocator<Secondary>& allocate);
0059
0060
0061 template<class Engine>
0062 inline CELER_FUNCTION Interaction operator()(Engine& rng);
0063
0064 private:
0065
0066 MollerBhabhaData const& shared_;
0067
0068 Energy inc_energy_;
0069
0070 Momentum inc_momentum_;
0071
0072 Real3 const& inc_direction_;
0073
0074 Energy electron_cutoff_;
0075
0076 StackAllocator<Secondary>& allocate_;
0077
0078 bool const inc_particle_is_electron_;
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 CELER_FUNCTION MollerBhabhaInteractor::MollerBhabhaInteractor(
0091 MollerBhabhaData const& shared,
0092 ParticleTrackView const& particle,
0093 CutoffView const& cutoffs,
0094 Real3 const& inc_direction,
0095 StackAllocator<Secondary>& allocate)
0096 : shared_(shared)
0097 , inc_energy_(particle.energy())
0098 , inc_momentum_(particle.momentum())
0099 , inc_direction_(inc_direction)
0100 , electron_cutoff_(cutoffs.energy(shared_.ids.electron))
0101 , allocate_(allocate)
0102 , inc_particle_is_electron_(particle.particle_id() == shared_.ids.electron)
0103 {
0104 CELER_EXPECT(particle.particle_id() == shared_.ids.electron
0105 || particle.particle_id() == shared_.ids.positron);
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115 template<class Engine>
0116 CELER_FUNCTION Interaction MollerBhabhaInteractor::operator()(Engine& rng)
0117 {
0118 if (inc_energy_ <= (inc_particle_is_electron_ ? 2 : 1) * electron_cutoff_)
0119 {
0120
0121
0122
0123
0124 return Interaction::from_unchanged();
0125 }
0126
0127
0128 Secondary* electron_secondary = allocate_(1);
0129
0130 if (electron_secondary == nullptr)
0131 {
0132
0133 return Interaction::from_failure();
0134 }
0135
0136
0137 Energy secondary_energy = inc_energy_ * [this, &rng] {
0138 if (inc_particle_is_electron_)
0139 {
0140 return MollerEnergyDistribution(
0141 shared_.electron_mass, electron_cutoff_, inc_energy_)(rng);
0142 }
0143 return BhabhaEnergyDistribution(
0144 shared_.electron_mass, electron_cutoff_, inc_energy_)(rng);
0145 }();
0146 CELER_ASSERT(secondary_energy >= electron_cutoff_);
0147
0148
0149 detail::IoniFinalStateHelper sample_interaction(inc_energy_,
0150 inc_direction_,
0151 inc_momentum_,
0152 shared_.electron_mass,
0153 secondary_energy,
0154 shared_.electron_mass,
0155 shared_.ids.electron,
0156 electron_secondary);
0157
0158
0159 return sample_interaction(rng);
0160 }
0161
0162
0163 }