Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/celeritas/phys/Interaction.hh was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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/phys/Interaction.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Config.hh"
0010 
0011 #include "corecel/Types.hh"
0012 #include "corecel/cont/Array.hh"
0013 #include "corecel/cont/Span.hh"
0014 #include "corecel/math/ArrayUtils.hh"
0015 #include "corecel/math/SoftEqual.hh"
0016 #include "celeritas/Quantities.hh"
0017 #include "celeritas/Types.hh"
0018 
0019 #include "Secondary.hh"
0020 #if CELERITAS_DEBUG
0021 #    include "corecel/math/NumericLimits.hh"
0022 #endif
0023 
0024 namespace celeritas
0025 {
0026 //---------------------------------------------------------------------------//
0027 /*!
0028  * Change in state due to an interaction.
0029  */
0030 struct Interaction
0031 {
0032     //! Interaction result category
0033     enum class Action
0034     {
0035         scattered,  //!< Still alive, state has changed
0036         absorbed,  //!< Absorbed or transformed to another particle type
0037         unchanged,  //!< No state change, no secondaries
0038         failed,  //!< Ran out of memory during sampling
0039     };
0040 
0041     units::MevEnergy energy;  //!< Post-interaction energy
0042     Real3 direction;  //!< Post-interaction direction
0043     Span<Secondary> secondaries;  //!< Emitted secondaries
0044     units::MevEnergy energy_deposition{0};  //!< Energy loss locally to
0045                                             //!< material
0046     Action action{Action::scattered};  //!< Flags for interaction result
0047 
0048     // Return an interaction representing a recoverable error
0049     static inline CELER_FUNCTION Interaction from_failure();
0050 
0051     // Return an interaction representing an absorbed process
0052     static inline CELER_FUNCTION Interaction from_absorption();
0053 
0054     // Return an interaction with no change in the track state
0055     static inline CELER_FUNCTION Interaction from_unchanged();
0056 
0057     //! Whether the state changed but did not fail
0058     CELER_FUNCTION bool changed() const
0059     {
0060         return static_cast<int>(action) < static_cast<int>(Action::unchanged);
0061     }
0062 };
0063 
0064 //---------------------------------------------------------------------------//
0065 /*!
0066  * Step lengths and properties needed to apply multiple scattering.
0067  *
0068  * \todo Document and/or refactor into a class that hides details
0069  * - alpha == small_step_alpha() ? "true path is very small" (true path scaling
0070  *   changes)
0071  * - is_displaced == false ? limit_min is unchanged and alpha ==
0072  *   small_step_alpha()
0073  * - true_step >= geom_path
0074  *
0075  * The value \f$ \alpha \f$ is used in the approximation of the MSC
0076  * transport cross section as a linear function over the current step. It is
0077  * the negative slope of the transport MFP from start to stop, divided by the
0078  * starting MFP. (Since the transport cross section generally decreases
0079  * monotonically with increasing energy over the step, alpha will usually be
0080  * positive or zero for the step. Some known errors in the cross sections for
0081  * positrons result in negative alpha around a discontinuity at 10 MeV.)
0082  */
0083 struct MscStep
0084 {
0085     //! Use a small step approximation for the path length correction
0086     static CELER_CONSTEXPR_FUNCTION real_type small_step_alpha() { return 0; }
0087 
0088     bool is_displaced{true};  //!< Flag for the lateral displacement
0089     real_type true_path{};  //!< True path length due to the msc [len]
0090     real_type geom_path{};  //!< Geometrical path length [len]
0091     real_type alpha = small_step_alpha();  //!< Scaled MFP slope [1/len]
0092 };
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Persistent range properties for multiple scattering (msc) within a volume.
0097  *
0098  * These values are calculated at the first step in every msc tracking volume
0099  * and reused at subsequent steps within the same volume.
0100  */
0101 struct MscRange
0102 {
0103     real_type range_init{};  //!< Initial msc range [len]
0104     real_type range_factor{};  //!< Scale factor for the msc range
0105     real_type limit_min{};  //!< Minimum of the true path limit [len]
0106 
0107     explicit CELER_FUNCTION operator bool() const
0108     {
0109         return range_init > 0 && range_factor > 0 && limit_min > 0;
0110     }
0111 };
0112 
0113 //---------------------------------------------------------------------------//
0114 /*!
0115  * Result of multiple scattering.
0116  */
0117 struct MscInteraction
0118 {
0119     //! Interaction result category
0120     enum class Action
0121     {
0122         unchanged,  //!< No state change
0123         scattered,  //!< Only direction changed
0124         displaced,  //!< Direction and position changed
0125         size_
0126     };
0127 
0128     Real3 direction;  //!< Post-step direction
0129     Real3 displacement;  //!< Lateral displacement
0130     Action action{Action::unchanged};  //!< Flags for interaction result
0131 };
0132 
0133 //---------------------------------------------------------------------------//
0134 // INLINE DEFINITIONS
0135 //---------------------------------------------------------------------------//
0136 /*!
0137  * Indicate a failure to allocate memory for secondaries.
0138  */
0139 CELER_FUNCTION Interaction Interaction::from_failure()
0140 {
0141     Interaction result;
0142     result.action = Action::failed;
0143     return result;
0144 }
0145 
0146 //---------------------------------------------------------------------------//
0147 /*!
0148  * Construct an interaction from a particle that was totally absorbed.
0149  */
0150 CELER_FUNCTION Interaction Interaction::from_absorption()
0151 {
0152     Interaction result;
0153     result.energy = zero_quantity();
0154 #if CELERITAS_DEBUG
0155     // Direction should *not* be accessed if incident particle is absorbed.
0156     constexpr auto nan = numeric_limits<real_type>::quiet_NaN();
0157     result.direction = {nan, nan, nan};
0158 #endif
0159     result.action = Action::absorbed;
0160     return result;
0161 }
0162 
0163 //---------------------------------------------------------------------------//
0164 /*!
0165  * Construct an interaction for edge cases where there is no state change.
0166  */
0167 CELER_FUNCTION Interaction Interaction::from_unchanged()
0168 {
0169     Interaction result;
0170     result.action = Action::unchanged;
0171     return result;
0172 }
0173 
0174 //---------------------------------------------------------------------------//
0175 }  // namespace celeritas