fourdst::libcomposition v2.3.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#include <expected>
30
31#include "fourdst/config/config.h"
32#include "fourdst/logging/logging.h"
35
36namespace fourdst::composition {
47 double X = 0.0;
48 double Y = 0.0;
49 double Z = 0.0;
50
57 friend std::ostream& operator<<(std::ostream& os, const CanonicalComposition& composition) {
58 os << "<CanonicalComposition: "
59 << "X = " << composition.X << ", "
60 << "Y = " << composition.Y << ", "
61 << "Z = " << composition.Z << ">";
62 return os;
63 }
64 };
65
98 // ReSharper disable once CppClassCanBeFinal
99 class Composition final : public CompositionAbstract {
100 public:
103 private:
112 std::optional<CanonicalComposition> canonicalComp;
113 std::optional<std::vector<double>> massFractions;
114 std::optional<std::vector<double>> numberFractions;
115 std::optional<std::vector<double>> molarAbundances;
116 std::optional<std::vector<atomic::Species>> sortedSpecies;
117 std::optional<std::vector<std::string>> sortedSymbols;
118 std::optional<double> Ye;
119 std::optional<std::size_t> hash;
120
124 void clear() {
125 canonicalComp = std::nullopt;
126 massFractions = std::nullopt;
127 numberFractions = std::nullopt;
128 molarAbundances = std::nullopt;
129 sortedSymbols = std::nullopt;
130 sortedSpecies = std::nullopt;
131 Ye = std::nullopt;
132 hash = std::nullopt;
133 }
134
139 [[nodiscard]] bool is_clear() const {
140 return !canonicalComp.has_value() && !massFractions.has_value() &&
141 !numberFractions.has_value() && !molarAbundances.has_value() && !sortedSymbols.has_value() &&
142 !Ye.has_value() && !sortedSpecies.has_value() && !hash.has_value();
143 }
144 };
145
150 private:
156 static quill::Logger* getLogger() {
157 static quill::Logger* logger = logging::LogManager::getInstance().getLogger("log");
158 return logger;
159 }
160
161 // std::set<atomic::Species> m_registeredSpecies; ///< Set of registered species in the composition.
162 // std::map<atomic::Species, double> m_molarAbundances; ///< Map of species to their molar abundances.
163
164 std::vector<atomic::Species> m_species;
165 std::vector<double> m_molarAbundances;
166
168
169 private:
170 [[nodiscard]] std::expected<std::ptrdiff_t, SpeciesIndexLookupError> findSpeciesIndex(const atomic::Species &species) const noexcept;
171 [[nodiscard]] static std::vector<atomic::Species> symbolVectorToSpeciesVector(const std::vector<std::string>& symbols);
172
173 public:
179 Composition() = default;
180
184 ~Composition() override = default;
185
196 explicit Composition(const std::vector<std::string>& symbols);
197
211 explicit Composition(const std::vector<atomic::Species>& species);
212
223 explicit Composition(const std::set<std::string>& symbols);
224
238 explicit Composition(const std::set<atomic::Species>& species);
239
240 explicit Composition(const std::unordered_set<std::string>& symbols);
241 explicit Composition(const std::unordered_set<atomic::Species>& species);
242
258 Composition(const std::vector<std::string>& symbols, const std::vector<double>& molarAbundances);
259
274 Composition(const std::vector<atomic::Species>& species, const std::vector<double>& molarAbundances);
275
291 Composition(const std::set<std::string>& symbols, const std::vector<double>& molarAbundances);
292
293 explicit Composition(const std::unordered_map<std::string, double>& symbolMolarAbundances);
294 explicit Composition(const std::map<std::string, double>& symbolMolarAbundances);
295
296 explicit Composition(const std::unordered_map<atomic::Species, double>& speciesMolarAbundances);
297 explicit Composition(const std::map<atomic::Species, double>& speciesMolarAbundances);
298
299
305
307
313 Composition& operator=(Composition const& other);
315
330 void registerSymbol(const std::string& symbol);
331
346 void registerSymbol(const std::vector<std::string>& symbols);
347
370 void registerSpecies(const atomic::Species& species) noexcept;
371
372
392 void registerSpecies(const std::vector<atomic::Species>& species) noexcept;
393
399 [[nodiscard]] bool contains(const atomic::Species& species) const noexcept override;
400
407 [[nodiscard]] bool contains(const std::string& symbol) const override;
408
413 [[nodiscard]] size_t size() const noexcept override;
414
432 const std::string& symbol,
433 const double& molar_abundance
434 );
435
456 const atomic::Species& species,
457 const double& molar_abundance
458 );
459
476 const std::vector<std::string>& symbols,
477 const std::vector<double>& molar_abundances
478 );
479
499 const std::vector<atomic::Species>& species,
500 const std::vector<double>& molar_abundances
501 );
502
520 const std::set<std::string>& symbols,
521 const std::vector<double>& molar_abundances
522 );
523
544 const std::set<atomic::Species>& species,
545 const std::vector<double>& molar_abundances
546 );
547
556 [[nodiscard]] std::set<std::string> getRegisteredSymbols() const noexcept override;
557
566 [[nodiscard]] const std::vector<atomic::Species> &getRegisteredSpecies() const noexcept override;
567
574 [[nodiscard]] std::unordered_map<atomic::Species, double> getMassFraction() const noexcept override;
575
584 [[nodiscard]] double getMassFraction(const std::string& symbol) const override;
585
603 [[nodiscard]] double getMassFraction(const atomic::Species& species) const override;
604
613 [[nodiscard]] double getNumberFraction(const std::string& symbol) const override;
614
631 [[nodiscard]] double getNumberFraction(const atomic::Species& species) const override;
632
639 [[nodiscard]] std::unordered_map<atomic::Species, double> getNumberFraction() const noexcept override;
640
651 [[nodiscard]] double getMolarAbundance(const std::string& symbol) const override;
652
662 [[nodiscard]] double getMolarAbundance(const atomic::Species& species) const override;
663
677 [[nodiscard]] double getMeanParticleMass() const noexcept override;
678
692 [[nodiscard]] double getElectronAbundance() const noexcept override;
693
694
709 [[nodiscard]] CanonicalComposition getCanonicalComposition() const;
710
716 [[nodiscard]] std::vector<double> getMassFractionVector() const noexcept override;
717
723 [[nodiscard]] std::vector<double> getNumberFractionVector() const noexcept override;
724
730 [[nodiscard]] std::vector<double> getMolarAbundanceVector() const noexcept override;
731
740 [[nodiscard]] size_t getSpeciesIndex(const std::string& symbol) const override;
741
749 [[nodiscard]] size_t getSpeciesIndex(const atomic::Species& species) const override;
750
758 [[nodiscard]] atomic::Species getSpeciesAtIndex(size_t index) const override;
759
760 [[nodiscard]] std::unique_ptr<CompositionAbstract> clone() const override;
761
768 friend std::ostream& operator<<(std::ostream& os, const Composition& composition);
769
787 [[nodiscard]] iterator begin() override {
788 return {m_species.begin(), m_molarAbundances.begin()};
789 }
790
808 [[nodiscard]] const_iterator begin() const override {
809 return {m_species.cbegin(), m_molarAbundances.cbegin()};
810 }
811
829 [[nodiscard]] detail::CompositionIterator<false> end() override {
830 return {m_species.end(), m_molarAbundances.end()};
831 }
832
850 [[nodiscard]] detail::CompositionIterator<true> end() const override {
851 return {m_species.cend(), m_molarAbundances.cend()};
852 }
853
854 [[nodiscard]] std::size_t hash() const override;
855
856 };
857
858 inline bool operator==(const Composition& a, const Composition& b) noexcept {
859 if (a.size() != b.size()) return false;
860
861 if (a.getRegisteredSpecies() != b.getRegisteredSpecies())
862 return false;
863
864 return a.hash() == b.hash();
865 }
866}; // namespace fourdst::composition
Abstract base class for chemical composition representations.
Manages a collection of chemical species and their abundances.
Definition composition.h:99
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
bool contains(const atomic::Species &species) const noexcept override
Checks if a given species is present 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.
double getNumberFraction(const std::string &symbol) const override
Gets the number fraction for a given symbol. See the overload for species-based lookup for more detai...
detail::CompositionIterator< true > const_iterator
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.
static std::vector< atomic::Species > symbolVectorToSpeciesVector(const std::vector< std::string > &symbols)
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::size_t hash() const override
iterator begin() override
Returns an iterator to the beginning of the molar abundance map.
detail::CompositionIterator< false > iterator
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::vector< atomic::Species > m_species
detail::CompositionIterator< false > end() override
Returns an iterator to the end of the molar abundance map.
detail::CompositionIterator< true > end() const override
Returns a const iterator to the end of the molar abundance map.
CanonicalComposition getCanonicalComposition() const
Compute the canonical composition (X, Y, Z) of the composition.
std::vector< double > m_molarAbundances
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::expected< std::ptrdiff_t, SpeciesIndexLookupError > findSpeciesIndex(const atomic::Species &species) const noexcept
const_iterator begin() const override
Returns a const iterator to the beginning of the molar abundance map.
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.
const std::vector< atomic::Species > & getRegisteredSpecies() const noexcept override
Get a set of all species that are registered in the composition.
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.
Contains canonical information about atomic species and elements used by 4D-STAR.
Utilities and types for representing and manipulating chemical compositions.
bool operator==(const Composition &a, const Composition &b) noexcept
Represents an atomic species (isotope) with its fundamental physical properties.
Represents the canonical (X, Y, Z) composition of stellar material.
Definition composition.h:46
friend std::ostream & operator<<(std::ostream &os, const CanonicalComposition &composition)
Overloads the stream insertion operator for easy printing.
Definition composition.h:57
double Y
Mass fraction of Helium.
Definition composition.h:48
double X
Mass fraction of Hydrogen.
Definition composition.h:47
double Z
Mass fraction of Metals.
Definition composition.h:49
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).