Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:26

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 #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 // Avogadro constant
0028 constexpr double kAvogadro = 6.02214076e23 / UnitConstants::mol;
0029 }  // namespace
0030 
0031 Material Material::fromMassDensity(float x0, float l0, float ar, float z,
0032                                    float massRho) {
0033   using namespace UnitLiterals;
0034 
0035   Material mat;
0036   mat.m_x0 = x0;
0037   mat.m_l0 = l0;
0038   mat.m_ar = ar;
0039   mat.m_z = z;
0040   // mass density is defined as
0041   //
0042   //     mass-density = atomic-mass * number-of-atoms / volume
0043   //                  = atomic-mass * molar-density * avogadro-constant
0044   // -> molar-density = mass-density / (atomic-mass * avogadro-constant)
0045   //
0046   // with the atomic mass given by
0047   //
0048   //      atomic-mass = relative-atomic-mass * atomic-mass-unit
0049   //
0050   // perform computations in double precision to avoid loss of precision
0051   const double atomicMass = static_cast<double>(ar) * 1_u;
0052   mat.m_molarRho = static_cast<double>(massRho) / (atomicMass * kAvogadro);
0053   return mat;
0054 }
0055 
0056 Material Material::fromMolarDensity(float x0, float l0, float ar, float z,
0057                                     float molarRho) {
0058   Material mat;
0059   mat.m_x0 = x0;
0060   mat.m_l0 = l0;
0061   mat.m_ar = ar;
0062   mat.m_z = z;
0063   mat.m_molarRho = molarRho;
0064   return mat;
0065 }
0066 
0067 Material::Material(const ParametersVector& parameters)
0068     : m_x0(parameters[eRadiationLength]),
0069       m_l0(parameters[eInteractionLength]),
0070       m_ar(parameters[eRelativeAtomicMass]),
0071       m_z(parameters[eNuclearCharge]),
0072       m_molarRho(parameters[eMolarDensity]) {}
0073 
0074 float Material::massDensity() const {
0075   using namespace UnitLiterals;
0076 
0077   // perform computations in double precision to avoid loss of precision
0078   const double atomicMass = static_cast<double>(m_ar) * 1_u;
0079   const double numberDensity = static_cast<double>(m_molarRho) * kAvogadro;
0080   return atomicMass * numberDensity;
0081 }
0082 
0083 float Material::meanExcitationEnergy() const {
0084   using namespace UnitLiterals;
0085 
0086   // use approximative computation as defined in ATL-SOFT-PUB-2008-003
0087   return 16_eV * std::pow(m_z, 0.9f);
0088 }
0089 
0090 Material::ParametersVector Material::parameters() const {
0091   ParametersVector parameters;
0092   parameters[eRadiationLength] = m_x0;
0093   parameters[eInteractionLength] = m_l0;
0094   parameters[eRelativeAtomicMass] = m_ar;
0095   parameters[eNuclearCharge] = m_z;
0096   parameters[eMolarDensity] = m_molarRho;
0097   return parameters;
0098 }
0099 
0100 std::ostream& operator<<(std::ostream& os, const Material& material) {
0101   if (!material.isValid()) {
0102     os << "vacuum";
0103   } else {
0104     os << "x0=" << material.X0();
0105     os << "|l0=" << material.L0();
0106     os << "|ar=" << material.Ar();
0107     os << "|z=" << material.Z();
0108     os << "|molar_rho=" << material.molarDensity();
0109   }
0110   return os;
0111 }
0112 
0113 }  // namespace Acts