Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:15

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2021-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/data/UrbanMscData.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/data/Collection.hh"
0013 #include "celeritas/Quantities.hh"
0014 #include "celeritas/Types.hh"
0015 #include "celeritas/grid/XsGridData.hh"
0016 
0017 #include "CommonCoulombData.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Settable parameters and default values for Urban multiple scattering.
0024  *
0025  * \f$ \tau = t/\lambda \f$ where t is the true path length and \f$ \lambda \f$
0026  * is the mean free path of the multiple scattering. The range and safety
0027  * factors are used in step limitation algorithms and default values are
0028  * chosen to balance between simulation time and precision.
0029  */
0030 struct UrbanMscParameters
0031 {
0032     using Energy = units::MevEnergy;
0033 
0034     real_type tau_small{1e-16};  //!< small value of tau
0035     real_type tau_big{8};  //!< big value of tau
0036     real_type tau_limit{1e-6};  //!< limit of tau
0037     real_type safety_tol{0.01};  //!< safety tolerance
0038     real_type geom_limit{5e-8 * units::millimeter};  //!< minimum step
0039     Energy low_energy_limit{0};
0040     Energy high_energy_limit{0};
0041 
0042     //! Fraction of the range below which a step is assumed constant xs
0043     static CELER_CONSTEXPR_FUNCTION real_type dtrl() { return 0.05; }
0044 
0045     //! The minimum value of the true path length limit: 0.01 nm
0046     static CELER_CONSTEXPR_FUNCTION real_type limit_min_fix()
0047     {
0048         return real_type(0.01) * units::nanometer;
0049     }
0050 
0051     //! Minimum true path when not calculated in the step limiting
0052     static CELER_CONSTEXPR_FUNCTION real_type limit_min()
0053     {
0054         return 10 * limit_min_fix();
0055     }
0056 
0057     //! For steps below this value, true = geometrical (no MSC to be applied)
0058     static CELER_CONSTEXPR_FUNCTION real_type min_step()
0059     {
0060         return 1 * units::nanometer;
0061     }
0062 
0063     //! Below this endpoint energy, don't sample scattering: 1 eV
0064     static CELER_CONSTEXPR_FUNCTION Energy min_sampling_energy()
0065     {
0066         return units::MevEnergy{1e-6};
0067     }
0068 
0069     //! The lower bound of energy to scale the minimum true path length limit
0070     static CELER_CONSTEXPR_FUNCTION Energy min_scaling_energy()
0071     {
0072         return units::MevEnergy(5e-3);
0073     }
0074 };
0075 
0076 //---------------------------------------------------------------------------//
0077 /*!
0078  * Material-dependent data for Urban MSC.
0079  *
0080  * UrbanMsc material data (see UrbanMscParams::calc_material_data) is a set of
0081  * precalculated material dependent parameters used in sampling the angular
0082  * distribution of MSC, \f$ \cos\theta \f$, and in the step limiter. The
0083  * coeffient vectors are used in polynomial evaluation.
0084  */
0085 struct UrbanMscMaterialData
0086 {
0087     using Real2 = Array<real_type, 2>;
0088     using Real3 = Array<real_type, 3>;
0089 
0090     // Step limiter
0091     Real2 stepmin_coeff{0, 0};  //!< Coefficients for step minimum
0092 
0093     // Scattering angle
0094     Real2 theta_coeff{0, 0};  //!< Coeffecients for theta_0 correction
0095     Real3 tail_coeff{0, 0, 0};  //!< Coefficients for tail parameter
0096     real_type tail_corr{0};  //!< Additional radiation length tail correction
0097 };
0098 
0099 //---------------------------------------------------------------------------//
0100 /*!
0101  * Particle- and material-dependent data for MSC.
0102  *
0103  * The scaled Zeff parameters are:
0104  *
0105  *   Particle | a    | b
0106  *   -------- | ---- | ----
0107  *   electron | 0.87 | 2/3
0108  *   positron | 0.7  | 1/2
0109  */
0110 struct UrbanMscParMatData
0111 {
0112     real_type scaled_zeff{};  //!< a * Z^b
0113     real_type d_over_r{};  //!< Maximum distance/range heuristic
0114 
0115     //! Whether the data is assigned
0116     explicit CELER_FUNCTION operator bool() const { return scaled_zeff > 0; }
0117 };
0118 
0119 //---------------------------------------------------------------------------//
0120 /*!
0121  * Device data for Urban MSC.
0122  *
0123  * Since the model currently applies only to electrons and positrons, the
0124  * particles are hardcoded to be length 2. TODO: extend to other charged
0125  * particles when further physics is implemented.
0126  */
0127 template<Ownership W, MemSpace M>
0128 struct UrbanMscData
0129 {
0130     //// TYPES ////
0131 
0132     template<class T>
0133     using Items = Collection<T, W, M>;
0134     template<class T>
0135     using MaterialItems = celeritas::Collection<T, W, M, MaterialId>;
0136 
0137     //// DATA ////
0138 
0139     //! Particle IDs
0140     CoulombIds ids;
0141     //! Mass of of electron in MeV
0142     units::MevMass electron_mass;
0143     //! User-assignable options
0144     UrbanMscParameters params;
0145     //! Material-dependent data
0146     MaterialItems<UrbanMscMaterialData> material_data;
0147     //! Particle and material-dependent data
0148     Items<UrbanMscParMatData> par_mat_data;  //!< [mat][particle]
0149     //! Scaled xs data
0150     Items<XsGridData> xs;  //!< [mat][particle]
0151 
0152     // Backend storage
0153     Items<real_type> reals;
0154 
0155     //// METHODS ////
0156 
0157     //! Check whether the data is assigned
0158     explicit CELER_FUNCTION operator bool() const
0159     {
0160         return ids && electron_mass > zero_quantity() && !material_data.empty()
0161                && !par_mat_data.empty() && !xs.empty() && !reals.empty();
0162     }
0163 
0164     //! Assign from another set of data
0165     template<Ownership W2, MemSpace M2>
0166     UrbanMscData& operator=(UrbanMscData<W2, M2> const& other)
0167     {
0168         CELER_EXPECT(other);
0169         ids = other.ids;
0170         electron_mass = other.electron_mass;
0171         params = other.params;
0172         material_data = other.material_data;
0173         par_mat_data = other.par_mat_data;
0174         xs = other.xs;
0175         reals = other.reals;
0176         return *this;
0177     }
0178 
0179     //! Get the data location for a material + particle
0180     template<class T>
0181     CELER_FUNCTION ItemId<T> at(MaterialId mat, ParticleId par) const
0182     {
0183         CELER_EXPECT(mat && par);
0184         size_type result = mat.unchecked_get() * 2;
0185         result += (par == this->ids.electron ? 0 : 1);
0186         CELER_ENSURE(result < this->par_mat_data.size());
0187         return ItemId<T>{result};
0188     }
0189 };
0190 
0191 }  // namespace celeritas