File indexing completed on 2025-02-22 10:31:25
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/math/ArrayOperators.hh"
0013 #include "celeritas/Constants.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/mat/IsotopeView.hh"
0016 #include "celeritas/neutron/data/NeutronElasticData.hh"
0017 #include "celeritas/phys/FourVector.hh"
0018 #include "celeritas/phys/Interaction.hh"
0019 #include "celeritas/phys/ParticleTrackView.hh"
0020 #include "celeritas/random/distribution/UniformRealDistribution.hh"
0021
0022 #include "detail/MomentumTransferSampler.hh"
0023
0024 namespace celeritas
0025 {
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 class ChipsNeutronElasticInteractor
0036 {
0037 public:
0038
0039
0040 using Energy = units::MevEnergy;
0041 using Mass = units::MevMass;
0042 using Momentum = units::MevMomentum;
0043
0044
0045 public:
0046
0047 inline CELER_FUNCTION
0048 ChipsNeutronElasticInteractor(NeutronElasticRef const& shared,
0049 ParticleTrackView const& particle,
0050 Real3 const& inc_direction,
0051 IsotopeView const& target);
0052
0053
0054 template<class Engine>
0055 inline CELER_FUNCTION Interaction operator()(Engine& rng);
0056
0057 private:
0058
0059
0060 using UniformRealDist = UniformRealDistribution<real_type>;
0061
0062
0063
0064
0065 NeutronElasticRef const& shared_;
0066
0067 Real3 const& inc_direction_;
0068
0069 IsotopeView const& target_;
0070
0071
0072 real_type neutron_mass_;
0073 real_type neutron_energy_;
0074 Momentum neutron_p_;
0075
0076
0077 UniformRealDist sample_phi_;
0078 detail::MomentumTransferSampler sample_momentum_square_;
0079 };
0080
0081
0082
0083
0084
0085
0086
0087 CELER_FUNCTION ChipsNeutronElasticInteractor::ChipsNeutronElasticInteractor(
0088 NeutronElasticRef const& shared,
0089 ParticleTrackView const& particle,
0090 Real3 const& inc_direction,
0091 IsotopeView const& target)
0092 : shared_(shared)
0093 , inc_direction_(inc_direction)
0094 , target_(target)
0095 , neutron_mass_(value_as<Mass>(shared_.neutron_mass))
0096 , neutron_energy_(neutron_mass_ + value_as<Energy>(particle.energy()))
0097 , neutron_p_(particle.momentum())
0098 , sample_phi_(0, 2 * constants::pi)
0099 , sample_momentum_square_(shared_, target_, neutron_p_)
0100 {
0101 CELER_EXPECT(particle.particle_id() == shared_.neutron);
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 template<class Engine>
0121 CELER_FUNCTION Interaction ChipsNeutronElasticInteractor::operator()(Engine& rng)
0122 {
0123
0124 Interaction result;
0125
0126
0127 real_type target_mass = value_as<Mass>(target_.nuclear_mass());
0128
0129 real_type cm_p = value_as<units::MevMomentum>(neutron_p_)
0130 / std::sqrt(1 + ipow<2>(neutron_mass_ / target_mass)
0131 + 2 * neutron_energy_ / target_mass);
0132
0133
0134
0135 real_type cos_theta
0136 = 1 - real_type(0.5) * sample_momentum_square_(rng) / ipow<2>(cm_p);
0137 CELER_ASSERT(std::fabs(cos_theta) <= 1);
0138
0139
0140 Real3 cm_mom = cm_p * from_spherical(cos_theta, sample_phi_(rng));
0141 FourVector nlv1(
0142 {cm_mom, std::sqrt(ipow<2>(cm_p) + ipow<2>(neutron_mass_))});
0143
0144 FourVector lv({{0, 0, value_as<units::MevMomentum>(neutron_p_)},
0145 neutron_energy_ + target_mass});
0146 boost(boost_vector(lv), &nlv1);
0147
0148 result.direction = rotate(make_unit_vector(nlv1.mom), inc_direction_);
0149
0150
0151 lv.energy -= nlv1.energy;
0152 result.energy = Energy(nlv1.energy - neutron_mass_);
0153 real_type recoil_energy = clamp_to_nonneg(lv.energy - target_mass);
0154 result.energy_deposition = Energy{recoil_energy};
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 CELER_ENSURE(result.action == Interaction::Action::scattered);
0165
0166 return result;
0167 }
0168
0169
0170 }