Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:11:38

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/WlsGeneratorAction.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <memory>
0010 
0011 #include "corecel/Macros.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/data/AuxInterface.hh"
0014 #include "corecel/data/AuxStateVec.hh"
0015 #include "celeritas/optical/action/ActionInterface.hh"
0016 #include "celeritas/phys/GeneratorInterface.hh"
0017 
0018 #include "GeneratorBase.hh"
0019 #include "GeneratorData.hh"
0020 #include "OffloadData.hh"
0021 
0022 namespace celeritas
0023 {
0024 namespace optical
0025 {
0026 class CoreParams;
0027 class CoreStateBase;
0028 class WavelengthShiftModel;
0029 
0030 //---------------------------------------------------------------------------//
0031 /*!
0032  * Generate photons from optical wavelength shifting distribution data.
0033  *
0034  * This samples and initializes optical photons directly in a track slot in a
0035  * reproducible way. At each step of the optical loop:
0036  * - The distribution buffer is compacted to remove invalid distributions
0037  * - An inclusive scan over \c num_photons is computed. All distributions up to
0038  *   the buffer size are guaranteed to have a positive photon count.
0039  * - Each thread is assigned to exactly one photon via the cumulative sum \c
0040  *   offsets array and generates one WLS secondary in a vacant track slot.
0041  * - The photon count in the distribution is decremented atomically after
0042  *   generation. Because the thread to distribution mapping is determined from
0043  *   the pre-generation cumulative sum, \c num_photons can only reach zero
0044  *   after all threads assigned to a distribution have generated from it. The
0045  *   updated counts are used solely to identify exhausted distributions during
0046  *   the subsequent compaction.
0047  * - The buffer is compacted again to free space for new distributions that may
0048  *   be added during the step.
0049  *
0050  * This differs from the Cherenkov/scintillation generation in a few ways:
0051  * - New WLS distributions can be added during the optical stepping loop, so
0052  *   the buffer must be compacted each step to reclaim space.
0053  * - Because the buffer is compacted before generation, there are no
0054  *   zero-photon distributions in the active portion of the buffer; the
0055  *   executor does not need to skip over them by finding the \c buffer_start
0056  *   offset.
0057  * - The number of photons generated in a WLS interaction is small (O(1))
0058  *   compared to scintillation, which can be large (O(1000)), so there should
0059  *   be very few collisions in the atomic update and it should have no
0060  *   performance impact.
0061  */
0062 class WlsGeneratorAction final : public GeneratorBase
0063 {
0064   public:
0065     //!@{
0066     //! \name Type aliases
0067     using SPConstWavelengthShiftModel
0068         = std::shared_ptr<WavelengthShiftModel const>;
0069     //!@}
0070 
0071   public:
0072     struct Input
0073     {
0074         ActionId action_id;
0075         AuxId aux_id;
0076         GeneratorId gen_id;
0077         SPConstWavelengthShiftModel wls;
0078         SPConstWavelengthShiftModel wls2;
0079         size_type capacity{};
0080     };
0081 
0082     // Construct with IDs, WLS model, and buffer capacity
0083     explicit WlsGeneratorAction(Input&&);
0084 
0085     //!@{
0086     //! \name Aux interface
0087 
0088     // Build state data for a stream
0089     UPState create_state(MemSpace, StreamId, size_type) const final;
0090     //!@}
0091 
0092     //!@{
0093     //! \name StepAction interface
0094 
0095     // Launch kernel with host data
0096     void step(CoreParams const&, CoreStateHost&) const final;
0097     // Launch kernel with device data
0098     void step(CoreParams const&, CoreStateDevice&) const final;
0099     //!@}
0100 
0101   private:
0102     //// DATA ////
0103 
0104     SPConstWavelengthShiftModel wls_;
0105     SPConstWavelengthShiftModel wls2_;
0106     size_type capacity_;
0107 
0108     //// HELPER FUNCTIONS ////
0109 
0110     template<MemSpace M>
0111     void step_impl(CoreParams const&, CoreState<M>&) const;
0112 
0113     void generate(CoreParams const&, CoreStateHost&) const;
0114     void generate(CoreParams const&, CoreStateDevice&) const;
0115 };
0116 
0117 //---------------------------------------------------------------------------//
0118 }  // namespace optical
0119 }  // namespace celeritas