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