Back to home page

EIC code displayed by LXR

 
 

    


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

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