Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:44

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/optical/InteractionApplier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/sys/KernelTraits.hh"
0011 #include "celeritas/geo/GeoFwd.hh"
0012 
0013 #include "CoreTrackView.hh"
0014 #include "Interaction.hh"
0015 #include "ParticleTrackView.hh"
0016 #include "SimTrackView.hh"
0017 
0018 namespace celeritas
0019 {
0020 namespace optical
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Wrap an interaction executor and apply it to a track.
0025  *
0026  * The function F must take a \c CoreTrackView and return a \c Interaction
0027  */
0028 template<class F>
0029 struct InteractionApplierBaseImpl
0030 {
0031     F sample_interaction;
0032 
0033     CELER_FUNCTION void operator()(CoreTrackView const&);
0034 };
0035 
0036 //---------------------------------------------------------------------------//
0037 /*!
0038  * This class is partially specialized with a second template argument to
0039  * extract any launch bounds from the functor class.
0040  *
0041  * \todo Generalize this with the core interaction applier
0042  */
0043 template<class F, typename = void>
0044 struct InteractionApplier : public InteractionApplierBaseImpl<F>
0045 {
0046     CELER_FUNCTION InteractionApplier(F&& f)
0047         : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0048     {
0049     }
0050 };
0051 
0052 template<class F>
0053 struct InteractionApplier<F, std::enable_if_t<kernel_max_blocks_min_warps<F>>>
0054     : public InteractionApplierBaseImpl<F>
0055 {
0056     static constexpr int max_block_size = F::max_block_size;
0057     static constexpr int min_warps_per_eu = F::min_warps_per_eu;
0058 
0059     CELER_FUNCTION InteractionApplier(F&& f)
0060         : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0061     {
0062     }
0063 };
0064 
0065 template<class F>
0066 struct InteractionApplier<F, std::enable_if_t<kernel_max_blocks<F>>>
0067     : public InteractionApplierBaseImpl<F>
0068 {
0069     static constexpr int max_block_size = F::max_block_size;
0070 
0071     CELER_FUNCTION InteractionApplier(F&& f)
0072         : InteractionApplierBaseImpl<F>{celeritas::forward<F>(f)}
0073     {
0074     }
0075 };
0076 
0077 //---------------------------------------------------------------------------//
0078 // DEDUCTION GUIDES
0079 //---------------------------------------------------------------------------//
0080 template<class F>
0081 CELER_FUNCTION InteractionApplier(F&&) -> InteractionApplier<F>;
0082 
0083 //---------------------------------------------------------------------------//
0084 // INLINE DEFINITIONS
0085 //---------------------------------------------------------------------------//
0086 /*!
0087  * Sample an interaction and apply to the track view.
0088  *
0089  * The given track *must* be an active track with the correct step limit action
0090  * ID.
0091  */
0092 template<class F>
0093 CELER_FUNCTION void
0094 InteractionApplierBaseImpl<F>::operator()(CoreTrackView const& track)
0095 {
0096     Interaction result = this->sample_interaction(track);
0097 
0098     // Currently we have no optical actions capable of failing. This can be
0099     // added in the future as necessary.
0100     CELER_ASSERT(result.action != Interaction::Action::failed);
0101 
0102     if (result.action == Interaction::Action::absorbed)
0103     {
0104         // Mark particle as killed
0105         track.sim().status(TrackStatus::killed);
0106     }
0107     else
0108     {
0109         // Update direction and polarization
0110         track.geometry().set_dir(result.direction);
0111         track.particle().polarization(result.polarization);
0112     }
0113 }
0114 
0115 //---------------------------------------------------------------------------//
0116 }  // namespace optical
0117 }  // namespace celeritas