![]() |
|
|||
File indexing completed on 2025-02-22 10:31:15
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2022-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/distribution/EnergyLossGaussianDistribution.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <cmath> 0011 0012 #include "corecel/Assert.hh" 0013 #include "corecel/Macros.hh" 0014 #include "corecel/Types.hh" 0015 #include "corecel/math/Algorithms.hh" 0016 #include "celeritas/random/distribution/NormalDistribution.hh" 0017 0018 #include "EnergyLossHelper.hh" 0019 0020 namespace celeritas 0021 { 0022 //---------------------------------------------------------------------------// 0023 /*! 0024 * Sample energy loss from a Gaussian distribution. 0025 * 0026 * In a thick absorber, the total energy transfer is a result of many small 0027 * energy losses from a large number of collisions. The central limit theorem 0028 * applies, and the energy loss fluctuations can be described by a Gaussian 0029 * distribution. See section 7.3.1 of the Geant4 Physics Reference Manual and 0030 * GEANT3 PHYS332 section 2.3. 0031 * 0032 * The Gaussian approximation is valid for heavy particles and in the 0033 * regime \f$ \kappa = \xi / T_\textrm{max} > 10 \f$. 0034 * Fluctuations of the unrestricted energy loss 0035 * follow a Gaussian distribution if \f$ \Delta E > \kappa T_{max} \f$, 0036 * where \f$ T_{max} \f$ is the maximum energy transfer (PHYS332 section 0037 * 2). For fluctuations of the \em restricted energy loss, the condition is 0038 * modified to \f$ \Delta E > \kappa T_{c} \f$ and \f$ T_{max} \le 2 T_c 0039 * \f$, where \f$ T_c \f$ is the delta ray cutoff energy (PRM Eq. 7.6-7.7). 0040 */ 0041 class EnergyLossGaussianDistribution 0042 { 0043 public: 0044 //!@{ 0045 //! \name Type aliases 0046 using Energy = units::MevEnergy; 0047 using EnergySq = Quantity<UnitProduct<units::Mev, units::Mev>>; 0048 //!@} 0049 0050 public: 0051 // Construct from distribution parameters 0052 inline CELER_FUNCTION 0053 EnergyLossGaussianDistribution(Energy mean_loss, Energy bohr_stddev); 0054 0055 // Construct from helper distribution parameters 0056 inline CELER_FUNCTION 0057 EnergyLossGaussianDistribution(Energy mean_loss, EnergySq bohr_var); 0058 0059 // Construct from helper-calculated data 0060 explicit inline CELER_FUNCTION 0061 EnergyLossGaussianDistribution(EnergyLossHelper const& helper); 0062 0063 // Sample energy loss according to the distribution 0064 template<class Generator> 0065 inline CELER_FUNCTION Energy operator()(Generator& rng); 0066 0067 private: 0068 real_type const max_loss_; 0069 NormalDistribution<real_type> sample_normal_; 0070 }; 0071 0072 //---------------------------------------------------------------------------// 0073 // INLINE DEFINITIONS 0074 //---------------------------------------------------------------------------// 0075 /*! 0076 * Construct from mean/stddev. 0077 * 0078 * This formulation is used internally by the Urban distribution. 0079 */ 0080 CELER_FUNCTION EnergyLossGaussianDistribution::EnergyLossGaussianDistribution( 0081 Energy mean_loss, Energy bohr_stddev) 0082 : max_loss_(2 * mean_loss.value()) 0083 , sample_normal_(mean_loss.value(), bohr_stddev.value()) 0084 0085 { 0086 CELER_EXPECT(mean_loss > zero_quantity()); 0087 CELER_EXPECT(bohr_stddev > zero_quantity()); 0088 } 0089 0090 //---------------------------------------------------------------------------// 0091 /*! 0092 * Construct from distribution parameters. 0093 * 0094 * The mean loss is the energy lost over the step, and the standard deviation 0095 * is the square root of Bohr's variance (PRM Eq. 7.8). For thick absorbers, 0096 * the straggling function approaches a Gaussian distribution with this 0097 * standard deviation. 0098 */ 0099 CELER_FUNCTION EnergyLossGaussianDistribution::EnergyLossGaussianDistribution( 0100 Energy mean_loss, EnergySq bohr_var) 0101 : EnergyLossGaussianDistribution{mean_loss, 0102 Energy{std::sqrt(bohr_var.value())}} 0103 { 0104 } 0105 0106 //---------------------------------------------------------------------------// 0107 /*! 0108 * Construct from helper-calculated data. 0109 */ 0110 CELER_FUNCTION EnergyLossGaussianDistribution::EnergyLossGaussianDistribution( 0111 EnergyLossHelper const& helper) 0112 : EnergyLossGaussianDistribution{helper.mean_loss(), helper.bohr_variance()} 0113 { 0114 } 0115 0116 //---------------------------------------------------------------------------// 0117 /*! 0118 * Sample energy loss according to the distribution. 0119 */ 0120 template<class Generator> 0121 CELER_FUNCTION auto 0122 EnergyLossGaussianDistribution::operator()(Generator& rng) -> Energy 0123 { 0124 real_type result; 0125 do 0126 { 0127 result = sample_normal_(rng); 0128 } while (result <= 0 || result > max_loss_); 0129 return Energy{result}; 0130 } 0131 0132 //---------------------------------------------------------------------------// 0133 } // 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 |
![]() ![]() |