File indexing completed on 2025-06-30 07:52:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Material/Material.hpp"
0010
0011 #include "Acts/Definitions/Units.hpp"
0012
0013 #include <cmath>
0014 #include <ostream>
0015
0016 namespace Acts {
0017
0018 namespace {
0019 enum MaterialClassificationNumberIndices {
0020 eRadiationLength = 0,
0021 eInteractionLength = 1,
0022 eRelativeAtomicMass = 2,
0023 eNuclearCharge = 3,
0024 eMolarDensity = 4,
0025 };
0026
0027
0028 constexpr double kAvogadro = 6.02214076e23 / UnitConstants::mol;
0029
0030 constexpr float calculateMolarElectronDensity(float z, float molarRho) {
0031 return z * molarRho;
0032 }
0033
0034 constexpr float approximateMeanExcitationEnergy(float z) {
0035 using namespace UnitLiterals;
0036
0037
0038 return 16_eV * std::pow(z, 0.9f);
0039 }
0040 }
0041
0042 Material Material::fromMassDensity(float x0, float l0, float ar, float z,
0043 float massRho) {
0044 using namespace UnitLiterals;
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 const double atomicMass = static_cast<double>(ar) * 1_u;
0058 float molarRho = static_cast<float>(massRho / (atomicMass * kAvogadro));
0059
0060 return Material::fromMolarDensity(x0, l0, ar, z, molarRho);
0061 }
0062
0063 Material Material::fromMolarDensity(float x0, float l0, float ar, float z,
0064 float molarRho) {
0065 return Material::fromMolarDensity(x0, l0, ar, z, molarRho,
0066 calculateMolarElectronDensity(z, molarRho),
0067 std::nullopt);
0068 }
0069
0070 Material Material::fromMolarDensity(float x0, float l0, float ar, float z,
0071 float molarRho, float molarElectronRho,
0072 std::optional<float> meanExcitationEnergy) {
0073 Material mat;
0074 mat.m_x0 = x0;
0075 mat.m_l0 = l0;
0076 mat.m_ar = ar;
0077 mat.m_z = z;
0078 mat.m_molarRho = molarRho;
0079 mat.m_molarElectronRho = molarElectronRho;
0080 mat.m_meanExcitationEnergy =
0081 meanExcitationEnergy.value_or(approximateMeanExcitationEnergy(z));
0082 return mat;
0083 }
0084
0085 Material::Material(const ParametersVector& parameters)
0086 : m_x0(parameters[eRadiationLength]),
0087 m_l0(parameters[eInteractionLength]),
0088 m_ar(parameters[eRelativeAtomicMass]),
0089 m_z(parameters[eNuclearCharge]),
0090 m_molarRho(parameters[eMolarDensity]),
0091 m_molarElectronRho(calculateMolarElectronDensity(m_z, m_molarRho)),
0092 m_meanExcitationEnergy(approximateMeanExcitationEnergy(m_z)) {}
0093
0094 float Material::massDensity() const {
0095 using namespace UnitLiterals;
0096
0097
0098 const double atomicMass = static_cast<double>(m_ar) * 1_u;
0099 const double numberDensity = static_cast<double>(m_molarRho) * kAvogadro;
0100 return atomicMass * numberDensity;
0101 }
0102
0103 Material::ParametersVector Material::parameters() const {
0104 ParametersVector parameters;
0105 parameters[eRadiationLength] = m_x0;
0106 parameters[eInteractionLength] = m_l0;
0107 parameters[eRelativeAtomicMass] = m_ar;
0108 parameters[eNuclearCharge] = m_z;
0109 parameters[eMolarDensity] = m_molarRho;
0110 return parameters;
0111 }
0112
0113 std::ostream& operator<<(std::ostream& os, const Material& material) {
0114 if (material.isVacuum()) {
0115 os << "vacuum";
0116 } else {
0117 os << "x0=" << material.X0();
0118 os << "|l0=" << material.L0();
0119 os << "|ar=" << material.Ar();
0120 os << "|z=" << material.Z();
0121 os << "|molar_rho=" << material.molarDensity();
0122 os << "|molar_e_rho=" << material.molarElectronDensity();
0123 os << "|mean_excitation_energy=" << material.meanExcitationEnergy();
0124 }
0125 return os;
0126 }
0127
0128 }