fourdst::libcomposition v2.3.1
Robust atomic species information library
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
6#include "fourdst/logging/logging.h"
7
8#include <numeric>
9#include <ranges>
10#include <vector>
11#include <set>
12#include <string>
13
14#include "quill/LogMacros.h"
15
16namespace {
17 quill::Logger* getLogger() {
18 static quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log");
19 return logger;
20 }
21
22 void throw_unknown_symbol(const std::string& symbol) {
23 LOG_ERROR(getLogger(), "Symbol {} is not a valid species symbol (not in the species database)", symbol);
24 throw fourdst::composition::exceptions::UnknownSymbolError("Symbol " + symbol + " is not a valid species symbol (not in the species database)");
25 }
26}
27
28namespace fourdst::composition {
30 const std::set<atomic::Species> &species,
31 const std::vector<double> &massFractions
32 ) {
33 const double sum = std::accumulate(
34 massFractions.begin(),
35 massFractions.end(),
36 0.0
37 );
38
39 if (std::abs(sum - 1.0) > 1e-10) {
41 "Mass fractions must sum to 1.0, got " + std::to_string(sum)
42 );
43 }
44
45 if (species.size() != massFractions.size()) {
47 "The number of species and mass fractions must be equal. Got " +
48 std::to_string(species.size()) + " species and " +
49 std::to_string(massFractions.size()) + " mass fractions."
50 );
51 }
52
54
55 for (const auto& [sp, xi] : std::views::zip(species, massFractions)) {
56 composition.registerSpecies(sp);
57 composition.setMolarAbundance(sp, xi/sp.mass());
58 }
59
60 return composition;
61 }
62
63 Composition buildCompositionFromMassFractions(const std::vector<atomic::Species> &species, const std::vector<double> &massFractions) {
64 std::set<atomic::Species> speciesSet(species.begin(), species.end());
65 std::vector<double> sortedMassFractions;
66
67 sortedMassFractions.resize(massFractions.size());
68 for (const auto& [s, xi] : std::views::zip(species, massFractions)) {
69 const size_t index = std::distance(speciesSet.begin(), speciesSet.find(s));
70 assert (index < sortedMassFractions.size());
71 sortedMassFractions[index] = xi;
72 }
73
74 return buildCompositionFromMassFractions(speciesSet, sortedMassFractions);
75 }
76
77 Composition buildCompositionFromMassFractions(const std::vector<std::string> &symbols, const std::vector<double> &massFractions) {
78 std::set<atomic::Species> species;
79 for (const auto& symbol : symbols) {
80 auto result = getSpecies(symbol);
81 if (!result) {
82 throw_unknown_symbol(symbol);
83 }
84 species.insert(result.value());
85 }
86
87 std::vector<double> sortedMassFractions(massFractions.size());
88 for (const auto& [symbol, xi] : std::views::zip(symbols, massFractions)) {
89 auto result = getSpecies(symbol);
90 if (!result) {
91 throw_unknown_symbol(symbol);
92 }
93 const size_t index = std::distance(species.begin(), species.find(result.value()));
94 assert (index < sortedMassFractions.size());
95 sortedMassFractions[index] = xi;
96 }
97 return buildCompositionFromMassFractions(species, sortedMassFractions);
98 }
99
100 Composition buildCompositionFromMassFractions(const std::unordered_map<atomic::Species, double>& massFractionsMap) {
101 std::set<atomic::Species> species;
102 std::vector<double> massFractions;
103
104 massFractions.reserve(massFractionsMap.size());
105
106 for (const auto &sp: massFractionsMap | std::views::keys) {
107 species.insert(sp);
108 }
109
110 massFractions.resize(massFractionsMap.size());
111 for (const auto& [sp, xi] : massFractionsMap) {
112 const size_t index = std::distance(species.begin(), species.find(sp));
113 assert (index < massFractions.size());
114 massFractions[index] = xi;
115 }
116
117 return buildCompositionFromMassFractions(species, massFractions);
118 }
119
120 Composition buildCompositionFromMassFractions(std::map<atomic::Species, double> massFractions) {
121 std::set<atomic::Species> species;
122 std::vector<double> massFractionVector;
123
124 massFractionVector.reserve(massFractions.size());
125
126 for (const auto& [sp, xi] : massFractions) {
127 species.insert(sp);
128 massFractionVector.push_back(xi);
129 }
130
131 return buildCompositionFromMassFractions(species, massFractionVector);
132 }
133
134 Composition buildCompositionFromMassFractions(std::map<std::string, double> massFractions) {
135 std::set<atomic::Species> species;
136 std::vector<double> massFractionVector;
137
138
139 for (const auto &symbol: massFractions | std::views::keys) {
140 auto result = getSpecies(symbol);
141 if (!result) {
142 throw_unknown_symbol(symbol);
143 }
144 species.insert(result.value());
145 }
146
147 massFractionVector.resize(massFractions.size());
148
149 for (const auto& [symbol, xi] : massFractions) {
150 auto result = getSpecies(symbol);
151 if (!result) {
152 throw_unknown_symbol(symbol);
153 }
154 const size_t index = std::distance(species.begin(), species.find(result.value()));
155 assert (index < massFractionVector.size());
156 massFractionVector[index] = xi;
157 }
158
159
160 return buildCompositionFromMassFractions(species, massFractionVector);
161 }
162
163 Composition buildCompositionFromMassFractions(const std::unordered_map<std::string, double>& massFractions) {
164 std::set<atomic::Species> species;
165 std::vector<double> massFractionVector;
166
167 for (const auto &symbol: massFractions | std::views::keys) {
168 auto result = getSpecies(symbol);
169 if (!result) {
170 throw_unknown_symbol(symbol);
171 }
172 species.insert(result.value());
173 }
174
175 massFractionVector.resize(massFractions.size());
176 for (const auto& [sp, xi] : massFractions) {
177 auto result = getSpecies(sp);
178 if (!result) {
179 throw_unknown_symbol(sp);
180 }
181 const size_t index = std::distance(species.begin(), species.find(result.value()));
182 assert (index < massFractionVector.size());
183 massFractionVector[index] = xi;
184 }
185
186 return buildCompositionFromMassFractions(species, massFractionVector);
187 }
188
189 std::optional<fourdst::atomic::Species> getSpecies(const std::string& symbol) {
190 if (!fourdst::atomic::species.contains(symbol)) {
191 return std::nullopt;
192 }
193 return fourdst::atomic::species.at(symbol);
194 }
195
196}
Manages a collection of chemical species and their abundances.
Definition composition.h:99
Exception thrown when a composition is in an invalid or inconsistent state.
Exception thrown when an unknown symbol is encountered.
static const std::unordered_map< std::string, const Species & > species
Map of species names to their corresponding Species objects.
Definition species.h:3579
Utilities and types for representing and manipulating chemical compositions.
Composition buildCompositionFromMassFractions(const std::vector< std::string > &symbols, const std::vector< double > &massFractions)
Build a Composition object from symbols and their corresponding mass fractions.
Definition utils.cpp:77
std::optional< fourdst::atomic::Species > getSpecies(const std::string &symbol)
Definition utils.cpp:189