Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-04 08:34:59

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/LivermorePEData.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Range.hh"
0012 #include "corecel/data/Collection.hh"
0013 #include "corecel/grid/NonuniformGridData.hh"
0014 #include "corecel/math/Quantity.hh"
0015 #include "celeritas/Quantities.hh"
0016 #include "celeritas/Types.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Electron subshell data.
0023  *
0024  * The binding energy of consecutive shells is *not* always decreasing.
0025  * However, it is guaranteed to be less than or equal to the parent element's
0026  * \c thresh_lo value.
0027  */
0028 struct LivermoreSubshell
0029 {
0030     using EnergyUnits = units::Mev;
0031     using XsUnits = units::Barn;
0032     using Energy = RealQuantity<EnergyUnits>;
0033     using Real6 = Array<real_type, 6>;
0034 
0035     // Binding energy of the electron
0036     Energy binding_energy;
0037 
0038     // Tabulated subshell photoionization cross section (used below 5 keV)
0039     NonuniformGridRecord xs;
0040 
0041     // Fit parameters for the integrated subshell photoionization cross
0042     // sections in the two different energy ranges (used above 5 keV)
0043     Array<Real6, 2> param;
0044 
0045     //! True if assigned and valid
0046     explicit CELER_FUNCTION operator bool() const
0047     {
0048         return binding_energy > celeritas::zero_quantity() && xs;
0049     }
0050 };
0051 
0052 //---------------------------------------------------------------------------//
0053 /*!
0054  * Elemental photoelectric cross sections for the Livermore model.
0055  */
0056 struct LivermoreElement
0057 {
0058     using Energy = LivermoreSubshell::Energy;
0059 
0060     // TOTAL CROSS SECTIONS
0061 
0062     // Total cross section below the K-shell energy. Uses linear interpolation.
0063     NonuniformGridRecord xs_lo;
0064 
0065     // Total cross section above the K-shell energy but below the energy
0066     // threshold for the parameterized cross sections. Uses spline
0067     // interpolation.
0068     NonuniformGridRecord xs_hi;
0069 
0070     // SUBSHELL CROSS SECTIONS
0071 
0072     ItemRange<LivermoreSubshell> shells;
0073 
0074     // Energy threshold for using the parameterized subshell cross sections in
0075     // the lower and upper energy range
0076     Energy thresh_lo;  //!< Use tabulated XS below this energy
0077     Energy thresh_hi;  //!< Use lower parameterization below, upper above
0078 
0079     //! Energy below which cross sections are calculated on the fly
0080     static CELER_CONSTEXPR_FUNCTION Energy tabulated_threshold()
0081     {
0082         return Energy{0.2};
0083     }
0084 
0085     //! Whether all data are assigned and valid
0086     explicit CELER_FUNCTION operator bool() const
0087     {
0088         // Note: xs_lo is not present for elements with only one subshell, so
0089         // it's valid for xs_lo to be unassigned.
0090         return xs_hi && !shells.empty() && thresh_lo <= thresh_hi;
0091     }
0092 };
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Livermore photoelectric cross section data and binding energies.
0097  */
0098 template<Ownership W, MemSpace M>
0099 struct LivermorePEXsData
0100 {
0101     template<class T>
0102     using Items = Collection<T, W, M>;
0103     template<class T>
0104     using ElementItems = Collection<T, W, M, ElementId>;
0105 
0106     //// MEMBER DATA ////
0107 
0108     Items<LivermoreSubshell> shells;
0109     ElementItems<LivermoreElement> elements;
0110 
0111     // Backend data
0112     Items<real_type> reals;
0113 
0114     //// MEMBER FUNCTIONS ////
0115 
0116     //! Whether all data are assigned and valid
0117     explicit CELER_FUNCTION operator bool() const
0118     {
0119         return !shells.empty() && !elements.empty() && !reals.empty();
0120     }
0121 
0122     //! Assign from another set of data
0123     template<Ownership W2, MemSpace M2>
0124     LivermorePEXsData& operator=(LivermorePEXsData<W2, M2> const& other)
0125     {
0126         CELER_EXPECT(other);
0127         shells = other.shells;
0128         elements = other.elements;
0129         reals = other.reals;
0130         return *this;
0131     }
0132 };
0133 
0134 //---------------------------------------------------------------------------//
0135 /*!
0136  * Helper struct for making assignment easier
0137  */
0138 struct LivermorePEIds
0139 {
0140     //! ID of an electron
0141     ParticleId electron;
0142     //! ID of a gamma
0143     ParticleId gamma;
0144 
0145     //! Whether the IDs are assigned
0146     explicit CELER_FUNCTION operator bool() const { return electron && gamma; }
0147 };
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * Device data for creating a LivermorePEInteractor.
0152  */
0153 template<Ownership W, MemSpace M>
0154 struct LivermorePEData
0155 {
0156     using Mass = units::MevMass;
0157 
0158     //// MEMBER DATA ////
0159 
0160     //! IDs in a separate struct for readability/easier copying
0161     LivermorePEIds ids;
0162 
0163     //! 1 / electron mass [1 / Mass]
0164     real_type inv_electron_mass;
0165 
0166     //! Livermore EPICS2014 photoelectric data
0167     LivermorePEXsData<W, M> xs;
0168 
0169     //// MEMBER FUNCTIONS ////
0170 
0171     //! Whether all data are assigned and valid
0172     explicit CELER_FUNCTION operator bool() const
0173     {
0174         return ids && inv_electron_mass > 0 && xs;
0175     }
0176 
0177     //! Assign from another set of data
0178     template<Ownership W2, MemSpace M2>
0179     LivermorePEData& operator=(LivermorePEData<W2, M2> const& other)
0180     {
0181         CELER_EXPECT(other);
0182         ids = other.ids;
0183         inv_electron_mass = other.inv_electron_mass;
0184         xs = other.xs;
0185         return *this;
0186     }
0187 };
0188 
0189 //---------------------------------------------------------------------------//
0190 }  // namespace celeritas