File indexing completed on 2025-02-22 10:31:29
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Span.hh"
0012 #include "corecel/sys/KernelTraits.hh"
0013 #include "celeritas/Quantities.hh"
0014 #include "celeritas/Types.hh"
0015 #include "celeritas/geo/GeoFwd.hh"
0016 #include "celeritas/global/CoreTrackView.hh"
0017 #include "celeritas/track/SimTrackView.hh"
0018
0019 #include "CutoffView.hh"
0020 #include "Interaction.hh"
0021 #include "ParticleTrackView.hh"
0022 #include "ParticleView.hh"
0023 #include "PhysicsData.hh"
0024 #include "PhysicsStepView.hh"
0025 #include "PhysicsTrackView.hh"
0026 #include "Secondary.hh"
0027
0028 namespace celeritas
0029 {
0030
0031
0032
0033
0034
0035
0036 template<class F>
0037 struct InteractionApplierBaseImpl
0038 {
0039
0040
0041 F sample_interaction;
0042
0043
0044
0045 CELER_FUNCTION void operator()(celeritas::CoreTrackView const&);
0046 };
0047
0048
0049
0050
0051
0052
0053
0054
0055 template<class F, typename = void>
0056 struct InteractionApplier : public InteractionApplierBaseImpl<F>
0057 {
0058 CELER_FUNCTION InteractionApplier(F&& f)
0059 : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0060 {
0061 }
0062 };
0063
0064 template<class F>
0065 struct InteractionApplier<F, std::enable_if_t<kernel_max_blocks_min_warps<F>>>
0066 : public InteractionApplierBaseImpl<F>
0067 {
0068 static constexpr int max_block_size = F::max_block_size;
0069 static constexpr int min_warps_per_eu = F::min_warps_per_eu;
0070
0071 CELER_FUNCTION InteractionApplier(F&& f)
0072 : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0073 {
0074 }
0075 };
0076
0077 template<class F>
0078 struct InteractionApplier<F, std::enable_if_t<kernel_max_blocks<F>>>
0079 : public InteractionApplierBaseImpl<F>
0080 {
0081 static constexpr int max_block_size = F::max_block_size;
0082
0083 CELER_FUNCTION InteractionApplier(F&& f)
0084 : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0085 {
0086 }
0087 };
0088
0089
0090
0091
0092 template<class F>
0093 CELER_FUNCTION InteractionApplier(F&&) -> InteractionApplier<F>;
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 template<class F>
0105 CELER_FUNCTION void
0106 InteractionApplierBaseImpl<F>::operator()(celeritas::CoreTrackView const& track)
0107 {
0108 Interaction result = this->sample_interaction(track);
0109
0110 auto sim = track.make_sim_view();
0111 if (CELER_UNLIKELY(result.action == Interaction::Action::failed))
0112 {
0113 auto phys = track.make_physics_view();
0114
0115
0116
0117
0118 sim.step_limit({0, phys.scalars().failure_action()});
0119 return;
0120 }
0121 else if (!result.changed())
0122 {
0123 return;
0124 }
0125
0126
0127 {
0128
0129 auto particle = track.make_particle_view();
0130 particle.energy(result.energy);
0131 }
0132
0133 if (result.action != Interaction::Action::absorbed)
0134 {
0135
0136 auto geo = track.make_geo_view();
0137 geo.set_dir(result.direction);
0138 }
0139 else
0140 {
0141
0142 sim.status(TrackStatus::killed);
0143 }
0144
0145 real_type deposition = result.energy_deposition.value();
0146 auto cutoff = track.make_cutoff_view();
0147 if (cutoff.apply_post_interaction())
0148 {
0149
0150 for (auto& secondary : result.secondaries)
0151 {
0152 if (cutoff.apply(secondary))
0153 {
0154
0155
0156
0157 deposition += secondary.energy.value();
0158 auto sec_par = track.make_particle_view(secondary.particle_id);
0159 if (sec_par.is_antiparticle())
0160 {
0161
0162 deposition += 2 * sec_par.mass().value();
0163 }
0164 secondary = {};
0165 }
0166 }
0167 }
0168 auto phys = track.make_physics_step_view();
0169 phys.deposit_energy(units::MevEnergy{deposition});
0170 phys.secondaries(result.secondaries);
0171 }
0172
0173
0174 }