File indexing completed on 2026-01-01 09:40:25
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 #include "celeritas/global/CoreTrackData.hh"
0013 #include "celeritas/global/CoreTrackView.hh"
0014 #include "celeritas/user/StepData.hh"
0015
0016 namespace celeritas
0017 {
0018 namespace detail
0019 {
0020
0021
0022
0023
0024 template<StepPoint P>
0025 struct StepGatherExecutor
0026 {
0027 NativeCRef<StepParamsData> const params;
0028 NativeRef<StepStateData> const state;
0029
0030 inline CELER_FUNCTION void
0031 operator()(celeritas::CoreTrackView const& track);
0032
0033 inline CELER_FUNCTION void fill(celeritas::CoreTrackView const& track);
0034 };
0035
0036
0037
0038
0039
0040
0041
0042 template<StepPoint P>
0043 CELER_FUNCTION void
0044 StepGatherExecutor<P>::operator()(celeritas::CoreTrackView const& track)
0045 {
0046 CELER_EXPECT(params && state);
0047
0048 {
0049 auto const sim = track.sim();
0050 bool inactive = (sim.status() == TrackStatus::inactive
0051 || sim.status() == TrackStatus::errored);
0052
0053 if (P == StepPoint::post)
0054 {
0055
0056 this->state.data.track_id[track.track_slot_id()]
0057 = inactive ? TrackId{} : sim.track_id();
0058 }
0059
0060 if (inactive)
0061 {
0062 if (P == StepPoint::pre && !this->params.detector.empty())
0063 {
0064
0065 this->state.data.detector[track.track_slot_id()] = {};
0066 }
0067
0068
0069 return;
0070 }
0071 }
0072
0073 if (!this->params.detector.empty())
0074 {
0075
0076
0077 if (P == StepPoint::pre)
0078 {
0079 auto const geo = track.geometry();
0080 CELER_ASSERT(!geo.is_outside());
0081 VolumeId vol = geo.volume_id();
0082 CELER_ASSERT(vol);
0083
0084
0085 this->state.data.detector[track.track_slot_id()]
0086 = this->params.detector[vol];
0087 }
0088
0089 if (!this->state.data.detector[track.track_slot_id()])
0090 {
0091
0092 return;
0093 }
0094
0095 if (P == StepPoint::post && this->params.nonzero_energy_deposition)
0096 {
0097
0098 auto const pstep = track.physics_step();
0099 if (pstep.energy_deposition() == zero_quantity())
0100 {
0101
0102 this->state.data.detector[track.track_slot_id()] = {};
0103 return;
0104 }
0105 }
0106 }
0107
0108 this->fill(track);
0109 }
0110
0111
0112
0113
0114
0115 template<StepPoint P>
0116 CELER_FUNCTION void
0117 StepGatherExecutor<P>::fill(celeritas::CoreTrackView const& track)
0118 {
0119 #define SGL_SET_IF_SELECTED(ATTR, VALUE) \
0120 do \
0121 { \
0122 if (this->params.selection.ATTR) \
0123 { \
0124 this->state.data.ATTR[track.track_slot_id()] = VALUE; \
0125 } \
0126 } while (0)
0127
0128 {
0129 auto const sim = track.sim();
0130
0131 SGL_SET_IF_SELECTED(points[P].time, sim.time());
0132 if constexpr (P == StepPoint::post)
0133 {
0134 SGL_SET_IF_SELECTED(event_id, sim.event_id());
0135 SGL_SET_IF_SELECTED(parent_id, sim.parent_id());
0136 SGL_SET_IF_SELECTED(primary_id, sim.primary_id());
0137 SGL_SET_IF_SELECTED(track_step_count, sim.num_steps());
0138
0139 SGL_SET_IF_SELECTED(action_id, sim.post_step_action());
0140 SGL_SET_IF_SELECTED(step_length, sim.step_length());
0141 SGL_SET_IF_SELECTED(weight, sim.weight());
0142 }
0143 }
0144
0145 {
0146 auto const geo = track.geometry();
0147
0148 SGL_SET_IF_SELECTED(points[P].pos, geo.pos());
0149 SGL_SET_IF_SELECTED(points[P].dir, geo.dir());
0150 SGL_SET_IF_SELECTED(points[P].volume_id,
0151 geo.is_outside() ? VolumeId{} : geo.volume_id());
0152
0153 if (this->params.selection.points[P].volume_instance_ids)
0154 {
0155 auto dst = [this,
0156 &vid = this->state.data.points[P].volume_instance_ids,
0157 tid = track.track_slot_id()] {
0158
0159 size_type const size = this->params.volume_instance_depth;
0160 size_type offset = tid.unchecked_get() * size;
0161 auto all_ids = vid[AllItems<VolumeInstanceId>{}];
0162 return all_ids.subspan(offset, size);
0163 }();
0164
0165
0166 size_type depth
0167 = geo.is_outside() ? 0 : geo.level().unchecked_get() + 1;
0168 CELER_ASSERT(depth <= dst.size());
0169 if (depth != 0)
0170 {
0171 geo.volume_instance_id(dst.first(depth));
0172 }
0173 if constexpr (CELERITAS_DEBUG)
0174 {
0175 for (auto level : range(depth))
0176 {
0177 CELER_ASSERT(dst[level]);
0178 }
0179 }
0180
0181
0182 for (auto level : range<size_type>(depth, dst.size()))
0183 {
0184 dst[level] = {};
0185 }
0186 }
0187 }
0188
0189 {
0190 auto const par = track.particle();
0191
0192 if constexpr (P == StepPoint::post)
0193 {
0194 auto const pstep = track.physics_step();
0195 SGL_SET_IF_SELECTED(energy_deposition, pstep.energy_deposition());
0196 SGL_SET_IF_SELECTED(particle, par.particle_id());
0197 }
0198 SGL_SET_IF_SELECTED(points[P].energy, par.energy());
0199 }
0200 #undef SGL_SET_IF_SELECTED
0201 }
0202
0203
0204 }
0205 }