File indexing completed on 2025-02-22 10:31:31
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Macros.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/math/Atomics.hh"
0014 #include "corecel/sys/ThreadId.hh"
0015 #include "celeritas/Quantities.hh"
0016 #include "celeritas/Types.hh"
0017 #include "celeritas/geo/GeoTrackView.hh"
0018 #include "celeritas/global/CoreTrackData.hh"
0019 #include "celeritas/phys/ParticleData.hh"
0020 #include "celeritas/phys/ParticleTrackView.hh"
0021 #include "celeritas/phys/PhysicsStepView.hh"
0022 #include "celeritas/phys/PhysicsTrackView.hh"
0023 #include "celeritas/phys/Secondary.hh"
0024
0025 #include "../CoreStateCounters.hh"
0026 #include "../SimTrackView.hh"
0027
0028 namespace celeritas
0029 {
0030 namespace detail
0031 {
0032
0033
0034
0035
0036 struct ProcessSecondariesExecutor
0037 {
0038
0039
0040 using ParamsPtr = CRefPtr<CoreParamsData, MemSpace::native>;
0041 using StatePtr = RefPtr<CoreStateData, MemSpace::native>;
0042
0043
0044
0045 ParamsPtr params;
0046 StatePtr state;
0047 CoreStateCounters counters;
0048
0049
0050
0051
0052 inline CELER_FUNCTION void operator()(TrackSlotId tid) const;
0053
0054 CELER_FORCEINLINE_FUNCTION void operator()(ThreadId tid) const
0055 {
0056
0057
0058 return (*this)(TrackSlotId{tid.unchecked_get()});
0059 }
0060 };
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 CELER_FUNCTION void
0071 ProcessSecondariesExecutor::operator()(TrackSlotId tid) const
0072 {
0073 CELER_EXPECT(tid < state->size());
0074
0075 SimTrackView sim(params->sim, state->sim, tid);
0076 if (sim.status() == TrackStatus::inactive)
0077 {
0078
0079 return;
0080 }
0081
0082
0083 auto const& data = state->init;
0084 CELER_ASSERT(data.secondary_counts[tid] <= counters.num_secondaries);
0085 size_type offset = counters.num_secondaries - data.secondary_counts[tid];
0086
0087
0088 bool initialized = false;
0089
0090
0091
0092 TrackId const parent_id{sim.track_id()};
0093
0094 PhysicsStepView const phys_step(params->physics, state->physics, tid);
0095 for (auto const& secondary : phys_step.secondaries())
0096 {
0097 if (secondary)
0098 {
0099 CELER_ASSERT(secondary.energy > zero_quantity()
0100 && is_soft_unit_vector(secondary.direction));
0101
0102
0103
0104 GeoTrackView geo(params->geometry, state->geometry, tid);
0105 CELER_ASSERT(!geo.is_on_boundary());
0106
0107
0108
0109
0110
0111
0112
0113
0114 CELER_ASSERT(sim.event_id() < data.track_counters.size());
0115 TrackId::size_type track_id = atomic_add(
0116 &data.track_counters[sim.event_id()], size_type{1});
0117
0118
0119 TrackInitializer ti;
0120 ti.sim.track_id = TrackId{track_id};
0121 ti.sim.parent_id = parent_id;
0122 ti.sim.event_id = sim.event_id();
0123 ti.sim.time = sim.time();
0124 ti.geo.pos = geo.pos();
0125 ti.geo.dir = secondary.direction;
0126 ti.particle.particle_id = secondary.particle_id;
0127 ti.particle.energy = secondary.energy;
0128 CELER_ASSERT(ti);
0129
0130 if (!initialized && sim.status() != TrackStatus::alive
0131 && params->init.track_order != TrackOrder::init_charge)
0132 {
0133
0134
0135
0136
0137
0138
0139
0140
0141 ParticleTrackView particle(
0142 params->particles, state->particles, tid);
0143 PhysicsTrackView phys(
0144 params->physics, state->physics, {}, {}, tid);
0145
0146
0147
0148
0149
0150
0151
0152 sim = ti.sim;
0153 geo = GeoTrackView::DetailedInitializer{geo, ti.geo.dir};
0154 particle = ti.particle;
0155 phys = {};
0156 initialized = true;
0157
0158
0159
0160
0161
0162 }
0163 else
0164 {
0165
0166 CELER_ASSERT(offset > 0 && offset <= counters.num_initializers);
0167 data.initializers[ItemId<TrackInitializer>{
0168 counters.num_initializers - offset}]
0169 = ti;
0170
0171 if (offset <= data.parents.size()
0172 && (params->init.track_order != TrackOrder::init_charge
0173 || sim.status() == TrackStatus::alive))
0174 {
0175
0176
0177
0178
0179
0180
0181 data.parents[TrackSlotId(data.parents.size() - offset)]
0182 = tid;
0183 }
0184 --offset;
0185 }
0186 }
0187 }
0188
0189 if (!initialized && sim.status() == TrackStatus::killed)
0190 {
0191
0192 sim.status(TrackStatus::inactive);
0193 }
0194 CELER_ENSURE(sim.status() != TrackStatus::killed);
0195 }
0196
0197
0198 }
0199 }