feat(equations): Added EquationRegistry

This is a compile time pack of equations which can be used to do things like say "this model is described by this set of equations"
This commit is contained in:
2026-10-12 09:37:03 -04:00
parent cb2ac127aa
commit fee05a621d

View File

@@ -0,0 +1,72 @@
#pragma once
/**
* @file registry.hpp
* @author Emily M. Boudreaux
*
* @brief System for registering multiple equations. The idea here is that a model will be defined partly by an equation registry (e.g. all the
* equations that must be satisfied for a given model).
*/
#include <tuple>
#include <utility>
#include "serif/equations/concepts.hpp"
namespace serif::equations {
/**
* @class EquationRegistry
*
* @brief A compile-time registry of equations.
* @tparam EquationTs Pack of equation types to register.
*
* @requires There must be at least one equation type in the pack.
* @requires Each residual row must be defined exactly once.
*/
template <Equation... EquationTs>
class EquationRegistry final {
public:
static_assert(sizeof...(EquationTs) > 0, "An equation registry must contain at least one equation.");
using Equations = utils::types::TypeList<EquationTs...>; ///< The equation types in the registry.
using Rows = utils::types::TypeList<discretization::forms::Operand<typename EquationTs::Test>...>; ///< The residual row types in the registry
static_assert( ((OperandValues<Rows>::template index<typename EquationTs::Test>() < sizeof...(EquationTs)) && ...), "An equation registry must define each residual row exactly once.");
/**
* @brief Construct an equation registry with the given equations.
*
* @param equations The equations to register.
*/
explicit EquationRegistry(EquationTs... equations) : m_equations(std::move(equations)...) {}
/**
* @brief Apply some function to every type in the registry.
*
* @tparam FunctionT The type of the function to apply. The function must have the signature `void(const EquationT&)` where `EquationT` is the type of the equation in the registry.
* @param function The function to apply to each equation in the registry.
*/
template <typename FunctionT>
void for_each(FunctionT&& function) const {
std::apply([&](const auto&... equations) {
(function(equations), ...);
},
m_equations
);
}
/**
* @brief Get the equation of a given type from the registry.
*
* @tparam EquationT The type of the equation to get.
* @return The equation of the given type.
*/
template <Equation EquationT>
[[nodiscard]] const EquationT& get() const {
return std::get<EquationT>(m_equations);
}
private:
std::tuple<EquationTs...> m_equations; ///< The equations in the registry, stored as a tuple.
};
} // namespace serif::equations