![]() |
|
|||
File indexing completed on 2025-02-22 10:31:28
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/phys/Interaction.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include "corecel/Config.hh" 0011 0012 #include "corecel/Types.hh" 0013 #include "corecel/cont/Array.hh" 0014 #include "corecel/cont/Span.hh" 0015 #include "corecel/math/ArrayUtils.hh" 0016 #include "corecel/math/SoftEqual.hh" 0017 #include "celeritas/Quantities.hh" 0018 #include "celeritas/Types.hh" 0019 0020 #include "Secondary.hh" 0021 #if CELERITAS_DEBUG 0022 # include "corecel/math/NumericLimits.hh" 0023 #endif 0024 0025 namespace celeritas 0026 { 0027 //---------------------------------------------------------------------------// 0028 /*! 0029 * Change in state due to an interaction. 0030 */ 0031 struct Interaction 0032 { 0033 //! Interaction result category 0034 enum class Action 0035 { 0036 scattered, //!< Still alive, state has changed 0037 absorbed, //!< Absorbed or transformed to another particle type 0038 unchanged, //!< No state change, no secondaries 0039 failed, //!< Ran out of memory during sampling 0040 }; 0041 0042 units::MevEnergy energy; //!< Post-interaction energy 0043 Real3 direction; //!< Post-interaction direction 0044 Span<Secondary> secondaries; //!< Emitted secondaries 0045 units::MevEnergy energy_deposition{0}; //!< Energy loss locally to 0046 //!< material 0047 Action action{Action::scattered}; //!< Flags for interaction result 0048 0049 // Return an interaction representing a recoverable error 0050 static inline CELER_FUNCTION Interaction from_failure(); 0051 0052 // Return an interaction representing an absorbed process 0053 static inline CELER_FUNCTION Interaction from_absorption(); 0054 0055 // Return an interaction with no change in the track state 0056 static inline CELER_FUNCTION Interaction from_unchanged(); 0057 0058 //! Whether the state changed but did not fail 0059 CELER_FUNCTION bool changed() const 0060 { 0061 return static_cast<int>(action) < static_cast<int>(Action::unchanged); 0062 } 0063 }; 0064 0065 //---------------------------------------------------------------------------// 0066 /*! 0067 * Step lengths and properties needed to apply multiple scattering. 0068 * 0069 * \todo Document and/or refactor into a class that hides details 0070 * - alpha == small_step_alpha() ? "true path is very small" (true path scaling 0071 * changes) 0072 * - is_displaced == false ? limit_min is unchanged and alpha == 0073 * small_step_alpha() 0074 * - true_step >= geom_path 0075 * 0076 * The value \f$ \alpha \f$ is used in the approximation of the MSC 0077 * transport cross section as a linear function over the current step. It is 0078 * the negative slope of the transport MFP from start to stop, divided by the 0079 * starting MFP. (Since the transport cross section generally decreases 0080 * monotonically with increasing energy over the step, alpha will usually be 0081 * positive or zero for the step. Some known errors in the cross sections for 0082 * positrons result in negative alpha around a discontinuity at 10 MeV.) 0083 */ 0084 struct MscStep 0085 { 0086 //! Use a small step approximation for the path length correction 0087 static CELER_CONSTEXPR_FUNCTION real_type small_step_alpha() { return 0; } 0088 0089 bool is_displaced{true}; //!< Flag for the lateral displacement 0090 real_type true_path{}; //!< True path length due to the msc [len] 0091 real_type geom_path{}; //!< Geometrical path length [len] 0092 real_type alpha = small_step_alpha(); //!< Scaled MFP slope [1/len] 0093 }; 0094 0095 //---------------------------------------------------------------------------// 0096 /*! 0097 * Persistent range properties for multiple scattering (msc) within a volume. 0098 * 0099 * These values are calculated at the first step in every msc tracking volume 0100 * and reused at subsequent steps within the same volume. 0101 */ 0102 struct MscRange 0103 { 0104 real_type range_init{}; //!< Initial msc range [len] 0105 real_type range_factor{}; //!< Scale factor for the msc range 0106 real_type limit_min{}; //!< Minimum of the true path limit [len] 0107 0108 explicit CELER_FUNCTION operator bool() const 0109 { 0110 return range_init > 0 && range_factor > 0 && limit_min > 0; 0111 } 0112 }; 0113 0114 //---------------------------------------------------------------------------// 0115 /*! 0116 * Result of multiple scattering. 0117 */ 0118 struct MscInteraction 0119 { 0120 //! Interaction result category 0121 enum class Action 0122 { 0123 displaced, //!< Direction and position changed 0124 scattered, //!< Only direction changed 0125 unchanged //!< No state change 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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |