Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 08:18:11

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <iosfwd>
0012 #include <limits>
0013 #include <optional>
0014 
0015 #include <Eigen/Dense>
0016 
0017 namespace Acts {
0018 
0019 /// Material description for interactions with matter.
0020 ///
0021 /// @ingroup material
0022 ///
0023 /// The following parameters are used to specify the material and its
0024 /// interactions with traversing particles:
0025 ///
0026 /// - radiation length X0 (native length units)
0027 /// - nuclear interaction length L0 (native length units)
0028 /// - relative atomic mass Ar (unitless number)
0029 /// - nuclear charge number Z (elementary charge e)
0030 /// - molar density (native amount-of-substance unit / (native length unit)³)
0031 ///
0032 /// The parameters can be effective or average parameters e.g. when a mixture
0033 /// of materials is described.
0034 ///
0035 /// @note Always use the opaque parameters vector to serialize/deserialize the
0036 ///   material information. Since the internal storage might be different from
0037 ///   the external accessors, this ensures that always the numerically optimal
0038 ///   parameters are stored. Use the `ParametersVector` type and do not assume
0039 ///   any particular size since we might consider to store more parameters in
0040 ///   the future.
0041 class Material {
0042  public:
0043   /// Opaque parameters vector for serialization
0044   using ParametersVector = Eigen::Matrix<float, 5, 1>;
0045 
0046   /// Create a vacuum material
0047   /// @return Vacuum material
0048   static constexpr Material Vacuum() { return Material(); }
0049 
0050   // Both mass and molar density are stored as a float and can thus not be
0051   // distinguished by their types. Just changing the last element in the
0052   // previously existing constructor that took five floats as input to represent
0053   // molar density instead of mass density could have lead to significant
0054   // confusion compared to the previous behaviour. To avoid any ambiguity,
0055   // construction from separate material parameters must happen through the
0056   // following named constructors.
0057 
0058   /// Construct from material parameters using the molar density.
0059   ///
0060   /// @param x0 is the radiation length
0061   /// @param l0 is the nuclear interaction length
0062   /// @param ar is the relative atomic mass
0063   /// @param z is the nuclear charge number
0064   /// @param molarRho is the molar density
0065   /// @param molarElectronRho is the molar electron density
0066   /// @param meanExcitationEnergy is the mean electron excitation energy.
0067   ///        If not provided it will be approximated.
0068   /// @return Material instance constructed from the given parameters
0069   static Material fromMolarDensity(float x0, float l0, float ar, float z,
0070                                    float molarRho, float molarElectronRho,
0071                                    std::optional<float> meanExcitationEnergy);
0072 
0073   /// Construct from material parameters using the molar density.
0074   ///
0075   /// @param x0 is the radiation length
0076   /// @param l0 is the nuclear interaction length
0077   /// @param ar is the relative atomic mass
0078   /// @param z is the nuclear charge number
0079   /// @param molarRho is the molar density
0080   /// @return Material instance constructed from the given parameters
0081   static Material fromMolarDensity(float x0, float l0, float ar, float z,
0082                                    float molarRho);
0083 
0084   /// Construct from material parameters using the mass density.
0085   ///
0086   /// @param x0 is the radiation length
0087   /// @param l0 is the nuclear interaction length
0088   /// @param ar is the relative atomic mass
0089   /// @param z is the nuclear charge number
0090   /// @param massRho is the mass density
0091   /// @return Material instance constructed from the given parameters
0092   ///
0093   /// @warning Due to the choice of native mass units, using the mass density
0094   ///   can lead to numerical problems. Typical mass densities lead to
0095   ///   computations with values differing by 20+ orders of magnitude.
0096   static Material fromMassDensity(float x0, float l0, float ar, float z,
0097                                   float massRho);
0098 
0099   /// Construct from an encoded parameters vector.
0100   /// @param parameters Encoded material parameters
0101   explicit Material(const ParametersVector& parameters);
0102 
0103   /// Check if the material is vacuum.
0104   /// @return True if the material is vacuum
0105   bool isVacuum() const { return m_ar <= 0.f; }
0106 
0107   /// Return the radiation length. Infinity in case of vacuum.
0108   /// @return Radiation length
0109   constexpr float X0() const { return m_x0; }
0110   /// Return the nuclear interaction length. Infinity in case of vacuum.
0111   /// @return Nuclear interaction length
0112   constexpr float L0() const { return m_l0; }
0113   /// Return the relative atomic mass.
0114   /// @return Relative atomic mass
0115   constexpr float Ar() const { return m_ar; }
0116   /// Return the nuclear charge number.
0117   /// @return Nuclear charge number
0118   constexpr float Z() const { return m_z; }
0119   /// Return the molar density.
0120   /// @return Molar density
0121   constexpr float molarDensity() const { return m_molarRho; }
0122   /// Return the molar electron density.
0123   /// @return Molar electron density
0124   constexpr float molarElectronDensity() const { return m_molarElectronRho; }
0125   /// Return the mass density.
0126   /// @return Mass density
0127   float massDensity() const;
0128   /// Return the mean electron excitation energy.
0129   /// @return Mean electron excitation energy
0130   constexpr float meanExcitationEnergy() const {
0131     return m_meanExcitationEnergy;
0132   }
0133 
0134   /// Encode the properties into an opaque parameters vector.
0135   /// @return Encoded parameters vector
0136   ParametersVector parameters() const;
0137 
0138  private:
0139   float m_x0 = std::numeric_limits<float>::infinity();
0140   float m_l0 = std::numeric_limits<float>::infinity();
0141   float m_ar = 0.0f;
0142   float m_z = 0.0f;
0143   float m_molarRho = 0.0f;
0144   float m_molarElectronRho = 0.0f;
0145   float m_meanExcitationEnergy = 0.0f;
0146 
0147   constexpr Material() = default;
0148 
0149   /// @brief Check if two materials are exactly equal.
0150   ///
0151   /// This is a strict equality check, i.e. the materials must have identical
0152   /// properties.
0153   ///
0154   /// @param lhs is the left hand side material
0155   /// @param rhs is the right hand side material
0156   ///
0157   /// @return true if the materials are equal
0158   friend constexpr bool operator==(const Material& lhs, const Material& rhs) {
0159     return (lhs.m_x0 == rhs.m_x0) && (lhs.m_l0 == rhs.m_l0) &&
0160            (lhs.m_ar == rhs.m_ar) && (lhs.m_z == rhs.m_z) &&
0161            (lhs.m_molarRho == rhs.m_molarRho) &&
0162            (lhs.m_molarElectronRho == rhs.m_molarElectronRho) &&
0163            (lhs.m_meanExcitationEnergy == rhs.m_meanExcitationEnergy);
0164   }
0165 };
0166 
0167 /// Stream operator for Material
0168 /// @param os Output stream
0169 /// @param material Material to output
0170 /// @return Reference to output stream
0171 std::ostream& operator<<(std::ostream& os, const Material& material);
0172 
0173 }  // namespace Acts