Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-23 09:06:37

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/optical/detail/ScintGeneratorExecutor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/math/Algorithms.hh"
0012 #include "celeritas/track/CoreStateCounters.hh"
0013 
0014 #include "OpticalUtils.hh"
0015 #include "../CoreTrackView.hh"
0016 #include "../OffloadData.hh"
0017 #include "../ScintillationGenerator.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace detail
0022 {
0023 //---------------------------------------------------------------------------//
0024 // LAUNCHER
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Generate scintillation photons from optical distribution data.
0028  */
0029 struct ScintGeneratorExecutor
0030 {
0031     //// DATA ////
0032 
0033     RefPtr<CoreStateData, MemSpace::native> state;
0034     NativeCRef<celeritas::optical::ScintillationData> const scintillation;
0035     NativeRef<OffloadStateData> const offload_state;
0036     RefPtr<celeritas::optical::CoreStateData, MemSpace::native> optical_state;
0037     OpticalOffloadCounters<> size;
0038     CoreStateCounters counters;
0039 
0040     //// FUNCTIONS ////
0041 
0042     // Generate optical track initializers
0043     inline CELER_FUNCTION void operator()(CoreTrackView const& track) const;
0044 };
0045 
0046 //---------------------------------------------------------------------------//
0047 // INLINE DEFINITIONS
0048 //---------------------------------------------------------------------------//
0049 /*!
0050  * Generate scintillation photons from optical distribution data.
0051  */
0052 CELER_FUNCTION void
0053 ScintGeneratorExecutor::operator()(CoreTrackView const& track) const
0054 {
0055     CELER_EXPECT(state);
0056     CELER_EXPECT(scintillation);
0057     CELER_EXPECT(offload_state);
0058     CELER_EXPECT(optical_state);
0059     CELER_EXPECT(size.scintillation <= offload_state.scintillation.size());
0060 
0061     using DistId = ItemId<celeritas::optical::GeneratorDistributionData>;
0062     using InitId = ItemId<celeritas::optical::TrackInitializer>;
0063 
0064     // Get the cumulative sum of the number of photons in the distributions.
0065     // Each bin gives the range of thread IDs that will generate from the
0066     // corresponding distribution
0067     auto offsets = offload_state.offsets[ItemRange<size_type>(
0068         ItemId<size_type>(0), ItemId<size_type>(size.scintillation))];
0069 
0070     // Get the total number of initializers to generate
0071     size_type total_work = offsets.back();
0072 
0073     // Calculate the number of initializers for the thread to generate
0074     size_type local_work = LocalWorkCalculator<size_type>{
0075         total_work, state->size()}(track.thread_id().get());
0076 
0077     auto rng = track.rng();
0078 
0079     for (auto i : range(local_work))
0080     {
0081         // Calculate the index in the initializer buffer (minus the offset)
0082         size_type idx = i * state->size() + track.thread_id().get();
0083 
0084         // Find the distribution this thread will generate from
0085         size_type dist_idx = find_distribution_index(offsets, idx);
0086         CELER_ASSERT(dist_idx < size.scintillation);
0087         auto const& dist = offload_state.scintillation[DistId(dist_idx)];
0088         CELER_ASSERT(dist);
0089 
0090         // Generate one primary from the distribution
0091         celeritas::optical::ScintillationGenerator generate(scintillation,
0092                                                             dist);
0093         size_type init_idx = counters.num_initializers + idx;
0094         CELER_ASSERT(init_idx < optical_state->init.initializers.size());
0095         optical_state->init.initializers[InitId(init_idx)] = generate(rng);
0096     }
0097 }
0098 
0099 //---------------------------------------------------------------------------//
0100 }  // namespace detail
0101 }  // namespace celeritas