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/SeltzerBergerData.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/grid/TwodGridData.hh"
0015 #include "celeritas/Quantities.hh"
0016 #include "celeritas/Types.hh"
0017 
0018 #include "ElectronBremsData.hh"
0019 
0020 namespace celeritas
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Seltzer-Berger differential cross section tables for a single element.
0025  *
0026  * The 2D grid data is organized by log E on the x axis and fractional exiting
0027  * energy (0 to 1) on the y axis. The values are in millibarns, but their
0028  * magnitude isn't important since we always take ratios.
0029  *
0030  * \c argmax is the y index of the largest cross section at a given incident
0031  * energy point.
0032  *
0033  * \todo We could use way smaller integers for argmax, even i/j here, because
0034  * these tables are so small.
0035  */
0036 struct SBElementTableData
0037 {
0038     using EnergyUnits = units::LogMev;
0039     using XsUnits = units::Millibarn;
0040 
0041     TwodGridData grid;  //!< Cross section grid and data
0042     ItemRange<size_type> argmax;  //!< Y index of the largest XS for each
0043                                   //!< energy
0044 
0045     explicit CELER_FUNCTION operator bool() const
0046     {
0047         return grid && argmax.size() == grid.x.size();
0048     }
0049 };
0050 
0051 //---------------------------------------------------------------------------//
0052 /*!
0053  * Bremsstrahlung differential cross section (DCS) data for SB sampling.
0054  *
0055  * The value grids are organized per element ID, and each 2D grid is:
0056  * - x: logarithm of the energy [MeV] of the incident charged dparticle
0057  * - y: ratio of exiting photon energy to incident particle energy
0058  * - value: differential cross section (microbarns)
0059  */
0060 template<Ownership W, MemSpace M>
0061 struct SeltzerBergerTableData
0062 {
0063     //// MEMBER FUNCTIONS ////
0064 
0065     template<class T>
0066     using Items = Collection<T, W, M>;
0067     template<class T>
0068     using ElementItems = Collection<T, W, M, ElementId>;
0069 
0070     //// MEMBER DATA ////
0071 
0072     Items<real_type> reals;
0073     Items<size_type> sizes;
0074     ElementItems<SBElementTableData> elements;
0075 
0076     //// MEMBER FUNCTIONS ////
0077 
0078     //! Whether the data is assigned
0079     explicit CELER_FUNCTION operator bool() const
0080     {
0081         return !reals.empty() && !sizes.empty() && !elements.empty();
0082     }
0083 
0084     //! Assign from another set of data
0085     template<Ownership W2, MemSpace M2>
0086     SeltzerBergerTableData&
0087     operator=(SeltzerBergerTableData<W2, M2> const& other)
0088     {
0089         CELER_EXPECT(other);
0090         reals = other.reals;
0091         sizes = other.sizes;
0092         elements = other.elements;
0093         return *this;
0094     }
0095 };
0096 
0097 //---------------------------------------------------------------------------//
0098 /*!
0099  * Device data for sampling SeltzerBergerInteractor.
0100  */
0101 template<Ownership W, MemSpace M>
0102 struct SeltzerBergerData
0103 {
0104     using MevMass = units::MevMass;
0105 
0106     //// MEMBER DATA ////
0107 
0108     //! IDs in a separate struct for readability/easier copying
0109     ElectronBremIds ids;
0110 
0111     //! Electron mass [MeV / c^2]
0112     MevMass electron_mass;
0113 
0114     // Differential cross section storage
0115     SeltzerBergerTableData<W, M> differential_xs;
0116 
0117     //// MEMBER FUNCTIONS ////
0118 
0119     //! Whether the data is assigned
0120     explicit CELER_FUNCTION operator bool() const
0121     {
0122         return ids && electron_mass > zero_quantity() && differential_xs;
0123     }
0124 
0125     //! Assign from another set of data
0126     template<Ownership W2, MemSpace M2>
0127     SeltzerBergerData& operator=(SeltzerBergerData<W2, M2> const& other)
0128     {
0129         CELER_EXPECT(other);
0130         ids = other.ids;
0131         electron_mass = other.electron_mass;
0132         differential_xs = other.differential_xs;
0133         return *this;
0134     }
0135 };
0136 
0137 using SeltzerBergerDeviceRef = DeviceCRef<SeltzerBergerData>;
0138 using SeltzerBergerHostRef = HostCRef<SeltzerBergerData>;
0139 using SeltzerBergerRef = NativeCRef<SeltzerBergerData>;
0140 
0141 //---------------------------------------------------------------------------//
0142 }  // namespace celeritas