currently the barotope and the pressure force operator are migrated to the new support system
414 lines
12 KiB
C++
414 lines
12 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include <concepts>
|
|
#include <cstddef>
|
|
#include <string_view>
|
|
#include <type_traits>
|
|
|
|
import mean_field;
|
|
import test_helpers;
|
|
|
|
namespace field_base_test_utils {
|
|
namespace field = mean_field::field;
|
|
namespace domain = mean_field::utils::domain;
|
|
|
|
using IndependentL2Scalar = field::ScalarQ<field::FieldRelation::Independent, field::Disc<field::L2, 2>>;
|
|
|
|
using IndependentH1Scalar = field::ScalarQ<field::FieldRelation::Independent, field::Disc<field::H1, 3>>;
|
|
|
|
using IndependentH1Vector = field::VectorQ<field::FieldRelation::Independent, field::Disc<field::H1, 3>>;
|
|
|
|
using IndependentL2Vector = field::VectorQ<field::FieldRelation::Independent, field::Disc<field::L2, 2>>;
|
|
|
|
using Potential = field::ScalarQ<field::FieldRelation::Independent, field::Disc<field::L2, 2>>;
|
|
|
|
using Flux = field::VectorQ<field::FieldRelation::Gradient<Potential>, field::Disc<field::RT, 2>>;
|
|
|
|
using CurlSource = field::VectorQ<field::FieldRelation::Independent, field::Disc<field::ND, 2>>;
|
|
|
|
using CurlQuantity = field::VectorQ<field::FieldRelation::Curl<CurlSource>, field::Disc<field::ND, 2>>;
|
|
|
|
using SampleOperand = field::Operand<IndependentH1Scalar>;
|
|
|
|
using SampleGradientOperand = field::Operand<IndependentH1Scalar, field::FieldOperation::Gradient>;
|
|
|
|
using SampleForm = field::FormSpec<17, 2, SampleOperand, SampleGradientOperand>;
|
|
|
|
struct StellarSupportedObject {
|
|
using Support = field::DomainSupport<domain::Stellar>;
|
|
};
|
|
|
|
struct AllSupportedObject {
|
|
using Support = field::DomainSupport<domain::All>;
|
|
};
|
|
|
|
struct NonSpatialObject {
|
|
using Support = field::NonSpatialSupport;
|
|
};
|
|
} // namespace field_base_test_utils
|
|
|
|
TEST_CASE(
|
|
"Field Base Type Lists Track Compile Time Membership",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using List = field::TypeList<int, double, char>;
|
|
|
|
STATIC_REQUIRE(field::typeListContains<int, List>);
|
|
|
|
STATIC_REQUIRE(field::typeListContains<double, List>);
|
|
|
|
STATIC_REQUIRE(field::typeListContains<char, List>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::typeListContains<float, List>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::typeListContains<int, field::TypeList<>>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Function Space Tags Encode Supported Tensor Ranks",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
STATIC_REQUIRE(field::SpaceTag<field::L2>);
|
|
|
|
STATIC_REQUIRE(field::SpaceTag<field::H1>);
|
|
|
|
STATIC_REQUIRE(field::SpaceTag<field::RT>);
|
|
|
|
STATIC_REQUIRE(field::SpaceTag<field::ND>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::SpaceTag<int>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::L2, 0>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::L2, 1>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::H1, 0>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::H1, 1>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::spaceSupportsRank<field::RT, 0>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::RT, 1>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::spaceSupportsRank<field::ND, 0>);
|
|
|
|
STATIC_REQUIRE(field::spaceSupportsRank<field::ND, 1>);
|
|
|
|
CHECK(field::L2::name == std::string_view{"L2"});
|
|
|
|
CHECK(field::H1::name == std::string_view{"H1"});
|
|
|
|
CHECK(field::RT::name == std::string_view{"RT"});
|
|
|
|
CHECK(field::ND::name == std::string_view{"ND"});
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Discretization Descriptors Preserve Space And Family Order",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using L2Disc = field::Disc<field::L2, 2>;
|
|
|
|
using H1Disc = field::Disc<field::H1, 4>;
|
|
|
|
using RTDisc = field::Disc<field::RT, 1>;
|
|
|
|
using NDDisc = field::Disc<field::ND, 3>;
|
|
|
|
STATIC_REQUIRE(field::DiscretizationTag<L2Disc>);
|
|
|
|
STATIC_REQUIRE(field::DiscretizationTag<H1Disc>);
|
|
|
|
STATIC_REQUIRE(field::DiscretizationTag<RTDisc>);
|
|
|
|
STATIC_REQUIRE(field::DiscretizationTag<NDDisc>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename L2Disc::Space, field::L2>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename H1Disc::Space, field::H1>);
|
|
|
|
STATIC_REQUIRE(L2Disc::familyOrder == 2);
|
|
|
|
STATIC_REQUIRE(H1Disc::familyOrder == 4);
|
|
|
|
STATIC_REQUIRE(RTDisc::familyOrder == 1);
|
|
|
|
STATIC_REQUIRE(NDDisc::familyOrder == 3);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Relations Preserve Their Source Quantities",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Source = field_base_test_utils::IndependentL2Scalar;
|
|
|
|
using Gradient = field::FieldRelation::Gradient<Source>;
|
|
|
|
using Divergence = field::FieldRelation::Divergence<Source>;
|
|
|
|
using Curl = field::FieldRelation::Curl<Source>;
|
|
|
|
STATIC_REQUIRE(field::ValidRelation<field::FieldRelation::Independent>);
|
|
|
|
STATIC_REQUIRE(field::ValidRelation<Gradient>);
|
|
|
|
STATIC_REQUIRE(field::ValidRelation<Divergence>);
|
|
|
|
STATIC_REQUIRE(field::ValidRelation<Curl>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::ValidRelation<int>);
|
|
|
|
STATIC_REQUIRE(field::IsGradient<Gradient>::value);
|
|
|
|
STATIC_REQUIRE(field::IsDivergence<Divergence>::value);
|
|
|
|
STATIC_REQUIRE(field::IsCurl<Curl>::value);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename field::RelationTarget<Gradient>::Type, Source>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename field::RelationTarget<Divergence>::Type, Source>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename field::RelationTarget<Curl>::Type, Source>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename field::RelationTarget<field::FieldRelation::Independent>::Type, void>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Finite Element Quantities Preserve Rank Storage Space And Order",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Scalar = field_base_test_utils::IndependentL2Scalar;
|
|
|
|
using Vector = field_base_test_utils::IndependentH1Vector;
|
|
|
|
STATIC_REQUIRE(field::FieldQuantity<Scalar>);
|
|
|
|
STATIC_REQUIRE(field::FieldQuantity<Vector>);
|
|
|
|
STATIC_REQUIRE(field::RegisteredQuantity<Scalar>);
|
|
|
|
STATIC_REQUIRE(field::RegisteredQuantity<Vector>);
|
|
|
|
STATIC_REQUIRE(Scalar::rankValue == 0);
|
|
|
|
STATIC_REQUIRE(Vector::rankValue == 1);
|
|
|
|
STATIC_REQUIRE(Scalar::familyOrder == 2);
|
|
|
|
STATIC_REQUIRE(Vector::familyOrder == 3);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename Scalar::Space, field::L2>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename Vector::Space, field::H1>);
|
|
|
|
STATIC_REQUIRE(Scalar::storageKind == field::StorageKind::finite_element);
|
|
|
|
STATIC_REQUIRE(Vector::storageKind == field::StorageKind::finite_element);
|
|
|
|
STATIC_REQUIRE(Scalar::staticBlockSize == field::dynamicBlockSize);
|
|
|
|
STATIC_REQUIRE(Vector::staticBlockSize == field::dynamicBlockSize);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Global Scalars Are Registered But Are Not Finite Element Quantities",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
STATIC_REQUIRE(field::GlobalScalarQuantity<field::GlobalScalarQ>);
|
|
|
|
STATIC_REQUIRE(field::RegisteredQuantity<field::GlobalScalarQ>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::FieldQuantity<field::GlobalScalarQ>);
|
|
|
|
STATIC_REQUIRE(field::GlobalScalarQ::rankValue == 0);
|
|
|
|
STATIC_REQUIRE(field::GlobalScalarQ::storageKind == field::StorageKind::global_scalar);
|
|
|
|
STATIC_REQUIRE(field::GlobalScalarQ::staticBlockSize == 1);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename field::GlobalScalarQ::Relation, field::FieldRelation::Independent>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Derived Quantity Detection Follows Physical Relations",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Independent = field_base_test_utils::IndependentL2Scalar;
|
|
|
|
using Flux = field_base_test_utils::Flux;
|
|
|
|
using CurlQuantity = field_base_test_utils::CurlQuantity;
|
|
|
|
STATIC_REQUIRE_FALSE(field::DerivedQuantity<Independent>);
|
|
|
|
STATIC_REQUIRE(field::DerivedQuantity<Flux>);
|
|
|
|
STATIC_REQUIRE(field::DerivedQuantity<CurlQuantity>);
|
|
|
|
STATIC_REQUIRE(std::same_as<field::RelationTargetT<Flux>, field_base_test_utils::Potential>);
|
|
|
|
STATIC_REQUIRE(std::same_as<field::RelationTargetT<CurlQuantity>, field_base_test_utils::CurlSource>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base RT L2 Constraint Accepts The Registered Stable Pair Contract",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Potential = field_base_test_utils::Potential;
|
|
|
|
using Flux = field_base_test_utils::Flux;
|
|
|
|
using Constraint = field::RtL2StablePair<Flux, Potential>;
|
|
|
|
STATIC_REQUIRE(field::validate_constraints(field::TypeList<Constraint>{}));
|
|
|
|
STATIC_REQUIRE(field::validate_constraints(field::TypeList<>{}));
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Operations And Operands Preserve Mathematical Intent",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Quantity = field_base_test_utils::IndependentH1Scalar;
|
|
|
|
using ValueOperand = field::Operand<Quantity>;
|
|
|
|
using GradientOperand = field::Operand<Quantity, field::FieldOperation::Gradient>;
|
|
|
|
STATIC_REQUIRE(field::FieldOperationTag<field::FieldOperation::Value>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperationTag<field::FieldOperation::Gradient>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperationTag<field::FieldOperation::Divergence>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperationTag<field::FieldOperation::Curl>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperationTag<field::FieldOperation::NormalTrace>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::FieldOperationTag<int>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperand<ValueOperand>);
|
|
|
|
STATIC_REQUIRE(field::FieldOperand<GradientOperand>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename ValueOperand::Quantity, Quantity>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename ValueOperand::Operation, field::FieldOperation::Value>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename GradientOperand::Operation, field::FieldOperation::Gradient>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Form Specifications Preserve Policy Dynamic Orders And Operands",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
|
|
using Form = field_base_test_utils::SampleForm;
|
|
|
|
STATIC_REQUIRE(field::FieldForm<Form>);
|
|
|
|
STATIC_REQUIRE(Form::policyKey == 17);
|
|
|
|
STATIC_REQUIRE(Form::dynamicOrderCount == 2);
|
|
|
|
STATIC_REQUIRE(
|
|
std::same_as<
|
|
typename Form::Operands,
|
|
field::TypeList<field_base_test_utils::SampleOperand, field_base_test_utils::SampleGradientOperand>>
|
|
);
|
|
|
|
STATIC_REQUIRE(
|
|
field::isRegisteredQuantityList<field::TypeList<
|
|
field_base_test_utils::IndependentL2Scalar, field_base_test_utils::IndependentH1Vector,
|
|
field::GlobalScalarQ>>
|
|
);
|
|
|
|
STATIC_REQUIRE_FALSE(field::isRegisteredQuantityList<field::TypeList<int>>);
|
|
|
|
STATIC_REQUIRE(field::isFieldFormList<field::TypeList<Form>>);
|
|
|
|
STATIC_REQUIRE(field::isFieldFormList<field::TypeList<>>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::isFieldFormList<field::TypeList<int>>);
|
|
|
|
CHECK(true);
|
|
}
|
|
|
|
TEST_CASE(
|
|
"Field Base Support Types Distinguish Domain And Non Spatial Fields",
|
|
tags::unit &tags::field
|
|
) {
|
|
namespace field = mean_field::field;
|
|
namespace domain = mean_field::utils::domain;
|
|
|
|
using StellarSupport = field::DomainSupport<domain::Stellar>;
|
|
|
|
using AllSupport = field::DomainSupport<domain::All>;
|
|
|
|
STATIC_REQUIRE(field::IsFieldSupport<StellarSupport>);
|
|
|
|
STATIC_REQUIRE(field::IsFieldSupport<AllSupport>);
|
|
|
|
STATIC_REQUIRE(field::IsFieldSupport<field::NonSpatialSupport>);
|
|
|
|
STATIC_REQUIRE(field::IsDomainSupport<StellarSupport>);
|
|
|
|
STATIC_REQUIRE(field::IsDomainSupport<AllSupport>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::IsDomainSupport<field::NonSpatialSupport>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename StellarSupport::Domain, domain::Stellar>);
|
|
|
|
STATIC_REQUIRE(std::same_as<typename AllSupport::Domain, domain::All>);
|
|
|
|
STATIC_REQUIRE(field::DomainSupportedField<field_base_test_utils::StellarSupportedObject>);
|
|
|
|
STATIC_REQUIRE(field::DomainSupportedField<field_base_test_utils::AllSupportedObject>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::DomainSupportedField<field_base_test_utils::NonSpatialObject>);
|
|
|
|
STATIC_REQUIRE(field::NonSpatialField<field_base_test_utils::NonSpatialObject>);
|
|
|
|
STATIC_REQUIRE_FALSE(field::NonSpatialField<field_base_test_utils::StellarSupportedObject>);
|
|
|
|
STATIC_REQUIRE(std::same_as<field::FieldSupportT<field_base_test_utils::StellarSupportedObject>, StellarSupport>);
|
|
|
|
STATIC_REQUIRE(std::same_as<field::FieldDomainT<field_base_test_utils::StellarSupportedObject>, domain::Stellar>);
|
|
|
|
CHECK(true);
|
|
} |