File indexing completed on 2026-11-07 10:11:36
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/math/Algorithms.hh"
0012 #include "corecel/math/ArrayUtils.hh"
0013 #include "corecel/random/distribution/GenerateCanonical.hh"
0014 #include "corecel/random/distribution/IsotropicDistribution.hh"
0015 #include "celeritas/Quantities.hh"
0016 #include "celeritas/Units.hh"
0017 #include "celeritas/grid/NonuniformGridCalculator.hh"
0018 #include "celeritas/phys/Secondary.hh"
0019
0020 namespace celeritas
0021 {
0022 namespace detail
0023 {
0024
0025
0026
0027
0028
0029 inline CELER_FUNCTION real_type calc_momentum(units::MevEnergy const energy,
0030 units::MevMass const mass)
0031 {
0032 return std::sqrt(ipow<2>(value_as<units::MevEnergy>(energy))
0033 + 2 * value_as<units::MevMass>(mass)
0034 * value_as<units::MevEnergy>(energy));
0035 }
0036
0037
0038
0039
0040
0041
0042 inline CELER_FUNCTION units::MevEnergy calc_kinetic_energy(
0043 Real3 const& momentum_vec, units::MevMass const mass)
0044 {
0045 real_type momentum_mag = norm(momentum_vec);
0046 return units::MevEnergy{std::sqrt(ipow<2>(momentum_mag)
0047 + ipow<2>(value_as<units::MevMass>(mass)))
0048 - value_as<units::MevMass>(mass)};
0049 }
0050
0051
0052
0053
0054
0055
0056 template<class Engine>
0057 inline CELER_FUNCTION Secondary sample_mucf_secondary(
0058 ParticleId pid, units::MevEnergy energy, Engine& rng)
0059 {
0060 Secondary result;
0061 result.particle_id = pid;
0062 result.energy = energy;
0063 result.direction = IsotropicDistribution<real_type>()(rng);
0064 return result;
0065 }
0066
0067
0068
0069
0070
0071
0072
0073
0074 template<class Engine>
0075 inline CELER_FUNCTION Secondary sample_mucf_muon(
0076 ParticleId pid, NonuniformGridCalculator sample_energy, Engine& rng)
0077 {
0078 Secondary result;
0079 result.particle_id = pid;
0080 result.energy = units::MevEnergy{sample_energy(generate_canonical(rng))};
0081 result.direction = IsotropicDistribution<real_type>()(rng);
0082 return result;
0083 }
0084
0085
0086
0087
0088
0089 inline CELER_FUNCTION Real3 opposite(Real3 const& vec)
0090 {
0091 Real3 result;
0092 for (auto i : range(3))
0093 {
0094 result[i] = -vec[i];
0095 }
0096 return result;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 inline CELER_FUNCTION Secondary calc_third_secondary(
0108 Secondary sec_a,
0109 units::MevMass const mass_a,
0110 Secondary sec_b,
0111 units::MevMass const mass_b,
0112 ParticleId pid_c,
0113 units::MevMass const mass_c)
0114 {
0115 auto const momentum_a_mag = calc_momentum(sec_a.energy, mass_a);
0116 auto const momentum_b_mag = calc_momentum(sec_b.energy, mass_b);
0117
0118
0119 Real3 momentum_vec;
0120 for (auto i : range(3))
0121 {
0122 momentum_vec[i] = -(sec_a.direction[i] * momentum_a_mag
0123 + sec_b.direction[i] * momentum_b_mag);
0124 }
0125
0126 Secondary result;
0127 result.particle_id = pid_c;
0128 result.direction = make_unit_vector(momentum_vec);
0129 result.energy = calc_kinetic_energy(momentum_vec, mass_c);
0130 return result;
0131 }
0132
0133
0134 }
0135 }