docs(policy): added doxygen docs to policy system

This commit is contained in:
2025-11-05 18:37:31 -05:00
parent 9fdbb57996
commit 18d289da7e
4 changed files with 474 additions and 19 deletions

View File

@@ -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 <exception>
#include <string>
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) {}
};
}

View File

@@ -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<std::string> 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<std::string> 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<std::string> 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<std::unique_ptr<ReactionChainPolicy>>& get_chain_policies() const override;
/**
* @brief Returns the vector of child policies.
* @return const std::vector<std::unique_ptr<ReactionChainPolicy>>&
*
* @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<std::unique_ptr<ReactionChainPolicy>>& get_chain_policies() const override;
private:
std::vector<std::unique_ptr<ReactionChainPolicy>> m_chain_policies;
@@ -166,4 +272,3 @@ namespace gridfire::policy {
}

View File

@@ -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<fourdst::atomic::Species> 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<fourdst::atomic::Species> 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<std::unique_ptr<ReactionChainPolicy>>& get_chain_policies() const = 0;
/**
* @brief Returns the vector of child ReactionChainPolicy instances.
* @return const std::vector<std::unique_ptr<ReactionChainPolicy>>&
*/
[[nodiscard]] virtual const std::vector<std::unique_ptr<ReactionChainPolicy>>& get_chain_policies() const = 0;
};
}

View File

@@ -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 <vector>
@@ -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> species = {H_1, He_4, C_12, O_16};
* std::vector<double> mass_fractions = {0.7, 0.28, 0.01, 0.01};
* LowMassMainSequencePolicy policy(species, mass_fractions);
* @endcode
*/
explicit LowMassMainSequencePolicy(std::vector<fourdst::atomic::Species> seed_species, std::vector<double> 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<fourdst::atomic::Species> 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<fourdst::atomic::Species>&
*/
[[nodiscard]] const std::set<fourdst::atomic::Species> 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<fourdst::atomic::Species> m_seed_species = {
fourdst::atomic::H_1,