Back to home page

EIC code displayed by LXR

 
 

    


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

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/em/interactor/AtomicRelaxationHelper.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Span.hh"
0012 #include "corecel/sys/ThreadId.hh"
0013 #include "geocel/random/IsotropicDistribution.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/em/data/AtomicRelaxationData.hh"
0016 
0017 #include "AtomicRelaxation.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Helper class for atomic relaxation.
0024  *
0025  * This class can be used inside an \c Interactor to simplify the creation of
0026  * the sampling distribution for relaxation and the allocation of storage for
0027  * secondaries created in both relaxation and the primary process.
0028  *
0029  * \code
0030     // Allocate secondaries for a model that produces a single secondary
0031     Span<Secondary> secondaries;
0032     size_type       count = relax_helper.max_secondaries() + 1;
0033     if (Secondary* ptr = allocate_secondaries(count))
0034     {
0035         secondaries = {ptr, count};
0036     }
0037     else
0038     {
0039         return Interaction::from_failure();
0040     }
0041     Interaction result;
0042 
0043     // ...
0044 
0045     AtomicRelaxation sample_relaxation = relax_helper.build_distribution(
0046         cutoffs, shell_id, secondaries.subspan(1));
0047     auto outgoing             = sample_relaxation(rng);
0048     result.secondaries        = outgoing.secondaries;
0049     result.energy_deposition -= outgoing.energy;
0050    \endcode
0051  */
0052 class AtomicRelaxationHelper
0053 {
0054   public:
0055     // Construct with the currently interacting element
0056     inline CELER_FUNCTION
0057     AtomicRelaxationHelper(AtomicRelaxParamsRef const& shared,
0058                            AtomicRelaxStateRef const& states,
0059                            ElementId el_id,
0060                            TrackSlotId tid);
0061 
0062     // Whether atomic relaxation should be applied
0063     explicit inline CELER_FUNCTION operator bool() const;
0064 
0065     // Space needed for relaxation secondaries
0066     inline CELER_FUNCTION size_type max_secondaries() const;
0067 
0068     // Storage for subshell ID stack
0069     inline CELER_FUNCTION Span<SubshellId> scratch() const;
0070 
0071     // Create the sampling distribution from sampled shell and allocated mem
0072     inline CELER_FUNCTION AtomicRelaxation
0073     build_distribution(CutoffView const& cutoffs,
0074                        SubshellId shell_id,
0075                        Span<Secondary> secondaries) const;
0076 
0077   private:
0078     AtomicRelaxParamsRef const& shared_;
0079     AtomicRelaxStateRef const& states_;
0080     ElementId const el_id_;
0081     TrackSlotId const track_slot_;
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 // INLINE DEFINITIONS
0086 //---------------------------------------------------------------------------//
0087 /*!
0088  * Construct with shared and state data.
0089  */
0090 CELER_FUNCTION
0091 AtomicRelaxationHelper::AtomicRelaxationHelper(
0092     AtomicRelaxParamsRef const& shared,
0093     AtomicRelaxStateRef const& states,
0094     ElementId el_id,
0095     TrackSlotId tid)
0096     : shared_(shared), states_(states), el_id_(el_id), track_slot_(tid)
0097 {
0098     CELER_EXPECT(!shared_ || el_id_ < shared_.elements.size());
0099     CELER_EXPECT(!states_ || track_slot_ < states.size());
0100     CELER_EXPECT(bool(shared_) == bool(states_));
0101 }
0102 
0103 //---------------------------------------------------------------------------//
0104 /*!
0105  * Whether atomic relaxation should be applied.
0106  */
0107 CELER_FUNCTION AtomicRelaxationHelper::operator bool() const
0108 {
0109     // Atomic relaxation is enabled and the element has transition data
0110     return shared_ && shared_.elements[el_id_];
0111 }
0112 
0113 //---------------------------------------------------------------------------//
0114 /*!
0115  * Maximum number of secondaries that can be produced.
0116  */
0117 CELER_FUNCTION size_type AtomicRelaxationHelper::max_secondaries() const
0118 {
0119     CELER_EXPECT(*this);
0120     return shared_.elements[el_id_].max_secondary;
0121 }
0122 
0123 //---------------------------------------------------------------------------//
0124 /*!
0125  * Access scratch space.
0126  *
0127  * This temporary data is needed as part of a stack while processing the
0128  * cascade of electrons.
0129  */
0130 CELER_FUNCTION Span<SubshellId> AtomicRelaxationHelper::scratch() const
0131 {
0132     CELER_EXPECT(*this);
0133     auto offset = track_slot_.get() * shared_.max_stack_size;
0134     Span<SubshellId> all_scratch
0135         = states_.scratch[AllItems<SubshellId, MemSpace::native>{}];
0136     CELER_ENSURE(offset + shared_.max_stack_size <= all_scratch.size());
0137     return {all_scratch.data() + offset, shared_.max_stack_size};
0138 }
0139 
0140 //---------------------------------------------------------------------------//
0141 /*!
0142  * Create the sampling distribution.
0143  */
0144 CELER_FUNCTION AtomicRelaxation
0145 AtomicRelaxationHelper::build_distribution(CutoffView const& cutoffs,
0146                                            SubshellId shell_id,
0147                                            Span<Secondary> secondaries) const
0148 {
0149     CELER_EXPECT(*this);
0150     CELER_EXPECT(secondaries.size() == this->max_secondaries());
0151     return AtomicRelaxation{
0152         shared_, cutoffs, el_id_, shell_id, secondaries, this->scratch()};
0153 }
0154 
0155 //---------------------------------------------------------------------------//
0156 }  // namespace celeritas