Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-19 08:49:41

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/alongstep/detail/ElossApplier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "celeritas/global/CoreTrackView.hh"
0010 
0011 namespace celeritas
0012 {
0013 namespace detail
0014 {
0015 //---------------------------------------------------------------------------//
0016 /*!
0017  * Apply energy loss using the EnergyLossHandler interface.
0018  *
0019  * TODO: move apply-cut out of mean/fluct eloss to this function to reduce
0020  * duplicate code?
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 // DEDUCTION GUIDES
0032 //---------------------------------------------------------------------------//
0033 template<class EH>
0034 CELER_FUNCTION ElossApplier(EH&&) -> ElossApplier<EH>;
0035 
0036 //---------------------------------------------------------------------------//
0037 // INLINE DEFINITIONS
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     // Calculate energy loss, possibly applying tracking cuts
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         // Deposit energy loss
0061         auto step = track.physics_step();
0062         step.deposit_energy(deposited);
0063         particle.subtract_energy(deposited);
0064     }
0065 
0066     // Energy loss helper *must* apply the tracking cutoff
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         // Particle lost all energy over the step
0074         CELER_ASSERT(post_step_action != track.boundary_action());
0075         auto const phys = track.physics();
0076         if (!phys.at_rest_process())
0077         {
0078             // Immediately kill stopped particles with no at rest processes
0079             sim.status(TrackStatus::killed);
0080             sim.post_step_action(phys.scalars().range_action());
0081         }
0082         else
0083         {
0084             // Particle slowed down to zero: force a discrete interaction
0085             sim.post_step_action(phys.scalars().discrete_action());
0086         }
0087     }
0088 }
0089 
0090 //---------------------------------------------------------------------------//
0091 }  // namespace detail
0092 }  // namespace celeritas