File indexing completed on 2025-09-19 08:49:41
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "celeritas/global/CoreTrackView.hh"
0010
0011 namespace celeritas
0012 {
0013 namespace detail
0014 {
0015
0016
0017
0018
0019
0020
0021
0022 template<class EH>
0023 struct ElossApplier
0024 {
0025 inline CELER_FUNCTION void operator()(CoreTrackView const& track);
0026
0027 EH eloss;
0028 };
0029
0030
0031
0032
0033 template<class EH>
0034 CELER_FUNCTION ElossApplier(EH&&) -> ElossApplier<EH>;
0035
0036
0037
0038
0039 template<class EH>
0040 CELER_FUNCTION void ElossApplier<EH>::operator()(CoreTrackView const& track)
0041 {
0042 auto particle = track.particle();
0043 if (!eloss.is_applicable(track) || particle.is_stopped())
0044 {
0045 return;
0046 }
0047
0048 auto sim = track.sim();
0049 auto step = sim.step_length();
0050 auto post_step_action = sim.post_step_action();
0051
0052
0053 bool apply_cut = (post_step_action != track.boundary_action());
0054 auto deposited = eloss.calc_eloss(track, step, apply_cut);
0055 CELER_ASSERT(deposited <= particle.energy());
0056 CELER_ASSERT(apply_cut || deposited != particle.energy());
0057
0058 if (deposited > zero_quantity())
0059 {
0060
0061 auto step = track.physics_step();
0062 step.deposit_energy(deposited);
0063 particle.subtract_energy(deposited);
0064 }
0065
0066
0067 CELER_ASSERT(particle.energy()
0068 >= track.physics().particle_scalars().lowest_energy
0069 || !apply_cut || particle.is_stopped());
0070
0071 if (particle.is_stopped())
0072 {
0073
0074 CELER_ASSERT(post_step_action != track.boundary_action());
0075 auto const phys = track.physics();
0076 if (!phys.at_rest_process())
0077 {
0078
0079 sim.status(TrackStatus::killed);
0080 sim.post_step_action(phys.scalars().range_action());
0081 }
0082 else
0083 {
0084
0085 sim.post_step_action(phys.scalars().discrete_action());
0086 }
0087 }
0088 }
0089
0090
0091 }
0092 }