From 18d289da7e9747b3bbdc75fb13517aedb9851b96 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Wed, 5 Nov 2025 18:37:31 -0500 Subject: [PATCH] docs(policy): added doxygen docs to policy system --- .../gridfire/exceptions/error_policy.h | 61 +++++- src/include/gridfire/policy/chains.h | 117 ++++++++++- src/include/gridfire/policy/policy_abstract.h | 193 +++++++++++++++++- src/include/gridfire/policy/stellar_policy.h | 122 ++++++++++- 4 files changed, 474 insertions(+), 19 deletions(-) diff --git a/src/include/gridfire/exceptions/error_policy.h b/src/include/gridfire/exceptions/error_policy.h index 0f124017..4f8d8e3a 100644 --- a/src/include/gridfire/exceptions/error_policy.h +++ b/src/include/gridfire/exceptions/error_policy.h @@ -1,13 +1,39 @@ +/** + * @file error_policy.h + * @brief Defines custom exception types related to network policy construction and verification. + * + * This file contains a hierarchy of exception classes that are thrown by `NetworkPolicy` + * implementations (see `stellar_policy.h`) and `ReactionChainPolicy` implementations + * (see `chains.h`) when errors occur. + * + * The base class `PolicyError` inherits from `std::exception`, and specific error + * conditions are represented by derived classes. + */ #pragma once #include #include namespace gridfire::exceptions { - class PolicyError : std::exception { + /** + * @class PolicyError + * @brief Base class for all exceptions related to network policy operations. + * + * This exception is the parent for more specific policy-related errors. Catching this + * type will catch any exception originating from the policy system. + */ + class PolicyError : public std::exception { public: + /** + * @brief Constructs a PolicyError with a descriptive message. + * @param msg The error message. + */ explicit PolicyError(const std::string& msg) : m_message(msg) {}; + /** + * @brief Returns the explanatory string. + * @return A C-style string with the error message. + */ [[nodiscard]] const char* what() const noexcept override { return m_message.c_str(); } @@ -15,18 +41,51 @@ namespace gridfire::exceptions { std::string m_message; }; + /** + * @class MissingBaseReactionError + * @brief Exception thrown when a required reaction is missing from the underlying database (e.g., REACLIB). + * + * This typically occurs during the construction of a `ReactionChainPolicy` if the + * reaction library used by GridFire does not contain a reaction specified by the policy. + */ class MissingBaseReactionError final : public PolicyError { public: + /** + * @brief Constructs a MissingBaseReactionError with a descriptive message. + * @param msg The error message. + */ explicit MissingBaseReactionError(const std::string& msg) : PolicyError(msg) {}; }; + /** + * @class MissingSeedSpeciesError + * @brief Exception thrown when a required seed species is not found in the initial composition. + * + * This error occurs when a `NetworkPolicy` is initialized with a composition that lacks + * one or more of the essential species needed to construct the network. + */ class MissingSeedSpeciesError final : public PolicyError { public: + /** + * @brief Constructs a MissingSeedSpeciesError with a descriptive message. + * @param msg The error message. + */ explicit MissingSeedSpeciesError(const std::string& msg) : PolicyError(msg) {}; }; + /** + * @class MissingKeyReactionError + * @brief Exception thrown when a constructed network fails to include a key reaction required by the policy. + * + * This error is typically thrown from the `construct()` method of a `NetworkPolicy` after + * the network has been built but fails the final verification step. + */ class MissingKeyReactionError final : public PolicyError { public: + /** + * @brief Constructs a MissingKeyReactionError with a descriptive message. + * @param msg The error message. + */ explicit MissingKeyReactionError(const std::string& msg) : PolicyError(msg) {} }; } \ No newline at end of file diff --git a/src/include/gridfire/policy/chains.h b/src/include/gridfire/policy/chains.h index 288f9858..d6c09f7d 100644 --- a/src/include/gridfire/policy/chains.h +++ b/src/include/gridfire/policy/chains.h @@ -1,3 +1,19 @@ +/** + * @file chains.h + * @brief Concrete implementations of ReactionChainPolicy for key stellar reaction chains. + * + * This file provides concrete policies for fundamental nuclear reaction chains, such as the + * Proton-Proton chain and the CNO cycle. These policies inherit from ReactionChainPolicy (see + * `policy_abstract.h`) and provide a pre-defined set of reactions. + * + * They are typically used by higher-level NetworkPolicy implementations (e.g., `LowMassMainSequencePolicy` + * in `stellar_policy.h`) to compose a complete set of required reactions for a particular + * stellar environment. + * + * @note Constructors for these policies may throw `gridfire::exceptions::MissingBaseReactionError` + * if a required reaction is not found in the underlying REACLIB database. This usually + * indicates an issue with the GridFire installation or the bundled reaction data. + */ #pragma once #include "gridfire/policy/policy_abstract.h" @@ -11,11 +27,35 @@ namespace gridfire::policy { + /** + * @class ProtonProtonChainPolicy + * @brief A ReactionChainPolicy for the Proton-Proton (PP) chain. + * + * Encapsulates the set of reactions that constitute the three branches of the PP chain, + * which is the primary energy generation mechanism in stars like the Sun. + * + * @throws gridfire::exceptions::MissingBaseReactionError if a required reaction for the PP chain + * is not found in the REACLIB database during construction. + */ class ProtonProtonChainPolicy final: public ReactionChainPolicy { public: + /** + * @brief Constructs the policy and initializes its reaction set from REACLIB. + */ ProtonProtonChainPolicy(); - const reaction::ReactionSet& get_reactions() const override { return m_reactions; } + /** + * @brief Returns the set of reactions in the PP chain. + * @return const reaction::ReactionSet& + * + * @par Example + * @code + * ProtonProtonChainPolicy pp_policy; + * const auto& reactions = pp_policy.get_reactions(); + * std::cout << "PP chain has " << reactions.size() << " reactions." << std::endl; + * @endcode + */ + [[nodiscard]] const reaction::ReactionSet& get_reactions() const override { return m_reactions; } private: std::vector m_reactionIDs = { "p(p,e+)d", @@ -31,10 +71,34 @@ namespace gridfire::policy { reaction::ReactionSet m_reactions; }; + /** + * @class CNOChainPolicy + * @brief A ReactionChainPolicy for the Carbon-Nitrogen-Oxygen (CNO) cycle. + * + * Encapsulates the reactions of the CNO cycle, a catalytic cycle that is the dominant + * source of energy in massive stars. + * + * @throws gridfire::exceptions::MissingBaseReactionError if a required reaction for the CNO cycle + * is not found in the REACLIB database during construction. + */ class CNOChainPolicy final: public ReactionChainPolicy { public: + /** + * @brief Constructs the policy and initializes its reaction set from REACLIB. + */ CNOChainPolicy(); - const reaction::ReactionSet& get_reactions() const override { return m_reactions; } + /** + * @brief Returns the set of reactions in the CNO cycle. + * @return const reaction::ReactionSet& + * + * @par Example + * @code + * CNOChainPolicy cno_policy; + * const auto& reactions = cno_policy.get_reactions(); + * assert(reactions.contains("c12(p,g)n13")); + * @endcode + */ + [[nodiscard]] const reaction::ReactionSet& get_reactions() const override { return m_reactions; } private: std::set m_reactionIDs = { "c12(p,g)n13", @@ -68,10 +132,27 @@ namespace gridfire::policy { reaction::ReactionSet m_reactions; }; + /** + * @class HotCNOChainPolicy + * @brief A ReactionChainPolicy for the Hot CNO (HCNO) cycle. + * + * Encapsulates the reactions of the HCNO cycle, which becomes significant at higher + * temperatures and densities than the standard CNO cycle, often in explosive scenarios. + * + * @throws gridfire::exceptions::MissingBaseReactionError if a required reaction for the HCNO cycle + * is not found in the REACLIB database during construction. + */ class HotCNOChainPolicy final : public ReactionChainPolicy { public: + /** + * @brief Constructs the policy and initializes its reaction set from REACLIB. + */ HotCNOChainPolicy(); - const reaction::ReactionSet& get_reactions() const override { return m_reactions; } + /** + * @brief Returns the set of reactions in the HCNO cycle. + * @return const reaction::ReactionSet& + */ + [[nodiscard]] const reaction::ReactionSet& get_reactions() const override { return m_reactions; } private: std::set m_reactionIDs = { "c12(p,g)n13", @@ -99,13 +180,38 @@ namespace gridfire::policy { reaction::ReactionSet m_reactions; }; + /** + * @class LowMassMainSequenceReactionChainPolicy + * @brief A MultiReactionChainPolicy for low-mass main-sequence stars. + * + * This policy composes the `ProtonProtonChainPolicy` and `CNOChainPolicy` to represent the + * key energy-generating reaction chains active in low-mass stars like the Sun. + */ class LowMassMainSequenceReactionChainPolicy final : public MultiReactionChainPolicy { public: + /** + * @brief Constructs the policy and initializes its child policies. + */ LowMassMainSequenceReactionChainPolicy(); - const reaction::ReactionSet & get_reactions() const override; + /** + * @brief Returns the combined set of reactions from all child policies (PP and CNO). + * @return const reaction::ReactionSet& + */ + [[nodiscard]] const reaction::ReactionSet & get_reactions() const override; - const std::vector>& get_chain_policies() const override; + /** + * @brief Returns the vector of child policies. + * @return const std::vector>& + * + * @par Example + * @code + * LowMassMainSequenceReactionChainPolicy lmms_policy; + * const auto& child_policies = lmms_policy.get_chain_policies(); + * std::cout << "Low-mass policy has " << child_policies.size() << " child policies." << std::endl; + * @endcode + */ + [[nodiscard]] const std::vector>& get_chain_policies() const override; private: std::vector> m_chain_policies; @@ -166,4 +272,3 @@ namespace gridfire::policy { } - diff --git a/src/include/gridfire/policy/policy_abstract.h b/src/include/gridfire/policy/policy_abstract.h index bf325f52..9c4865e1 100644 --- a/src/include/gridfire/policy/policy_abstract.h +++ b/src/include/gridfire/policy/policy_abstract.h @@ -1,3 +1,24 @@ +/** + * @file policy_abstract.h + * @brief Abstract policy interfaces used to construct reaction networks (DynamicEngine) from seed compositions. + * + * This header declares the base interfaces for high-level "policies" that drive automatic network + * construction and verification. A NetworkPolicy encapsulates the information required to build + * a production-ready reaction network from an initial composition (seed species and seed reactions) + * and to return a constructed DynamicEngine ready for use by the solvers. + * + * Concrete policy implementations live in this directory and provide the real behaviour. See for + * example: + * - gridfire/policy/stellar_policy.h (concrete stellar network policy used in many examples) + * - gridfire/policy/chains.h (reaction-chain helper policies such as proton-proton, CNO) + * + * An example of using a concrete policy to construct and run an engine is available at: + * - tests/graphnet_sandbox/main.cpp + * + * @note Doxygen comments on public methods include @par Example usage blocks. Methods that may + * throw in concrete implementations include @throws tags. + */ + #pragma once #include "fourdst/composition/atomicSpecies.h" @@ -10,6 +31,14 @@ namespace gridfire::policy { + /** + * @enum NetworkPolicyStatus + * @brief Lifecycle/verification status for a NetworkPolicy instance. + * + * Used by concrete NetworkPolicy implementations to report the state of the policy and the + * constructed network during/after construction. Tests and callers can inspect the status + * to determine whether the resulting network meets the policy's requirements. + */ enum class NetworkPolicyStatus { UNINITIALIZED, INITIALIZED_UNVERIFIED, @@ -18,28 +47,176 @@ namespace gridfire::policy { INITIALIZED_VERIFIED }; + /** + * @class NetworkPolicy + * @brief Abstract interface for policies that construct DynamicEngine networks from a seed composition. + * + * A NetworkPolicy provides three main pieces of information: + * - A name identifying the policy. + * - A set of seed species and seed reactions required to initialize the network. + * - A constructor method that returns a fully constructed DynamicEngine (or view stack) built + * to satisfy the policy. + * + * Concrete implementations include `LowMassMainSequencePolicy` (see `stellar_policy.h`) and may + * throw policy-specific exceptions during construction (for example when required reactions or + * species are missing). + * + * @par Example + * @code + * // Example usage (see tests/graphnet_sandbox/main.cpp for a complete example): + * // fourdst::composition::Composition comp = prepared composition + * // gridfire::policy::LowMassMainSequencePolicy policy(comp); + * // // construct() returns a reference to a DynamicEngine (could be a view stack) + * // DynamicEngine &engine = policy.construct(); + * // // engine can now be passed to a solver (e.g. CVODESolverStrategy) + * @endcode + */ class NetworkPolicy { public: virtual ~NetworkPolicy() = default; - virtual std::string name() const = 0; - virtual const std::set get_seed_species() const = 0; - virtual const reaction::ReactionSet& get_seed_reactions() const = 0; + /** + * @brief Human-readable name for the policy. + * + * @return a std::string identifying the policy implementation (e.g. "LowMassMainSequencePolicy"). + * + * @par Example + * @code + * std::string n = policy.name(); + * std::cout << "Using policy: " << n << std::endl; + * @endcode + */ + [[nodiscard]] virtual std::string name() const = 0; - virtual DynamicEngine& construct() = 0; + /** + * @brief Returns the seed species the policy requires to initialize the network. + * + * The returned set contains atomic species identifiers (fourdst::atomic::Species) which the + * policy expects to be present in the initial composition used to build the network. + * + * Implementations should return a copy or an immutable reference to their internal set of + * required seed species. + * + * @par Example + * @code + * const auto seeds = policy.get_seed_species(); + * for (const auto &s : seeds) { std::cout << s.name() << std::endl; } + * @endcode + */ + [[nodiscard]] virtual const std::set get_seed_species() const = 0; - virtual NetworkPolicyStatus getStatus() const = 0; + /** + * @brief Returns the set of seed reactions the policy requires. + * + * The ReactionSet describes reactions that must be present in the constructed network for the + * policy to be considered satisfied. Concrete policies often implement their reaction + * requirements by composing one or more ReactionChainPolicy instances (see `chains.h`). + * + * @par Example + * @code + * const reaction::ReactionSet &reacs = policy.get_seed_reactions(); + * // inspect reaction IDs or count + * std::cout << "Policy requires " << reacs.size() << " reactions" << std::endl; + * @endcode + */ + [[nodiscard]] virtual const reaction::ReactionSet& get_seed_reactions() const = 0; + + /** + * @brief Construct and return a DynamicEngine instance (or engine view stack) satisfying the policy. + * + * Implementations typically build one or more engine layers (GraphEngine, MultiscalePartitioningEngineView, + * AdaptiveEngineView, etc.) and return a reference to the top-most DynamicEngine. The storage lifetime of + * the returned reference is implementation-defined (usually owned by the policy instance). + * + * @return DynamicEngine& reference to a running/constructed engine ready for solver consumption. + * + * @throws gridfire::exceptions::MissingKeyReactionError if required reactions are not present in the + * constructed network (see `gridfire/exceptions/error_policy.h`). + * @throws gridfire::exceptions::MissingSeedSpeciesError if required seed species are missing from the + * initializing composition. + * @throws gridfire::exceptions::PolicyError for other construction/verification failures. + * + * @par Example + * @code + * DynamicEngine &engine = policy.construct(); + * solver::CVODESolverStrategy solver(engine); + * NetOut out = solver.evaluate(netIn, true); + * @endcode + */ + [[nodiscard]] virtual DynamicEngine& construct() = 0; + + /** + * @brief Returns the current verification/construction status of the policy. + * + * The status reports whether the policy has been initialized and whether the constructed + * network satisfies the policy's key requirements. + * + * @par Example + * @code + * NetworkPolicyStatus s = policy.getStatus(); + * if (s != NetworkPolicyStatus::INITIALIZED_VERIFIED) { // handle error } + * @endcode + */ + [[nodiscard]] virtual NetworkPolicyStatus getStatus() const = 0; }; + /** + * @class ReactionChainPolicy + * @brief Abstract interface encapsulating a set of reactions representing a single chain or pathway. + * + * ReactionChainPolicy implementations (see `chains.h`) supply a ReactionSet describing the reactions + * that comprise a nuclear reaction chain (for example the proton-proton chain, CNO cycle, etc.). + * + * @par Example + * @code + * ProtonProtonChainPolicy pp; + * const auto &reacs = pp.get_reactions(); + * @endcode + * + * @note Concrete implementations may throw exceptions on construction if the underlying reaction + * database (e.g. REACLIB) does not include requested reactions. See `chains.h` for details. + */ class ReactionChainPolicy { public: virtual ~ReactionChainPolicy() = default; - virtual const reaction::ReactionSet& get_reactions() const = 0; + + /** + * @brief Returns the ReactionSet describing this chain. + * + * @return const reaction::ReactionSet& reference to the chain's reactions. + * + * @par Example + * @code + * const reaction::ReactionSet &set = chainPolicy.get_reactions(); + * std::cout << "Chain contains " << set.size() << " reactions\n"; + * @endcode + * + * @throws gridfire::exceptions::MissingBaseReactionError may be thrown by concrete implementations + * at construction time if the required reactions cannot be found in the base reaction set. + */ + [[nodiscard]] virtual const reaction::ReactionSet& get_reactions() const = 0; }; + /** + * @class MultiReactionChainPolicy + * @brief A ReactionChainPolicy composed of multiple child ReactionChainPolicy instances. + * + * Useful for policies that represent a union of several reaction chains (for example the + * `LowMassMainSequenceReactionChainPolicy` composes the proton-proton and CNO chains). + * + * @par Example + * @code + * LowMassMainSequenceReactionChainPolicy multi; + * const auto &chains = multi.get_chain_policies(); + * for (const auto &ch : chains) { std::cout << ch->get_reactions().size() << " reactions\n"; } + * @endcode + */ class MultiReactionChainPolicy : public ReactionChainPolicy { public: - virtual const std::vector>& get_chain_policies() const = 0; + /** + * @brief Returns the vector of child ReactionChainPolicy instances. + * @return const std::vector>& + */ + [[nodiscard]] virtual const std::vector>& get_chain_policies() const = 0; }; - } diff --git a/src/include/gridfire/policy/stellar_policy.h b/src/include/gridfire/policy/stellar_policy.h index 93cef85d..62324c62 100644 --- a/src/include/gridfire/policy/stellar_policy.h +++ b/src/include/gridfire/policy/stellar_policy.h @@ -1,3 +1,19 @@ +/** + * @file stellar_policy.h + * @brief High-level concrete NetworkPolicy for specific stellar environments. + * + * This file defines the `LowMassMainSequencePolicy`, a concrete implementation of the `NetworkPolicy` + * interface. This policy is designed to construct a reaction network suitable for simulating + * nucleosynthesis in low-mass main-sequence stars (like the Sun). + * + * It serves as a practical example of how to create a high-level policy by: + * 1. Defining a set of required seed species. + * 2. Composing lower-level `ReactionChainPolicy` instances (from `chains.h`) to specify + * the necessary reactions (e.g., PP-chain and CNO-cycle). + * 3. Implementing the `construct()` method to build a sophisticated, multi-layered `DynamicEngine` + * stack, ready for use with a solver. + * + */ #pragma once #include @@ -20,19 +36,117 @@ #include "gridfire/policy/chains.h" namespace gridfire::policy { + /** + * @class LowMassMainSequencePolicy + * @brief A NetworkPolicy for building reaction networks suitable for low-mass main-sequence stars. + * + * This policy ensures that a constructed network contains all necessary species and reactions + * for modeling the core hydrogen burning phase in low-mass stars, primarily the PP-chain and + * the CNO-cycle. + * + * The `construct()` method builds a stack of engine views (`GraphEngine` -> + * `MultiscalePartitioningEngineView` -> `AdaptiveEngineView`) to provide a dynamically + * adjusting, performance-optimized reaction network. + * + * This policy requires the following seed species: + * - H-1 + * - He-3 + * - He-4 + * - C-12 + * - N-14 + * - O-16 + * - Ne-20 + * - Mg-24 + * + * + * This policy composes the `ProtonProtonChainPolicy` and `CNOChainPolicy` to define + * the required reactions. + */ class LowMassMainSequencePolicy final: public NetworkPolicy { public: + /** + * @brief Constructs the policy from an existing composition object. + * + * @param composition The initial composition, which must contain all seed species required by the policy. + * + * @throws exceptions::MissingSeedSpeciesError if the provided `composition` is missing a required species. + * + * @par Example + * @code + * fourdst::composition::Composition comp; + * // ... populate composition ... + * LowMassMainSequencePolicy policy(comp); + * @endcode + */ explicit LowMassMainSequencePolicy(const fourdst::composition::Composition& composition); + /** + * @brief Constructs the policy from a list of species and their mass fractions. + * + * @param seed_species A vector of atomic species. + * @param mass_fractions A vector of corresponding mass fractions. + * + * @throws exceptions::MissingSeedSpeciesError if the provided species list is missing a required seed species. + * @throws fourdst::composition::exceptions::CompositionNotFinalizedError if the internal composition fails to finalize. + * + * @par Example + * @code + * using namespace fourdst::atomic; + * std::vector species = {H_1, He_4, C_12, O_16}; + * std::vector mass_fractions = {0.7, 0.28, 0.01, 0.01}; + * LowMassMainSequencePolicy policy(species, mass_fractions); + * @endcode + */ explicit LowMassMainSequencePolicy(std::vector seed_species, std::vector mass_fractions); - std::string name() const override { return "LowMassMainSequencePolicy"; } + /** + * @brief Returns the name of the policy. + * @return "LowMassMainSequencePolicy" + */ + [[nodiscard]] std::string name() const override { return "LowMassMainSequencePolicy"; } - const std::set get_seed_species() const override { return m_seed_species; } - const reaction::ReactionSet& get_seed_reactions() const override { return m_reaction_policy->get_reactions(); } + /** + * @brief Returns the set of seed species required by this policy. + * @return const std::set& + */ + [[nodiscard]] const std::set get_seed_species() const override { return m_seed_species; } + /** + * @brief Returns the set of seed reactions required by this policy (from the PP and CNO chains). + * @return const reaction::ReactionSet& + */ + [[nodiscard]] const reaction::ReactionSet& get_seed_reactions() const override { return m_reaction_policy->get_reactions(); } + /** + * @brief Constructs and returns the complete, multi-layered dynamic engine. + * + * This method builds the full network engine stack: + * - A base `GraphEngine` is created with the initial composition. This is constructed three layers deep which is sufficient to capture all required reactions. Further a + * composite ground state and Rauscher Thielemann partition function is used. + * - A `MultiscalePartitioningEngineView` is layered on top for performance optimization. This will put some species into equilibrium groups based on their reaction timescales. + * - An `AdaptiveEngineView` is added as the final layer to dynamically cull reaction pathways based on molar reaction flows. + * + * After construction, it verifies that the resulting network meets the policy's requirements. + * + * @return DynamicEngine& A reference to the top-level `AdaptiveEngineView`. + * + * @throws exceptions::MissingKeyReactionError if the final network is missing a required reaction. + * @throws exceptions::MissingSeedSpeciesError if the final network is missing a required species. + * @throws exceptions::PolicyError on other verification failures. + * + * @par Example + * @code + * LowMassMainSequencePolicy enginePolicy(composition); + * DynamicEngine& engine = enginePolicy.construct(); + * solver::CVODESolverStrategy solver(engine); + * // ... run solver ... + * @endcode + */ DynamicEngine& construct() override; - NetworkPolicyStatus getStatus() const override; + /** + * @brief Gets the current status of the policy. + * @return NetworkPolicyStatus The construction and verification status. + */ + [[nodiscard]] NetworkPolicyStatus getStatus() const override; private: std::set m_seed_species = { fourdst::atomic::H_1,