diff --git a/src/include/serif/discretization/domain/ids/boundary.hpp b/src/include/serif/discretization/domain/ids/boundary.hpp index e312f95a..ec4fbd1a 100644 --- a/src/include/serif/discretization/domain/ids/boundary.hpp +++ b/src/include/serif/discretization/domain/ids/boundary.hpp @@ -1,23 +1,41 @@ #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 stellarSurfaceBoundaryID; + * \endcode + * + * Read this as "boundary elements with attribute 1 are the stellar surface". + */ + #include #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 -// "boundary elements with attribute 1 are the stellar surface" 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 struct BoundaryID { - using boundary_type = BoundaryT; - static constexpr int ID = IdentifierValue; + using boundary_type = BoundaryT; ///< The semantic boundary type associated with this BoundaryID. + 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 { - std::string_view name; - int ID; + std::string_view name; ///< The name of the boundary, used for runtime identification. + int ID; ///< The integer attribute value in the mesh file that corresponds to this boundary. }; } diff --git a/src/include/serif/discretization/domain/ids/concepts.hpp b/src/include/serif/discretization/domain/ids/concepts.hpp index a0f16d43..67a0fdb6 100644 --- a/src/include/serif/discretization/domain/ids/concepts.hpp +++ b/src/include/serif/discretization/domain/ids/concepts.hpp @@ -1,27 +1,58 @@ #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/domain.hpp" 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 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 constexpr bool is_domain_id_v> = 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 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 constexpr bool is_boundary_id_v> = 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 concept IsDomainID = is_domain_id_v; + /** + * @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 concept IsBoundaryID = is_boundary_id_v; + /** + * @brief Concept for types that are either domain IDs or boundary IDs in the discretization framework. + */ template concept IsDomainOrBoundaryID = IsDomainID || IsBoundaryID; } diff --git a/src/include/serif/discretization/domain/ids/domain.hpp b/src/include/serif/discretization/domain/ids/domain.hpp index 679a8872..53171635 100644 --- a/src/include/serif/discretization/domain/ids/domain.hpp +++ b/src/include/serif/discretization/domain/ids/domain.hpp @@ -1,24 +1,42 @@ #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 coreDomainID; + * \endcode + * + * Read this as "elements with attribute 1 are the core". + */ + #include #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 "elements with attribute 1 are the core" 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 struct DomainID { - using domain_type = DomainT; - static constexpr int ID = IdentifierValue; + using domain_type = DomainT; ///< The semantic domain type associated with this DomainID. + 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 { - std::string_view name; - int ID; + std::string_view name; ///< The name of the domain, used for runtime identification. + int ID; ///< The integer attribute value in the mesh file that corresponds to this domain. }; } diff --git a/src/include/serif/discretization/domain/ids/lists/concepts.hpp b/src/include/serif/discretization/domain/ids/lists/concepts.hpp index 900108f6..7cb2612d 100644 --- a/src/include/serif/discretization/domain/ids/lists/concepts.hpp +++ b/src/include/serif/discretization/domain/ids/lists/concepts.hpp @@ -1,11 +1,23 @@ #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" 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 concept IsDomainIDList = is_domain_id_list_v; + /** + * @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 concept IsBoundaryIDList = is_boundary_id_list_v; } diff --git a/src/include/serif/discretization/domain/ids/lists/lists.hpp b/src/include/serif/discretization/domain/ids/lists/lists.hpp index f7c858cc..30788d5d 100644 --- a/src/include/serif/discretization/domain/ids/lists/lists.hpp +++ b/src/include/serif/discretization/domain/ids/lists/lists.hpp @@ -1,4 +1,9 @@ #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 #include @@ -9,21 +14,35 @@ namespace serif::discretization::domain::ids::lists { using utils::misc::std_helper::CountVariadicArguments; + /** + * @brief A list of domain IDs in the discretization framework. + */ template requires validation::AreDistinctDomainIDs struct DomainIDList { - static constexpr std::size_t count = CountVariadicArguments(); + static constexpr std::size_t count = CountVariadicArguments(); ///< 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 descriptors() noexcept { return {DomainDescriptor{.name = DomainIDTs::domain_type::name, .ID = DomainIDTs::ID}...}; } }; + /** + * @brief A list of boundary IDs in the discretization framework. + */ template requires validation::AreDistinctBoundaryIDs struct BoundaryIDList { - static constexpr std::size_t count = CountVariadicArguments(); + static constexpr std::size_t count = CountVariadicArguments(); ///< 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 descriptors() noexcept { return {BoundaryDescriptor{.name = BoundaryIDTs::boundary_type::name, .ID = BoundaryIDTs::ID}...}; } diff --git a/src/include/serif/discretization/domain/ids/lists/traits.hpp b/src/include/serif/discretization/domain/ids/lists/traits.hpp index 2c14f5b5..f214a524 100644 --- a/src/include/serif/discretization/domain/ids/lists/traits.hpp +++ b/src/include/serif/discretization/domain/ids/lists/traits.hpp @@ -1,17 +1,40 @@ #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" 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 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 constexpr bool is_domain_id_list_v> = 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 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 constexpr bool is_boundary_id_list_v> = true; } diff --git a/src/include/serif/discretization/domain/ids/validation/concepts.hpp b/src/include/serif/discretization/domain/ids/validation/concepts.hpp index ba428c58..eff7cb67 100644 --- a/src/include/serif/discretization/domain/ids/validation/concepts.hpp +++ b/src/include/serif/discretization/domain/ids/validation/concepts.hpp @@ -1,5 +1,11 @@ #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/validation/unique_ids.hpp" #include "serif/utils/misc/concepts/type_uniqueness.hpp" @@ -8,16 +14,34 @@ namespace serif::discretization::domain::ids::validation { using utils::misc::concepts::AllTypesAreUnique; // --- 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 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 concept HaveUniqueBoundaryIDs = all_unique_values(BoundaryIDTs::ID...); // --- 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 concept HaveUniqueDomains = AllTypesAreUnique; + /** + * @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 concept HaveUniqueBoundaries = AllTypesAreUnique; @@ -28,12 +52,21 @@ namespace serif::discretization::domain::ids::validation { // via a requires-clause. Writing them as a template parameter constraint // (e.g. template ) will apply them to each element // 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 concept AreDistinctDomainIDs = (IsDomainID && ...) && // 1. everything in the pack really is a DomainID HaveUniqueDomainIDs && // 2. no repeated integer attribute HaveUniqueDomains; // 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 concept AreDistinctBoundaryIDs = (IsBoundaryID && ...) && // 1. everything in the pack really is a BoundaryID diff --git a/src/include/serif/discretization/domain/ids/validation/unique_ids.hpp b/src/include/serif/discretization/domain/ids/validation/unique_ids.hpp index fefe504c..fa78fffa 100644 --- a/src/include/serif/discretization/domain/ids/validation/unique_ids.hpp +++ b/src/include/serif/discretization/domain/ids/validation/unique_ids.hpp @@ -1,5 +1,11 @@ #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 #include #include @@ -7,7 +13,14 @@ #include "serif/utils/misc/std_helper/variadic_cleaning.hpp" 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 requires (std::equality_comparable && ...) [[nodiscard]] consteval bool all_unique_values(Ts... values) noexcept {