Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:08:57

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/data/UrbanMscData.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/cont/Array.hh"
0011 #include "corecel/data/Collection.hh"
0012 #include "celeritas/Quantities.hh"
0013 #include "celeritas/Types.hh"
0014 #include "celeritas/grid/XsGridData.hh"
0015 
0016 #include "CommonCoulombData.hh"
0017 
0018 namespace celeritas
0019 {
0020 //! Particle categories for Urban MSC particle and material-dependent data
0021 enum class UrbanParMatType
0022 {
0023     electron = 0,
0024     positron,
0025     muhad,
0026     size_
0027 };
0028 
0029 //---------------------------------------------------------------------------//
0030 /*!
0031  * Settable parameters and default values for Urban multiple scattering.
0032  *
0033  * \f$ \tau = t/\lambda \f$ where t is the true path length and \f$ \lambda \f$
0034  * is the mean free path of the multiple scattering. The range and safety
0035  * factors are used in step limitation algorithms and default values are
0036  * chosen to balance between simulation time and precision.
0037  *
0038 <table>
0039   <caption>Mapping of parameter names from Geant4 to Celeritas</caption>
0040   <thead>
0041     <tr>
0042       <th>Geant4 Symbol</th>
0043       <th>Celeritas Symbol</th>
0044     </tr>
0045   </thead>
0046   <tbody>
0047     <tr><td><code>dtrl</code></td><td><code>small_range_frac</code></td></tr>
0048     <tr><td><code>tlimitminfix</code></td><td><code>min_step</code></td></tr>
0049     <tr><td><code>stepmin</code></td><td><code>min_step_fallback</code></td></tr>
0050     <tr><td><code>tlimitminfix2</code></td><td><code>min_step_transform</code></td></tr>
0051     <tr><td><em>(hardcoded)</em></td><td><code>min_endpoint_energy</code></td></tr>
0052     <tr><td><code>tlow</code></td><td><code>min_scaling_energy</code></td></tr>
0053   </tbody>
0054 </table>
0055  *
0056  * \todo Unify min_endpoint_energy with low energy limit
0057  * \todo Combine with lambda_limit, safety_factor in physics params
0058  */
0059 struct UrbanMscParameters
0060 {
0061     using Energy = units::MevEnergy;
0062 
0063     real_type tau_small{1e-16};  //!< small value of tau
0064     real_type tau_big{8};  //!< big value of tau
0065     real_type tau_limit{1e-6};  //!< limit of tau
0066     real_type safety_tol{0.01};  //!< safety tolerance
0067     real_type geom_limit{5e-8 * units::millimeter};  //!< minimum step
0068     // TODO: move these to along-step applicability
0069     Energy low_energy_limit{0};
0070     Energy high_energy_limit{0};
0071 
0072     //! Assume constant xs if step / range < small_range_frac ("dtrl")
0073     static constexpr real_type small_range_frac{0.05};
0074 
0075     //! For steps smaller than this, *ignore* MSC
0076     static constexpr real_type min_step{0.01 * units::nanometer};
0077 
0078     //! Minimum true path when not calculated in the step limiting
0079     static constexpr real_type min_step_fallback{10.0 * min_step};
0080 
0081     //! For steps smaller than this, true path = geometrical path
0082     static constexpr real_type min_step_transform{real_type{1}
0083                                                   * units::nanometer};
0084 
0085     //! Below this endpoint energy, don't sample scattering: 1 eV
0086     static constexpr Energy min_endpoint_energy{1e-6};
0087 
0088     //! The lower bound of energy to scale the minimum true path length limit
0089     static constexpr Energy min_scaling_energy{5e-3};
0090 };
0091 
0092 //---------------------------------------------------------------------------//
0093 /*!
0094  * Material-dependent data for Urban MSC.
0095  *
0096  * UrbanMsc material data (see UrbanMscParams::calc_material_data) is a set of
0097  * precalculated material dependent parameters used in sampling the angular
0098  * distribution of MSC, \f$ \cos\theta \f$, and in the step limiter. The
0099  * coeffient vectors are used in polynomial evaluation.
0100  */
0101 struct UrbanMscMaterialData
0102 {
0103     using Real2 = Array<real_type, 2>;
0104     using Real3 = Array<real_type, 3>;
0105 
0106     // Step limiter
0107     Real2 stepmin_coeff{0, 0};  //!< Coefficients for step minimum
0108 
0109     // Scattering angle
0110     Real2 theta_coeff{0, 0};  //!< Coeffecients for theta_0 correction
0111     Real3 tail_coeff{0, 0, 0};  //!< Coefficients for tail parameter
0112     real_type tail_corr{0};  //!< Additional radiation length tail correction
0113 };
0114 
0115 //---------------------------------------------------------------------------//
0116 /*!
0117  * Particle- and material-dependent data for MSC.
0118  *
0119  * The scaled Zeff parameters are:
0120  *
0121  *   Particle             | a    | b
0122  *   -------------------- | ---- | ----
0123  *   electron/muon/hadron | 0.87 | 2/3
0124  *   positron             | 0.7  | 1/2
0125  *
0126  * Two different \c d_over_r values are used: one for electrons and positrons,
0127  * and another for muons and hadrons.
0128  */
0129 struct UrbanMscParMatData
0130 {
0131     using UrbanParMatId = OpaqueId<UrbanMscParMatData>;
0132 
0133     real_type scaled_zeff{};  //!< a * Z^b
0134     real_type d_over_r{};  //!< Maximum distance/range heuristic
0135 
0136     //! Whether the data is assigned
0137     explicit CELER_FUNCTION operator bool() const { return scaled_zeff > 0; }
0138 };
0139 
0140 //---------------------------------------------------------------------------//
0141 /*!
0142  * Device data for Urban MSC.
0143  */
0144 template<Ownership W, MemSpace M>
0145 struct UrbanMscData
0146 {
0147     //// TYPES ////
0148 
0149     template<class T>
0150     using Items = Collection<T, W, M>;
0151     template<class T>
0152     using MaterialItems = Collection<T, W, M, PhysMatId>;
0153     template<class T>
0154     using ParticleItems = Collection<T, W, M, ParticleId>;
0155 
0156     //// DATA ////
0157 
0158     //! Particle IDs
0159     CoulombIds ids;
0160     //! Mass of of electron in MeV
0161     units::MevMass electron_mass;
0162     //! User-assignable options
0163     UrbanMscParameters params;
0164     //! Material-dependent data
0165     MaterialItems<UrbanMscMaterialData> material_data;
0166     //! Number of particles this model applies to
0167     ParticleId::size_type num_particles;
0168     //! Number of particle categories for particle and material-dependent data
0169     ParticleId::size_type num_par_mat;
0170     //! Map from particle ID to index in particle and material-dependent data
0171     ParticleItems<UrbanMscParMatData::UrbanParMatId> pid_to_pmdata;
0172     //! Map from particle ID to index in cross sections
0173     ParticleItems<MscParticleId> pid_to_xs;
0174     //! Particle and material-dependent data
0175     Items<UrbanMscParMatData> par_mat_data;  //!< [mat][particle]
0176     //! Scaled xs data
0177     Items<UniformGridRecord> xs;  //!< [mat][particle]
0178 
0179     // Backend storage
0180     Items<real_type> reals;
0181 
0182     //// METHODS ////
0183 
0184     //! Check whether the data is assigned
0185     explicit CELER_FUNCTION operator bool() const
0186     {
0187         return ids && electron_mass > zero_quantity() && !material_data.empty()
0188                && num_particles >= 2 && num_par_mat >= 2
0189                && !pid_to_pmdata.empty() && !pid_to_xs.empty()
0190                && !par_mat_data.empty() && !xs.empty() && !reals.empty();
0191     }
0192 
0193     //! Assign from another set of data
0194     template<Ownership W2, MemSpace M2>
0195     UrbanMscData& operator=(UrbanMscData<W2, M2> const& other)
0196     {
0197         CELER_EXPECT(other);
0198         ids = other.ids;
0199         electron_mass = other.electron_mass;
0200         params = other.params;
0201         material_data = other.material_data;
0202         num_particles = other.num_particles;
0203         num_par_mat = other.num_par_mat;
0204         pid_to_pmdata = other.pid_to_pmdata;
0205         pid_to_xs = other.pid_to_xs;
0206         par_mat_data = other.par_mat_data;
0207         xs = other.xs;
0208         reals = other.reals;
0209         return *this;
0210     }
0211 };
0212 
0213 }  // namespace celeritas