Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:27

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/optical/detail/ScintGeneratorExecutor.hh
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 // LAUNCHER
0026 //---------------------------------------------------------------------------//
0027 /*!
0028  * Generate scintillation photons from optical distribution data.
0029  */
0030 struct ScintGeneratorExecutor
0031 {
0032     //// DATA ////
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     //// 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 scintillation photons from optical distribution data.
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     // Get the cumulative sum of the number of photons in the distributions.
0066     // Each bin gives the range of thread IDs that will generate from the
0067     // corresponding distribution
0068     auto offsets = offload_state.offsets[ItemRange<size_type>(
0069         ItemId<size_type>(0), ItemId<size_type>(size.scintillation))];
0070 
0071     // Get the total number of initializers to generate
0072     size_type total_work = offsets.back();
0073 
0074     // Calculate the number of initializers for the thread to generate
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         // Calculate the index in the initializer buffer (minus the offset)
0083         size_type idx = i * state->size() + track.thread_id().get();
0084 
0085         // Find the distribution this thread will generate from
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         // Generate one primary from the distribution
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 }  // namespace detail
0102 }  // namespace celeritas