docs(docs): rebuilt docs

This commit is contained in:
2026-06-12 10:49:27 -04:00
parent 997c845b3d
commit 30da87c74c
387 changed files with 6889 additions and 8739 deletions

View File

@@ -63,55 +63,104 @@ namespace fourdst::composition::io {
};
/**
* @brief Fetch the raw byte array of the standard solar composition data
* @return Raw Byte array to be used with ChemicalFileParser
* @brief Returns a read-only span over the embedded standard solar composition data.
*
* The data are stored as a compile-time binary array generated from the
* embedded resource file at build time. The returned span references static
* storage directly — no copies are made.
*
* @return `std::span<const unsigned char>` Non-owning view over the raw tagged
* composition data bytes, suitable for passing to `ChemicalFileParser`.
*
* @par Examples
* @code{.cpp}
* auto raw = fourdst::composition::io::get_raw_standard_solar_composition_data();
* std::vector<char> buf(raw.begin(), raw.end());
* @endcode
*/
std::span<const unsigned char> get_raw_standard_solar_composition_data();
/**
* @class ChemicalFileParser
* @brief An abstract base class for chemical file parsers.
* @brief Parser for the tagged flat-text chemical composition data format.
*
* This class defines the interface for parsing fortran code files that contain
* nuclide fractions. Derived classes must implement the `parse`
* method to handle specific file formats.
* Reads data buffers that contain one or more named blocks delimited by
* `BEGIN <scheme>` / `END <scheme>` sentinels and extracts either bulk metal
* composition records or per-isotope percentage tables.
*/
class ChemicalFileParser {
private:
public:
/**
* @brief Parses a chemical file and returns the parsed data.
* @brief Parses a named composition block from a tagged flat-text data buffer.
*
* This is a pure virtual function that must be implemented by derived
* classes. It takes a filename as input and returns a `ParsedChemicalData`
* struct containing the information extracted from the file.
* Scans the buffer line by line for `BEGIN {scheme}`, then extracts five
* fixed-position fields (comment, He abundance, atomic-weight flag, element
* list, log10 abundance list) until `END {scheme}` is reached. He abundance
* and metal abundances are converted from log10 to linear scale via
* `pow(10, x)` before storage.
*
* @param filename The path to the Chemical file to parse.
* @return A `ParsedChemicalData` struct containing the parsed reaction data.
* @param[in] data Raw byte buffer (e.g., from
* `get_raw_standard_solar_composition_data()`).
* @param[in] scheme Block tag to extract (e.g., `"GS98"`, `"AGSS09"`).
*
* @throws std::runtime_error If the file cannot be opened or a parsing
* error occurs.
* @return `CompositionData` Populated struct; default-initialized if the
* scheme is not found.
*
* @b Usage
* @code
* std::unique_ptr<ChemicalFileParser> parser = std::make_unique<SimpleReactionListFileParser>();
* try {
* ParsedChemicalData data = parser->parse("my_reactions.txt");
* for (const auto& reaction_name : data.reactionPENames) {
* // ... process reaction name
const mfem::GridFunction& grav_potential_at_inf(FEM& fem, const Args& args, const mfem::GridFunction& rho, bool pho_warm) {
}
* }
* } catch (const std::runtime_error& e) {
* // ... handle error
* @throws std::invalid_argument If a numeric field cannot be parsed by
* `std::stod`.
* @throws std::out_of_range If a numeric field value is out of `double` range.
*
* @par Examples
* @code{.cpp}
* auto raw = fourdst::composition::io::get_raw_standard_solar_composition_data();
* std::vector<char> buf(raw.begin(), raw.end());
*
* fourdst::composition::io::ChemicalFileParser parser;
* auto comp = parser.parse_composition_data(buf, "GS98");
*
* for (size_t i = 0; i < comp.elements.size(); ++i) {
* std::println("{}: {:.6e}", comp.elements[i], comp.abundances[i]);
* }
* @endcode
*/
[[nodiscard]] static CompositionData parse_composition_data(const std::vector<char>& data,const std::string& scheme);
[[nodiscard]] static IsotopicPercentage parse_isotopic_percentage(const std::vector<char>& data,const std::string& scheme);
[[nodiscard]] static CompositionData parse_composition_data(const std::vector<char>& data, const std::string& scheme);
/**
* @brief Parses a named isotopic-percentage block from a tagged flat-text data buffer.
*
* Scans the buffer for `BEGIN {scheme}`, then extracts five fixed-position
* fields (comment, atomic numbers, element symbols, mass numbers, isotopic
* percentages) until `END {scheme}` is reached. Percentages are stored on
* the 0-100 scale.
*
* @param[in] data Raw byte buffer containing tagged isotopic percentage blocks.
* @param[in] scheme Block tag to extract (e.g., `"L03_data"`, `"L09_data"`).
*
* @return `IsotopicPercentage` Populated struct; default-initialized if the
* scheme is not found.
*
* @throws std::invalid_argument If an integer or double field cannot be
* parsed by `std::stoi` / `std::stod`.
* @throws std::out_of_range If any parsed value exceeds its target type range.
*
* @par Examples
* @code{.cpp}
* auto raw = fourdst::composition::io::get_raw_standard_solar_composition_data();
* std::vector<char> buf(raw.begin(), raw.end());
*
* fourdst::composition::io::ChemicalFileParser parser;
* auto iso = parser.parse_isotopic_percentage(buf, "L03_data");
*
* for (size_t i = 0; i < iso.elements.size(); ++i) {
* std::println("{}-{}: {:.4f}%",
* iso.elements[i], iso.mass_numbers[i], iso.percentages[i]);
* }
* @endcode
*/
[[nodiscard]] static IsotopicPercentage parse_isotopic_percentage(const std::vector<char>& data, const std::string& scheme);
};
@@ -119,29 +168,81 @@ namespace fourdst::composition::io {
namespace fourdst::composition {
/**
* @brief Function to retrieve a standard solar composition record indexed by their canonical names including
* - AG89
* - GN93
* - GS98
* - L03
* - AGS05
* - AGS08
* - A09_Pryzbilla
* - MB22_photospheric
* - AAG21_photospheric
* - L09
* Further, isotopic percentages can be selected as either
* - L03
* - L09
* @brief Constructs a stellar `Composition` from a named solar metal-fraction
* scheme and isotopic-percentage table, scaled to the supplied bulk
* hydrogen and helium mass fractions.
*
* These data have been extracted from chem_def.f90 from MESA <version>
* Available metal fraction schemes (extracted from MESA `chem_def.f90`):
* - `AG89` (Anders & Grevesse 1989)
* - `GN93` (Grevesse & Noels 1993)
* - `GS98` (Grevesse & Sauval 1998)
* - `L03` (Lodders 2003)
* - `AGS05` (Asplund, Grevesse & Sauval 2005)
* - `AGSS09` (Asplund et al. 2009)
* - `A09_Przybilla`
* - `MB22_photospheric`
* - `AAG21_photospheric`
* - `L09` (Lodders 2009)
*
* @note Composition names are case normalized; therefore, the inputs for metal fraction scheme and isotopic percentage scheme are case insensitive.
* Available isotopic percentage schemes:
* - `L03_data` (Lodders 2003)
* - `L09_data` (Lodders 2009)
*
* @param metal_fraction_scheme The name of the metal fraction scheme to use. Must be one of the following: AG89, GN93, GS98, L03, AGS05, AGS08, A09_Pryzbilla, MB22_photospheric, AAG21_photospheric, L09
* @param isotopic_percentage_scheme The name of the isotopic percentage scheme to use. Must be one of the following: L03, L09
* @param initial_z <poojan_documenent_here>
* @param initial_y <poojan document here>
* **Algorithm:**
* 1. **Data loading** — The embedded binary `StandardMetalFractions` is copied
* into a `std::vector<char>` and parsed twice: once for `metal_fraction_scheme`
* and once for `isotopic_percentage_scheme`.
* 2. **Species list** — The isotope table is iterated; any isotope whose element
* appears in the metals list or is `"H"` / `"He"` is looked up in the global
* `atomic::species` registry by `"<Element>-<A>"` and added to the list.
* 3. **H and He mass fractions** — Four entries are prepended (H-1, H-2, He-3,
* He-4) using Anders & Grevesse (1989) solar He3/He4 ratio:
* - X(H-1) = clamp(1 - Z - Y, 0, 1)
* - X(H-2) = 0
* - X(He-3) = Y * xsol_He3 / (xsol_He3 + xsol_He4)
* - X(He-4) = Y * xsol_He4 / (xsol_He3 + xsol_He4)
* where xsol_He3 = 2.9291e-5 and xsol_He4 = 2.7521e-1.
* 4. **Atomic-weight weighting** — When `CompositionData::requires_atomic_weight`
* is `true`, each metal's number-fraction abundance is multiplied by the
* atomic mass of its most-abundant isotope (determined from the isotopic table).
* 5. **Normalisation** — Metal fractions are summed and normalised to unity.
* 6. **Isotope distribution** — Per-isotope mass fractions are computed as:
* X_i = Z_total * f_E * (p_i * m_i) / sum_j(p_j * m_j)
* where f_E is the normalised metal fraction, p_i the isotopic percentage
* (0-100 scale), and m_i the isotope's atomic mass.
* 7. **Renormalisation** — Metal mass fractions are rescaled so their sum
* equals Z_total exactly.
* 8. **Assembly** — `buildCompositionFromMassFractions(species, massFracs)` builds
* the final `Composition` object.
*
* @param[in] metal_fraction_scheme Block tag of the desired solar metal
* composition (e.g., `"GS98"`, `"AGSS09"`). Case-sensitive; must
* match a `BEGIN`/`END` tag in the embedded data exactly.
* @param[in] isotopic_percentage_scheme Block tag of the isotopic percentage
* table (e.g., `"L03_data"`, `"L09_data"`).
* @param[in] initial_z Total metal mass fraction Z (0 <= Z < 1).
* @param[in] initial_y Total helium mass fraction Y (0 <= Y < 1,
* with X + Y + Z <= 1 recommended). X(H-1) is clamped to [0, 1]
* if the constraint is violated.
*
* @return `Composition` Fully populated composition object with per-isotope
* mass fractions normalised to `initial_z` and `initial_y`.
*
* @throws std::out_of_range If a species name derived from the isotopic table
* is absent from `atomic::species`, or if either scheme tag is not
* present in the embedded data.
* @throws std::invalid_argument If numeric fields in the embedded data are
* malformed (propagated from `std::stod` / `std::stoi`).
*
* @par Examples
* @code{.cpp}
* // Grevesse & Sauval (1998) at Z = 0.02, Y = 0.28
* fourdst::composition::Composition comp =
* fourdst::composition::get_composition_record("GS98", "L03_data", 0.02, 0.28);
*
* double x_h1 = comp.massFraction("H-1");
* std::println("X(H-1) = {:.6f}", x_h1); // approx 0.70
* @endcode
*/
[[nodiscard]] Composition get_composition_record(const std::string& metal_fraction_scheme,
const std::string& isotopic_percentage_scheme,
@@ -149,12 +250,41 @@ namespace fourdst::composition {
double initial_y);
/**
* @brief Overload of the string based version of this function which accepts the enums Solar
* @param metal_fraction_scheme Enum corresponding to the standard solar composition to select
* @param isotopic_percentage_scheme Enum corresponding to the isotopic percentages prescription to select
* @param initial_z <poojan_document_here>
* @param initial_y <poojan_document_here>
* @return
* @brief Enum-based overload of `get_composition_record()`.
*
* Translates strongly-typed enum values to their canonical string
* representations via `SolarCompositions_to_string_map` and
* `IsotopicPercentages_to_string_map`, then delegates to the string-based
* overload. This overload is preferred as it prevents scheme name typos.
*
* @param[in] metal_fraction_scheme Enum identifying the desired solar metal
* composition (e.g., `SolarCompositions::GS98`).
* @param[in] isotopic_percentage_scheme Enum identifying the isotopic percentage
* table (e.g., `IsotopicPercentages::L03`).
* @param[in] initial_z Total metal mass fraction Z (0 <= Z < 1).
* @param[in] initial_y Total helium mass fraction Y (0 <= Y < 1).
*
* @return `Composition` Fully populated composition; see the string-based
* overload for the complete algorithm description.
*
* @throws std::out_of_range If the enum value is absent from its lookup map
* (should not occur with valid named enum members).
*
* @par Examples
* @code{.cpp}
* using namespace fourdst::composition;
* using namespace fourdst::composition::io;
*
* // Asplund et al. (2009) at proto-solar Z and Y
* Composition comp = get_composition_record(
* SolarCompositions::AGSS09,
* IsotopicPercentages::L09,
* 0.0134, 0.2485
* );
*
* double x_he4 = comp.massFraction("He-4");
* std::println("X(He-4) = {:.6f}", x_he4);
* @endcode
*/
[[nodiscard]] Composition get_composition_record(io::SolarCompositions metal_fraction_scheme,
io::IsotopicPercentages isotopic_percentage_scheme,

View File

@@ -18,6 +18,14 @@
#include <cctype>
namespace {
/**
* @brief Removes leading whitespace from a string in-place.
*
* Uses `std::ranges::find_if` with an `std::isspace` predicate to locate the
* first non-whitespace character, then erases all characters before that position.
*
* @param[in,out] s String to modify.
*/
void ltrim(std::string &s) {
s.erase(
s.begin(),
@@ -28,6 +36,15 @@ namespace {
);
}
/**
* @brief Removes trailing whitespace from a string in-place.
*
* Iterates in reverse via a reverse iterator pair and `std::find_if` with an
* `std::isspace` predicate to locate the last non-whitespace character, then
* erases everything after it.
*
* @param[in,out] s String to modify.
*/
void rtrim(std::string &s) {
s.erase(
std::find_if(
@@ -40,12 +57,29 @@ namespace {
);
}
/**
* @brief Removes both leading and trailing whitespace from a string in-place.
*
* Delegates to ltrim() then rtrim() in sequence.
*
* @param[in,out] s String to modify.
*/
void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
/**
* @brief Converts a string to a boolean value, case-insensitively.
*
* Lower-cases every character via `std::ranges::transform` and returns `true`
* only when the resulting string is exactly `"true"`. All other inputs
* (including `"1"`, `"yes"`, empty string) return `false`.
*
* @param s String to interpret (e.g., `"true"`, `"True"`, `"TRUE"`, `"false"`).
* @return `true` if the lower-cased string equals `"true"`, `false` otherwise.
*/
bool to_bool(std::string s) {
std::ranges::transform(s, s.begin(),
[](const unsigned char c){ return std::tolower(c); });
@@ -62,11 +96,6 @@ namespace fourdst:: composition::io {
CompositionData ChemicalFileParser::parse_composition_data(const std::vector<char>& data,const std::string& scheme) {
// get file and metal_fraction_scheme
// Load the file
// find the metal_fraction_scheme
// return abundances
std::istringstream stream(std::string(data.begin(), data.end()));
// add error message if something goes wrong
@@ -144,10 +173,6 @@ namespace fourdst:: composition::io {
IsotopicPercentage ChemicalFileParser::parse_isotopic_percentage(const std::vector<char>& data,const std::string& scheme) {
// get file and iso_scheme
// Load the file
// find the iso_scheme
// get iso_comp data
// IsotopicPercentage object
std::istringstream stream(std::string(data.begin(), data.end()));