2025-03-24 12:58:30 -04:00
# ifndef COMPOSITION_H
# define COMPOSITION_H
# include <iostream>
# include <string>
# include <unordered_map>
# include <set>
2025-03-25 12:49:37 -04:00
# include <utility>
2025-03-24 12:58:30 -04:00
# include "probe.h"
# include "config.h"
# include "atomicSpecies.h"
namespace composition {
2025-03-25 12:49:37 -04:00
/**
* @ 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 < < " \t Specific Number Density: " < < comp . specificNumberDensity < < " \n " ;
os < < " \t Mean Particle Mass: " < < comp . meanParticleMass < < " \n " ;
return os ;
}
} ;
2025-03-24 12:58:30 -04:00
/**
* @ brief Represents an entry in the composition with a symbol and mass fraction .
*/
struct CompositionEntry {
2025-03-25 12:49:37 -04:00
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 ) ;
2025-03-24 12:58:30 -04:00
/**
* @ 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 ) {
2025-03-25 12:49:37 -04:00
os < < " < " < < entry . m_symbol < < " : m_frac = " < < entry . mass_fraction ( ) < < " > " ;
2025-03-24 12:58:30 -04:00
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 4 DSSE . There are a few rules when using this class .
* - Only species in the atomicSpecies . h database can be used . There are 1000 s ( 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
2025-03-24 13:20:24 -04:00
* std : : vector < std : : string > symbols = { " H " , " He " } ;
* std : : vector < double > mass_fractions = { 0.7 , 0.3 } ;
2025-03-24 12:58:30 -04:00
* Composition comp ( symbols , mass_fractions ) ;
* @ endcode
* @ example Constructing a composition with symbols and finalizing it later :
* @ code
2025-03-24 13:20:24 -04:00
* std : : vector < std : : string > symbols = { " H " , " He " } ;
2025-03-24 12:58:30 -04:00
* Composition comp ( symbols ) ;
2025-03-24 13:20:24 -04:00
* comp . setComposition ( " H " , 0.7 ) ;
* comp . setComposition ( " He " , 0.3 ) ;
2025-03-24 12:58:30 -04:00
* comp . finalize ( ) ;
* @ endcode
*/
class Composition {
private :
Probe : : LogManager & m_logManager = Probe : : LogManager : : getInstance ( ) ;
quill : : Logger * m_logger = m_logManager . getLogger ( " log " ) ;
2025-03-25 12:49:37 -04:00
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.
2025-03-24 12:58:30 -04:00
2025-03-25 12:49:37 -04:00
std : : set < std : : string > m_registeredSymbols ; ///< The registered symbols.
std : : unordered_map < std : : string , CompositionEntry > m_compositions ; ///< The compositions.
2025-03-24 12:58:30 -04:00
/**
* @ 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 .
*/
2025-03-25 12:49:37 -04:00
bool isValidComposition ( const std : : vector < double > & fractions ) const ;
2025-03-24 12:58:30 -04:00
/**
* @ brief Validates the given mass fractions .
* @ param mass_fractions The mass fractions to validate .
* @ throws std : : invalid_argument if the mass fractions are invalid .
*/
2025-03-25 12:49:37 -04:00
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 ) ;
2025-03-24 12:58:30 -04:00
public :
/**
* @ brief Default constructor .
*/
Composition ( ) = default ;
/**
* @ brief Default destructor .
*/
~ Composition ( ) = default ;
/**
* @ brief Finalizes the composition .
2025-03-25 12:49:37 -04:00
* @ param norm If true , the composition will be normalized to sum to 1 [ Default False ]
2025-03-24 12:58:30 -04:00
* @ return True if the composition is successfully finalized , false otherwise .
*/
2025-03-25 12:49:37 -04:00
bool finalize ( bool norm = false ) ;
2025-03-24 12:58:30 -04:00
/**
* @ 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 ) ;
2025-03-26 08:07:11 -04:00
/**
* @ brief Constructs a Composition with the given symbols as a set .
* @ param symbols The symbols to initialize the composition with .
* @ example
* @ code
* std : : set < std : : string > symbols = { " H " , " O " } ;
* Composition comp ( symbols ) ;
* @ endcode
*/
Composition ( const std : : set < std : : string > & symbols ) ;
2025-03-24 12:58:30 -04:00
/**
* @ 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 .
2025-03-25 12:49:37 -04:00
* @ param massFracMode True if mass fraction mode , false if number fraction mode .
2025-03-24 12:58:30 -04:00
* @ example
* @ code
* std : : vector < std : : string > symbols = { " H " , " O " } ;
* std : : vector < double > mass_fractions = { 0.1 , 0.9 } ;
* Composition comp ( symbols , mass_fractions ) ;
* @ endcode
*/
2025-03-25 12:49:37 -04:00
Composition ( const std : : vector < std : : string > & symbols , const std : : vector < double > & mass_fractions , bool massFracMode = true ) ;
2025-03-24 12:58:30 -04:00
/**
* @ brief Registers a new symbol .
* @ param symbol The symbol to register .
2025-03-25 12:49:37 -04:00
* @ param massFracMode True if mass fraction mode , false if number fraction mode .
2025-03-24 12:58:30 -04:00
* @ example
* @ code
* Composition comp ;
* comp . registerSymbol ( " H " ) ;
* @ endcode
*/
2025-03-25 12:49:37 -04:00
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 ) ;
2025-03-24 12:58:30 -04:00
/**
* @ brief Gets the registered symbols .
* @ return A set of registered symbols .
*/
std : : set < std : : string > getRegisteredSymbols ( ) const ;
/**
2025-03-25 12:49:37 -04:00
* @ brief Sets the mass fraction for a given symbol .
* @ param symbol The symbol to set the mass fraction for .
2025-03-24 12:58:30 -04:00
* @ param mass_fraction The mass fraction to set .
* @ return The mass fraction that was set .
* @ example
* @ code
* Composition comp ;
2025-03-25 12:49:37 -04:00
* comp . setMassFraction ( " H " , 0.1 ) ;
2025-03-24 12:58:30 -04:00
* @ endcode
*/
2025-03-25 12:49:37 -04:00
double setMassFraction ( const std : : string & symbol , const double & mass_fraction ) ;
2025-03-24 12:58:30 -04:00
/**
2025-03-25 12:49:37 -04:00
* @ brief Sets the mass fraction for multiple symbols .
* @ param symbols The symbols to set the mass fraction for .
2025-03-24 12:58:30 -04:00
* @ 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 ;
2025-03-25 12:49:37 -04:00
* comp . setMassFraction ( symbols , mass_fractions ) ;
2025-03-24 12:58:30 -04:00
* @ endcode
*/
2025-03-25 12:49:37 -04:00
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 ) ;
2025-03-26 08:07:11 -04:00
/**
* @ brief Mix two compositions together with a given fraction .
* @ param other The other composition to mix with .
* @ param fraction The fraction of the other composition to mix with . This is the fraction of the other composition wrt . to the current . i . e . fraction = 1 would mean that 50 % of the new composition is from the other and 50 % from the current ) .
*/
Composition mix ( const Composition & other , double fraction ) const ;
2025-03-25 12:49:37 -04:00
/**
* @ 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 ;
2025-03-24 12:58:30 -04:00
/**
2025-03-25 12:49:37 -04:00
* @ 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 .
2025-03-24 12:58:30 -04:00
*/
2025-03-25 12:49:37 -04:00
double getMassFraction ( const std : : string & symbol ) const ;
2025-03-24 12:58:30 -04:00
/**
2025-03-25 12:49:37 -04:00
* @ 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 .
2025-03-24 12:58:30 -04:00
* @ param symbol The symbol to get the composition for .
2025-03-25 12:49:37 -04:00
* @ 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 .
2025-03-24 12:58:30 -04:00
*/
2025-03-25 12:49:37 -04:00
Composition subset ( const std : : vector < std : : string > & symbols , std : : string method = " norm " ) const ;
2025-03-24 12:58:30 -04:00
2025-03-26 08:07:11 -04:00
/**
* @ brief Check if a symbol is registered .
* @ param symbol The symbol to check .
* @ return True if the symbol is registered , false otherwise .
*/
bool hasSymbol ( const std : : string & symbol ) const ;
2025-03-25 13:01:22 -04:00
/**
* @ brief Sets the composition mode .
* @ param massFracMode True if mass fraction mode , false if number fraction mode .
*/
void setCompositionMode ( bool massFracMode ) ;
2025-03-24 12:58:30 -04:00
/**
* @ brief Overloaded output stream operator for Composition .
* @ param os The output stream .
* @ param composition The Composition to output .
* @ return The output stream .
*/
2025-03-26 08:07:11 -04:00
friend std : : ostream & operator < < ( std : : ostream & os , const Composition & composition ) ;
// Overload the + operator to call mix with a fraction of 0.5
/**
* @ brief Overloads the + operator to mix two compositions together with a fraction of 0.5 .
* @ param other The other composition to mix with .
* @ return The mixed composition .
*/
Composition operator + ( const Composition & other ) const ;
2025-03-24 12:58:30 -04:00
} ;
} ;
# endif // COMPOSITION_H