Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-10 10:05:47

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/gen/detail/GeneratorExecutor.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/optical/CoreTrackView.hh"
0013 #include "celeritas/optical/MaterialData.hh"
0014 #include "celeritas/track/CoreStateCounters.hh"
0015 #include "celeritas/track/detail/Utils.hh"
0016 
0017 #include "GeneratorTraits.hh"
0018 #include "OpticalGenAlgorithms.hh"
0019 #include "../OffloadData.hh"
0020 
0021 namespace celeritas
0022 {
0023 namespace detail
0024 {
0025 //---------------------------------------------------------------------------//
0026 // LAUNCHER
0027 //---------------------------------------------------------------------------//
0028 /*!
0029  * Generate photons from optical distribution data.
0030  */
0031 template<GeneratorType G>
0032 struct GeneratorExecutor
0033 {
0034     //// TYPES ////
0035 
0036     template<Ownership W, MemSpace M>
0037     using Data = typename GeneratorTraits<G>::template Data<W, M>;
0038     using Generator = typename GeneratorTraits<G>::Generator;
0039 
0040     //// DATA ////
0041 
0042     CRefPtr<celeritas::optical::CoreParamsData, MemSpace::native> params;
0043     RefPtr<celeritas::optical::CoreStateData, MemSpace::native> state;
0044     NativeCRef<celeritas::optical::MaterialParamsData> const material;
0045     NativeCRef<Data> const shared;
0046     NativeRef<GeneratorStateData> const offload;
0047     size_type buffer_size{};
0048     CoreStateCounters counters;
0049 
0050     //// FUNCTIONS ////
0051 
0052     // Generate optical photons
0053     inline CELER_FUNCTION void operator()(TrackSlotId tid) const;
0054     CELER_FORCEINLINE_FUNCTION void operator()(ThreadId tid) const
0055     {
0056         return (*this)(TrackSlotId{tid.unchecked_get()});
0057     }
0058 };
0059 
0060 //---------------------------------------------------------------------------//
0061 // INLINE DEFINITIONS
0062 //---------------------------------------------------------------------------//
0063 /*!
0064  * Generate photons from optical distribution data.
0065  */
0066 template<GeneratorType G>
0067 CELER_FUNCTION void GeneratorExecutor<G>::operator()(TrackSlotId tid) const
0068 {
0069     CELER_EXPECT(state);
0070     CELER_EXPECT(shared);
0071     CELER_EXPECT(material);
0072     CELER_EXPECT(offload);
0073 
0074     using DistId = ItemId<GeneratorDistributionData>;
0075 
0076     celeritas::optical::CoreTrackView track(*params, *state, tid);
0077 
0078     // Find the index of the first distribution that has a nonzero number of
0079     // primaries left to generate
0080     auto all_offsets = offload.offsets[ItemRange<size_type>(
0081         ItemId<size_type>(0), ItemId<size_type>(buffer_size))];
0082     auto buffer_start = celeritas::upper_bound(
0083         all_offsets.begin(), all_offsets.end(), size_type(0));
0084     CELER_ASSERT(buffer_start != all_offsets.end());
0085 
0086     // Get the cumulative sum of the number of photons in the distributions.
0087     // The values are used to determine which threads will generate from the
0088     // corresponding distribution
0089     Span<size_type> offsets{buffer_start, all_offsets.end()};
0090 
0091     // Find the distribution this thread will generate from
0092     size_type dist_idx = find_distribution_index(offsets, tid.get());
0093     CELER_ASSERT(dist_idx < offload.distributions.size());
0094     auto const& dist = offload.distributions[DistId(dist_idx)];
0095     CELER_ASSERT(dist);
0096 
0097     // Create the view to the new track to be initialized
0098     celeritas::optical::CoreTrackView vacancy{
0099         *params, *state, [&] {
0100             // Get the vacancy from the back in case there are more vacancies
0101             // than photons left to generate
0102             TrackSlotId idx{
0103                 index_before(counters.num_vacancies, ThreadId(tid.get()))};
0104             return state->init.vacancies[idx];
0105         }()};
0106 
0107     // Generate one primary from the distribution
0108     auto rng = track.rng();
0109     optical::MaterialView opt_mat{material, dist.material};
0110     vacancy = Generator(opt_mat, shared, dist)(rng);
0111 }
0112 
0113 //---------------------------------------------------------------------------//
0114 }  // namespace detail
0115 }  // namespace celeritas