File indexing completed on 2025-02-22 10:31:26
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/CerenkovGenerator.hh"
0015 #include "celeritas/optical/OffloadData.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 CerenkovGeneratorExecutor
0031 {
0032
0033
0034 RefPtr<CoreStateData, MemSpace::native> state;
0035 NativeCRef<celeritas::optical::MaterialParamsData> const material;
0036 NativeCRef<celeritas::optical::CerenkovData> const cerenkov;
0037 NativeRef<OffloadStateData> const offload_state;
0038 RefPtr<celeritas::optical::CoreStateData, MemSpace::native> optical_state;
0039 OffloadBufferSize size;
0040 CoreStateCounters counters;
0041
0042
0043
0044
0045 inline CELER_FUNCTION void operator()(CoreTrackView const& track) const;
0046 };
0047
0048
0049
0050
0051
0052
0053
0054 CELER_FUNCTION void
0055 CerenkovGeneratorExecutor::operator()(CoreTrackView const& track) const
0056 {
0057 CELER_EXPECT(state);
0058 CELER_EXPECT(cerenkov);
0059 CELER_EXPECT(material);
0060 CELER_EXPECT(offload_state);
0061 CELER_EXPECT(optical_state);
0062 CELER_EXPECT(size.cerenkov <= offload_state.cerenkov.size());
0063
0064 using DistId = ItemId<celeritas::optical::GeneratorDistributionData>;
0065 using InitId = ItemId<celeritas::optical::TrackInitializer>;
0066
0067
0068
0069
0070 auto offsets = offload_state.offsets[ItemRange<size_type>(
0071 ItemId<size_type>(0), ItemId<size_type>(size.cerenkov))];
0072
0073
0074 size_type total_work = offsets.back();
0075
0076
0077 size_type local_work = LocalWorkCalculator<size_type>{
0078 total_work, state->size()}(track.thread_id().get());
0079
0080 auto rng = track.make_rng_engine();
0081
0082 for (auto i : range(local_work))
0083 {
0084
0085 size_type idx = i * state->size() + track.thread_id().get();
0086
0087
0088 size_type dist_idx = find_distribution_index(offsets, idx);
0089 CELER_ASSERT(dist_idx < size.cerenkov);
0090 auto const& dist = offload_state.cerenkov[DistId(dist_idx)];
0091 CELER_ASSERT(dist);
0092
0093
0094 optical::MaterialView opt_mat{material, dist.material};
0095 celeritas::optical::CerenkovGenerator generate(opt_mat, cerenkov, dist);
0096 size_type init_idx = counters.num_initializers + idx;
0097 CELER_ASSERT(init_idx < optical_state->init.initializers.size());
0098 optical_state->init.initializers[InitId(init_idx)] = generate(rng);
0099 }
0100 }
0101
0102
0103 }
0104 }