docs(domain): added doxygen comments throughout

This commit is contained in:
2026-10-01 15:20:14 -04:00
parent f94f4ee8d6
commit b030d3010f
8 changed files with 189 additions and 22 deletions

View File

@@ -1,23 +1,41 @@
#pragma once #pragma once
/**
* @file boundary.hpp
* @author Emily M. Boudreaux
* @brief This file defines the BoundaryID type, which is used to bind a semantic surface (a Boundary) to the integer boundary attribute MFEM stores in the mesh file.
*
* For example, the following code defines a BoundaryID that associates the StellarSurfaceBoundary with the integer attribute 1 in the mesh file:
*
* \code{.cpp}
* BoundaryID<StellarSurfaceBoundary, 1> stellarSurfaceBoundaryID;
* \endcode
*
* Read this as "boundary elements with attribute 1 are the stellar surface".
*/
#include <string_view> #include <string_view>
#include "serif/discretization/domain/concepts.hpp" #include "serif/discretization/domain/concepts.hpp"
// BoundaryID binds a semantic surface (a Boundary) to the integer boundary
// attribute MFEM stores in the mesh file.
//
// BoundaryID<StellarSurfaceBoundary, 1>
// "boundary elements with attribute 1 are the stellar surface"
namespace serif::discretization::domain::ids { namespace serif::discretization::domain::ids {
/**
* @brief The BoundaryID struct is a compile-time type that associates a semantic boundary (a Boundary) with an integer attribute in the mesh file. This allows the discretization framework to identify which boundary elements in the mesh correspond to which semantic boundaries in the simulation.
* @tparam BoundaryT The semantic boundary type (must satisfy the IsBoundary concept).
* @tparam IdentifierValue The integer attribute value in the mesh file that corresponds to this boundary.
*/
template <IsBoundary BoundaryT, int IdentifierValue> template <IsBoundary BoundaryT, int IdentifierValue>
struct BoundaryID { struct BoundaryID {
using boundary_type = BoundaryT; using boundary_type = BoundaryT; ///< The semantic boundary type associated with this BoundaryID.
static constexpr int ID = IdentifierValue; static constexpr int ID = IdentifierValue; ///< The integer attribute value in the mesh file that corresponds to this boundary.
}; };
/**
* @brief The BoundaryDescriptor struct is a runtime representation of a boundary, containing its name and integer attribute ID. This is used to project compile-time BoundaryID types into runtime values.
*/
struct BoundaryDescriptor { struct BoundaryDescriptor {
std::string_view name; std::string_view name; ///< The name of the boundary, used for runtime identification.
int ID; int ID; ///< The integer attribute value in the mesh file that corresponds to this boundary.
}; };
} }

View File

@@ -1,27 +1,58 @@
#pragma once #pragma once
/**
* @file concepts.hpp
* @author Emily M. Boudreaux
* @brief This file defines concepts for domain and boundary IDs in the discretization framework. These are specifically used to validate that a type is a valid DomainID or BoundaryID.
*/
#include "serif/discretization/domain/ids/boundary.hpp" #include "serif/discretization/domain/ids/boundary.hpp"
#include "serif/discretization/domain/ids/domain.hpp" #include "serif/discretization/domain/ids/domain.hpp"
namespace serif::discretization::domain::ids { namespace serif::discretization::domain::ids {
/**
* @brief Trait to determine if a type is a domain ID. Defaults to false for all types.
* @tparam T The type to check.
*/
template <typename T> template <typename T>
constexpr bool is_domain_id_v = false; constexpr bool is_domain_id_v = false;
/**
* @brief Trait to determine if a type is a domain ID. Specialization which is true for valid DomainID types.
* @tparam T The type to check.
*/
template <IsDomain DomainT, int IdentifierValue> template <IsDomain DomainT, int IdentifierValue>
constexpr bool is_domain_id_v<DomainID<DomainT, IdentifierValue>> = true; constexpr bool is_domain_id_v<DomainID<DomainT, IdentifierValue>> = true;
/**
* @brief Trait to determine if a type is a boundary ID. Defaults to false for all types.
* @tparam T The type to check.
*/
template <typename T> template <typename T>
constexpr bool is_boundary_id_v = false; constexpr bool is_boundary_id_v = false;
/**
* @brief Trait to determine if a type is a boundary ID. Specialization which is true for valid BoundaryID types.
* @tparam T The type to check.
*/
template <IsBoundary BoundaryT, int IdentifierValue> template <IsBoundary BoundaryT, int IdentifierValue>
constexpr bool is_boundary_id_v<BoundaryID<BoundaryT, IdentifierValue>> = true; constexpr bool is_boundary_id_v<BoundaryID<BoundaryT, IdentifierValue>> = true;
/**
* @brief Concept for types that are domain IDs in the discretization framework. To be a domain ID a type must satisfy the is_domain_id_v trait.
*/
template <typename T> template <typename T>
concept IsDomainID = is_domain_id_v<T>; concept IsDomainID = is_domain_id_v<T>;
/**
* @brief Concept for types that are boundary IDs in the discretization framework. To be a boundary ID a type must satisfy the is_boundary_id_v trait.
*/
template <typename T> template <typename T>
concept IsBoundaryID = is_boundary_id_v<T>; concept IsBoundaryID = is_boundary_id_v<T>;
/**
* @brief Concept for types that are either domain IDs or boundary IDs in the discretization framework.
*/
template <typename T> template <typename T>
concept IsDomainOrBoundaryID = IsDomainID<T> || IsBoundaryID<T>; concept IsDomainOrBoundaryID = IsDomainID<T> || IsBoundaryID<T>;
} }

View File

@@ -1,24 +1,42 @@
#pragma once #pragma once
/**
* @file domain.hpp
* @author Emily M. Boudreaux
* @brief This file defines the DomainID type, which is used to bind a semantic volume (a Domain) to the integer element attribute MFEM stores in the mesh file.
*
* For example, the following code defines a DomainID that associates the CoreDomain with the integer attribute 1 in the mesh file:
*
* \code{.cpp}
* DomainID<CoreDomain, 1> coreDomainID;
* \endcode
*
* Read this as "elements with attribute 1 are the core".
*/
#include <string_view> #include <string_view>
#include "serif/discretization/domain/concepts.hpp" #include "serif/discretization/domain/concepts.hpp"
// DomainID binds a semantic volume (a Domain) to the integer element attribute
// MFEM stores in the mesh file. In MFEM's own vocabulary this integer is the
// element "attribute"; in a mesh generator it is usually the "material id".
//
// DomainID<CoreDomain, 1> "elements with attribute 1 are the core"
namespace serif::discretization::domain::ids { namespace serif::discretization::domain::ids {
/**
* @brief The DomainID struct is a compile-time type that associates a semantic domain (a Domain) with an integer attribute in the mesh file. This allows the discretization framework to identify which elements in the mesh correspond to which semantic domains in the simulation.
* @tparam DomainT The semantic domain type (must satisfy the IsDomain concept).
* @tparam IdentifierValue The integer attribute value in the mesh file that corresponds to this domain.
*/
template <IsDomain DomainT, int IdentifierValue> template <IsDomain DomainT, int IdentifierValue>
struct DomainID { struct DomainID {
using domain_type = DomainT; using domain_type = DomainT; ///< The semantic domain type associated with this DomainID.
static constexpr int ID = IdentifierValue; static constexpr int ID = IdentifierValue; ///< The integer attribute value in the mesh file that corresponds to this domain.
}; };
// Runtime-friendly (name, ID) pair, for logging and error messages.
/**
* @brief The DomainDescriptor struct is a runtime representation of a domain, containing its name and integer attribute ID. This is used to project compile-time DomainID types into runtime values.
*/
struct DomainDescriptor { struct DomainDescriptor {
std::string_view name; std::string_view name; ///< The name of the domain, used for runtime identification.
int ID; int ID; ///< The integer attribute value in the mesh file that corresponds to this domain.
}; };
} }

View File

@@ -1,11 +1,23 @@
#pragma once #pragma once
/**
* @file concepts.hpp
* @author Emily M. Boudreaux
* @brief This file defines concepts for domain ID lists in the discretization framework.
*/
#include "serif/discretization/domain/ids/lists/traits.hpp" #include "serif/discretization/domain/ids/lists/traits.hpp"
namespace serif::discretization::domain::ids::lists { namespace serif::discretization::domain::ids::lists {
/**
* @brief Concept for types that are domain ID lists in the discretization framework. To be a domain ID list a type must satisfy the is_domain_id_list_v trait.
*/
template <typename T> template <typename T>
concept IsDomainIDList = is_domain_id_list_v<T>; concept IsDomainIDList = is_domain_id_list_v<T>;
/**
* @brief Concept for types that are boundary ID lists in the discretization framework. To be a boundary ID list a type must satisfy the is_boundary_id_list_v trait.
*/
template <typename T> template <typename T>
concept IsBoundaryIDList = is_boundary_id_list_v<T>; concept IsBoundaryIDList = is_boundary_id_list_v<T>;
} }

View File

@@ -1,4 +1,9 @@
#pragma once #pragma once
/**
* @file lists.hpp
* @author Emily M. Boudreaux
* @brief This file defines the DomainIDList and BoundaryIDList types, specifically these types are used to project down compile time types to runtime values.
*/
#include <array> #include <array>
#include <cstddef> #include <cstddef>
@@ -9,21 +14,35 @@
namespace serif::discretization::domain::ids::lists { namespace serif::discretization::domain::ids::lists {
using utils::misc::std_helper::CountVariadicArguments; using utils::misc::std_helper::CountVariadicArguments;
/**
* @brief A list of domain IDs in the discretization framework.
*/
template <IsDomainID... DomainIDTs> template <IsDomainID... DomainIDTs>
requires validation::AreDistinctDomainIDs<DomainIDTs...> requires validation::AreDistinctDomainIDs<DomainIDTs...>
struct DomainIDList { struct DomainIDList {
static constexpr std::size_t count = CountVariadicArguments<DomainIDTs...>(); static constexpr std::size_t count = CountVariadicArguments<DomainIDTs...>(); ///< The number of domain IDs in the list.
/**
* @brief Get an array of DomainDescriptor objects for the domain IDs in the list.
* @return An array of DomainDescriptor objects, each containing the name and ID of a domain.
*/
[[nodiscard]] static constexpr std::array<DomainDescriptor, count> descriptors() noexcept { [[nodiscard]] static constexpr std::array<DomainDescriptor, count> descriptors() noexcept {
return {DomainDescriptor{.name = DomainIDTs::domain_type::name, .ID = DomainIDTs::ID}...}; return {DomainDescriptor{.name = DomainIDTs::domain_type::name, .ID = DomainIDTs::ID}...};
} }
}; };
/**
* @brief A list of boundary IDs in the discretization framework.
*/
template <IsBoundaryID... BoundaryIDTs> template <IsBoundaryID... BoundaryIDTs>
requires validation::AreDistinctBoundaryIDs<BoundaryIDTs...> requires validation::AreDistinctBoundaryIDs<BoundaryIDTs...>
struct BoundaryIDList { struct BoundaryIDList {
static constexpr std::size_t count = CountVariadicArguments<BoundaryIDTs...>(); static constexpr std::size_t count = CountVariadicArguments<BoundaryIDTs...>(); ///< The number of boundary IDs in the list.
/**
* @brief Get an array of BoundaryDescriptor objects for the boundary IDs in the list.
* @return An array of BoundaryDescriptor objects, each containing the name and ID of a boundary.
*/
[[nodiscard]] static constexpr std::array<BoundaryDescriptor, count> descriptors() noexcept { [[nodiscard]] static constexpr std::array<BoundaryDescriptor, count> descriptors() noexcept {
return {BoundaryDescriptor{.name = BoundaryIDTs::boundary_type::name, .ID = BoundaryIDTs::ID}...}; return {BoundaryDescriptor{.name = BoundaryIDTs::boundary_type::name, .ID = BoundaryIDTs::ID}...};
} }

View File

@@ -1,17 +1,40 @@
#pragma once #pragma once
/**
* @file traits.hpp
* @author Emily M. Boudreaux
* @brief Compile-time traits for domain ID lists, used to extract types and properties from template parameters.
*/
#include "serif/discretization/domain/ids/lists/lists.hpp" #include "serif/discretization/domain/ids/lists/lists.hpp"
namespace serif::discretization::domain::ids::lists { namespace serif::discretization::domain::ids::lists {
/**
* @brief Trait to determine if a type is a domain ID list. Defaults to false for all types.
* @tparam T The type to check.
*/
template <typename T> template <typename T>
constexpr bool is_domain_id_list_v = false; constexpr bool is_domain_id_list_v = false;
/**
* @brief Trait to determine if a type is a boundary ID list. Specialization which is true for valid BoundaryIDList types.
* @tparam T The type to check.
*/
template <IsDomainID... DomainIDTs> template <IsDomainID... DomainIDTs>
constexpr bool is_domain_id_list_v<DomainIDList<DomainIDTs...>> = true; constexpr bool is_domain_id_list_v<DomainIDList<DomainIDTs...>> = true;
/**
* @brief Trait to determine if a type is a boundary ID list. Defaults to false for all types.
* @tparam T The type to check.
*/
template <typename T> template <typename T>
constexpr bool is_boundary_id_list_v = false; constexpr bool is_boundary_id_list_v = false;
/**
* @brief Trait to determine if a type is a boundary ID list. Specialization which is true for valid BoundaryIDList types.
* @tparam T The type to check.
*/
template <IsBoundaryID... BoundaryIDTs> template <IsBoundaryID... BoundaryIDTs>
constexpr bool is_boundary_id_list_v<BoundaryIDList<BoundaryIDTs...>> = true; constexpr bool is_boundary_id_list_v<BoundaryIDList<BoundaryIDTs...>> = true;
} }

View File

@@ -1,5 +1,11 @@
#pragma once #pragma once
/**
* @file concepts.hpp
* @author Emily M. Boudreaux
* @brief This file defines concepts for domain ID lists in the discretization framework. Specifically we define here concepts used to validate traits of a domain.
*/
#include "serif/discretization/domain/ids/concepts.hpp" #include "serif/discretization/domain/ids/concepts.hpp"
#include "serif/discretization/domain/ids/validation/unique_ids.hpp" #include "serif/discretization/domain/ids/validation/unique_ids.hpp"
#include "serif/utils/misc/concepts/type_uniqueness.hpp" #include "serif/utils/misc/concepts/type_uniqueness.hpp"
@@ -8,16 +14,34 @@ namespace serif::discretization::domain::ids::validation {
using utils::misc::concepts::AllTypesAreUnique; using utils::misc::concepts::AllTypesAreUnique;
// --- ID value validation --- // --- ID value validation ---
/**
* @brief Concept to check if a pack of domain IDs have unique ID values. This is used to ensure that no two domain IDs in a list have the same ID.
* @tparam DomainIDTs The pack of domain ID types to check.
*/
template <typename... DomainIDTs> template <typename... DomainIDTs>
concept HaveUniqueDomainIDs = all_unique_values(DomainIDTs::ID...); concept HaveUniqueDomainIDs = all_unique_values(DomainIDTs::ID...);
/**
* @brief Concept to check if a pack of boundary IDs have unique ID values. This is used to ensure that no two boundary IDs in a list have the same ID.
* @tparam BoundaryIDTs The pack of boundary ID types to check.
*/
template <typename... BoundaryIDTs> template <typename... BoundaryIDTs>
concept HaveUniqueBoundaryIDs = all_unique_values(BoundaryIDTs::ID...); concept HaveUniqueBoundaryIDs = all_unique_values(BoundaryIDTs::ID...);
// --- Type validation (Domains & Boundaries) --- // --- Type validation (Domains & Boundaries) ---
/**
* @brief Concept to check if a pack of domain IDs have unique domain types. This is used to ensure that no two domain IDs in a list refer to the same domain type.
* @tparam DomainIDTs The pack of domain ID types to check.
*/
template <typename... DomainIDTs> template <typename... DomainIDTs>
concept HaveUniqueDomains = AllTypesAreUnique<typename DomainIDTs::domain_type...>; concept HaveUniqueDomains = AllTypesAreUnique<typename DomainIDTs::domain_type...>;
/**
* @brief Concept to check if a pack of boundary IDs have unique boundary types. This is used to ensure that no two boundary IDs in a list refer to the same boundary type.
* @tparam BoundaryIDTs The pack of boundary ID types to check.
*/
template <typename... BoundaryIDTs> template <typename... BoundaryIDTs>
concept HaveUniqueBoundaries = AllTypesAreUnique<typename BoundaryIDTs::boundary_type...>; concept HaveUniqueBoundaries = AllTypesAreUnique<typename BoundaryIDTs::boundary_type...>;
@@ -28,12 +52,21 @@ namespace serif::discretization::domain::ids::validation {
// via a requires-clause. Writing them as a template parameter constraint // via a requires-clause. Writing them as a template parameter constraint
// (e.g. template <AreDistinctDomainIDs... Ts>) will apply them to each element // (e.g. template <AreDistinctDomainIDs... Ts>) will apply them to each element
// individually, this checks nothing. // individually, this checks nothing.
/**
* @brief Concept to check if a pack of domain IDs are distinct. This means that each ID is a valid domain ID, no two IDs have the same integer value, and no two IDs refer to the same domain type.
* @tparam DomainIDTs The pack of domain ID types to check.
*/
template <typename... DomainIDTs> template <typename... DomainIDTs>
concept AreDistinctDomainIDs = concept AreDistinctDomainIDs =
(IsDomainID<DomainIDTs> && ...) && // 1. everything in the pack really is a DomainID (IsDomainID<DomainIDTs> && ...) && // 1. everything in the pack really is a DomainID
HaveUniqueDomainIDs<DomainIDTs...> && // 2. no repeated integer attribute HaveUniqueDomainIDs<DomainIDTs...> && // 2. no repeated integer attribute
HaveUniqueDomains<DomainIDTs...>; // 3. no volume tagged twice HaveUniqueDomains<DomainIDTs...>; // 3. no volume tagged twice
/**
* @brief Concept to check if a pack of boundary IDs are distinct. This means that each ID is a valid boundary ID, no two IDs have the same integer value, and no two IDs refer to the same boundary type.
* @tparam BoundaryIDTs The pack of boundary ID types to check.
*/
template <typename... BoundaryIDTs> template <typename... BoundaryIDTs>
concept AreDistinctBoundaryIDs = concept AreDistinctBoundaryIDs =
(IsBoundaryID<BoundaryIDTs> && ...) && // 1. everything in the pack really is a BoundaryID (IsBoundaryID<BoundaryIDTs> && ...) && // 1. everything in the pack really is a BoundaryID

View File

@@ -1,5 +1,11 @@
#pragma once #pragma once
/**
* @file unique_ids.hpp
* @author Emily M. Boudreaux
* @brief This file defines a utility function to check if a pack of values are all unique. This is used to validate that domain and boundary IDs are distinct.
*/
#include <array> #include <array>
#include <concepts> #include <concepts>
#include <type_traits> #include <type_traits>
@@ -7,7 +13,14 @@
#include "serif/utils/misc/std_helper/variadic_cleaning.hpp" #include "serif/utils/misc/std_helper/variadic_cleaning.hpp"
namespace serif::discretization::domain::ids::validation { namespace serif::discretization::domain::ids::validation {
// Returns true when every value handed to it is distinct. /**
* @brief Utility function to check if a pack of values are all unique.
* @tparam Ts The types of the values to check.
* @param values The values to check for uniqueness.
* @return true if all values are unique, false otherwise.
*
* @todo Really this should probably be refactored into the utils module since this is not super specific to domainIDs.
*/
template <typename... Ts> template <typename... Ts>
requires (std::equality_comparable<Ts> && ...) requires (std::equality_comparable<Ts> && ...)
[[nodiscard]] consteval bool all_unique_values(Ts... values) noexcept { [[nodiscard]] consteval bool all_unique_values(Ts... values) noexcept {