docs(functional_space): added doxygen comments throughout
This commit is contained in:
@@ -1,61 +1,104 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file space.hpp
|
||||
* @author Emily M. Boudreaux
|
||||
* @brief This file defines the functional space types used in the discretization framework, including compile-time descriptors and runtime descriptors.
|
||||
*/
|
||||
|
||||
#include <type_traits>
|
||||
#include <format>
|
||||
|
||||
#include "serif/meta/enums.hpp"
|
||||
|
||||
namespace serif::discretization::functional_space {
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for the rank of a functional space.
|
||||
* @tparam R The rank of the functional space.
|
||||
*/
|
||||
template <std::size_t R>
|
||||
struct Rank {
|
||||
constexpr static std::size_t value = R;
|
||||
constexpr static std::size_t value = R; ///< The rank of the functional space.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for the family, continuity, trace, and mapping of a functional space.
|
||||
*
|
||||
* @note These are almost all of the functional spaces that MFEM supports, if in the future MFEM adds some other space and
|
||||
* you wish to extend SERiF to support it (or you introduce some non MFEM backend with another space) then one early
|
||||
* place you will need to modify is this enum.
|
||||
*
|
||||
* @note We do not support mfem::ceed::ParAlgebraicCoarseSpace
|
||||
*/
|
||||
enum class Family {
|
||||
l2,
|
||||
h1,
|
||||
hdiv,
|
||||
hcurl
|
||||
l2, ///< L2 space, typically used for discontinuous functions.
|
||||
h1, ///< H1 space, typically used for continuous functions.
|
||||
hdiv, ///< H(div) space, typically used for vector fields with normal continuity.
|
||||
hcurl ///< H(curl) space, typically used for vector fields with tangential continuity.
|
||||
};
|
||||
|
||||
inline static auto Family2StringMap = meta::enum_to_enum_string_map<Family>();
|
||||
inline static auto String2FamilyMap = meta::enum_to_string_enum_map<Family>();
|
||||
inline static auto Family2StringMap = meta::enum_to_enum_string_map<Family>(); ///< Mapping from Family enum values to their string representations.
|
||||
inline static auto String2FamilyMap = meta::enum_to_string_enum_map<Family>(); ///< Mapping from string representations to Family enum values.
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for the continuity of a functional space. This enum is parallel to the @ref Family enum.
|
||||
*
|
||||
* @todo There may be a better way to store these relations that forces them to be parallel rather than just relying on the programmer to keep them in sync.
|
||||
*/
|
||||
enum class Continuity {
|
||||
discontinuous,
|
||||
continuous,
|
||||
normal_continuous,
|
||||
tangential_continuous
|
||||
discontinuous, ///< Discontinuous functions, typically used for L2 spaces.
|
||||
continuous, ///< C0 continuous functions, typically used for H1 spaces.
|
||||
normal_continuous, ///< Functions with normal continuity, typically used for H(div) spaces.
|
||||
tangential_continuous ///< Functions with tangential continuity, typically used for H(curl) spaces.
|
||||
};
|
||||
|
||||
inline static auto Continuity2StringMap = meta::enum_to_enum_string_map<Continuity>();
|
||||
inline static auto String2ContinuityMap = meta::enum_to_string_enum_map<Continuity>();
|
||||
inline static auto Continuity2StringMap = meta::enum_to_enum_string_map<Continuity>(); ///< Mapping from Continuity enum values to their string representations.
|
||||
inline static auto String2ContinuityMap = meta::enum_to_string_enum_map<Continuity>(); ///< Mapping from string representations to Continuity enum values.
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for the trace of a functional space. This enum is parallel to the @ref Family enum.
|
||||
*/
|
||||
enum class Trace {
|
||||
none,
|
||||
value,
|
||||
normal,
|
||||
tangential
|
||||
none, ///< No trace, typically used for L2 spaces.
|
||||
value, ///< Value trace, typically used for H1 spaces.
|
||||
normal, ///< Normal trace, typically used for H(div) spaces.
|
||||
tangential ///< Tangential trace, typically used for H(curl) spaces.
|
||||
};
|
||||
|
||||
inline static auto Trace2StringMap = meta::enum_to_enum_string_map<Trace>();
|
||||
inline static auto String2TraceMap = meta::enum_to_string_enum_map<Trace>();
|
||||
inline static auto Trace2StringMap = meta::enum_to_enum_string_map<Trace>(); ///< Mapping from Trace enum values to their string representations.
|
||||
inline static auto String2TraceMap = meta::enum_to_string_enum_map<Trace>(); ///< Mapping from string representations to Trace enum values.
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for the mapping of a functional space. This tells the DomainMapper which piola transformations to use when moving between reference and physical spaces.
|
||||
*/
|
||||
enum class Mapping {
|
||||
identity,
|
||||
contravariant_piola,
|
||||
covariant_piola
|
||||
identity, ///< Identity mapping, typically used for L2 and H1 spaces.
|
||||
contravariant_piola, ///< Contravariant Piola mapping, preserving the normal trace, typically used for H(div) spaces. (\f$ \frac{1}{\text{det(J)}}J\hat{\phi}(F^{-1}(x)) \f$ transforming some vector field \f$\phi(x)\f$ for some transformation \f$ F \f$ with Jacobian \f$ J \f$)
|
||||
covariant_piola ///< Covariant Piola mapping, preserving the tangential trace, typically used for H(curl) spaces. (\f$ J^{-T}\hat{\phi}(F^{-1}(x)) \f$ transforming some vector field \f$\phi(x)\f$ for some transformation \f$ F \f$ with Jacobian \f$ J \f$)
|
||||
};
|
||||
|
||||
inline static auto Mapping2StringMap = meta::enum_to_enum_string_map<Mapping>();
|
||||
inline static auto String2MappingMap = meta::enum_to_string_enum_map<Mapping>();
|
||||
inline static auto Mapping2StringMap = meta::enum_to_enum_string_map<Mapping>(); ///< Mapping from Mapping enum values to their string representations.
|
||||
inline static auto String2MappingMap = meta::enum_to_string_enum_map<Mapping>(); ///< Mapping from string representations to Mapping enum values.
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for a functional space. This struct is used to describe the family, continuity, trace, and mapping of a functional space at compile time.
|
||||
*/
|
||||
struct SpaceDescriptor final {
|
||||
const Family family;
|
||||
const Continuity continuity;
|
||||
const Trace trace;
|
||||
const Mapping mapping;
|
||||
const Family family; ///< The family of the functional space (e.g. L2, H1, H(div), H(curl)).
|
||||
const Continuity continuity; ///< The continuity of the functional space (e.g. discontinuous, continuous, normal continuous, tangential continuous).
|
||||
const Trace trace; ///< The trace of the functional space (e.g. none, value, normal, tangential).
|
||||
const Mapping mapping; ///< The mapping of the functional space (e.g. identity, contravariant_piola, covariant_piola).
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for an L2 functional space. This is a convenience descriptor that allows you to easily create an L2 functional space descriptor without having to specify all the parameters.
|
||||
* The specifications are
|
||||
* - family = Family::l2
|
||||
* - continuity = Continuity::discontinuous
|
||||
* - trace = Trace::none
|
||||
* - mapping = Mapping::identity
|
||||
*/
|
||||
inline static constexpr SpaceDescriptor L2{
|
||||
.family = Family::l2,
|
||||
.continuity = Continuity::discontinuous,
|
||||
@@ -63,6 +106,14 @@ namespace serif::discretization::functional_space {
|
||||
.mapping = Mapping::identity
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for an H1 functional space. This is a convenience descriptor that allows you to easily create an H1 functional space descriptor without having to specify all the parameters.
|
||||
* The specifications are
|
||||
* - family = Family::h1
|
||||
* - continuity = Continuity::continuous
|
||||
* - trace = Trace::value
|
||||
* - mapping = Mapping::identity
|
||||
*/
|
||||
inline static constexpr SpaceDescriptor H1{
|
||||
.family = Family::h1,
|
||||
.continuity = Continuity::continuous,
|
||||
@@ -70,6 +121,14 @@ namespace serif::discretization::functional_space {
|
||||
.mapping = Mapping::identity
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for an H(div) functional space. This is a convenience descriptor that allows you to easily create an H(div) functional space descriptor without having to specify all the parameters.
|
||||
* The specifications are
|
||||
* - family = Family::hdiv
|
||||
* - continuity = Continuity::normal_continuous
|
||||
* - trace = Trace::normal
|
||||
* - mapping = Mapping::contravariant_piola
|
||||
*/
|
||||
inline static constexpr SpaceDescriptor Hdiv{
|
||||
.family = Family::hdiv,
|
||||
.continuity = Continuity::normal_continuous,
|
||||
@@ -77,6 +136,14 @@ namespace serif::discretization::functional_space {
|
||||
.mapping = Mapping::contravariant_piola
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for an H(curl) functional space. This is a convenience descriptor that allows you to easily create an H(curl) functional space descriptor without having to specify all the parameters.
|
||||
* The specifications are
|
||||
* - family = Family::hcurl
|
||||
* - continuity = Continuity::tangential_continuous
|
||||
* - trace = Trace::tangential
|
||||
* - mapping = Mapping::covariant_piola
|
||||
*/
|
||||
inline static constexpr SpaceDescriptor Hcurl{
|
||||
.family = Family::hcurl,
|
||||
.continuity = Continuity::tangential_continuous,
|
||||
@@ -84,17 +151,35 @@ namespace serif::discretization::functional_space {
|
||||
.mapping = Mapping::covariant_piola
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Concept to validate a valid space descriptor. A space descriptor is valid if it is of type SpaceDescriptor. This is a very simple concept that just checks that the type is exactly SpaceDescriptor.
|
||||
*/
|
||||
template <typename SpaceDescriptorCandidate>
|
||||
concept IsSpaceDescriptor = std::is_same_v<SpaceDescriptor, SpaceDescriptorCandidate>;
|
||||
|
||||
/**
|
||||
* @brief Compile-time descriptor for a discrete functional space. The difference between a FunctionalSpace and a discrete functional space is that
|
||||
* a discrete functional space carries some additional information which is needed to actually construct a finite element space (e.g. polynomial order, and rank).
|
||||
* Once you have a discrete functional space you have, for MFEM at least, enough information to fully define a finite element space.
|
||||
*
|
||||
* @tparam Space The functional space descriptor (e.g. L2, H1, H(div), H(curl)).
|
||||
* @tparam Order The order of the finite element family (e.g. 0 for P0, 1 for P1, etc.).
|
||||
* @tparam R The rank of the functional space (e.g. 0 for scalar, 1 for vector, 2 for tensor).
|
||||
*/
|
||||
template <SpaceDescriptor Space, int Order, std::size_t R>
|
||||
struct DiscreteFunctionalSpace {
|
||||
static_assert(Order >= 0, "Finite-element family order must be non-negative.");
|
||||
static_assert((Space.family != Family::hdiv && Space.family != Family::hcurl) || R == 1, "H(div) and H(curl) spaces must be vector-valued.");
|
||||
|
||||
static constexpr SpaceDescriptor functional_space = Space;
|
||||
static constexpr int order = Order;
|
||||
using rank = Rank<R>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the functional space types. This allows us to use std::format to format the functional space types as strings.
|
||||
*/
|
||||
template <std::size_t R>
|
||||
struct std::formatter<serif::discretization::functional_space::Rank<R>> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
@@ -109,6 +194,9 @@ struct std::formatter<serif::discretization::functional_space::Rank<R>> : std::f
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the SpaceDescriptor types. This allows us to use std::format to format the SpaceDescriptor types as strings.
|
||||
*/
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::functional_space::SpaceDescriptor> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
@@ -121,6 +209,9 @@ struct std::formatter<serif::discretization::functional_space::SpaceDescriptor>
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the DiscreteFunctionalSpace types. This allows us to use std::format to format the DiscreteFunctionalSpace types as strings.
|
||||
*/
|
||||
// formatter for DiscreteFunctionalSpace
|
||||
template <serif::discretization::functional_space::SpaceDescriptor Space, int Order, std::size_t R>
|
||||
struct std::formatter<serif::discretization::functional_space::DiscreteFunctionalSpace<Space, Order, R>> : std::formatter<std::string> {
|
||||
@@ -129,11 +220,13 @@ struct std::formatter<serif::discretization::functional_space::DiscreteFunctiona
|
||||
return std::formatter<std::string>::format(std::format("DiscreteFunctionalSpace(functional_space={}, order={}, rank={})",
|
||||
space.functional_space,
|
||||
space.order,
|
||||
space.rank), ctx);
|
||||
serif::discretization::functional_space::Rank<R>{}), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
// formatter for each enum
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the Family enum. This allows us to use std::format to format the Family enum as strings.
|
||||
*/
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::functional_space::Family> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
@@ -142,6 +235,9 @@ struct std::formatter<serif::discretization::functional_space::Family> : std::fo
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the Continuity enum. This allows us to use std::format to format the Continuity enum as strings.
|
||||
*/
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::functional_space::Continuity> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
@@ -150,6 +246,9 @@ struct std::formatter<serif::discretization::functional_space::Continuity> : std
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the Trace enum. This allows us to use std::format to format the Trace enum as strings.
|
||||
*/
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::functional_space::Trace> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
@@ -158,6 +257,9 @@ struct std::formatter<serif::discretization::functional_space::Trace> : std::for
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specialization of the std::formatter for the Mapping enum. This allows us to use std::format to format the Mapping enum as strings.
|
||||
*/
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::functional_space::Mapping> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
|
||||
Reference in New Issue
Block a user