Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:59

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 /// Detray include(s)
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/detail/qualifiers.hpp"
0014 #include "detray/definitions/math.hpp"
0015 #include "detray/definitions/units.hpp"
0016 #include "detray/material/detail/density_effect_data.hpp"
0017 #include "detray/utils/invalid_values.hpp"
0018 #include "detray/utils/type_traits.hpp"
0019 
0020 // System include(s)
0021 #include <ratio>
0022 #include <sstream>
0023 
0024 namespace detray {
0025 
0026 /// Material State
0027 enum class material_state {
0028   e_solid = 0,
0029   e_liquid = 1,
0030   e_gas = 2,
0031   e_unknown = 3
0032 };
0033 
0034 template <concepts::scalar scalar_t, typename R = std::ratio<1, 1>>
0035 struct material {
0036   using ratio = R;
0037   using scalar_type = scalar_t;
0038 
0039   constexpr material() = default;
0040 
0041   /// Construct from material parameters
0042   DETRAY_HOST_DEVICE
0043   constexpr material(const scalar_type x0, const scalar_type l0,
0044                      const scalar_type ar, const scalar_type z,
0045                      const scalar_type mass_rho, const material_state state)
0046       : m_x0(x0),
0047         m_l0(l0),
0048         m_ar(ar),
0049         m_z(z),
0050         m_mass_rho(mass_rho),
0051         m_state(state) {
0052     m_molar_rho = mass_to_molar_density(ar, mass_rho);
0053   }
0054 
0055   /// Construct from material parameters with density effect data
0056   DETRAY_HOST_DEVICE
0057   constexpr material(const scalar_type x0, const scalar_type l0,
0058                      const scalar_type ar, const scalar_type z,
0059                      const scalar_type mass_rho, const material_state state,
0060                      const scalar_type d_a, const scalar_type d_m,
0061                      const scalar_type d_X0, const scalar_type d_X1,
0062                      const scalar_type d_I, const scalar_type d_nC,
0063                      const scalar_type d_delta0)
0064       : m_x0(x0),
0065         m_l0(l0),
0066         m_ar(ar),
0067         m_z(z),
0068         m_mass_rho(mass_rho),
0069         m_state(state),
0070         m_density(d_a, d_m, d_X0, d_X1, d_I, d_nC, d_delta0),
0071         m_has_density_effect_data(true) {
0072     m_molar_rho = mass_to_molar_density(ar, mass_rho);
0073   }
0074 
0075   /// Equality operator
0076   ///
0077   /// @param rhs is the right hand side to be compared to
0078   DETRAY_HOST_DEVICE
0079   constexpr bool operator==(const material<scalar_type> &rhs) const {
0080     return (m_x0 == rhs.X0() && m_l0 == rhs.L0() && m_ar == rhs.Ar() &&
0081             m_z == rhs.Z());
0082   }
0083 
0084   /// Equality operator
0085   ///
0086   /// @param rhs is the right hand side to be compared to
0087   DETRAY_HOST_DEVICE
0088   constexpr bool operator!=(const material<scalar_type> &rhs) const {
0089     return !(*this == rhs);
0090   }
0091 
0092   /// @returns the radition length. Infinity in case of vacuum.
0093   DETRAY_HOST_DEVICE
0094   constexpr scalar_type X0() const { return m_x0; }
0095   /// @returns the nuclear interaction length. Infinity in case of vacuum.
0096   DETRAY_HOST_DEVICE
0097   constexpr scalar_type L0() const { return m_l0; }
0098   /// @returns the relative atomic mass.
0099   DETRAY_HOST_DEVICE
0100   constexpr scalar_type Ar() const { return m_ar; }
0101   /// @returns the nuclear charge number.
0102   DETRAY_HOST_DEVICE
0103   constexpr scalar_type Z() const { return m_z; }
0104   /// @returns the mass density.
0105   DETRAY_HOST_DEVICE
0106   constexpr scalar_type mass_density() const { return m_mass_rho; }
0107   /// @returns the molar density.
0108   /// @brief mass_density / A
0109   DETRAY_HOST_DEVICE
0110   constexpr scalar_type molar_density() const { return m_molar_rho; }
0111   /// @returns the material state.
0112   DETRAY_HOST_DEVICE
0113   constexpr material_state state() const { return m_state; }
0114   /// @returns the molar electron density.
0115   /// @brief (Z/A) * mass_density
0116   DETRAY_HOST_DEVICE
0117   constexpr scalar_type molar_electron_density() const {
0118     return m_z * m_molar_rho;
0119   }
0120 
0121   /// @returns the density effect data
0122   DETRAY_HOST_DEVICE
0123   constexpr const detail::density_effect_data<scalar_type> &
0124   density_effect_data() const {
0125     return m_density;
0126   }
0127 
0128   /// @returns the (Approximated) mean excitation energy
0129   DETRAY_HOST_DEVICE
0130   scalar_type mean_excitation_energy() const {
0131     if (!m_has_density_effect_data) {
0132       // use approximative computation as defined in ATL-SOFT-PUB-2008-003
0133       return 16.f * unit<scalar_type>::eV *
0134              math::pow(m_z, static_cast<scalar_type>(0.9));
0135     } else {
0136       return m_density.get_mean_excitation_energy();
0137     }
0138   }
0139 
0140   DETRAY_HOST_DEVICE
0141   constexpr scalar_type fraction() const {
0142     if constexpr (ratio::num == 0) {
0143       return 0.f;
0144     } else if constexpr (ratio::den == 0) {
0145       return detail::invalid_value<scalar_type>();
0146     } else {
0147       return static_cast<scalar_type>(ratio::num) /
0148              static_cast<scalar_type>(ratio::den);
0149     }
0150   }
0151 
0152   /// @returns a string that contains the material details
0153   DETRAY_HOST
0154   std::string to_string() const {
0155     std::stringstream strm;
0156     if (m_ar <= 0.f) {
0157       strm << "vacuum";
0158       return strm.str();
0159     }
0160     strm << "material: ";
0161     strm << " X0 = " << m_x0;
0162     strm << " | L0 = " << m_l0;
0163     strm << " | Z = " << m_z;
0164 
0165     strm << " | state = ";
0166     switch (m_state) {
0167       using enum material_state;
0168       case e_solid: {
0169         strm << "solid";
0170         break;
0171       }
0172       case e_liquid: {
0173         strm << "liquid";
0174         break;
0175       }
0176       case e_gas: {
0177         strm << "gaseous";
0178         break;
0179       }
0180       default: {
0181         strm << "unknown";
0182         break;
0183       }
0184     }
0185 
0186     return strm.str();
0187   }
0188 
0189   /// @returns a string stream that prints the material details
0190   DETRAY_HOST
0191   friend std::ostream &operator<<(std::ostream &os, const material &mat) {
0192     os << mat.to_string();
0193     return os;
0194   }
0195 
0196   /// @returns true if density effect data is present
0197   DETRAY_HOST_DEVICE
0198   bool has_density_effect_data() const { return m_has_density_effect_data; }
0199 
0200  protected:
0201   /// Set the radition length.
0202   DETRAY_HOST_DEVICE
0203   constexpr void set_X0(scalar_type x0) { m_x0 = x0; }
0204   /// Set the nuclear interaction length.
0205   DETRAY_HOST_DEVICE
0206   constexpr void set_L0(scalar_type l0) { m_l0 = l0; }
0207   /// Set the relative atomic mass.
0208   DETRAY_HOST_DEVICE
0209   constexpr void set_Ar(scalar_type ar) { m_ar = ar; }
0210   /// Set the nuclear charge number.
0211   DETRAY_HOST_DEVICE
0212   constexpr void set_Z(scalar_type z) { m_z = z; }
0213   /// Set the mass density.
0214   DETRAY_HOST_DEVICE
0215   constexpr void set_mass_density(scalar_type mass_rho) {
0216     m_mass_rho = mass_rho;
0217   }
0218   /// Set the molar density.
0219   DETRAY_HOST_DEVICE
0220   constexpr void set_molar_density(scalar_type molar_rho) {
0221     m_molar_rho = molar_rho;
0222   }
0223   DETRAY_HOST_DEVICE
0224   /// @return [mass_density / A]
0225   constexpr scalar_type mass_to_molar_density(double ar, double mass_rho) {
0226     if (mass_rho == 0.) {
0227       return 0.f;
0228     }
0229 
0230     const double molar_mass{ar * unit<double>::g / unit<double>::mol};
0231 
0232     return static_cast<scalar_type>(mass_rho / molar_mass);
0233   }
0234 
0235  private:
0236   // Material properties
0237   scalar_type m_x0 = detail::invalid_value<scalar_type>();
0238   scalar_type m_l0 = detail::invalid_value<scalar_type>();
0239   scalar_type m_ar = 0.f;
0240   scalar_type m_z = 0.f;
0241   scalar_type m_mass_rho = 0.f;
0242   scalar_type m_molar_rho = 0.f;
0243   material_state m_state = material_state::e_unknown;
0244   detail::density_effect_data<scalar_type> m_density = {};
0245   bool m_has_density_effect_data = false;
0246 };
0247 
0248 // Macro for declaring the predefined materials (w/o Density effect data)
0249 #define DETRAY_DECLARE_MATERIAL(MATERIAL_NAME, X0, L0, Ar, Z, Rho, State) \
0250   template <concepts::scalar scalar_t, typename R = std::ratio<1, 1>>     \
0251   struct MATERIAL_NAME final : public material<scalar_t, R> {             \
0252     using base_type = material<scalar_t, R>;                              \
0253     using base_type::base_type;                                           \
0254     DETRAY_HOST_DEVICE                                                    \
0255     constexpr MATERIAL_NAME() : base_type(X0, L0, Ar, Z, Rho, State) {}   \
0256   }
0257 
0258 // !EXPERIMENTAL!
0259 // Macro for declaring the predefined materials (with Density effect data)
0260 #define DETRAY_DECLARE_MATERIAL_WITH_DED(                                    \
0261     MATERIAL_NAME, X0, L0, Ar, Z, Rho, State, Density0, Density1, Density2,  \
0262     Density3, Density4, Density5, Density6)                                  \
0263   template <concepts::scalar scalar_t, typename R = std::ratio<1, 1>>        \
0264   struct MATERIAL_NAME final : public material<scalar_t, R> {                \
0265     using base_type = material<scalar_t, R>;                                 \
0266     using base_type::base_type;                                              \
0267     DETRAY_HOST_DEVICE                                                       \
0268     constexpr MATERIAL_NAME()                                                \
0269         : base_type(X0, L0, Ar, Z, Rho, State, Density0, Density1, Density2, \
0270                     Density3, Density4, Density5, Density6) {}               \
0271   }
0272 
0273 }  // namespace detray