File indexing completed on 2025-09-19 08:49:41
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "celeritas/global/CoreTrackView.hh"
0011 #include "celeritas/phys/PhysicsStepUtils.hh"
0012
0013 namespace celeritas
0014 {
0015 namespace detail
0016 {
0017
0018
0019
0020
0021 class MeanELoss
0022 {
0023 public:
0024
0025
0026 using Energy = ParticleTrackView::Energy;
0027
0028
0029 public:
0030
0031 inline CELER_FUNCTION bool is_applicable(CoreTrackView const&) const;
0032
0033
0034 inline CELER_FUNCTION Energy calc_eloss(CoreTrackView const& track,
0035 real_type step,
0036 bool apply_cut);
0037
0038
0039 static CELER_CONSTEXPR_FUNCTION bool imprecise_range() { return false; }
0040 };
0041
0042
0043
0044
0045
0046
0047
0048 CELER_FUNCTION bool MeanELoss::is_applicable(CoreTrackView const& track) const
0049 {
0050
0051
0052 if (track.sim().status() == TrackStatus::errored)
0053 return false;
0054
0055
0056 return static_cast<bool>(track.physics().energy_loss_grid());
0057 }
0058
0059
0060
0061
0062
0063 CELER_FUNCTION auto MeanELoss::calc_eloss(CoreTrackView const& track,
0064 real_type step,
0065 bool apply_cut) -> Energy
0066 {
0067 CELER_EXPECT(step > 0);
0068
0069 auto particle = track.particle();
0070 auto phys = track.physics();
0071
0072 if (apply_cut && particle.energy() < phys.particle_scalars().lowest_energy)
0073 {
0074
0075 return particle.energy();
0076 }
0077
0078
0079 Energy eloss = calc_mean_energy_loss(particle, phys, step);
0080
0081 if (apply_cut
0082 && (particle.energy() - eloss <= phys.particle_scalars().lowest_energy))
0083 {
0084
0085 return particle.energy();
0086 }
0087
0088 CELER_ENSURE(eloss <= particle.energy());
0089 CELER_ENSURE(eloss != particle.energy()
0090 || track.sim().post_step_action()
0091 == phys.scalars().range_action());
0092 return eloss;
0093 }
0094
0095
0096 }
0097 }