Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 08:50:31

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     //! Whether all data are assigned and valid
0080     explicit CELER_FUNCTION operator bool() const
0081     {
0082         // Note: xs_lo is not present for elements with only one subshell, so
0083         // it's valid for xs_lo to be unassigned.
0084         return xs_hi && !shells.empty() && thresh_lo <= thresh_hi;
0085     }
0086 };
0087 
0088 //---------------------------------------------------------------------------//
0089 /*!
0090  * Livermore photoelectric cross section data and binding energies.
0091  */
0092 template<Ownership W, MemSpace M>
0093 struct LivermorePEXsData
0094 {
0095     template<class T>
0096     using Items = Collection<T, W, M>;
0097     template<class T>
0098     using ElementItems = Collection<T, W, M, ElementId>;
0099 
0100     //// MEMBER DATA ////
0101 
0102     Items<LivermoreSubshell> shells;
0103     ElementItems<LivermoreElement> elements;
0104 
0105     // Backend data
0106     Items<real_type> reals;
0107 
0108     //// MEMBER FUNCTIONS ////
0109 
0110     //! Whether all data are assigned and valid
0111     explicit CELER_FUNCTION operator bool() const
0112     {
0113         return !shells.empty() && !elements.empty() && !reals.empty();
0114     }
0115 
0116     //! Assign from another set of data
0117     template<Ownership W2, MemSpace M2>
0118     LivermorePEXsData& operator=(LivermorePEXsData<W2, M2> const& other)
0119     {
0120         CELER_EXPECT(other);
0121         shells = other.shells;
0122         elements = other.elements;
0123         reals = other.reals;
0124         return *this;
0125     }
0126 };
0127 
0128 //---------------------------------------------------------------------------//
0129 /*!
0130  * Helper struct for making assignment easier
0131  */
0132 struct LivermorePEIds
0133 {
0134     //! ID of an electron
0135     ParticleId electron;
0136     //! ID of a gamma
0137     ParticleId gamma;
0138 
0139     //! Whether the IDs are assigned
0140     explicit CELER_FUNCTION operator bool() const { return electron && gamma; }
0141 };
0142 
0143 //---------------------------------------------------------------------------//
0144 /*!
0145  * Device data for creating a LivermorePEInteractor.
0146  */
0147 template<Ownership W, MemSpace M>
0148 struct LivermorePEData
0149 {
0150     using Mass = units::MevMass;
0151 
0152     //// MEMBER DATA ////
0153 
0154     //! IDs in a separate struct for readability/easier copying
0155     LivermorePEIds ids;
0156 
0157     //! 1 / electron mass [1 / Mass]
0158     real_type inv_electron_mass;
0159 
0160     //! Livermore EPICS2014 photoelectric data
0161     LivermorePEXsData<W, M> xs;
0162 
0163     //// MEMBER FUNCTIONS ////
0164 
0165     //! Whether all data are assigned and valid
0166     explicit CELER_FUNCTION operator bool() const
0167     {
0168         return ids && inv_electron_mass > 0 && xs;
0169     }
0170 
0171     //! Assign from another set of data
0172     template<Ownership W2, MemSpace M2>
0173     LivermorePEData& operator=(LivermorePEData<W2, M2> const& other)
0174     {
0175         CELER_EXPECT(other);
0176         ids = other.ids;
0177         inv_electron_mass = other.inv_electron_mass;
0178         xs = other.xs;
0179         return *this;
0180     }
0181 };
0182 
0183 using LivermorePEDeviceRef = DeviceCRef<LivermorePEData>;
0184 using LivermorePEHostRef = HostCRef<LivermorePEData>;
0185 using LivermorePERef = NativeCRef<LivermorePEData>;
0186 
0187 //---------------------------------------------------------------------------//
0188 }  // namespace celeritas