Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:22

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