File indexing completed on 2025-08-06 08:10:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <algorithm>
0012 #include <cassert>
0013 #include <cstdint>
0014 #include <vector>
0015
0016 namespace Acts {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 class ElementFraction {
0034 public:
0035
0036
0037
0038
0039 constexpr ElementFraction(unsigned int e, float f)
0040 : m_element(static_cast<uint8_t>(e)),
0041 m_fraction(static_cast<uint8_t>(f * UINT8_MAX)) {
0042 assert((0u < e) && ("The atomic number must be positive"));
0043 assert((0.0f <= f) && (f <= 1.0f) && "Relative fraction must be in [0,1]");
0044 }
0045
0046
0047
0048
0049 constexpr explicit ElementFraction(unsigned int e, unsigned int w)
0050 : m_element(static_cast<uint8_t>(e)),
0051 m_fraction(static_cast<uint8_t>(w)) {
0052 assert((0u < e) && ("The atomic number must be positive"));
0053 assert((w < 256u) && "Integer weight must be in [0,256)");
0054 }
0055
0056
0057 ElementFraction() = delete;
0058 ElementFraction(ElementFraction&&) = default;
0059 ElementFraction(const ElementFraction&) = default;
0060 ~ElementFraction() = default;
0061 ElementFraction& operator=(ElementFraction&&) = default;
0062 ElementFraction& operator=(const ElementFraction&) = default;
0063
0064
0065 constexpr uint8_t element() const { return m_element; }
0066
0067 constexpr float fraction() const {
0068 return static_cast<float>(m_fraction) / UINT8_MAX;
0069 }
0070
0071 private:
0072
0073 uint8_t m_element;
0074
0075 uint8_t m_fraction;
0076
0077 friend constexpr bool operator==(ElementFraction lhs, ElementFraction rhs) {
0078 return (lhs.m_fraction == rhs.m_fraction) &&
0079 (lhs.m_element == rhs.m_element);
0080 }
0081
0082 friend constexpr bool operator<(ElementFraction lhs, ElementFraction rhs) {
0083 return lhs.m_fraction < rhs.m_fraction;
0084 }
0085 friend class MaterialComposition;
0086 };
0087
0088
0089
0090
0091 class MaterialComposition {
0092 public:
0093
0094 MaterialComposition() = default;
0095
0096
0097
0098 MaterialComposition(std::vector<ElementFraction> elements)
0099 : m_elements(std::move(elements)) {
0100 std::sort(m_elements.begin(), m_elements.end());
0101
0102 unsigned total = 0u;
0103 for (auto element : m_elements) {
0104 total += element.m_fraction;
0105 }
0106
0107 float scale = float(UINT8_MAX) / float(total);
0108 for (auto& element : m_elements) {
0109 element.m_fraction = static_cast<uint8_t>(element.m_fraction * scale);
0110 }
0111 }
0112
0113 MaterialComposition(MaterialComposition&&) = default;
0114 MaterialComposition(const MaterialComposition&) = default;
0115 ~MaterialComposition() = default;
0116 MaterialComposition& operator=(MaterialComposition&&) = default;
0117 MaterialComposition& operator=(const MaterialComposition&) = default;
0118
0119
0120 auto begin() const { return m_elements.begin(); }
0121 auto end() const { return m_elements.end(); }
0122
0123
0124 operator bool() const { return !m_elements.empty(); }
0125
0126 std::size_t size() const { return m_elements.size(); }
0127
0128 private:
0129 std::vector<ElementFraction> m_elements;
0130
0131 friend inline bool operator==(const MaterialComposition& lhs,
0132 const MaterialComposition& rhs) {
0133 return (lhs.m_elements == rhs.m_elements);
0134 }
0135 };
0136
0137 }