Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/celeritas/em/distribution/EnergyLossGaussianDistribution.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/em/distribution/EnergyLossGaussianDistribution.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cmath>
0010 
0011 #include "corecel/Assert.hh"
0012 #include "corecel/Macros.hh"
0013 #include "corecel/Types.hh"
0014 #include "corecel/random/distribution/NormalDistribution.hh"
0015 #include "corecel/random/distribution/TruncatedDistribution.hh"
0016 
0017 #include "EnergyLossHelper.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Sample energy loss from a Gaussian distribution.
0024  *
0025  * In a thick absorber, the total energy transfer is a result of many small
0026  * energy losses from a large number of collisions. The central limit theorem
0027  * applies, and the energy loss fluctuations can be described by a Gaussian
0028  * distribution. See section 7.3.1 of \cite{g4prm} and
0029  * PHYS332 section 2.3 of \cite{geant3-1993} .
0030  *
0031  * The Gaussian approximation is valid for heavy particles and in the
0032  * regime \f$ \kappa = \xi / T_\textrm{max} > 10 \f$.
0033  * Fluctuations of the unrestricted energy loss follow a Gaussian distribution
0034  * if \f$ \Delta E > \kappa T_\textrm{max} \f$, where \f$ T_\textrm{max} \f$
0035  * is the maximum energy transfer (PHYS332 section 2 of \cite{geant3-1993} ).
0036  * For fluctuations of the \em restricted energy loss, the condition is
0037  * modified to \f$ \Delta E > \kappa T_c \f$ and
0038  * \f$ T_\textrm{max} \le 2 T_c \f$,
0039  * where \f$ T_c \f$ is the delta ray cutoff energy (Eq. 7.6--7.7 from
0040  * \cite{g4prm} ).
0041  */
0042 class EnergyLossGaussianDistribution
0043 {
0044   public:
0045     //!@{
0046     //! \name Type aliases
0047     using Energy = units::MevEnergy;
0048     using EnergySq = RealQuantity<UnitProduct<units::Mev, units::Mev>>;
0049     //!@}
0050 
0051   public:
0052     // Construct from distribution parameters
0053     inline CELER_FUNCTION EnergyLossGaussianDistribution(Energy mean_loss,
0054                                                          Energy bohr_stddev);
0055 
0056     // Construct from helper distribution parameters
0057     inline CELER_FUNCTION EnergyLossGaussianDistribution(Energy mean_loss,
0058                                                          EnergySq bohr_var);
0059 
0060     // Construct from helper-calculated data
0061     explicit inline CELER_FUNCTION EnergyLossGaussianDistribution(
0062         EnergyLossHelper const& helper);
0063 
0064     // Sample energy loss according to the distribution
0065     template<class Generator>
0066     inline CELER_FUNCTION Energy operator()(Generator& rng);
0067 
0068   private:
0069     TruncatedDistribution<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     : sample_normal_(
0083           0, 2 * mean_loss.value(), 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 EnergyLossGaussianDistribution::operator()(Generator& rng)
0122     -> Energy
0123 {
0124     return Energy{sample_normal_(rng)};
0125 }
0126 
0127 //---------------------------------------------------------------------------//
0128 }  // namespace celeritas