Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-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/user/detail/StepGatherExecutor.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Macros.hh"
0012 #include "celeritas/global/CoreTrackData.hh"
0013 #include "celeritas/global/CoreTrackView.hh"
0014 
0015 namespace celeritas
0016 {
0017 namespace detail
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Gather step data for transfer to user hits.
0022  */
0023 template<StepPoint P>
0024 struct StepGatherExecutor
0025 {
0026     inline CELER_FUNCTION void
0027     operator()(celeritas::CoreTrackView const& track);
0028 
0029     NativeCRef<StepParamsData> const params;
0030     NativeRef<StepStateData> const state;
0031 };
0032 
0033 //---------------------------------------------------------------------------//
0034 // INLINE DEFINITIONS
0035 //---------------------------------------------------------------------------//
0036 /*!
0037  * Gather step data on device based on the user selection.
0038  */
0039 template<StepPoint P>
0040 CELER_FUNCTION void
0041 StepGatherExecutor<P>::operator()(celeritas::CoreTrackView const& track)
0042 {
0043     CELER_EXPECT(params && state);
0044 
0045 #define SGL_SET_IF_SELECTED(ATTR, VALUE)                          \
0046     do                                                            \
0047     {                                                             \
0048         if (this->params.selection.ATTR)                          \
0049         {                                                         \
0050             this->state.data.ATTR[track.track_slot_id()] = VALUE; \
0051         }                                                         \
0052     } while (0)
0053 
0054     {
0055         auto const sim = track.make_sim_view();
0056         bool inactive = (sim.status() == TrackStatus::inactive);
0057 
0058         if (P == StepPoint::post)
0059         {
0060             // Always save track ID to clear output from inactive slots
0061             this->state.data.track_id[track.track_slot_id()]
0062                 = inactive ? TrackId{} : sim.track_id();
0063         }
0064 
0065         if (inactive)
0066         {
0067             if (P == StepPoint::pre && !this->params.detector.empty())
0068             {
0069                 // Clear detector ID for inactive threads
0070                 this->state.data.detector[track.track_slot_id()] = {};
0071             }
0072 
0073             // No more data to be written
0074             return;
0075         }
0076     }
0077 
0078     if (!this->params.detector.empty())
0079     {
0080         // Apply detector filter at beginning of step (volume in which we're
0081         // stepping)
0082         if (P == StepPoint::pre)
0083         {
0084             auto const geo = track.make_geo_view();
0085             CELER_ASSERT(!geo.is_outside());
0086             VolumeId vol = geo.volume_id();
0087             CELER_ASSERT(vol);
0088 
0089             // Map volume ID to detector ID
0090             this->state.data.detector[track.track_slot_id()]
0091                 = this->params.detector[vol];
0092         }
0093 
0094         if (!this->state.data.detector[track.track_slot_id()])
0095         {
0096             // We're not in a sensitive detector: don't save any further data
0097             return;
0098         }
0099 
0100         if (P == StepPoint::post && this->params.nonzero_energy_deposition)
0101         {
0102             // Filter out tracks that didn't deposit energy over the step
0103             auto const pstep = track.make_physics_step_view();
0104             if (pstep.energy_deposition() == zero_quantity())
0105             {
0106                 // Clear detector ID and stop recording
0107                 this->state.data.detector[track.track_slot_id()] = {};
0108                 return;
0109             }
0110         }
0111     }
0112 
0113     {
0114         auto const sim = track.make_sim_view();
0115 
0116         SGL_SET_IF_SELECTED(points[P].time, sim.time());
0117         if (P == StepPoint::post)
0118         {
0119             SGL_SET_IF_SELECTED(event_id, sim.event_id());
0120             SGL_SET_IF_SELECTED(parent_id, sim.parent_id());
0121             SGL_SET_IF_SELECTED(track_step_count, sim.num_steps());
0122 
0123             SGL_SET_IF_SELECTED(action_id, sim.post_step_action());
0124             SGL_SET_IF_SELECTED(step_length, sim.step_length());
0125         }
0126     }
0127 
0128     {
0129         auto const geo = track.make_geo_view();
0130 
0131         SGL_SET_IF_SELECTED(points[P].pos, geo.pos());
0132         SGL_SET_IF_SELECTED(points[P].dir, geo.dir());
0133         SGL_SET_IF_SELECTED(points[P].volume_id,
0134                             geo.is_outside() ? VolumeId{} : geo.volume_id());
0135     }
0136 
0137     {
0138         auto const par = track.make_particle_view();
0139 
0140         if (P == StepPoint::post)
0141         {
0142             auto const pstep = track.make_physics_step_view();
0143             SGL_SET_IF_SELECTED(energy_deposition, pstep.energy_deposition());
0144             SGL_SET_IF_SELECTED(particle, par.particle_id());
0145         }
0146         SGL_SET_IF_SELECTED(points[P].energy, par.energy());
0147     }
0148 #undef SGL_SET_IF_SELECTED
0149 }
0150 
0151 //---------------------------------------------------------------------------//
0152 }  // namespace detail
0153 }  // namespace celeritas