feat(field-support): added field support system, mid migration
currently the barotope and the pressure force operator are migrated to the new support system
This commit is contained in:
@@ -6,6 +6,7 @@ module;
|
||||
#include <type_traits>
|
||||
|
||||
export module mean_field:field.base;
|
||||
export import :utils.domain;
|
||||
|
||||
export namespace mean_field::field {
|
||||
template <typename... Ts> struct TypeList { };
|
||||
@@ -13,11 +14,9 @@ export namespace mean_field::field {
|
||||
template <typename T, typename ListT> struct TypeListContains;
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TypeListContains<T, TypeList<Ts...>>
|
||||
: std::bool_constant<(std::same_as<T, Ts> || ...)> { };
|
||||
struct TypeListContains<T, TypeList<Ts...>> : std::bool_constant<(std::same_as<T, Ts> || ...)> { };
|
||||
|
||||
template <typename T, typename ListT>
|
||||
inline constexpr bool typeListContains = TypeListContains<T, ListT>::value;
|
||||
template <typename T, typename ListT> inline constexpr bool typeListContains = TypeListContains<T, ListT>::value;
|
||||
|
||||
enum class StorageKind { finite_element, global_scalar };
|
||||
|
||||
@@ -44,14 +43,13 @@ export namespace mean_field::field {
|
||||
};
|
||||
|
||||
template <typename SpaceT>
|
||||
concept SpaceTag = std::same_as<SpaceT, L2> || std::same_as<SpaceT, H1> ||
|
||||
std::same_as<SpaceT, RT> || std::same_as<SpaceT, ND>;
|
||||
concept SpaceTag =
|
||||
std::same_as<SpaceT, L2> || std::same_as<SpaceT, H1> || std::same_as<SpaceT, RT> || std::same_as<SpaceT, ND>;
|
||||
|
||||
template <SpaceTag SpaceT, int RankV>
|
||||
inline constexpr bool spaceSupportsRank =
|
||||
(std::same_as<SpaceT, H1> && (RankV == 0 || RankV == 1)) ||
|
||||
(std::same_as<SpaceT, L2> && (RankV == 0 || RankV == 1)) ||
|
||||
(std::same_as<SpaceT, RT> && RankV == 1) ||
|
||||
(std::same_as<SpaceT, L2> && (RankV == 0 || RankV == 1)) || (std::same_as<SpaceT, RT> && RankV == 1) ||
|
||||
(std::same_as<SpaceT, ND> && RankV == 1);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -105,51 +103,39 @@ export namespace mean_field::field {
|
||||
|
||||
template <typename T> struct IsCurl : std::false_type { };
|
||||
|
||||
template <typename SourceT>
|
||||
struct IsGradient<FieldRelation::Gradient<SourceT>> : std::true_type { };
|
||||
template <typename SourceT> struct IsGradient<FieldRelation::Gradient<SourceT>> : std::true_type { };
|
||||
|
||||
template <typename SourceT>
|
||||
struct IsDivergence<FieldRelation::Divergence<SourceT>> : std::true_type {
|
||||
};
|
||||
template <typename SourceT> struct IsDivergence<FieldRelation::Divergence<SourceT>> : std::true_type { };
|
||||
|
||||
template <typename SourceT>
|
||||
struct IsCurl<FieldRelation::Curl<SourceT>> : std::true_type { };
|
||||
template <typename SourceT> struct IsCurl<FieldRelation::Curl<SourceT>> : std::true_type { };
|
||||
|
||||
template <typename RelationT>
|
||||
concept ValidRelation =
|
||||
std::same_as<RelationT, FieldRelation::Independent> ||
|
||||
IsGradient<RelationT>::value || IsDivergence<RelationT>::value ||
|
||||
IsCurl<RelationT>::value;
|
||||
concept ValidRelation = std::same_as<RelationT, FieldRelation::Independent> || IsGradient<RelationT>::value ||
|
||||
IsDivergence<RelationT>::value || IsCurl<RelationT>::value;
|
||||
|
||||
template <typename RelationT> struct RelationTarget {
|
||||
using Type = void;
|
||||
};
|
||||
|
||||
template <typename SourceT>
|
||||
struct RelationTarget<FieldRelation::Gradient<SourceT>> {
|
||||
template <typename SourceT> struct RelationTarget<FieldRelation::Gradient<SourceT>> {
|
||||
using Type = SourceT;
|
||||
};
|
||||
|
||||
template <typename SourceT>
|
||||
struct RelationTarget<FieldRelation::Divergence<SourceT>> {
|
||||
template <typename SourceT> struct RelationTarget<FieldRelation::Divergence<SourceT>> {
|
||||
using Type = SourceT;
|
||||
};
|
||||
|
||||
template <typename SourceT>
|
||||
struct RelationTarget<FieldRelation::Curl<SourceT>> {
|
||||
template <typename SourceT> struct RelationTarget<FieldRelation::Curl<SourceT>> {
|
||||
using Type = SourceT;
|
||||
};
|
||||
|
||||
template <typename QuantityT>
|
||||
using RelationTargetT =
|
||||
typename RelationTarget<typename QuantityT::Relation>::Type;
|
||||
template <typename QuantityT> using RelationTargetT = typename RelationTarget<typename QuantityT::Relation>::Type;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Field quantities
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
template <int RankV, ValidRelation RelationT, DiscretizationTag DiscT>
|
||||
struct Quantity {
|
||||
template <int RankV, ValidRelation RelationT, DiscretizationTag DiscT> struct Quantity {
|
||||
using Relation = RelationT;
|
||||
using Discretization = DiscT;
|
||||
using Space = typename DiscT::Space;
|
||||
@@ -173,11 +159,9 @@ export namespace mean_field::field {
|
||||
);
|
||||
};
|
||||
|
||||
template <ValidRelation RelationT, DiscretizationTag DiscT>
|
||||
using ScalarQ = Quantity<0, RelationT, DiscT>;
|
||||
template <ValidRelation RelationT, DiscretizationTag DiscT> using ScalarQ = Quantity<0, RelationT, DiscT>;
|
||||
|
||||
template <ValidRelation RelationT, DiscretizationTag DiscT>
|
||||
using VectorQ = Quantity<1, RelationT, DiscT>;
|
||||
template <ValidRelation RelationT, DiscretizationTag DiscT> using VectorQ = Quantity<1, RelationT, DiscT>;
|
||||
|
||||
struct GlobalScalarQ {
|
||||
using Relation = FieldRelation::Independent;
|
||||
@@ -188,73 +172,57 @@ export namespace mean_field::field {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept FieldQuantity =
|
||||
requires {
|
||||
typename T::Relation;
|
||||
typename T::Discretization;
|
||||
typename T::Space;
|
||||
concept FieldQuantity = requires {
|
||||
typename T::Relation;
|
||||
typename T::Discretization;
|
||||
typename T::Space;
|
||||
|
||||
{ T::rankValue } -> std::convertible_to<int>;
|
||||
{ T::familyOrder } -> std::convertible_to<int>;
|
||||
{ T::storageKind } -> std::convertible_to<StorageKind>;
|
||||
{ T::staticBlockSize } -> std::convertible_to<int>;
|
||||
} && SpaceTag<typename T::Space> &&
|
||||
T::storageKind == StorageKind::finite_element;
|
||||
{ T::rankValue } -> std::convertible_to<int>;
|
||||
{ T::familyOrder } -> std::convertible_to<int>;
|
||||
{ T::storageKind } -> std::convertible_to<StorageKind>;
|
||||
{ T::staticBlockSize } -> std::convertible_to<int>;
|
||||
} && SpaceTag<typename T::Space> && T::storageKind == StorageKind::finite_element;
|
||||
|
||||
template <typename T>
|
||||
concept GlobalScalarQuantity =
|
||||
requires {
|
||||
typename T::Relation;
|
||||
concept GlobalScalarQuantity = requires {
|
||||
typename T::Relation;
|
||||
|
||||
{ T::rankValue } -> std::convertible_to<int>;
|
||||
{ T::storageKind } -> std::convertible_to<StorageKind>;
|
||||
{ T::staticBlockSize } -> std::convertible_to<int>;
|
||||
} && T::rankValue == 0 &&
|
||||
T::storageKind == StorageKind::global_scalar && T::staticBlockSize == 1;
|
||||
{ T::rankValue } -> std::convertible_to<int>;
|
||||
{ T::storageKind } -> std::convertible_to<StorageKind>;
|
||||
{ T::staticBlockSize } -> std::convertible_to<int>;
|
||||
} && T::rankValue == 0 && T::storageKind == StorageKind::global_scalar && T::staticBlockSize == 1;
|
||||
|
||||
template <typename T>
|
||||
concept RegisteredQuantity = FieldQuantity<T> || GlobalScalarQuantity<T>;
|
||||
|
||||
template <typename QuantityT>
|
||||
concept DerivedQuantity = FieldQuantity<QuantityT> &&
|
||||
(!std::same_as<RelationTargetT<QuantityT>, void>);
|
||||
concept DerivedQuantity = FieldQuantity<QuantityT> && (!std::same_as<RelationTargetT<QuantityT>, void>);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Compile-time discretization constraints
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
template <FieldQuantity FluxT, FieldQuantity PotentialT>
|
||||
struct RtL2StablePair {
|
||||
template <FieldQuantity FluxT, FieldQuantity PotentialT> struct RtL2StablePair {
|
||||
static consteval void validate() {
|
||||
static_assert(
|
||||
std::same_as<typename FluxT::Space, RT>,
|
||||
"The flux in an RT/L2 pair must use Raviart-Thomas elements."
|
||||
std::same_as<typename FluxT::Space, RT>, "The flux in an RT/L2 pair must use Raviart-Thomas elements."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
std::same_as<typename PotentialT::Space, L2>,
|
||||
"The potential in an RT/L2 pair must use L2 elements."
|
||||
std::same_as<typename PotentialT::Space, L2>, "The potential in an RT/L2 pair must use L2 elements."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
FluxT::rankValue == 1,
|
||||
"The flux in an RT/L2 pair must be vector-valued."
|
||||
);
|
||||
static_assert(FluxT::rankValue == 1, "The flux in an RT/L2 pair must be vector-valued.");
|
||||
|
||||
static_assert(PotentialT::rankValue == 0, "The potential in an RT/L2 pair must be scalar-valued.");
|
||||
|
||||
static_assert(
|
||||
PotentialT::rankValue == 0,
|
||||
"The potential in an RT/L2 pair must be scalar-valued."
|
||||
);
|
||||
|
||||
static_assert(
|
||||
FluxT::familyOrder == PotentialT::familyOrder,
|
||||
"The MFEM RT and L2 family orders must match."
|
||||
FluxT::familyOrder == PotentialT::familyOrder, "The MFEM RT and L2 family orders must match."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... ConstraintTs>
|
||||
consteval bool validate_constraints(TypeList<ConstraintTs...>) {
|
||||
template <typename... ConstraintTs> consteval bool validate_constraints(TypeList<ConstraintTs...>) {
|
||||
(ConstraintTs::validate(), ...);
|
||||
return true;
|
||||
}
|
||||
@@ -276,16 +244,11 @@ export namespace mean_field::field {
|
||||
|
||||
template <typename OperationT>
|
||||
concept FieldOperationTag =
|
||||
std::same_as<OperationT, FieldOperation::Value> ||
|
||||
std::same_as<OperationT, FieldOperation::Gradient> ||
|
||||
std::same_as<OperationT, FieldOperation::Divergence> ||
|
||||
std::same_as<OperationT, FieldOperation::Curl> ||
|
||||
std::same_as<OperationT, FieldOperation::Value> || std::same_as<OperationT, FieldOperation::Gradient> ||
|
||||
std::same_as<OperationT, FieldOperation::Divergence> || std::same_as<OperationT, FieldOperation::Curl> ||
|
||||
std::same_as<OperationT, FieldOperation::NormalTrace>;
|
||||
|
||||
template <
|
||||
RegisteredQuantity QuantityT,
|
||||
FieldOperationTag OperationT = FieldOperation::Value>
|
||||
struct Operand {
|
||||
template <RegisteredQuantity QuantityT, FieldOperationTag OperationT = FieldOperation::Value> struct Operand {
|
||||
using Quantity = QuantityT;
|
||||
using Operation = OperationT;
|
||||
|
||||
@@ -298,12 +261,10 @@ export namespace mean_field::field {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept FieldOperand =
|
||||
requires {
|
||||
typename T::Quantity;
|
||||
typename T::Operation;
|
||||
} && RegisteredQuantity<typename T::Quantity> &&
|
||||
FieldOperationTag<typename T::Operation>;
|
||||
concept FieldOperand = requires {
|
||||
typename T::Quantity;
|
||||
typename T::Operation;
|
||||
} && RegisteredQuantity<typename T::Quantity> && FieldOperationTag<typename T::Operation>;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Weak-form descriptions
|
||||
@@ -315,11 +276,7 @@ export namespace mean_field::field {
|
||||
// coefficient supplied at runtime contributes one dynamic order.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
auto PolicyKeyV,
|
||||
std::size_t DynamicOrderCountV,
|
||||
FieldOperand... OperandTs>
|
||||
struct FormSpec {
|
||||
template <auto PolicyKeyV, std::size_t DynamicOrderCountV, FieldOperand... OperandTs> struct FormSpec {
|
||||
static constexpr auto policyKey = PolicyKeyV;
|
||||
static constexpr std::size_t dynamicOrderCount = DynamicOrderCountV;
|
||||
|
||||
@@ -335,22 +292,46 @@ export namespace mean_field::field {
|
||||
{ T::dynamicOrderCount } -> std::convertible_to<std::size_t>;
|
||||
};
|
||||
|
||||
template <typename ListT>
|
||||
struct IsRegisteredQuantityList : std::false_type { };
|
||||
template <typename ListT> struct IsRegisteredQuantityList : std::false_type { };
|
||||
|
||||
template <RegisteredQuantity... QuantityTs>
|
||||
struct IsRegisteredQuantityList<TypeList<QuantityTs...>> : std::true_type {
|
||||
};
|
||||
struct IsRegisteredQuantityList<TypeList<QuantityTs...>> : std::true_type { };
|
||||
|
||||
template <typename ListT>
|
||||
inline constexpr bool isRegisteredQuantityList =
|
||||
IsRegisteredQuantityList<ListT>::value;
|
||||
template <typename ListT> inline constexpr bool isRegisteredQuantityList = IsRegisteredQuantityList<ListT>::value;
|
||||
|
||||
template <typename ListT> struct IsFieldFormList : std::false_type { };
|
||||
|
||||
template <FieldForm... FormTs>
|
||||
struct IsFieldFormList<TypeList<FormTs...>> : std::true_type { };
|
||||
template <FieldForm... FormTs> struct IsFieldFormList<TypeList<FormTs...>> : std::true_type { };
|
||||
|
||||
template <typename ListT> inline constexpr bool isFieldFormList = IsFieldFormList<ListT>::value;
|
||||
|
||||
struct FieldSupport { };
|
||||
|
||||
template <utils::domain::IsDomainOrSet DomainT> struct DomainSupport final : FieldSupport {
|
||||
using Domain = DomainT;
|
||||
};
|
||||
|
||||
struct NonSpatialSupport final : FieldSupport { };
|
||||
|
||||
template <typename T> constexpr bool isDomainSupportV = false;
|
||||
|
||||
template <utils::domain::IsDomainOrSet DomainT> constexpr bool isDomainSupportV<DomainSupport<DomainT>> = true;
|
||||
|
||||
template <typename T>
|
||||
concept IsDomainSupport = isDomainSupportV<T>;
|
||||
|
||||
template <typename T>
|
||||
concept IsFieldSupport = std::derived_from<T, FieldSupport>;
|
||||
|
||||
template <typename FieldT> using FieldSupportT = typename FieldT::Support;
|
||||
|
||||
template <typename FieldT>
|
||||
concept DomainSupportedField = requires { typename FieldT::Support; } && IsDomainSupport<FieldSupportT<FieldT>>;
|
||||
|
||||
template <typename FieldT>
|
||||
concept NonSpatialField =
|
||||
requires { typename FieldT::Support; } && std::same_as<FieldSupportT<FieldT>, NonSpatialSupport>;
|
||||
|
||||
template <DomainSupportedField FieldT> using FieldDomainT = typename FieldSupportT<FieldT>::Domain;
|
||||
|
||||
template <typename ListT>
|
||||
inline constexpr bool isFieldFormList = IsFieldFormList<ListT>::value;
|
||||
} // namespace mean_field::field
|
||||
Reference in New Issue
Block a user