Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:25

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