diff --git a/src/include/serif/equations/concepts.hpp b/src/include/serif/equations/concepts.hpp new file mode 100644 index 00000000..c9294133 --- /dev/null +++ b/src/include/serif/equations/concepts.hpp @@ -0,0 +1,90 @@ +#pragma once + +/** + * @file concepts.hpp + * @author Emily M. Boudreaux + * @brief Concepts for equations, contributions, and pointwise evaluation. + */ + +#include +#include +#include "serif/equations/contributions.hpp" +#include "serif/equations/point.hpp" + +namespace serif::equations { + + /** + * @concept PointEquation + * + * @brief A concept that defines the requirements for a pointwise equation. + * + * @requires The equation must have a test type (::Test) and an operand type (::Operands). + * @requires The test type (::Test) must be either a spatial term or a global scalar term. + * @requires The test type must have a residual block. + * @requires The operand type must be a valid operand + * @requires The operant term type (::term_type) must be the same as the test type (::Test). + * @requires The equation must have a method called ::evaluate() that takes an EquationPoint of the operand type and returns a PointLinearization of the operand type and the operand value of the test operand. + * + */ + template + concept PointEquation = + requires { + typename T::Test; + typename T::Operands; + } && + (discretization::blocks::SpatialTerm || discretization::blocks::GlobalScalarTerm) && + discretization::blocks::HasResidualBlock && + discretization::forms::IsOperand> && + std::same_as::term_type, typename T::Test> && + requires(const T& equation, const EquationPoint& point) { + { + equation.evaluate(point) + } -> std::same_as>>>; + }; + + /** + * @struct ValidContributions + * + * @brief A compile-time check to ensure that a tuple of contributions is valid for a given residual row type. This is the default false specialization. + * + * @tparam RowT The type of the residual row that the contributions must share. + * @tparam TupleT A tuple of contributions to validate. + */ + template + struct ValidContributions : std::false_type {}; + + /** + * @struct ValidContributions + * + * @brief A compile-time check to ensure that a tuple of contributions is valid for a given residual row type. This is the specialization for a non-empty tuple of contributions. + * + * @tparam RowT The type of the residual row that the contributions must share. + * @tparam C The first contribution type in the tuple. + * @tparam RestCs The remaining contribution types in the tuple. + * + * @true_if The size of C (contributions) is not zero + * @true_if Each contribution satisfies the PointEquation concept + * @true_if Each contribution's test type is the same as RowT + */ + template + struct ValidContributions> : std::bool_constant< + sizeof...(C) != 0 && (requires { + requires PointEquation; + requires std::same_as; } && ...)> {}; + + + /** + * @concept Equation + * + * @brief A concept that defines the requirements for a valid SERiF equation. + * + * @requires The equation must have a test type (::Test) and a name (::name). + * @requires The name must be convertible to a std::string_view. + * @requires The contributions of the equation must be valid for the test type, as defined by the ValidContributions struct. + */ + template + concept Equation = requires { + typename T::Test; + { T::name } -> std::convertible_to; + } && ValidContributions>::value; +} // namespace serif::equations