feat(eos): EOS now uses composition module
EOS code updated to make use of composition module. This is part of the larger change to change all composition handling to use the composition module. Note that the current implimentation is a bit hacky since it simply copies back and forth to the alredy used HELMEOSInput and HELMEOSOutput structs. In furture this can be more tightly connected to avoid extra copies.
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -32,13 +33,15 @@
|
|||||||
|
|
||||||
namespace serif::composition {
|
namespace serif::composition {
|
||||||
|
|
||||||
CompositionEntry::CompositionEntry() : m_symbol("H-1"), m_isotope(chemSpecies::species.at("H-1")), m_initialized(false) {}
|
CompositionEntry::CompositionEntry() : m_symbol("H-1"), m_isotope(chemSpecies::species.at("H-1")),
|
||||||
|
m_initialized(false) {
|
||||||
|
}
|
||||||
|
|
||||||
CompositionEntry::CompositionEntry(const std::string& symbol, bool massFracMode) : m_symbol(symbol), m_isotope(chemSpecies::species.at(symbol)), m_massFracMode(massFracMode) {
|
CompositionEntry::CompositionEntry(const std::string& symbol, const bool massFracMode) : m_symbol(symbol), m_isotope(chemSpecies::species.at(symbol)), m_massFracMode(massFracMode) {
|
||||||
setSpecies(symbol);
|
setSpecies(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositionEntry::CompositionEntry(const CompositionEntry& entry) :
|
CompositionEntry::CompositionEntry(const CompositionEntry& entry) :
|
||||||
m_symbol(entry.m_symbol),
|
m_symbol(entry.m_symbol),
|
||||||
m_isotope(entry.m_isotope),
|
m_isotope(entry.m_isotope),
|
||||||
m_massFracMode(entry.m_massFracMode),
|
m_massFracMode(entry.m_massFracMode),
|
||||||
@@ -47,7 +50,7 @@ CompositionEntry::CompositionEntry(const CompositionEntry& entry) :
|
|||||||
m_relAbundance(entry.m_relAbundance),
|
m_relAbundance(entry.m_relAbundance),
|
||||||
m_initialized(entry.m_initialized) {}
|
m_initialized(entry.m_initialized) {}
|
||||||
|
|
||||||
void CompositionEntry::setSpecies(const std::string& symbol) {
|
void CompositionEntry::setSpecies(const std::string& symbol) {
|
||||||
if (m_initialized) {
|
if (m_initialized) {
|
||||||
throw std::runtime_error("Composition entry is already initialized.");
|
throw std::runtime_error("Composition entry is already initialized.");
|
||||||
}
|
}
|
||||||
@@ -57,100 +60,100 @@ void CompositionEntry::setSpecies(const std::string& symbol) {
|
|||||||
m_symbol = symbol;
|
m_symbol = symbol;
|
||||||
m_isotope = chemSpecies::species.at(symbol);
|
m_isotope = chemSpecies::species.at(symbol);
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CompositionEntry::symbol() const {
|
std::string CompositionEntry::symbol() const {
|
||||||
return m_symbol;
|
return m_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CompositionEntry::mass_fraction() const {
|
double CompositionEntry::mass_fraction() const {
|
||||||
if (!m_massFracMode) {
|
if (!m_massFracMode) {
|
||||||
throw std::runtime_error("Composition entry is in number fraction mode.");
|
throw std::runtime_error("Composition entry is in number fraction mode.");
|
||||||
}
|
}
|
||||||
return m_massFraction;
|
return m_massFraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CompositionEntry::mass_fraction(double meanMolarMass) const {
|
double CompositionEntry::mass_fraction(double meanMolarMass) const {
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
return m_massFraction;
|
return m_massFraction;
|
||||||
}
|
}
|
||||||
return m_relAbundance / meanMolarMass;
|
return m_relAbundance / meanMolarMass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double CompositionEntry::number_fraction() const {
|
double CompositionEntry::number_fraction() const {
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
throw std::runtime_error("Composition entry is in mass fraction mode.");
|
throw std::runtime_error("Composition entry is in mass fraction mode.");
|
||||||
}
|
}
|
||||||
return m_numberFraction;
|
return m_numberFraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CompositionEntry::number_fraction(double totalMoles) const {
|
double CompositionEntry::number_fraction(double totalMoles) const {
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
return m_relAbundance / totalMoles;
|
return m_relAbundance / totalMoles;
|
||||||
}
|
}
|
||||||
return m_numberFraction;
|
return m_numberFraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CompositionEntry::rel_abundance() const {
|
double CompositionEntry::rel_abundance() const {
|
||||||
return m_relAbundance;
|
return m_relAbundance;
|
||||||
}
|
}
|
||||||
|
|
||||||
chemSpecies::Species CompositionEntry::isotope() const {
|
chemSpecies::Species CompositionEntry::isotope() const {
|
||||||
return m_isotope;
|
return m_isotope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompositionEntry::setMassFraction(double mass_fraction) {
|
void CompositionEntry::setMassFraction(double mass_fraction) {
|
||||||
if (!m_massFracMode) {
|
if (!m_massFracMode) {
|
||||||
throw std::runtime_error("Composition entry is in number fraction mode.");
|
throw std::runtime_error("Composition entry is in number fraction mode.");
|
||||||
}
|
}
|
||||||
m_massFraction = mass_fraction;
|
m_massFraction = mass_fraction;
|
||||||
m_relAbundance = m_massFraction / m_isotope.mass();
|
m_relAbundance = m_massFraction / m_isotope.mass();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompositionEntry::setNumberFraction(double number_fraction) {
|
void CompositionEntry::setNumberFraction(double number_fraction) {
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
throw std::runtime_error("Composition entry is in mass fraction mode.");
|
throw std::runtime_error("Composition entry is in mass fraction mode.");
|
||||||
}
|
}
|
||||||
m_numberFraction = number_fraction;
|
m_numberFraction = number_fraction;
|
||||||
m_relAbundance = m_numberFraction * m_isotope.mass();
|
m_relAbundance = m_numberFraction * m_isotope.mass();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompositionEntry::setMassFracMode(double meanParticleMass) {
|
bool CompositionEntry::setMassFracMode(double meanParticleMass) {
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_massFracMode = true;
|
m_massFracMode = true;
|
||||||
m_massFraction = m_relAbundance / meanParticleMass;
|
m_massFraction = m_relAbundance / meanParticleMass;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompositionEntry::setNumberFracMode(double specificNumberDensity) {
|
bool CompositionEntry::setNumberFracMode(double specificNumberDensity) {
|
||||||
if (!m_massFracMode) {
|
if (!m_massFracMode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_massFracMode = false;
|
m_massFracMode = false;
|
||||||
m_numberFraction = m_relAbundance / specificNumberDensity;
|
m_numberFraction = m_relAbundance / specificNumberDensity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompositionEntry::getMassFracMode() const {
|
bool CompositionEntry::getMassFracMode() const {
|
||||||
return m_massFracMode;
|
return m_massFracMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition::Composition(const std::vector<std::string>& symbols) {
|
Composition::Composition(const std::vector<std::string>& symbols) {
|
||||||
for (const auto& symbol : symbols) {
|
for (const auto& symbol : symbols) {
|
||||||
registerSymbol(symbol);
|
registerSymbol(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition::Composition(const std::set<std::string>& symbols) {
|
Composition::Composition(const std::set<std::string>& symbols) {
|
||||||
for (const auto& symbol : symbols) {
|
for (const auto& symbol : symbols) {
|
||||||
registerSymbol(symbol);
|
registerSymbol(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition::Composition(const std::vector<std::string>& symbols, const std::vector<double>& fractions, bool massFracMode) : m_massFracMode(massFracMode) {
|
Composition::Composition(const std::vector<std::string>& symbols, const std::vector<double>& fractions, bool massFracMode) : m_massFracMode(massFracMode) {
|
||||||
if (symbols.size() != fractions.size()) {
|
if (symbols.size() != fractions.size()) {
|
||||||
LOG_ERROR(m_logger, "The number of symbols and fractions must be equal.");
|
LOG_ERROR(m_logger, "The number of symbols and fractions must be equal.");
|
||||||
throw std::runtime_error("The number of symbols and fractions must be equal.");
|
throw std::runtime_error("The number of symbols and fractions must be equal.");
|
||||||
@@ -170,9 +173,32 @@ Composition::Composition(const std::vector<std::string>& symbols, const std::vec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
finalize();
|
finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Composition::registerSymbol(const std::string& symbol, bool massFracMode) {
|
Composition::Composition(const Composition &composition) {
|
||||||
|
m_finalized = composition.m_finalized;
|
||||||
|
m_specificNumberDensity = composition.m_specificNumberDensity;
|
||||||
|
m_meanParticleMass = composition.m_meanParticleMass;
|
||||||
|
m_massFracMode = composition.m_massFracMode;
|
||||||
|
m_registeredSymbols = composition.m_registeredSymbols;
|
||||||
|
m_compositions = composition.m_compositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Composition& Composition::operator=(const Composition &other) {
|
||||||
|
if (this != &other) {
|
||||||
|
m_finalized = other.m_finalized;
|
||||||
|
m_specificNumberDensity = other.m_specificNumberDensity;
|
||||||
|
m_meanParticleMass = other.m_meanParticleMass;
|
||||||
|
m_massFracMode = other.m_massFracMode;
|
||||||
|
m_registeredSymbols = other.m_registeredSymbols;
|
||||||
|
m_compositions = other.m_compositions;
|
||||||
|
// note: m_config remains bound to the same singleton, so we skip it
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composition::registerSymbol(const std::string& symbol, bool massFracMode) {
|
||||||
if (!isValidSymbol(symbol)) {
|
if (!isValidSymbol(symbol)) {
|
||||||
LOG_ERROR(m_logger, "Invalid symbol: {}", symbol);
|
LOG_ERROR(m_logger, "Invalid symbol: {}", symbol);
|
||||||
throw std::runtime_error("Invalid symbol.");
|
throw std::runtime_error("Invalid symbol.");
|
||||||
@@ -197,26 +223,26 @@ void Composition::registerSymbol(const std::string& symbol, bool massFracMode) {
|
|||||||
CompositionEntry entry(symbol, m_massFracMode);
|
CompositionEntry entry(symbol, m_massFracMode);
|
||||||
m_compositions[symbol] = entry;
|
m_compositions[symbol] = entry;
|
||||||
LOG_INFO(m_logger, "Registered symbol: {}", symbol);
|
LOG_INFO(m_logger, "Registered symbol: {}", symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Composition::registerSymbol(const std::vector<std::string>& symbols, bool massFracMode) {
|
void Composition::registerSymbol(const std::vector<std::string>& symbols, bool massFracMode) {
|
||||||
for (const auto& symbol : symbols) {
|
for (const auto& symbol : symbols) {
|
||||||
registerSymbol(symbol, massFracMode);
|
registerSymbol(symbol, massFracMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> Composition::getRegisteredSymbols() const {
|
std::set<std::string> Composition::getRegisteredSymbols() const {
|
||||||
return m_registeredSymbols;
|
return m_registeredSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Composition::validateComposition(const std::vector<double>& fractions) const {
|
void Composition::validateComposition(const std::vector<double>& fractions) const {
|
||||||
if (!isValidComposition(fractions)) {
|
if (!isValidComposition(fractions)) {
|
||||||
LOG_ERROR(m_logger, "Invalid composition.");
|
LOG_ERROR(m_logger, "Invalid composition.");
|
||||||
throw std::runtime_error("Invalid composition.");
|
throw std::runtime_error("Invalid composition.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::isValidComposition(const std::vector<double>& fractions) const {
|
bool Composition::isValidComposition(const std::vector<double>& fractions) const {
|
||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
for (const auto& fraction : fractions) {
|
for (const auto& fraction : fractions) {
|
||||||
sum += fraction;
|
sum += fraction;
|
||||||
@@ -227,13 +253,13 @@ bool Composition::isValidComposition(const std::vector<double>& fractions) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::isValidSymbol(const std::string& symbol) const {
|
bool Composition::isValidSymbol(const std::string& symbol) const {
|
||||||
return chemSpecies::species.count(symbol) > 0;
|
return chemSpecies::species.count(symbol) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Composition::setMassFraction(const std::string& symbol, const double& mass_fraction) {
|
double Composition::setMassFraction(const std::string& symbol, const double& mass_fraction) {
|
||||||
if (m_registeredSymbols.find(symbol) == m_registeredSymbols.end()) {
|
if (m_registeredSymbols.find(symbol) == m_registeredSymbols.end()) {
|
||||||
LOG_ERROR(m_logger, "Symbol {} is not registered.", symbol);
|
LOG_ERROR(m_logger, "Symbol {} is not registered.", symbol);
|
||||||
throw std::runtime_error("Symbol is not registered.");
|
throw std::runtime_error("Symbol is not registered.");
|
||||||
@@ -254,9 +280,9 @@ double Composition::setMassFraction(const std::string& symbol, const double& mas
|
|||||||
m_compositions.at(symbol).setMassFraction(mass_fraction);
|
m_compositions.at(symbol).setMassFraction(mass_fraction);
|
||||||
|
|
||||||
return old_mass_fraction;
|
return old_mass_fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> Composition::setMassFraction(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions) {
|
std::vector<double> Composition::setMassFraction(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions) {
|
||||||
if (symbols.size() != mass_fractions.size()) {
|
if (symbols.size() != mass_fractions.size()) {
|
||||||
LOG_ERROR(m_logger, "The number of symbols and mass fractions must be equal.");
|
LOG_ERROR(m_logger, "The number of symbols and mass fractions must be equal.");
|
||||||
throw std::runtime_error("The number of symbols and mass fractions must be equal.");
|
throw std::runtime_error("The number of symbols and mass fractions must be equal.");
|
||||||
@@ -268,9 +294,9 @@ std::vector<double> Composition::setMassFraction(const std::vector<std::string>&
|
|||||||
old_mass_fractions.push_back(setMassFraction(symbols[i], mass_fractions[i]));
|
old_mass_fractions.push_back(setMassFraction(symbols[i], mass_fractions[i]));
|
||||||
}
|
}
|
||||||
return old_mass_fractions;
|
return old_mass_fractions;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Composition::setNumberFraction(const std::string& symbol, const double& number_fraction) {
|
double Composition::setNumberFraction(const std::string& symbol, const double& number_fraction) {
|
||||||
if (m_registeredSymbols.find(symbol) == m_registeredSymbols.end()) {
|
if (m_registeredSymbols.find(symbol) == m_registeredSymbols.end()) {
|
||||||
LOG_ERROR(m_logger, "Symbol {} is not registered.", symbol);
|
LOG_ERROR(m_logger, "Symbol {} is not registered.", symbol);
|
||||||
throw std::runtime_error("Symbol is not registered.");
|
throw std::runtime_error("Symbol is not registered.");
|
||||||
@@ -291,9 +317,9 @@ double Composition::setNumberFraction(const std::string& symbol, const double& n
|
|||||||
m_compositions.at(symbol).setNumberFraction(number_fraction);
|
m_compositions.at(symbol).setNumberFraction(number_fraction);
|
||||||
|
|
||||||
return old_number_fraction;
|
return old_number_fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> Composition::setNumberFraction(const std::vector<std::string>& symbols, const std::vector<double>& number_fractions) {
|
std::vector<double> Composition::setNumberFraction(const std::vector<std::string>& symbols, const std::vector<double>& number_fractions) {
|
||||||
if (symbols.size() != number_fractions.size()) {
|
if (symbols.size() != number_fractions.size()) {
|
||||||
LOG_ERROR(m_logger, "The number of symbols and number fractions must be equal.");
|
LOG_ERROR(m_logger, "The number of symbols and number fractions must be equal.");
|
||||||
throw std::runtime_error("The number of symbols and number fractions must be equal.");
|
throw std::runtime_error("The number of symbols and number fractions must be equal.");
|
||||||
@@ -305,9 +331,9 @@ std::vector<double> Composition::setNumberFraction(const std::vector<std::string
|
|||||||
old_number_fractions.push_back(setNumberFraction(symbols[i], number_fractions[i]));
|
old_number_fractions.push_back(setNumberFraction(symbols[i], number_fractions[i]));
|
||||||
}
|
}
|
||||||
return old_number_fractions;
|
return old_number_fractions;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::finalize(bool norm) {
|
bool Composition::finalize(bool norm) {
|
||||||
bool finalized = false;
|
bool finalized = false;
|
||||||
if (m_massFracMode) {
|
if (m_massFracMode) {
|
||||||
finalized = finalizeMassFracMode(norm);
|
finalized = finalizeMassFracMode(norm);
|
||||||
@@ -318,9 +344,9 @@ bool Composition::finalize(bool norm) {
|
|||||||
m_finalized = true;
|
m_finalized = true;
|
||||||
}
|
}
|
||||||
return finalized;
|
return finalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::finalizeMassFracMode(bool norm) {
|
bool Composition::finalizeMassFracMode(bool norm) {
|
||||||
std::vector<double> mass_fractions;
|
std::vector<double> mass_fractions;
|
||||||
mass_fractions.reserve(m_compositions.size());
|
mass_fractions.reserve(m_compositions.size());
|
||||||
for (const auto& [_, entry] : m_compositions) {
|
for (const auto& [_, entry] : m_compositions) {
|
||||||
@@ -354,9 +380,9 @@ bool Composition::finalizeMassFracMode(bool norm) {
|
|||||||
}
|
}
|
||||||
m_meanParticleMass = 1.0/m_specificNumberDensity;
|
m_meanParticleMass = 1.0/m_specificNumberDensity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::finalizeNumberFracMode(bool norm) {
|
bool Composition::finalizeNumberFracMode(bool norm) {
|
||||||
std::vector<double> number_fractions;
|
std::vector<double> number_fractions;
|
||||||
number_fractions.reserve(m_compositions.size());
|
number_fractions.reserve(m_compositions.size());
|
||||||
for (const auto& [_, entry] : m_compositions) {
|
for (const auto& [_, entry] : m_compositions) {
|
||||||
@@ -387,9 +413,9 @@ bool Composition::finalizeNumberFracMode(bool norm) {
|
|||||||
}
|
}
|
||||||
m_specificNumberDensity = 1.0/m_meanParticleMass;
|
m_specificNumberDensity = 1.0/m_meanParticleMass;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition Composition::mix(const Composition& other, double fraction) const {
|
Composition Composition::mix(const Composition& other, double fraction) const {
|
||||||
if (!m_finalized || !other.m_finalized) {
|
if (!m_finalized || !other.m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Compositions have not both been finalized.");
|
LOG_ERROR(m_logger, "Compositions have not both been finalized.");
|
||||||
throw std::runtime_error("Compositions have not been finalized (Consider running .finalize()).");
|
throw std::runtime_error("Compositions have not been finalized (Consider running .finalize()).");
|
||||||
@@ -416,9 +442,9 @@ Composition Composition::mix(const Composition& other, double fraction) const {
|
|||||||
}
|
}
|
||||||
mixedComposition.finalize();
|
mixedComposition.finalize();
|
||||||
return mixedComposition;
|
return mixedComposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Composition::getMassFraction(const std::string& symbol) const {
|
double Composition::getMassFraction(const std::string& symbol) const {
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
||||||
@@ -432,18 +458,18 @@ double Composition::getMassFraction(const std::string& symbol) const {
|
|||||||
} else {
|
} else {
|
||||||
return m_compositions.at(symbol).mass_fraction(m_meanParticleMass);
|
return m_compositions.at(symbol).mass_fraction(m_meanParticleMass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, double> Composition::getMassFraction() const {
|
std::unordered_map<std::string, double> Composition::getMassFraction() const {
|
||||||
std::unordered_map<std::string, double> mass_fractions;
|
std::unordered_map<std::string, double> mass_fractions;
|
||||||
for (const auto& [symbol, entry] : m_compositions) {
|
for (const auto& [symbol, entry] : m_compositions) {
|
||||||
mass_fractions[symbol] = getMassFraction(symbol);
|
mass_fractions[symbol] = getMassFraction(symbol);
|
||||||
}
|
}
|
||||||
return mass_fractions;
|
return mass_fractions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double Composition::getNumberFraction(const std::string& symbol) const {
|
double Composition::getNumberFraction(const std::string& symbol) const {
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
||||||
@@ -457,17 +483,17 @@ double Composition::getNumberFraction(const std::string& symbol) const {
|
|||||||
} else {
|
} else {
|
||||||
return m_compositions.at(symbol).number_fraction(m_specificNumberDensity);
|
return m_compositions.at(symbol).number_fraction(m_specificNumberDensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, double> Composition::getNumberFraction() const {
|
std::unordered_map<std::string, double> Composition::getNumberFraction() const {
|
||||||
std::unordered_map<std::string, double> number_fractions;
|
std::unordered_map<std::string, double> number_fractions;
|
||||||
for (const auto& [symbol, entry] : m_compositions) {
|
for (const auto& [symbol, entry] : m_compositions) {
|
||||||
number_fractions[symbol] = getNumberFraction(symbol);
|
number_fractions[symbol] = getNumberFraction(symbol);
|
||||||
}
|
}
|
||||||
return number_fractions;
|
return number_fractions;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CompositionEntry, GlobalComposition> Composition::getComposition(const std::string& symbol) const {
|
std::pair<CompositionEntry, GlobalComposition> Composition::getComposition(const std::string& symbol) const {
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
||||||
@@ -477,17 +503,53 @@ std::pair<CompositionEntry, GlobalComposition> Composition::getComposition(const
|
|||||||
throw std::runtime_error("Symbol is not in the composition.");
|
throw std::runtime_error("Symbol is not in the composition.");
|
||||||
}
|
}
|
||||||
return {m_compositions.at(symbol), {m_specificNumberDensity, m_meanParticleMass}};
|
return {m_compositions.at(symbol), {m_specificNumberDensity, m_meanParticleMass}};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::unordered_map<std::string, CompositionEntry>, GlobalComposition> Composition::getComposition() const {
|
std::pair<std::unordered_map<std::string, CompositionEntry>, GlobalComposition> Composition::getComposition() const {
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
||||||
}
|
}
|
||||||
return {m_compositions, {m_specificNumberDensity, m_meanParticleMass}};
|
return {m_compositions, {m_specificNumberDensity, m_meanParticleMass}};
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition Composition::subset(const std::vector<std::string>& symbols, std::string method) const {
|
double Composition::getMeanParticleMass() const {
|
||||||
|
if (!m_finalized) {
|
||||||
|
LOG_ERROR(m_logger, "Composition has not been finalized.");
|
||||||
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()).");
|
||||||
|
}
|
||||||
|
return m_meanParticleMass;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Composition::getMeanAtomicNumber() const {
|
||||||
|
if (!m_finalized) {
|
||||||
|
LOG_ERROR(m_logger, "Composition must be finalized before getting the mean atomic mass number.");
|
||||||
|
throw std::runtime_error("Composition not finalized. Cannot retrieve mean atomic mass number.");
|
||||||
|
}
|
||||||
|
|
||||||
|
double mean_A = 0.0;
|
||||||
|
|
||||||
|
// Loop through all registered species in the composition.
|
||||||
|
for (const auto &val: m_compositions | std::views::values) {
|
||||||
|
const CompositionEntry& entry = val;
|
||||||
|
const chemSpecies::Species& species = entry.isotope();
|
||||||
|
|
||||||
|
const double mass_fraction = entry.mass_fraction();
|
||||||
|
const double particle_mass_g = species.mass();
|
||||||
|
const int mass_number = species.a();
|
||||||
|
|
||||||
|
// Avoid division by zero, though a valid species should have a positive mass.
|
||||||
|
if (particle_mass_g > 0) {
|
||||||
|
// Calculate the number fraction for this species.
|
||||||
|
const double number_fraction = (mass_fraction / particle_mass_g) * m_meanParticleMass;
|
||||||
|
mean_A += number_fraction * mass_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mean_A;
|
||||||
|
}
|
||||||
|
|
||||||
|
Composition Composition::subset(const std::vector<std::string>& symbols, std::string method) const {
|
||||||
std::array<std::string, 2> methods = {"norm", "none"};
|
std::array<std::string, 2> methods = {"norm", "none"};
|
||||||
|
|
||||||
if (std::find(methods.begin(), methods.end(), method) == methods.end()) {
|
if (std::find(methods.begin(), methods.end(), method) == methods.end()) {
|
||||||
@@ -514,9 +576,9 @@ Composition Composition::subset(const std::vector<std::string>& symbols, std::st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return subsetComposition;
|
return subsetComposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Composition::setCompositionMode(bool massFracMode) {
|
void Composition::setCompositionMode(bool massFracMode) {
|
||||||
if (!m_finalized) {
|
if (!m_finalized) {
|
||||||
LOG_ERROR(m_logger, "Composition has not been finalized. Mode cannot be set unless composition is finalized.");
|
LOG_ERROR(m_logger, "Composition has not been finalized. Mode cannot be set unless composition is finalized.");
|
||||||
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()). The mode cannot be set unless the composition is finalized.");
|
throw std::runtime_error("Composition has not been finalized (Consider running .finalize()). The mode cannot be set unless the composition is finalized.");
|
||||||
@@ -535,36 +597,36 @@ void Composition::setCompositionMode(bool massFracMode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_massFracMode = massFracMode;
|
m_massFracMode = massFracMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Composition::hasSymbol(const std::string& symbol) const {
|
bool Composition::hasSymbol(const std::string& symbol) const {
|
||||||
return m_compositions.count(symbol) > 0;
|
return m_compositions.count(symbol) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// OVERLOADS
|
/// OVERLOADS
|
||||||
|
|
||||||
Composition Composition::operator+(const Composition& other) const {
|
Composition Composition::operator+(const Composition& other) const {
|
||||||
return mix(other, 0.5);
|
return mix(other, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp) {
|
std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp) {
|
||||||
os << "Global Composition: \n";
|
os << "Global Composition: \n";
|
||||||
os << "\tSpecific Number Density: " << comp.specificNumberDensity << "\n";
|
os << "\tSpecific Number Density: " << comp.specificNumberDensity << "\n";
|
||||||
os << "\tMean Particle Mass: " << comp.meanParticleMass << "\n";
|
os << "\tMean Particle Mass: " << comp.meanParticleMass << "\n";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
|
std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
|
||||||
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
|
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const Composition& composition) {
|
std::ostream& operator<<(std::ostream& os, const Composition& composition) {
|
||||||
os << "Composition: \n";
|
os << "Composition: \n";
|
||||||
for (const auto& [symbol, entry] : composition.m_compositions) {
|
for (const auto& [symbol, entry] : composition.m_compositions) {
|
||||||
os << entry << "\n";
|
os << entry << "\n";
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace serif::composition
|
} // namespace serif::composition
|
||||||
@@ -277,7 +277,7 @@ namespace serif::composition {
|
|||||||
* Composition comp(symbols);
|
* Composition comp(symbols);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
Composition(const std::vector<std::string>& symbols);
|
explicit Composition(const std::vector<std::string>& symbols);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructs a Composition with the given symbols as a set.
|
* @brief Constructs a Composition with the given symbols as a set.
|
||||||
@@ -288,7 +288,7 @@ namespace serif::composition {
|
|||||||
* Composition comp(symbols);
|
* Composition comp(symbols);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
Composition(const std::set<std::string>& symbols);
|
explicit Composition(const std::set<std::string>& symbols);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructs a Composition with the given symbols and mass fractions.
|
* @brief Constructs a Composition with the given symbols and mass fractions.
|
||||||
@@ -304,6 +304,14 @@ namespace serif::composition {
|
|||||||
*/
|
*/
|
||||||
Composition(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions, bool massFracMode=true);
|
Composition(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions, bool massFracMode=true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructs a Composition from another Composition.
|
||||||
|
* @param composition The Composition to copy.
|
||||||
|
*/
|
||||||
|
Composition(const Composition& composition);
|
||||||
|
|
||||||
|
Composition& operator=(Composition const& other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Registers a new symbol.
|
* @brief Registers a new symbol.
|
||||||
* @param symbol The symbol to register.
|
* @param symbol The symbol to register.
|
||||||
@@ -333,7 +341,7 @@ namespace serif::composition {
|
|||||||
* @brief Gets the registered symbols.
|
* @brief Gets the registered symbols.
|
||||||
* @return A set of registered symbols.
|
* @return A set of registered symbols.
|
||||||
*/
|
*/
|
||||||
std::set<std::string> getRegisteredSymbols() const;
|
[[nodiscard]] std::set<std::string> getRegisteredSymbols() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the mass fraction for a given symbol.
|
* @brief Sets the mass fraction for a given symbol.
|
||||||
@@ -390,40 +398,52 @@ namespace serif::composition {
|
|||||||
* @brief Gets the mass fractions of all compositions.
|
* @brief Gets the mass fractions of all compositions.
|
||||||
* @return An unordered map of compositions with their mass fractions.
|
* @return An unordered map of compositions with their mass fractions.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<std::string, double> getMassFraction() const;
|
[[nodiscard]] std::unordered_map<std::string, double> getMassFraction() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the mass fraction for a given symbol.
|
* @brief Gets the mass fraction for a given symbol.
|
||||||
* @param symbol The symbol to get the mass fraction for.
|
* @param symbol The symbol to get the mass fraction for.
|
||||||
* @return The mass fraction for the given symbol.
|
* @return The mass fraction for the given symbol.
|
||||||
*/
|
*/
|
||||||
double getMassFraction(const std::string& symbol) const;
|
[[nodiscard]] double getMassFraction(const std::string& symbol) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the number fraction for a given symbol.
|
* @brief Gets the number fraction for a given symbol.
|
||||||
* @param symbol The symbol to get the number fraction for.
|
* @param symbol The symbol to get the number fraction for.
|
||||||
* @return The number fraction for the given symbol.
|
* @return The number fraction for the given symbol.
|
||||||
*/
|
*/
|
||||||
double getNumberFraction(const std::string& symbol) const;
|
[[nodiscard]] double getNumberFraction(const std::string& symbol) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the number fractions of all compositions.
|
* @brief Gets the number fractions of all compositions.
|
||||||
* @return An unordered map of compositions with their number fractions.
|
* @return An unordered map of compositions with their number fractions.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<std::string, double> getNumberFraction() const;
|
[[nodiscard]] std::unordered_map<std::string, double> getNumberFraction() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the composition entry and global composition for a given symbol.
|
* @brief Gets the composition entry and global composition for a given symbol.
|
||||||
* @param symbol The symbol to get the composition for.
|
* @param symbol The symbol to get the composition for.
|
||||||
* @return A pair containing the CompositionEntry and GlobalComposition for the given symbol.
|
* @return A pair containing the CompositionEntry and GlobalComposition for the given symbol.
|
||||||
*/
|
*/
|
||||||
std::pair<CompositionEntry, GlobalComposition> getComposition(const std::string& symbol) const;
|
[[nodiscard]] std::pair<CompositionEntry, GlobalComposition> getComposition(const std::string& symbol) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets all composition entries and the global composition.
|
* @brief Gets all composition entries and the global composition.
|
||||||
* @return A pair containing an unordered map of CompositionEntries and the GlobalComposition.
|
* @return A pair containing an unordered map of CompositionEntries and the GlobalComposition.
|
||||||
*/
|
*/
|
||||||
std::pair<std::unordered_map<std::string, CompositionEntry>, GlobalComposition> getComposition() const;
|
[[nodiscard]] std::pair<std::unordered_map<std::string, CompositionEntry>, GlobalComposition> getComposition() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the mean particle mass of the composition.
|
||||||
|
* @return Mean particle mass in g.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] double getMeanParticleMass() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the mean atomic mass number of the composition.
|
||||||
|
* @return Mean atomic mass number.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] double getMeanAtomicNumber() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a subset of the composition.
|
* @brief Gets a subset of the composition.
|
||||||
|
|||||||
Reference in New Issue
Block a user