429 lines
18 KiB
C++
429 lines
18 KiB
C++
#ifndef COMPOSITION_H
|
|
#define COMPOSITION_H
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <set>
|
|
|
|
#include <utility>
|
|
|
|
#include "probe.h"
|
|
#include "config.h"
|
|
|
|
#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 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.
|
|
* @param os The output stream.
|
|
* @param entry The CompositionEntry to output.
|
|
* @return The output stream.
|
|
*/
|
|
friend std::ostream& operator<<(std::ostream& os, const CompositionEntry& entry) {
|
|
os << "<" << entry.m_symbol << " : m_frac = " << entry.mass_fraction() << ">";
|
|
return os;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Manages the composition of elements.
|
|
* @details The composition is a collection of elements with their respective mass fractions.
|
|
* The general purpose of this class is to provide a standardized interface for managing the composition of
|
|
* any part of 4DSSE. There are a few rules when using this class.
|
|
* - Only species in the atomicSpecies.h database can be used. There are 1000s (All species from AME2020) in there so it should not be a problem.
|
|
* - Before a mass fraction can be set with a particular instance of Composition, the symbol must be registered. (i.e. register He-3 before setting its mass fraction)
|
|
* - Before any composition information can be retrived (e.g. getComposition), the composition must be finalized (call to .finalize()). This checks if the total mass fraction sums to approximatly 1 (within 1 part in 10^8)
|
|
* - Any changes made to the composition after finalization will "unfinalize" the composition. This means that the composition must be finalized again before any information can be retrived.
|
|
* - The mass fraction of any individual species must be no more than 1 and no less than 0.
|
|
* - The only exception to the finalize rule is if the compositon was constructed with symbols and mass fractions at instantiation time. In this case, the composition is automatically finalized.
|
|
* however, this means that the composition passed to the constructor must be valid.
|
|
*
|
|
* @example Constructing a finalized composition with symbols and mass fractions:
|
|
* @code
|
|
* std::vector<std::string> symbols = {"H", "He"};
|
|
* std::vector<double> mass_fractions = {0.7, 0.3};
|
|
* Composition comp(symbols, mass_fractions);
|
|
* @endcode
|
|
* @example Constructing a composition with symbols and finalizing it later:
|
|
* @code
|
|
* std::vector<std::string> symbols = {"H", "He"};
|
|
* Composition comp(symbols);
|
|
* comp.setComposition("H", 0.7);
|
|
* comp.setComposition("He", 0.3);
|
|
* comp.finalize();
|
|
* @endcode
|
|
*/
|
|
class Composition {
|
|
private:
|
|
Config& m_config = Config::getInstance();
|
|
Probe::LogManager& m_logManager = Probe::LogManager::getInstance();
|
|
quill::Logger* m_logger = m_logManager.getLogger("log");
|
|
|
|
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; ///< The registered symbols.
|
|
std::unordered_map<std::string, CompositionEntry> m_compositions; ///< The compositions.
|
|
|
|
/**
|
|
* @brief Checks if the given symbol is valid.
|
|
* @details A symbol is valid if it is in the atomic species database (species in atomicSpecies.h). These include all the isotopes from AME2020.
|
|
* @param symbol The symbol to check.
|
|
* @return True if the symbol is valid, false otherwise.
|
|
*/
|
|
bool isValidSymbol(const std::string& symbol) const;
|
|
|
|
/**
|
|
* @brief Checks if the given mass fractions are valid.
|
|
* @param mass_fractions The mass fractions to check.
|
|
* @return True if the mass fractions are valid, false otherwise.
|
|
*/
|
|
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>& 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:
|
|
/**
|
|
* @brief Default constructor.
|
|
*/
|
|
Composition() = default;
|
|
|
|
/**
|
|
* @brief Default destructor.
|
|
*/
|
|
~Composition() = default;
|
|
|
|
/**
|
|
* @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 norm=false);
|
|
|
|
/**
|
|
* @brief Constructs a Composition with the given symbols.
|
|
* @param symbols The symbols to initialize the composition with.
|
|
* @example
|
|
* @code
|
|
* std::vector<std::string> symbols = {"H", "O"};
|
|
* Composition comp(symbols);
|
|
* @endcode
|
|
*/
|
|
Composition(const std::vector<std::string>& symbols);
|
|
|
|
/**
|
|
* @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"};
|
|
* std::vector<double> mass_fractions = {0.1, 0.9};
|
|
* Composition comp(symbols, mass_fractions);
|
|
* @endcode
|
|
*/
|
|
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, 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.
|
|
* @return A set of registered symbols.
|
|
*/
|
|
std::set<std::string> getRegisteredSymbols() const;
|
|
|
|
/**
|
|
* @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.setMassFraction("H", 0.1);
|
|
* @endcode
|
|
*/
|
|
double setMassFraction(const std::string& symbol, const double& mass_fraction);
|
|
|
|
/**
|
|
* @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
|
|
* @code
|
|
* std::vector<std::string> symbols = {"H", "O"};
|
|
* std::vector<double> mass_fractions = {0.1, 0.9};
|
|
* Composition comp;
|
|
* comp.setMassFraction(symbols, mass_fractions);
|
|
* @endcode
|
|
*/
|
|
std::vector<double> setMassFraction(const std::vector<std::string>& symbols, const std::vector<double>& mass_fractions);
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
double setNumberFraction(const std::string& symbol, const double& number_fraction);
|
|
|
|
/**
|
|
* @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 A pair containing the CompositionEntry and GlobalComposition for the given symbol.
|
|
*/
|
|
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 Sets the composition mode.
|
|
* @param massFracMode True if mass fraction mode, false if number fraction mode.
|
|
*/
|
|
void setCompositionMode(bool massFracMode);
|
|
|
|
/**
|
|
* @brief Overloaded output stream operator for Composition.
|
|
* @param os The output stream.
|
|
* @param composition The Composition to output.
|
|
* @return The output stream.
|
|
*/
|
|
friend std::ostream& operator<<(std::ostream& os, const Composition& composition) {
|
|
os << "Composition: \n";
|
|
for (const auto& [symbol, entry] : composition.m_compositions) {
|
|
os << entry << "\n";
|
|
}
|
|
return os;
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
#endif // COMPOSITION_H
|