Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:52:27

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 /// @defgroup Material Material
0021 ///
0022 /// The following parameters are used to specify the material and its
0023 /// interactions with traversing particles:
0024 ///
0025 /// - radiation length X0 (native length units)
0026 /// - nuclear interaction length L0 (native length units)
0027 /// - relative atomic mass Ar (unitless number)
0028 /// - nuclear charge number Z (elementary charge e)
0029 /// - molar density (native amount-of-substance unit / (native length unit)³)
0030 ///
0031 /// The parameters can be effective or average parameters e.g. when a mixture
0032 /// of materials is described.
0033 ///
0034 /// @note Always use the opaque parameters vector to serialize/deserialize the
0035 ///   material information. Since the internal storage might be different from
0036 ///   the external accessors, this ensures that always the numerically optimal
0037 ///   parameters are stored. Use the `ParametersVector` type and do not assume
0038 ///   any particular size since we might consider to store more parameters in
0039 ///   the future.
0040 class Material {
0041  public:
0042   using ParametersVector = Eigen::Matrix<float, 5, 1>;
0043 
0044   static constexpr Material Vacuum() { return Material(); }
0045 
0046   // Both mass and molar density are stored as a float and can thus not be
0047   // distinguished by their types. Just changing the last element in the
0048   // previously existing constructor that took five floats as input to represent
0049   // molar density instead of mass density could have lead to significant
0050   // confusion compared to the previous behaviour. To avoid any ambiguity,
0051   // construction from separate material parameters must happen through the
0052   // following named constructors.
0053 
0054   /// Construct from material parameters using the molar density.
0055   ///
0056   /// @param x0 is the radiation length
0057   /// @param l0 is the nuclear interaction length
0058   /// @param ar is the relative atomic mass
0059   /// @param z is the nuclear charge number
0060   /// @param molarRho is the molar density
0061   /// @param molarElectronRho is the molar electron density
0062   /// @param meanExcitationEnergy is the mean electron excitation energy.
0063   ///        If not provided it will be approximated.
0064   static Material fromMolarDensity(float x0, float l0, float ar, float z,
0065                                    float molarRho, float molarElectronRho,
0066                                    std::optional<float> meanExcitationEnergy);
0067 
0068   /// Construct from material parameters using the molar density.
0069   ///
0070   /// @param x0 is the radiation length
0071   /// @param l0 is the nuclear interaction length
0072   /// @param ar is the relative atomic mass
0073   /// @param z is the nuclear charge number
0074   /// @param molarRho is the molar density
0075   static Material fromMolarDensity(float x0, float l0, float ar, float z,
0076                                    float molarRho);
0077 
0078   /// Construct from material parameters using the mass density.
0079   ///
0080   /// @param x0 is the radiation length
0081   /// @param l0 is the nuclear interaction length
0082   /// @param ar is the relative atomic mass
0083   /// @param z is the nuclear charge number
0084   /// @param massRho is the mass density
0085   ///
0086   /// @warning Due to the choice of native mass units, using the mass density
0087   ///   can lead to numerical problems. Typical mass densities lead to
0088   ///   computations with values differing by 20+ orders of magnitude.
0089   static Material fromMassDensity(float x0, float l0, float ar, float z,
0090                                   float massRho);
0091 
0092   /// Construct from an encoded parameters vector.
0093   explicit Material(const ParametersVector& parameters);
0094 
0095   /// Check if the material is vacuum.
0096   bool isVacuum() const { return m_ar <= 0.f; }
0097 
0098   /// Return the radiation length. Infinity in case of vacuum.
0099   constexpr float X0() const { return m_x0; }
0100   /// Return the nuclear interaction length. Infinity in case of vacuum.
0101   constexpr float L0() const { return m_l0; }
0102   /// Return the relative atomic mass.
0103   constexpr float Ar() const { return m_ar; }
0104   /// Return the nuclear charge number.
0105   constexpr float Z() const { return m_z; }
0106   /// Return the molar density.
0107   constexpr float molarDensity() const { return m_molarRho; }
0108   /// Return the molar electron density.
0109   constexpr float molarElectronDensity() const { return m_molarElectronRho; }
0110   /// Return the mass density.
0111   float massDensity() const;
0112   /// Return the mean electron excitation energy.
0113   constexpr float meanExcitationEnergy() const {
0114     return m_meanExcitationEnergy;
0115   }
0116 
0117   /// Encode the properties into an opaque parameters vector.
0118   ParametersVector parameters() const;
0119 
0120  private:
0121   float m_x0 = std::numeric_limits<float>::infinity();
0122   float m_l0 = std::numeric_limits<float>::infinity();
0123   float m_ar = 0.0f;
0124   float m_z = 0.0f;
0125   float m_molarRho = 0.0f;
0126   float m_molarElectronRho = 0.0f;
0127   float m_meanExcitationEnergy = 0.0f;
0128 
0129   constexpr Material() = default;
0130 
0131   /// @brief Check if two materials are exactly equal.
0132   ///
0133   /// This is a strict equality check, i.e. the materials must have identical
0134   /// properties.
0135   ///
0136   /// @param lhs is the left hand side material
0137   /// @param rhs is the right hand side material
0138   ///
0139   /// @return true if the materials are equal
0140   friend constexpr bool operator==(const Material& lhs, const Material& rhs) {
0141     return (lhs.m_x0 == rhs.m_x0) && (lhs.m_l0 == rhs.m_l0) &&
0142            (lhs.m_ar == rhs.m_ar) && (lhs.m_z == rhs.m_z) &&
0143            (lhs.m_molarRho == rhs.m_molarRho) &&
0144            (lhs.m_molarElectronRho == rhs.m_molarElectronRho) &&
0145            (lhs.m_meanExcitationEnergy == rhs.m_meanExcitationEnergy);
0146   }
0147 };
0148 
0149 std::ostream& operator<<(std::ostream& os, const Material& material);
0150 
0151 }  // namespace Acts