fourdst::libcomposition v2.2.1
Robust atomic species information library
Loading...
Searching...
No Matches
composition.h
Go to the documentation of this file.
1/* ***********************************************************************
2//
3// Copyright (C) 2025 -- The 4D-STAR Collaboration
4// File Author: Emily Boudreaux
5// Last Modified: March 26, 2025
6//
7// 4DSSE is free software; you can use it and/or modify
8// it under the terms and restrictions the GNU General Library Public
9// License version 3 (GPLv3) as published by the Free Software Foundation.
10//
11// 4DSSE is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14// See the GNU Library General Public License for more details.
15//
16// You should have received a copy of the GNU Library General Public License
17// along with this software; if not, write to the Free Software
18// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19//
20// *********************************************************************** */
21#pragma once
22
23#include <string>
24#include <unordered_map>
25#include <set>
26
27#include <optional>
28#include <unordered_set>
29
30#include "fourdst/config/config.h"
31#include "fourdst/logging/logging.h"
34
35namespace fourdst::composition {
46 double X = 0.0;
47 double Y = 0.0;
48 double Z = 0.0;
49
56 friend std::ostream& operator<<(std::ostream& os, const CanonicalComposition& composition) {
57 os << "<CanonicalComposition: "
58 << "X = " << composition.X << ", "
59 << "Y = " << composition.Y << ", "
60 << "Z = " << composition.Z << ">";
61 return os;
62 }
63 };
64
97 // ReSharper disable once CppClassCanBeFinal
98 class Composition final : public CompositionAbstract {
99 private:
108 std::optional<CanonicalComposition> canonicalComp;
109 std::optional<std::vector<double>> massFractions;
110 std::optional<std::vector<double>> numberFractions;
111 std::optional<std::vector<double>> molarAbundances;
112 std::optional<std::vector<atomic::Species>> sortedSpecies;
113 std::optional<std::vector<std::string>> sortedSymbols;
114 std::optional<double> Ye;
115
119 void clear() {
120 canonicalComp = std::nullopt;
121 massFractions = std::nullopt;
122 numberFractions = std::nullopt;
123 molarAbundances = std::nullopt;
124 sortedSymbols = std::nullopt;
125 sortedSpecies = std::nullopt;
126 Ye = std::nullopt;
127 }
128
133 [[nodiscard]] bool is_clear() const {
134 return !canonicalComp.has_value() && !massFractions.has_value() &&
135 !numberFractions.has_value() && !molarAbundances.has_value() && !sortedSymbols.has_value() &&
136 !Ye.has_value() && !sortedSpecies.has_value();
137 }
138 };
139 private:
145 static quill::Logger* getLogger() {
146 static quill::Logger* logger = logging::LogManager::getInstance().getLogger("log");
147 return logger;
148 }
149
150 std::set<atomic::Species> m_registeredSpecies;
151 std::map<atomic::Species, double> m_molarAbundances;
152
154
155 public:
161 Composition() = default;
162
166 ~Composition() override = default;
167
178 explicit Composition(const std::vector<std::string>& symbols);
179
193 explicit Composition(const std::vector<atomic::Species>& species);
194
205 explicit Composition(const std::set<std::string>& symbols);
206
220 explicit Composition(const std::set<atomic::Species>& species);
221
222 explicit Composition(const std::unordered_set<std::string>& symbols);
223 explicit Composition(const std::unordered_set<atomic::Species>& species);
224
240 Composition(const std::vector<std::string>& symbols, const std::vector<double>& molarAbundances);
241
256 Composition(const std::vector<atomic::Species>& species, const std::vector<double>& molarAbundances);
257
273 Composition(const std::set<std::string>& symbols, const std::vector<double>& molarAbundances);
274
275 explicit Composition(const std::unordered_map<std::string, double>& symbolMolarAbundances);
276 explicit Composition(const std::map<std::string, double>& symbolMolarAbundances);
277
278 explicit Composition(const std::unordered_map<atomic::Species, double>& speciesMolarAbundances);
279 explicit Composition(const std::map<atomic::Species, double>& speciesMolarAbundances);
280
281
286 Composition(const Composition& composition);
287
288 explicit Composition(const CompositionAbstract& composition);
289
295 Composition& operator=(Composition const& other);
296
311 void registerSymbol(const std::string& symbol);
312
327 void registerSymbol(const std::vector<std::string>& symbols);
328
351 void registerSpecies(const atomic::Species& species) noexcept;
352
353
373 void registerSpecies(const std::vector<atomic::Species>& species) noexcept;
374
380 [[nodiscard]] bool contains(const atomic::Species& species) const noexcept override;
381
388 [[nodiscard]] bool contains(const std::string& symbol) const override;
389
394 [[nodiscard]] size_t size() const noexcept override;
395
413 const std::string& symbol,
414 const double& molar_abundance
415 );
416
437 const atomic::Species& species,
438 const double& molar_abundance
439 );
440
457 const std::vector<std::string>& symbols,
458 const std::vector<double>& molar_abundances
459 );
460
480 const std::vector<atomic::Species>& species,
481 const std::vector<double>& molar_abundances
482 );
483
501 const std::set<std::string>& symbols,
502 const std::vector<double>& molar_abundances
503 );
504
525 const std::set<atomic::Species>& species,
526 const std::vector<double>& molar_abundances
527 );
528
537 [[nodiscard]] std::set<std::string> getRegisteredSymbols() const noexcept override;
538
547 [[nodiscard]] const std::set<atomic::Species> &getRegisteredSpecies() const noexcept override;
548
555 [[nodiscard]] std::unordered_map<atomic::Species, double> getMassFraction() const noexcept override;
556
565 [[nodiscard]] double getMassFraction(const std::string& symbol) const override;
566
584 [[nodiscard]] double getMassFraction(const atomic::Species& species) const override;
585
594 [[nodiscard]] double getNumberFraction(const std::string& symbol) const override;
595
612 [[nodiscard]] double getNumberFraction(const atomic::Species& species) const override;
613
620 [[nodiscard]] std::unordered_map<atomic::Species, double> getNumberFraction() const noexcept override;
621
632 [[nodiscard]] double getMolarAbundance(const std::string& symbol) const override;
633
643 [[nodiscard]] double getMolarAbundance(const atomic::Species& species) const override;
644
658 [[nodiscard]] double getMeanParticleMass() const noexcept override;
659
673 [[nodiscard]] double getElectronAbundance() const noexcept override;
674
675
690 [[nodiscard]] CanonicalComposition getCanonicalComposition() const;
691
697 [[nodiscard]] std::vector<double> getMassFractionVector() const noexcept override;
698
704 [[nodiscard]] std::vector<double> getNumberFractionVector() const noexcept override;
705
711 [[nodiscard]] std::vector<double> getMolarAbundanceVector() const noexcept override;
712
721 [[nodiscard]] size_t getSpeciesIndex(const std::string& symbol) const override;
722
730 [[nodiscard]] size_t getSpeciesIndex(const atomic::Species& species) const override;
731
739 [[nodiscard]] atomic::Species getSpeciesAtIndex(size_t index) const override;
740
741 [[nodiscard]] std::unique_ptr<CompositionAbstract> clone() const override;
742
749 friend std::ostream& operator<<(std::ostream& os, const Composition& composition);
750
768 [[nodiscard]] std::map<atomic::Species, double>::iterator begin() override {
769 return m_molarAbundances.begin();
770 }
771
789 [[nodiscard]] std::map<atomic::Species, double>::const_iterator begin() const override {
790 return m_molarAbundances.cbegin();
791 }
792
810 [[nodiscard]] std::map<atomic::Species, double>::iterator end() override {
811 return m_molarAbundances.end();
812 }
813
831 [[nodiscard]] std::map<atomic::Species, double>::const_iterator end() const override {
832 return m_molarAbundances.cend();
833 }
834
835 };
836
837 inline bool operator==(const Composition& a, const Composition& b) noexcept {
838 if (a.size() != b.size()) return false;
839
840 // Compare species sets quickly
841 if (a.getRegisteredSpecies() != b.getRegisteredSpecies())
842 return false;
843
844 // Compare all abundances
845 for (auto itA = a.begin(), itB = b.begin();
846 itA != a.end() && itB != b.end(); ++itA, ++itB) {
847 if (itA->first != itB->first)
848 return false;
849 if (itA->second != itB->second)
850 return false;
851 }
852 return true;
853 }
854}; // namespace fourdst::composition
Abstract base class for chemical composition representations.
Manages a collection of chemical species and their abundances.
Definition composition.h:98
CompositionCache m_cache
Cache for computed properties to avoid redundant calculations.
~Composition() override=default
Default destructor.
size_t getSpeciesIndex(const std::string &symbol) const override
get the index in the sorted vector representation for a given symbol
std::map< atomic::Species, double >::const_iterator end() const override
Returns a const iterator to the end of the molar abundance map.
bool contains(const atomic::Species &species) const noexcept override
Checks if a given species is present in the composition.
std::unordered_map< atomic::Species, double > getNumberFraction() const noexcept override
Gets the number fractions of all species in the composition.
Composition()=default
Default constructor.
void setMolarAbundance(const std::string &symbol, const double &molar_abundance)
Sets the molar abundance for a given symbol.
const std::set< atomic::Species > & getRegisteredSpecies() const noexcept override
Get a set of all species that are registered in the composition.
void registerSpecies(const atomic::Species &species) noexcept
Registers a new species by extracting its symbol.
void registerSymbol(const std::string &symbol)
Registers a new symbol for inclusion in the composition.
std::set< std::string > getRegisteredSymbols() const noexcept override
Gets the registered symbols.
std::set< atomic::Species > m_registeredSpecies
Set of registered species in the composition.
static quill::Logger * getLogger()
Gets the logger instance for the Composition class. This is static to ensure that all composition obj...
Composition & operator=(Composition const &other)
Assignment operator.
std::unique_ptr< CompositionAbstract > clone() const override
std::map< atomic::Species, double >::const_iterator begin() const override
Returns a const iterator to the beginning of the molar abundance map.
std::map< atomic::Species, double >::iterator begin() override
Returns an iterator to the beginning of the molar abundance map.
std::map< atomic::Species, double >::iterator end() override
Returns an iterator to the end of the molar abundance map.
double getElectronAbundance() const noexcept override
Compute the electron abundance of the composition.
size_t size() const noexcept override
Gets the number of registered species in the composition.
std::unordered_map< atomic::Species, double > getMassFraction() const noexcept override
Gets the mass fractions of all species in the composition.
std::map< atomic::Species, double > m_molarAbundances
Map of species to their molar abundances.
CanonicalComposition getCanonicalComposition() const
Compute the canonical composition (X, Y, Z) of the composition.
std::vector< double > getMolarAbundanceVector() const noexcept override
Get a uniform vector representation of the molar abundances stored in the composition object sorted s...
double getMolarAbundance(const std::string &symbol) const override
Gets the molar abundances of all species in the composition.
std::vector< double > getNumberFractionVector() const noexcept override
Get a uniform vector representation of the number fractions stored in the composition object sorted s...
atomic::Species getSpeciesAtIndex(size_t index) const override
Get the species at a given index in the sorted vector representation.
std::vector< double > getMassFractionVector() const noexcept override
Get a uniform vector representation of the mass fraction stored in the composition object sorted such...
double getMeanParticleMass() const noexcept override
Compute the mean particle mass of the composition.
Utilities and types for representing and manipulating chemical compositions.
bool operator==(const Composition &a, const Composition &b) noexcept
STL namespace.
Represents an atomic species (isotope) with its fundamental physical properties.
Represents the canonical (X, Y, Z) composition of stellar material.
Definition composition.h:45
friend std::ostream & operator<<(std::ostream &os, const CanonicalComposition &composition)
Overloads the stream insertion operator for easy printing.
Definition composition.h:56
double Y
Mass fraction of Helium.
Definition composition.h:47
double X
Mass fraction of Hydrogen.
Definition composition.h:46
double Z
Mass fraction of Metals.
Definition composition.h:48
Caches computed properties of the composition to avoid redundant calculations.
std::optional< std::vector< atomic::Species > > sortedSpecies
Cached vector of sorted species (by mass).
std::optional< std::vector< double > > numberFractions
Cached vector of number fractions.
std::optional< CanonicalComposition > canonicalComp
Cached canonical composition data.
std::optional< std::vector< double > > molarAbundances
Cached vector of molar abundances.
std::optional< std::vector< std::string > > sortedSymbols
Cached vector of sorted species (by mass).
std::optional< std::vector< double > > massFractions
Cached vector of mass fractions.
std::optional< double > Ye
Cached electron abundance.
bool is_clear() const
Checks if the cache is clear (i.e., all cached values are empty).