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