Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:42

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/CherenkovGeneratorExecutor.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 "../CherenkovGenerator.hh"
0016 #include "../CoreTrackView.hh"
0017 #include "../OffloadData.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace detail
0022 {
0023 //---------------------------------------------------------------------------//
0024 // LAUNCHER
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Generate Cherenkov photons from optical distribution data.
0028  */
0029 struct CherenkovGeneratorExecutor
0030 {
0031     //// DATA ////
0032 
0033     RefPtr<CoreStateData, MemSpace::native> state;
0034     NativeCRef<celeritas::optical::MaterialParamsData> const material;
0035     NativeCRef<celeritas::optical::CherenkovData> const cherenkov;
0036     NativeRef<OffloadStateData> const offload_state;
0037     RefPtr<celeritas::optical::CoreStateData, MemSpace::native> optical_state;
0038     OpticalOffloadCounters<> size;
0039     CoreStateCounters counters;
0040 
0041     //// FUNCTIONS ////
0042 
0043     // Generate optical track initializers
0044     inline CELER_FUNCTION void operator()(CoreTrackView const& track) const;
0045 };
0046 
0047 //---------------------------------------------------------------------------//
0048 // INLINE DEFINITIONS
0049 //---------------------------------------------------------------------------//
0050 /*!
0051  * Generate Cherenkov photons from optical distribution data.
0052  */
0053 CELER_FUNCTION void
0054 CherenkovGeneratorExecutor::operator()(CoreTrackView const& track) const
0055 {
0056     CELER_EXPECT(state);
0057     CELER_EXPECT(cherenkov);
0058     CELER_EXPECT(material);
0059     CELER_EXPECT(offload_state);
0060     CELER_EXPECT(optical_state);
0061     CELER_EXPECT(size.cherenkov <= offload_state.cherenkov.size());
0062 
0063     using DistId = ItemId<celeritas::optical::GeneratorDistributionData>;
0064     using InitId = ItemId<celeritas::optical::TrackInitializer>;
0065 
0066     // Get the cumulative sum of the number of photons in the distributions.
0067     // Each bin gives the range of thread IDs that will generate from the
0068     // corresponding distribution
0069     auto offsets = offload_state.offsets[ItemRange<size_type>(
0070         ItemId<size_type>(0), ItemId<size_type>(size.cherenkov))];
0071 
0072     // Get the total number of initializers to generate
0073     size_type total_work = offsets.back();
0074 
0075     // Calculate the number of initializers for the thread to generate
0076     size_type local_work = LocalWorkCalculator<size_type>{
0077         total_work, state->size()}(track.thread_id().get());
0078 
0079     auto rng = track.rng();
0080 
0081     for (auto i : range(local_work))
0082     {
0083         // Calculate the index in the initializer buffer (minus the offset)
0084         size_type idx = i * state->size() + track.thread_id().get();
0085 
0086         // Find the distribution this thread will generate from
0087         size_type dist_idx = find_distribution_index(offsets, idx);
0088         CELER_ASSERT(dist_idx < size.cherenkov);
0089         auto const& dist = offload_state.cherenkov[DistId(dist_idx)];
0090         CELER_ASSERT(dist);
0091 
0092         // Generate one primary from the distribution
0093         optical::MaterialView opt_mat{material, dist.material};
0094         celeritas::optical::CherenkovGenerator generate(opt_mat, cherenkov, dist);
0095         size_type init_idx = counters.num_initializers + idx;
0096         CELER_ASSERT(init_idx < optical_state->init.initializers.size());
0097         optical_state->init.initializers[InitId(init_idx)] = generate(rng);
0098     }
0099 }
0100 
0101 //---------------------------------------------------------------------------//
0102 }  // namespace detail
0103 }  // namespace celeritas