File indexing completed on 2025-02-22 10:31:27
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/math/Algorithms.hh"
0013 #include "celeritas/global/CoreTrackView.hh"
0014 #include "celeritas/optical/OffloadData.hh"
0015 #include "celeritas/optical/ScintillationGenerator.hh"
0016 #include "celeritas/track/CoreStateCounters.hh"
0017
0018 #include "OpticalUtils.hh"
0019
0020 namespace celeritas
0021 {
0022 namespace detail
0023 {
0024
0025
0026
0027
0028
0029
0030 struct ScintGeneratorExecutor
0031 {
0032
0033
0034 RefPtr<CoreStateData, MemSpace::native> state;
0035 NativeCRef<celeritas::optical::ScintillationData> const scintillation;
0036 NativeRef<OffloadStateData> const offload_state;
0037 RefPtr<celeritas::optical::CoreStateData, MemSpace::native> optical_state;
0038 OffloadBufferSize size;
0039 CoreStateCounters counters;
0040
0041
0042
0043
0044 inline CELER_FUNCTION void operator()(CoreTrackView const& track) const;
0045 };
0046
0047
0048
0049
0050
0051
0052
0053 CELER_FUNCTION void
0054 ScintGeneratorExecutor::operator()(CoreTrackView const& track) const
0055 {
0056 CELER_EXPECT(state);
0057 CELER_EXPECT(scintillation);
0058 CELER_EXPECT(offload_state);
0059 CELER_EXPECT(optical_state);
0060 CELER_EXPECT(size.scintillation <= offload_state.scintillation.size());
0061
0062 using DistId = ItemId<celeritas::optical::GeneratorDistributionData>;
0063 using InitId = ItemId<celeritas::optical::TrackInitializer>;
0064
0065
0066
0067
0068 auto offsets = offload_state.offsets[ItemRange<size_type>(
0069 ItemId<size_type>(0), ItemId<size_type>(size.scintillation))];
0070
0071
0072 size_type total_work = offsets.back();
0073
0074
0075 size_type local_work = LocalWorkCalculator<size_type>{
0076 total_work, state->size()}(track.thread_id().get());
0077
0078 auto rng = track.make_rng_engine();
0079
0080 for (auto i : range(local_work))
0081 {
0082
0083 size_type idx = i * state->size() + track.thread_id().get();
0084
0085
0086 size_type dist_idx = find_distribution_index(offsets, idx);
0087 CELER_ASSERT(dist_idx < size.scintillation);
0088 auto const& dist = offload_state.scintillation[DistId(dist_idx)];
0089 CELER_ASSERT(dist);
0090
0091
0092 celeritas::optical::ScintillationGenerator generate(scintillation,
0093 dist);
0094 size_type init_idx = counters.num_initializers + idx;
0095 CELER_ASSERT(init_idx < optical_state->init.initializers.size());
0096 optical_state->init.initializers[InitId(init_idx)] = generate(rng);
0097 }
0098 }
0099
0100
0101 }
0102 }