Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:54

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