feat(composition): added numberFrac methods and subset method

Composition can now be placed in either number fraction or mass fraction mode and can (after finalization) convert between them. Subsets of compositions can also be made. Normalization has also been added to finalize. Tests have been added
This commit is contained in:
2025-03-25 12:49:37 -04:00
parent 39461ba145
commit 95e4d10c59
3 changed files with 680 additions and 92 deletions

View File

@@ -1,13 +1,12 @@
#ifndef COMPOSITION_H
#define COMPOSITION_H
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
#include <set>
#include "quill/LogMacros.h"
#include <utility>
#include "probe.h"
#include "config.h"
@@ -15,12 +14,139 @@
#include "atomicSpecies.h"
namespace composition{
/**
* @brief Represents the global composition of a system. This tends to be used after finalize and is primarily for internal use.
*/
struct GlobalComposition {
double specificNumberDensity; ///< The specific number density of the composition (\sum_{i} X_i m_i. Where X_i is the number fraction of the ith species and m_i is the mass of the ith species).
double meanParticleMass; ///< The mean particle mass of the composition (\sum_{i} \frac{n_i}{m_i}. where n_i is the number fraction of the ith species and m_i is the mass of the ith species).
// Overload the output stream operator for GlobalComposition
friend std::ostream& operator<<(std::ostream& os, const GlobalComposition& comp) {
os << "Global Composition: \n";
os << "\tSpecific Number Density: " << comp.specificNumberDensity << "\n";
os << "\tMean Particle Mass: " << comp.meanParticleMass << "\n";
return os;
}
};
/**
* @brief Represents an entry in the composition with a symbol and mass fraction.
*/
struct CompositionEntry {
std::string symbol; ///< The chemical symbol of the element.
double mass_fraction; ///< The mass fraction of the element.
std::string m_symbol; ///< The chemical symbol of the species.
chemSpecies::Species m_isotope; ///< The isotope of the species.
bool m_massFracMode = true; ///< The mode of the composition entry. True if mass fraction, false if number fraction.
double m_massFraction = 0.0; ///< The mass fraction of the species.
double m_numberFraction = 0.0; ///< The number fraction of the species.
double m_relAbundance = 0.0; ///< The relative abundance of the species for converting between mass and number fractions.
bool m_initialized = false; ///< True if the composition entry has been initialized.
/**
* @brief Default constructor.
*/
CompositionEntry();
/**
* @brief Constructs a CompositionEntry with the given symbol and mode.
* @param symbol The chemical symbol of the species.
* @param massFracMode True if mass fraction mode, false if number fraction mode.
* @example
* @code
* CompositionEntry entry("H", true);
* @endcode
*/
CompositionEntry(const std::string& symbol, bool massFracMode=true);
/**
* @brief Copy constructor.
* @param entry The CompositionEntry to copy.
*/
CompositionEntry(const CompositionEntry& entry);
/**
* @brief Sets the species for the composition entry.
* @param symbol The chemical symbol of the species.
*/
void setSpecies(const std::string& symbol);
/**
* @brief Gets the chemical symbol of the species.
* @return The chemical symbol of the species.
*/
std::string symbol() const;
/**
* @brief Gets the mass fraction of the species.
* @return The mass fraction of the species.
*/
double mass_fraction() const;
/**
* @brief Gets the mass fraction of the species given the mean molar mass.
* @param meanMolarMass The mean molar mass.
* @return The mass fraction of the species.
*/
double mass_fraction(double meanMolarMass) const;
/**
* @brief Gets the number fraction of the species.
* @return The number fraction of the species.
*/
double number_fraction() const;
/**
* @brief Gets the number fraction of the species given the total moles.
* @param totalMoles The total moles.
* @return The number fraction of the species.
*/
double number_fraction(double totalMoles) const;
/**
* @brief Gets the relative abundance of the species.
* @return The relative abundance of the species.
*/
double rel_abundance() const;
/**
* @brief Gets the isotope of the species.
* @return The isotope of the species.
*/
chemSpecies::Species isotope() const;
/**
* @brief Gets the mode of the composition entry.
* @return True if mass fraction mode, false if number fraction mode.
*/
bool getMassFracMode() const;
/**
* @brief Sets the mass fraction of the species.
* @param mass_fraction The mass fraction to set.
*/
void setMassFraction(double mass_fraction);
/**
* @brief Sets the number fraction of the species.
* @param number_fraction The number fraction to set.
*/
void setNumberFraction(double number_fraction);
/**
* @brief Sets the mode to mass fraction mode.
* @param meanMolarMass The mean molar mass.
* @return True if the mode was successfully set, false otherwise.
*/
bool setMassFracMode(double meanMolarMass);
/**
* @brief Sets the mode to number fraction mode.
* @param totalMoles The total moles.
* @return True if the mode was successfully set, false otherwise.
*/
bool setNumberFracMode(double totalMoles);
/**
* @brief Overloaded output stream operator for CompositionEntry.
@@ -29,7 +155,7 @@ namespace composition{
* @return The output stream.
*/
friend std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
os << "<" << entry.symbol << " : " << entry.mass_fraction << ">";
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
return os;
}
};
@@ -68,10 +194,13 @@ namespace composition{
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
quill::Logger* m_logger = m_logManager.getLogger("log");
bool m_finalized = false;
bool m_finalized = false; ///< True if the composition is finalized.
double m_specificNumberDensity = 0.0; ///< The specific number density of the composition (\sum_{i} X_i m_i. Where X_i is the number fraction of the ith species and m_i is the mass of the ith species).
double m_meanParticleMass = 0.0; ///< The mean particle mass of the composition (\sum_{i} \frac{n_i}{m_i}. where n_i is the number fraction of the ith species and m_i is the mass of the ith species).
bool m_massFracMode = true; ///< True if mass fraction mode, false if number fraction mode.
std::set<std::string> m_registeredSymbols;
std::unordered_map<std::string, CompositionEntry> m_compositions;
std::set<std::string> m_registeredSymbols; ///< The registered symbols.
std::unordered_map<std::string, CompositionEntry> m_compositions; ///< The compositions.
/**
* @brief Checks if the given symbol is valid.
@@ -86,14 +215,28 @@ namespace composition{
* @param mass_fractions The mass fractions to check.
* @return True if the mass fractions are valid, false otherwise.
*/
bool isValidComposition(const std::vector<double>& mass_fractions) const;
bool isValidComposition(const std::vector<double>& fractions) const;
/**
* @brief Validates the given mass fractions.
* @param mass_fractions The mass fractions to validate.
* @throws std::invalid_argument if the mass fractions are invalid.
*/
void validateComposition(const std::vector<double>& mass_fractions) const;
void validateComposition(const std::vector<double>& fractions) const;
/**
* @brief Finalizes the composition in mass fraction mode.
* @param norm If true, the composition will be normalized to sum to 1.
* @return True if the composition is successfully finalized, false otherwise.
*/
bool finalizeMassFracMode(bool norm);
/**
* @brief Finalizes the composition in number fraction mode.
* @param norm If true, the composition will be normalized to sum to 1.
* @return True if the composition is successfully finalized, false otherwise.
*/
bool finalizeNumberFracMode(bool norm);
public:
/**
@@ -108,9 +251,10 @@ namespace composition{
/**
* @brief Finalizes the composition.
* @param norm If true, the composition will be normalized to sum to 1 [Default False]
* @return True if the composition is successfully finalized, false otherwise.
*/
bool finalize();
bool finalize(bool norm=false);
/**
* @brief Constructs a Composition with the given symbols.
@@ -127,6 +271,7 @@ namespace composition{
* @brief Constructs a Composition with the given symbols and mass fractions.
* @param symbols The symbols to initialize the composition with.
* @param mass_fractions The mass fractions corresponding to the symbols.
* @param massFracMode True if mass fraction mode, false if number fraction mode.
* @example
* @code
* std::vector<std::string> symbols = {"H", "O"};
@@ -134,18 +279,32 @@ namespace composition{
* Composition comp(symbols, mass_fractions);
* @endcode
*/
Composition(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions);
Composition(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions, bool massFracMode=true);
/**
* @brief Registers a new symbol.
* @param symbol The symbol to register.
* @param massFracMode True if mass fraction mode, false if number fraction mode.
* @example
* @code
* Composition comp;
* comp.registerSymbol("H");
* @endcode
*/
void registerSymbol(const std::string& symbol);
void registerSymbol(const std::string& symbol, bool massFracMode=true);
/**
* @brief Registers multiple new symbols.
* @param symbols The symbols to register.
* @param massFracMode True if mass fraction mode, false if number fraction mode.
* @example
* @code
* std::vector<std::string> symbols = {"H", "O"};
* Composition comp;
* comp.registerSymbol(symbols);
* @endcode
*/
void registerSymbol(const std::vector<std::string>& symbols, bool massFracMode=true);
/**
* @brief Gets the registered symbols.
@@ -154,21 +313,21 @@ namespace composition{
std::set<std::string> getRegisteredSymbols() const;
/**
* @brief Sets the composition for a given symbol.
* @param symbol The symbol to set the composition for.
* @brief Sets the mass fraction for a given symbol.
* @param symbol The symbol to set the mass fraction for.
* @param mass_fraction The mass fraction to set.
* @return The mass fraction that was set.
* @example
* @code
* Composition comp;
* comp.setComposition("H", 0.1);
* comp.setMassFraction("H", 0.1);
* @endcode
*/
double setComposition(const std::string& symbol, const double& mass_fraction);
double setMassFraction(const std::string& symbol, const double& mass_fraction);
/**
* @brief Sets the composition for multiple symbols.
* @param symbols The symbols to set the composition for.
* @brief Sets the mass fraction for multiple symbols.
* @param symbols The symbols to set the mass fraction for.
* @param mass_fractions The mass fractions corresponding to the symbols.
* @return A vector of mass fractions that were set.
* @example
@@ -176,23 +335,73 @@ namespace composition{
* std::vector<std::string> symbols = {"H", "O"};
* std::vector<double> mass_fractions = {0.1, 0.9};
* Composition comp;
* comp.setComposition(symbols, mass_fractions);
* comp.setMassFraction(symbols, mass_fractions);
* @endcode
*/
std::vector<double> setComposition(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions);
std::vector<double> setMassFraction(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions);
/**
* @brief Gets the compositions.
* @return An unordered map of compositions.
* @brief Sets the number fraction for a given symbol.
* @param symbol The symbol to set the number fraction for.
* @param number_fraction The number fraction to set.
* @return The number fraction that was set.
*/
std::unordered_map<std::string, CompositionEntry> getCompositions() const;
double setNumberFraction(const std::string& symbol, const double& number_fraction);
/**
* @brief Gets the composition for a given symbol.
* @brief Sets the number fraction for multiple symbols.
* @param symbols The symbols to set the number fraction for.
* @param number_fractions The number fractions corresponding to the symbols.
* @return A vector of number fractions that were set.
*/
std::vector<double> setNumberFraction(const std::vector<std::string>& symbols, const std::vector<double>& number_fractions);
/**
* @brief Gets the mass fractions of all compositions.
* @return An unordered map of compositions with their mass fractions.
*/
std::unordered_map<std::string, double> getMassFraction() const;
/**
* @brief Gets the mass fraction for a given symbol.
* @param symbol The symbol to get the mass fraction for.
* @return The mass fraction for the given symbol.
*/
double getMassFraction(const std::string& symbol) const;
/**
* @brief Gets the number fraction for a given symbol.
* @param symbol The symbol to get the number fraction for.
* @return The number fraction for the given symbol.
*/
double getNumberFraction(const std::string& symbol) const;
/**
* @brief Gets the number fractions of all compositions.
* @return An unordered map of compositions with their number fractions.
*/
std::unordered_map<std::string, double> getNumberFraction() const;
/**
* @brief Gets the composition entry and global composition for a given symbol.
* @param symbol The symbol to get the composition for.
* @return The CompositionEntry for the given symbol.
* @return A pair containing the CompositionEntry and GlobalComposition for the given symbol.
*/
CompositionEntry getComposition(const std::string& symbol) const;
std::pair<CompositionEntry, GlobalComposition> getComposition(const std::string& symbol) const;
/**
* @brief Gets all composition entries and the global composition.
* @return A pair containing an unordered map of CompositionEntries and the GlobalComposition.
*/
std::pair<std::unordered_map<std::string, CompositionEntry>, GlobalComposition> getComposition() const;
/**
* @brief Gets a subset of the composition.
* @param symbols The symbols to include in the subset.
* @param method The method to use for the subset (default is "norm").
* @return A Composition object containing the subset.
*/
Composition subset(const std::vector<std::string>& symbols, std::string method="norm") const;
/**
* @brief Overloaded output stream operator for Composition.