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:
72
src/include/serif/equations/registry.hpp
Normal file
72
src/include/serif/equations/registry.hpp
Normal 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
|
||||
Reference in New Issue
Block a user