Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:10:58

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/mat/MaterialParams.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <memory>
0010 #include <string>
0011 #include <utility>
0012 #include <vector>
0013 
0014 #include "corecel/Assert.hh"
0015 #include "corecel/Types.hh"
0016 #include "corecel/cont/LabelIdMultiMap.hh"
0017 #include "corecel/cont/Span.hh"
0018 #include "corecel/data/Collection.hh"
0019 #include "corecel/data/CollectionMirror.hh"
0020 #include "corecel/data/ParamsDataInterface.hh"
0021 #include "corecel/io/Label.hh"
0022 #include "celeritas/Quantities.hh"
0023 #include "celeritas/Types.hh"
0024 #include "celeritas/phys/AtomicNumber.hh"
0025 
0026 #include "ElementView.hh"
0027 #include "IsotopeView.hh"
0028 #include "MaterialData.hh"
0029 #include "MaterialView.hh"
0030 
0031 namespace celeritas
0032 {
0033 struct ImportData;
0034 
0035 //---------------------------------------------------------------------------//
0036 /*!
0037  * Manage material, element, and nuclide properties.
0038  *
0039  * Materials in Celeritas currently correspond to "material cut couples" in
0040  * Geant4, i.e. the outer product of geometry model-defined materials and
0041  * user-defined physics regions.
0042  *
0043  * \todo Replace id_to_label etc. with direct access to LabelIdMultiMap
0044  * \todo Split into isotope/element/geo material
0045  */
0046 class MaterialParams final : public ParamsDataInterface<MaterialParamsData>
0047 {
0048   public:
0049     //!@{
0050     //! \name Type aliases
0051     using MatId = PhysMatId;
0052     using SpanConstMaterialId = Span<MatId const>;
0053     using SpanConstElementId = Span<ElementId const>;
0054     using SpanConstIsotopeId = Span<IsotopeId const>;
0055     //!@}
0056 
0057     //! Define an element's isotope input data
0058     struct IsotopeInput
0059     {
0060         //!@{
0061         //! \name Type aliases
0062         using AtomicMassNumber = AtomicNumber;
0063         using MevEnergy = units::MevEnergy;
0064         //!@}
0065 
0066         AtomicNumber atomic_number;  //!< Atomic number Z
0067         AtomicMassNumber atomic_mass_number;  //!< Atomic number A
0068         MevEnergy binding_energy;  //!< Nuclear binding energy (BE)
0069         MevEnergy proton_loss_energy;  //!< BE(A, Z) - BE(A-1, Z-1)
0070         MevEnergy neutron_loss_energy;  //!< BE(A, Z) - BE(A-1, Z)
0071         units::MevMass nuclear_mass;  //!< Nucleons' mass + binding energy
0072         Label label;  //!< Isotope name
0073     };
0074 
0075     //! Define an element's input data
0076     struct ElementInput
0077     {
0078         AtomicNumber atomic_number;  //!< Atomic number Z
0079         units::AmuMass atomic_mass;  //!< Isotope-weighted average atomic mass
0080         std::vector<std::pair<IsotopeId, real_type>>
0081             isotopes_fractions;  //!< Isotopic fractional abundance
0082         Label label;  //!< Element name
0083     };
0084 
0085     //! Define a material's input data
0086     struct MaterialInput
0087     {
0088         real_type number_density;  //!< Atomic number density [1/length^3]
0089         real_type temperature;  //!< Temperature [K]
0090         MatterState matter_state;  //!< Solid, liquid, gas
0091         std::vector<std::pair<ElementId, real_type>>
0092             elements_fractions;  //!< Fraction of number density
0093         Label label;  //!< Material name
0094     };
0095 
0096     //! Input data to construct this class
0097     struct Input
0098     {
0099         std::vector<IsotopeInput> isotopes;
0100         std::vector<ElementInput> elements;
0101         std::vector<MaterialInput> materials;
0102         std::vector<OptMatId> mat_to_optical;
0103     };
0104 
0105   public:
0106     // Construct with imported data
0107     static std::shared_ptr<MaterialParams> from_import(ImportData const& data);
0108 
0109     // Construct with a vector of material definitions
0110     explicit MaterialParams(Input const& inp);
0111 
0112     //! Number of material definitions
0113     MatId::size_type size() const { return mat_labels_.size(); }
0114 
0115     //!@{
0116     //! \name Material metadata
0117 
0118     //! Number of materials
0119     MatId::size_type num_materials() const { return mat_labels_.size(); }
0120 
0121     // Get material name
0122     Label const& id_to_label(MatId id) const;
0123 
0124     // Find a material from a name
0125     MatId find_material(std::string const& name) const;
0126 
0127     // Find all materials that share a name
0128     SpanConstMaterialId find_materials(std::string const& name) const;
0129     //!@}
0130 
0131     //!@{
0132     //! \name Element metadata
0133 
0134     //! Number of distinct elements definitions
0135     ElementId::size_type num_elements() const { return el_labels_.size(); }
0136 
0137     // Get element name
0138     Label const& id_to_label(ElementId id) const;
0139 
0140     // Find an element from a name
0141     ElementId find_element(std::string const& name) const;
0142 
0143     // Find all elements that share a name
0144     SpanConstElementId find_elements(std::string const& name) const;
0145     //!@}
0146 
0147     //!@{
0148     //! \name Isotope metadata
0149 
0150     //! Number of distinct isotope definitions
0151     IsotopeId::size_type num_isotopes() const { return isot_labels_.size(); }
0152 
0153     // Get isotope name
0154     Label const& id_to_label(IsotopeId id) const;
0155 
0156     // Find an isotope from a name
0157     IsotopeId find_isotope(std::string const& name) const;
0158 
0159     // Find all isotopes that share a name
0160     SpanConstIsotopeId find_isotopes(std::string const& name) const;
0161     //!@}
0162 
0163     // Access material definitions on host
0164     inline MaterialView get(MatId id) const;
0165 
0166     // Access element definitions on host
0167     inline ElementView get(ElementId id) const;
0168 
0169     // Access isotope definitions on host
0170     inline IsotopeView get(IsotopeId id) const;
0171 
0172     // Maximum number of isotopes in any one element
0173     inline IsotopeComponentId::size_type max_isotope_components() const;
0174 
0175     // Maximum number of elements in any one material
0176     inline ElementComponentId::size_type max_element_components() const;
0177 
0178     //! Whether isotopic data is present (may be false for EM-only physics)
0179     inline bool is_missing_isotopes() const { return this->num_isotopes(); }
0180 
0181     //! Access material properties on the host
0182     HostRef const& host_ref() const final { return data_.host_ref(); }
0183 
0184     //! Access material properties on the device
0185     DeviceRef const& device_ref() const final { return data_.device_ref(); }
0186 
0187   private:
0188     // Metadata
0189     LabelIdMultiMap<MatId> mat_labels_;
0190     LabelIdMultiMap<ElementId> el_labels_;
0191     LabelIdMultiMap<IsotopeId> isot_labels_;
0192 
0193     // Host/device storage and reference
0194     CollectionMirror<MaterialParamsData> data_;
0195 
0196     // HELPER FUNCTIONS
0197     using HostValue = HostVal<MaterialParamsData>;
0198     void append_element_def(ElementInput const& inp, HostValue*);
0199     void append_isotope_def(IsotopeInput const& inp, HostValue*);
0200     ItemRange<MatElementComponent>
0201     extend_elcomponents(MaterialInput const& inp, HostValue*) const;
0202     void append_material_def(MaterialInput const& inp, HostValue*);
0203 };
0204 
0205 //---------------------------------------------------------------------------//
0206 // INLINE DEFINITIONS
0207 //---------------------------------------------------------------------------//
0208 /*!
0209  * Get material properties for the given material.
0210  */
0211 MaterialView MaterialParams::get(MatId id) const
0212 {
0213     CELER_EXPECT(id < this->host_ref().materials.size());
0214     return MaterialView(this->host_ref(), id);
0215 }
0216 
0217 //---------------------------------------------------------------------------//
0218 /*!
0219  * Get properties for the given element.
0220  */
0221 ElementView MaterialParams::get(ElementId id) const
0222 {
0223     CELER_EXPECT(id < this->host_ref().elements.size());
0224     return ElementView(this->host_ref(), id);
0225 }
0226 
0227 //---------------------------------------------------------------------------//
0228 /*!
0229  * Get properties for the given isotope.
0230  */
0231 IsotopeView MaterialParams::get(IsotopeId id) const
0232 {
0233     CELER_EXPECT(id < this->host_ref().isotopes.size());
0234     return IsotopeView(this->host_ref(), id);
0235 }
0236 
0237 //---------------------------------------------------------------------------//
0238 /*!
0239  * Maximum number of isotopes in any one element.
0240  */
0241 IsotopeComponentId::size_type MaterialParams::max_isotope_components() const
0242 {
0243     return this->host_ref().max_isotope_components;
0244 }
0245 
0246 //---------------------------------------------------------------------------//
0247 /*!
0248  * Maximum number of elements in any one material.
0249  */
0250 ElementComponentId::size_type MaterialParams::max_element_components() const
0251 {
0252     return this->host_ref().max_element_components;
0253 }
0254 
0255 //---------------------------------------------------------------------------//
0256 }  // namespace celeritas