Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-07 10:01:37

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/xs/ScreeningFunctions.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/math/PolyEvaluator.hh"
0012 #include "corecel/math/Quantity.hh"
0013 #include "corecel/math/UnitUtils.hh"
0014 #include "celeritas/Quantities.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Bethe-Heitler-Wheeler-Lamb screening factors for use in atomic showers.
0021  *
0022  * These are derived from \citet{bethe-stopping-1934,
0023  * https://doi.org/10.1098/rspa.1934.0140} (Eq. 31) for the \f$ \phi\f$
0024  * (elastic) components and \citet{wheeler-electrons-1939,
0025  * https://doi.org/10.1103/PhysRev.55.858} for the \f$ \psi \f$ (inelastic)
0026  * components.
0027  */
0028 struct BhwlScreeningFactors
0029 {
0030     //! Elastic component, to be multiplied into Z^2
0031     real_type phi1{};
0032     //! \f$\phi_1 - \phi_2\f$ corrective term for low-energy secondary
0033     real_type dphi{};
0034     //! Inelastic component, to be multiplied into Z
0035     real_type psi1{};
0036     //! \f$\psi_1 - \psi_2\f$ corrective term for low-energy secondary
0037     real_type dpsi{};
0038 };
0039 
0040 //---------------------------------------------------------------------------//
0041 /*!
0042  * Thomas-Fermi screening functions from Tsai.
0043  *
0044  * This calculates atomic screening factors given by  \citet{tsai-1974,
0045  * https://doi.org/10.1103/RevModPhys.46.815} Eq. 3.30-31, as part of the
0046  * relativistic bremsstrahlung cross section calculation.
0047  * This model is valid for \f$ Z \ge 5 \f$.
0048  *
0049  * The calculator argument is the fraction \f[
0050  * \delta = \frac{k}{E(k - E)} \equiv \frac{2\delta_\mathrm{Tsai}}{m_e}
0051  * \f]
0052  * where \f$E\f$ is the kinetic plus rest mass energy of the electron
0053  * and \f$k\f$ is the photon energy. (For Bremsstrahlung, the electron is
0054  * incident and photon is exiting.)
0055  *
0056  * The calculated screening functions are:
0057  * \f[
0058    \begin{aligned}
0059    \varphi_1(\gamma) &= 20.863 - 2 \ln \left( 1 + (0.55846\gamma)^2 \right)
0060      - 4 \left( 1 - 0.6 \exp(-0.9\gamma) - 0.4 \exp(-1.5\gamma) \right), \\
0061    \varphi_2(\gamma) = \varphi_1(\gamma)
0062      - \frac{2}{3} \left( 1 + 6.5\gamma + 6\gamma^2 \right)^{-1}, \\
0063    \psi_1(\epsilon) &= 28.340 - 2 \ln \left( 1 + (3.621\epsilon)^2 \right)
0064      - 4 \left( 1 - 0.7 \exp(-8\epsilon) - 0.3 \exp(-29.2\epsilon) \right),
0065    \psi_2(\epsilon) &= \psi_1(\epsilon)
0066      - \frac{2}{3} \left( 1 + 40\epsilon + 400\epsilon^2 \right)^{-1}.
0067    \end{aligned}
0068  * \f]
0069  *
0070  * Here,
0071  * \f[
0072    \begin{aligned}
0073    \gamma &= \frac{100 m_e k}{E (k - E) Z^{1/3}} \\
0074    \epsilon &= \frac{100 m_e k}{E (k - E) Z^{2/3}}
0075    \end{aligned}
0076  * \f]
0077  * from which we extract input factors precalculated in
0078  * \c celeritas::RelativisticBremModel:
0079  * \f[
0080  * f_\gamma = \frac{100 m_e}{Z^{1/3}}
0081  * \f]
0082  * and
0083  * \f[
0084  * f_\epsilon = \frac{100 m_e}{Z^{2/3}}
0085  * \f]
0086  *
0087  * \sa RBDiffXsCalculator
0088  */
0089 class TsaiScreeningCalculator
0090 {
0091   public:
0092     //!@{
0093     //! \name Type aliases
0094     using result_type = BhwlScreeningFactors;
0095     using Mass = units::MevMass;
0096     using InvEnergy = RealQuantity<UnitInverse<units::Mev>>;
0097     //!@}
0098 
0099   public:
0100     // Construct with defaults
0101     CELER_FUNCTION inline TsaiScreeningCalculator(Mass gamma_factor,
0102                                                   Mass epsilon_factor);
0103 
0104     // Calculate screening function from energy transfer
0105     CELER_FUNCTION inline result_type operator()(InvEnergy delta) const;
0106 
0107   private:
0108     real_type f_gamma_;
0109     real_type f_epsilon_;
0110 };
0111 
0112 //---------------------------------------------------------------------------//
0113 // INLINE DEFINITIONS
0114 //---------------------------------------------------------------------------//
0115 /*!
0116  * Construct with gamma and epsilon factors.
0117  */
0118 CELER_FUNCTION
0119 TsaiScreeningCalculator::TsaiScreeningCalculator(Mass gamma_factor,
0120                                                  Mass epsilon_factor)
0121     : f_gamma_{gamma_factor.value()}, f_epsilon_{epsilon_factor.value()}
0122 {
0123     CELER_EXPECT(epsilon_factor > zero_quantity());
0124     CELER_EXPECT(gamma_factor > epsilon_factor);
0125 }
0126 
0127 //---------------------------------------------------------------------------//
0128 /*!
0129  * Calculate screening function from energy transfer.
0130  */
0131 CELER_FUNCTION auto TsaiScreeningCalculator::operator()(InvEnergy delta) const
0132     -> result_type
0133 {
0134     real_type gam = delta.value() * f_gamma_;
0135     real_type eps = delta.value() * f_epsilon_;
0136 
0137     using PolyQuad = PolyEvaluator<real_type, 2>;
0138     using R = real_type;
0139     result_type func;
0140 
0141     func.phi1 = R(20.863 - 4) - 2 * std::log(1 + ipow<2>(R(0.55846) * gam))
0142                 + R(-4 * -0.6) * std::exp(R(-0.9) * gam)
0143                 + R(-4 * -0.4) * std::exp(R(-1.5) * gam);
0144     func.dphi = (R{2} / R{3}) / PolyQuad{1, 6.5, 6}(gam);
0145 
0146     func.psi1 = R(28.340 - 4) - 2 * std::log(1 + ipow<2>(R(3.621) * eps))
0147                 + R(-4 * -0.7) * std::exp(R(-8) * eps)
0148                 + R(-4 * -0.3) * std::exp(R(-29.2) * eps);
0149     func.dpsi = (R{2} / R{3}) / PolyQuad{1, 40, 400}(eps);
0150 
0151     return func;
0152 }
0153 
0154 //---------------------------------------------------------------------------//
0155 }  // namespace celeritas