diff --git a/src/include/serif/utils/projection/projection.hpp b/src/include/serif/utils/projection/projection.hpp new file mode 100644 index 00000000..73a459e8 --- /dev/null +++ b/src/include/serif/utils/projection/projection.hpp @@ -0,0 +1,4 @@ +#pragma once + +#include "serif/utils/projection/radial.hpp" +#include "serif/backend/mfem/projection/radial.hpp" diff --git a/src/include/serif/utils/projection/radial.hpp b/src/include/serif/utils/projection/radial.hpp new file mode 100644 index 00000000..40824f71 --- /dev/null +++ b/src/include/serif/utils/projection/radial.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace serif::utils::projection { + using RadialValue = std::expected; + + /** @brief A radial profile accepts physical radius and returns a value or a numerical rejection. */ + template + concept RadialFunction = std::invocable && + (std::same_as, double> || + std::same_as, RadialValue>); + + namespace detail { + /** @brief Borrow a profile for one synchronous projection without requiring it to be copyable. */ + template + [[nodiscard]] std::function checked_profile(const Function& function) { + return [&function](const double radius) -> RadialValue { + return std::invoke(function, radius); + }; + } + } +}