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