feat(mean_field): added dimensions, discritization, and start of eos
The full rewrite of mean_field into something maintainable is progressing. dimensions is mostly done, discritization (domain, blocks, and fields) is done, and eos is progressing quickly
This commit is contained in:
BIN
tests/discritization/domain/schema/.DS_Store
vendored
Normal file
BIN
tests/discritization/domain/schema/.DS_Store
vendored
Normal file
Binary file not shown.
55
tests/discritization/domain/schema/domain_schema.cpp
Normal file
55
tests/discritization/domain/schema/domain_schema.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "serif/discretization/domain/ids/boundary.hpp"
|
||||
#include "serif/discretization/domain/ids/domain.hpp"
|
||||
#include "serif/discretization/domain/ids/lists/lists.hpp"
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/relation/lists/relation_list.hpp"
|
||||
#include "serif/discretization/domain/relation/relations.hpp"
|
||||
#include "serif/discretization/domain/schema/domain_schema.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace ids = domain::ids;
|
||||
namespace relation = domain::relation;
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Schemas Reject Relations That Reference Unregistered Entities",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
using IncompleteDomainIDs = ids::lists::DomainIDList<
|
||||
ids::DomainID<domain::CoreDomain, 1>,
|
||||
ids::DomainID<domain::VacuumDomain, 3>>;
|
||||
|
||||
using CompleteDomainIDs = ids::lists::DomainIDList<
|
||||
ids::DomainID<domain::CoreDomain, 1>,
|
||||
ids::DomainID<domain::EnvelopeDomain, 2>,
|
||||
ids::DomainID<domain::VacuumDomain, 3>>;
|
||||
|
||||
using CompleteBoundaryIDs = ids::lists::BoundaryIDList<
|
||||
ids::BoundaryID<domain::StellarSurfaceBoundary, 1>,
|
||||
ids::BoundaryID<domain::InfinitySurfaceBoundary, 2>>;
|
||||
|
||||
using InfinityOnlyBoundaryIDs = ids::lists::BoundaryIDList<
|
||||
ids::BoundaryID<domain::InfinitySurfaceBoundary, 2>>;
|
||||
|
||||
using MissingEnvelopeRelation = relation::lists::RelationList<
|
||||
relation::FullyConnected<domain::EnvelopeDomain>>;
|
||||
|
||||
using MissingBoundaryRelation = relation::lists::RelationList<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>;
|
||||
|
||||
STATIC_REQUIRE_FALSE(
|
||||
domain_test_utils::CanFormSchema<IncompleteDomainIDs, CompleteBoundaryIDs, MissingEnvelopeRelation>
|
||||
);
|
||||
|
||||
STATIC_REQUIRE_FALSE(
|
||||
domain_test_utils::CanFormSchema<CompleteDomainIDs, InfinityOnlyBoundaryIDs, MissingBoundaryRelation>
|
||||
);
|
||||
|
||||
CHECK(true);
|
||||
}
|
||||
64
tests/discritization/domain/schema/schemas.cpp
Normal file
64
tests/discritization/domain/schema/schemas.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/schema/concepts.hpp"
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace schema = domain::schema;
|
||||
|
||||
TEST_CASE(
|
||||
"Core Envelope Vacuum Schema Exposes Exact Compile Time And Runtime "
|
||||
"Metadata",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
using SchemaT = schema::CoreEnvelopeVacuumDomainSchema;
|
||||
|
||||
STATIC_REQUIRE(schema::IsSchema<SchemaT>);
|
||||
STATIC_REQUIRE(SchemaT::domain_id_count == 3);
|
||||
STATIC_REQUIRE(SchemaT::boundary_id_count == 2);
|
||||
STATIC_REQUIRE(SchemaT::relation_count == 7);
|
||||
|
||||
constexpr auto domainDescriptors = SchemaT::domain_descriptors();
|
||||
constexpr auto boundaryDescriptors = SchemaT::boundary_descriptors();
|
||||
|
||||
STATIC_REQUIRE(domainDescriptors[0].name == std::string_view{"core"});
|
||||
STATIC_REQUIRE(domainDescriptors[0].ID == 1);
|
||||
|
||||
STATIC_REQUIRE(domainDescriptors[1].name == std::string_view{"envelope"});
|
||||
STATIC_REQUIRE(domainDescriptors[1].ID == 2);
|
||||
|
||||
STATIC_REQUIRE(domainDescriptors[2].name == std::string_view{"vacuum"});
|
||||
STATIC_REQUIRE(domainDescriptors[2].ID == 3);
|
||||
|
||||
STATIC_REQUIRE(boundaryDescriptors[0].name == std::string_view{"stellar_surface"});
|
||||
STATIC_REQUIRE(boundaryDescriptors[0].ID == 1);
|
||||
|
||||
STATIC_REQUIRE(boundaryDescriptors[1].name == std::string_view{"infinity_surface"});
|
||||
STATIC_REQUIRE(boundaryDescriptors[1].ID == 2);
|
||||
|
||||
STATIC_REQUIRE(SchemaT::template contains_domain<domain::CoreDomain>());
|
||||
STATIC_REQUIRE(SchemaT::template contains_domain<domain::StellarDomains>());
|
||||
STATIC_REQUIRE(SchemaT::template contains_domain<domain::AllDomains>());
|
||||
STATIC_REQUIRE(SchemaT::template domain_id_belongs_to<domain::StellarDomains>(1));
|
||||
STATIC_REQUIRE(SchemaT::template domain_id_belongs_to<domain::StellarDomains>(2));
|
||||
STATIC_REQUIRE_FALSE(SchemaT::template domain_id_belongs_to<domain::StellarDomains>(3));
|
||||
STATIC_REQUIRE(SchemaT::template domain_id_belongs_to<domain::AllDomains>(1));
|
||||
STATIC_REQUIRE(SchemaT::template domain_id_belongs_to<domain::AllDomains>(2));
|
||||
STATIC_REQUIRE(SchemaT::template domain_id_belongs_to<domain::AllDomains>(3));
|
||||
STATIC_REQUIRE(SchemaT::template domain_id<domain::CoreDomain>() == 1);
|
||||
STATIC_REQUIRE(SchemaT::template domain_id<domain::EnvelopeDomain>() == 2);
|
||||
STATIC_REQUIRE(SchemaT::template domain_id<domain::VacuumDomain>() == 3);
|
||||
|
||||
STATIC_REQUIRE(SchemaT::template contains_boundary<domain::StellarSurfaceBoundary>());
|
||||
STATIC_REQUIRE(SchemaT::template contains_boundary<domain::InfinitySurfaceBoundary>());
|
||||
STATIC_REQUIRE(SchemaT::template boundary_id<domain::StellarSurfaceBoundary>() == 1);
|
||||
STATIC_REQUIRE(SchemaT::template boundary_id<domain::InfinitySurfaceBoundary>() == 2);
|
||||
|
||||
CHECK(true);
|
||||
}
|
||||
42
tests/discritization/domain/schema/utils.cpp
Normal file
42
tests/discritization/domain/schema/utils.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <mfem.hpp>
|
||||
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/schema/utils.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace schema = domain::schema;
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Schema Builds Exact MFEM Attribute Markers",
|
||||
tags::domain &tags::utils &tags::unit
|
||||
) {
|
||||
using Schema = schema::CoreEnvelopeVacuumDomainSchema;
|
||||
|
||||
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh();
|
||||
|
||||
const mfem::Array<int> stellarMarker = schema::make_attribute_marker<domain::StellarDomains, Schema>(mesh);
|
||||
const mfem::Array<int> vacuumMarker = schema::make_attribute_marker<domain::VacuumDomain, Schema>(mesh);
|
||||
const mfem::Array<int> allMarker = schema::make_attribute_marker<domain::AllDomains, Schema>(mesh);
|
||||
|
||||
REQUIRE(stellarMarker.Size() == 3);
|
||||
REQUIRE(vacuumMarker.Size() == 3);
|
||||
REQUIRE(allMarker.Size() == 3);
|
||||
|
||||
CHECK(stellarMarker[0] == 1);
|
||||
CHECK(stellarMarker[1] == 1);
|
||||
CHECK(stellarMarker[2] == 0);
|
||||
|
||||
CHECK(vacuumMarker[0] == 0);
|
||||
CHECK(vacuumMarker[1] == 0);
|
||||
CHECK(vacuumMarker[2] == 1);
|
||||
|
||||
CHECK(allMarker[0] == 1);
|
||||
CHECK(allMarker[1] == 1);
|
||||
CHECK(allMarker[2] == 1);
|
||||
}
|
||||
182
tests/discritization/domain/schema/validation/all.cpp
Normal file
182
tests/discritization/domain/schema/validation/all.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <mfem.hpp>
|
||||
#include <stroid/stroid.h>
|
||||
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/schema/validation/all.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace schema = domain::schema;
|
||||
namespace schema_validation = schema::validation;
|
||||
|
||||
TEST_CASE(
|
||||
"Complete Schema Validation Accepts A Synthetic Core Envelope Vacuum Mesh",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh();
|
||||
|
||||
const auto validation =
|
||||
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
|
||||
|
||||
REQUIRE(validation.valid());
|
||||
REQUIRE(validation.relationResults.size() == 7);
|
||||
CHECK(validation.failed_relation_count() == 0);
|
||||
CHECK(validation.passed_relation_count() == 7);
|
||||
CHECK_FALSE(validation.first_failed_relation_index().has_value());
|
||||
|
||||
constexpr std::array<std::string_view, 7> expectedRelationNames{"fully_connected", "fully_connected",
|
||||
"fully_connected", "inscribed",
|
||||
"inscribed", "domain_boundary",
|
||||
"domain_boundary"};
|
||||
|
||||
for (std::size_t relationIndex = 0; relationIndex < expectedRelationNames.size(); ++relationIndex) {
|
||||
CHECK(validation.relationResults[relationIndex].relationIndex == relationIndex);
|
||||
CHECK(validation.relationResults[relationIndex].relationName == expectedRelationNames[relationIndex]);
|
||||
CHECK(validation.relationResults[relationIndex].valid());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Complete Schema Validation Evaluates Every Relation After A Failure",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
/*
|
||||
* All material topology and the outer vacuum boundary are valid.
|
||||
* Only the Stellar/Vacuum boundary tagging is intentionally absent.
|
||||
*/
|
||||
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh(false, true);
|
||||
const auto validation =
|
||||
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
|
||||
CHECK_FALSE(validation.valid());
|
||||
REQUIRE(validation.relationResults.size() == 7);
|
||||
CHECK(validation.failed_relation_count() == 1);
|
||||
CHECK(validation.passed_relation_count() == 6);
|
||||
REQUIRE(validation.first_failed_relation_index().has_value());
|
||||
CHECK(*validation.first_failed_relation_index() == 5);
|
||||
|
||||
for (std::size_t relationIndex = 0; relationIndex < 7; ++relationIndex) {
|
||||
CAPTURE(relationIndex);
|
||||
|
||||
if (relationIndex == 5) {
|
||||
CHECK_FALSE(validation.relationResults[relationIndex].valid());
|
||||
CHECK(
|
||||
validation.relationResults[relationIndex].result.failure ==
|
||||
schema_validation::RelationValidationFailure::DomainBoundaryExpectedFaceIsUntagged
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
CHECK(validation.relationResults[relationIndex].valid());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"STROID Meshes Satisfy The Core Envelope Vacuum Domain Schema",
|
||||
tags::integration &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
constexpr std::array<domain_test_utils::StroidCase, 3> testCases{
|
||||
domain_test_utils::StroidCase{
|
||||
.name = "spherical_low_order", .refinementLevels = 0, .order = 1, .flattening = 0.0
|
||||
},
|
||||
domain_test_utils::StroidCase{.name = "oblate", .refinementLevels = 0, .order = 2, .flattening = 0.15},
|
||||
domain_test_utils::StroidCase{.name = "refined_oblate", .refinementLevels = 1, .order = 2, .flattening = 0.10}
|
||||
};
|
||||
|
||||
for (const auto &[name, refinementLevels, order, flattening] : testCases) {
|
||||
INFO("STROID case = " << name);
|
||||
INFO("Refinement levels = " << refinementLevels);
|
||||
INFO("Order = " << order);
|
||||
INFO("Flattening = " << flattening);
|
||||
|
||||
const stroid::config::MeshConfig config = domain_test_utils::make_stroid_config(refinementLevels, order, flattening);
|
||||
stroid::StroidMesh stroidMesh = stroid::GenerateMesh(config);
|
||||
|
||||
REQUIRE(stroidMesh.reference_mesh != nullptr);
|
||||
REQUIRE(stroidMesh.mesh != nullptr);
|
||||
|
||||
/*
|
||||
* Validate both the reference topology and the projected
|
||||
* physical mesh. The mapping/projection must not alter
|
||||
* material or boundary semantics.
|
||||
*/
|
||||
domain_test_utils::check_schema_is_valid<schema::CoreEnvelopeVacuumDomainSchema>(
|
||||
*stroidMesh.reference_mesh
|
||||
);
|
||||
|
||||
domain_test_utils::check_schema_is_valid<schema::CoreEnvelopeVacuumDomainSchema>(
|
||||
*stroidMesh.mesh
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"STROID Material And Boundary Id Conventions Are Fully Schema Driven",
|
||||
tags::integration &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
stroid::config::MeshConfig config = domain_test_utils::make_stroid_config(0, 1, 0.0);
|
||||
|
||||
config.core_id = 11;
|
||||
config.envelope_id = 17;
|
||||
config.vacuum_id = 29;
|
||||
config.surface_bdr_id = 101;
|
||||
config.inf_bdr_id = 203;
|
||||
|
||||
stroid::StroidMesh stroidMesh = stroid::GenerateMesh(config);
|
||||
|
||||
REQUIRE(stroidMesh.reference_mesh != nullptr);
|
||||
REQUIRE(stroidMesh.mesh != nullptr);
|
||||
|
||||
/*
|
||||
* The same semantic topology must validate when a mesh generator
|
||||
* uses an entirely different attribute numbering convention.
|
||||
*/
|
||||
domain_test_utils::check_schema_is_valid<domain_test_utils::AlternateIdSchema>(*stroidMesh.reference_mesh);
|
||||
domain_test_utils::check_schema_is_valid<domain_test_utils::AlternateIdSchema>(*stroidMesh.mesh);
|
||||
|
||||
/*
|
||||
* Conversely, the production 1/2/3 + 1/2 schema must not silently
|
||||
* accept a mesh generated under another numbering convention.
|
||||
*/
|
||||
const auto productionValidation =
|
||||
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(*stroidMesh.mesh);
|
||||
|
||||
CHECK_FALSE(productionValidation.valid());
|
||||
CHECK(productionValidation.failed_relation_count() > 0);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Complete Schema Validation Rejects A Mesh Without Vacuum",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(3, 3, {2, 2, 2, 2, 1, 2, 2, 2, 2}, {});
|
||||
|
||||
const auto validation = schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
|
||||
|
||||
CHECK_FALSE(validation.valid());
|
||||
REQUIRE(validation.relationResults.size() == 7);
|
||||
|
||||
/*
|
||||
* FullyConnected<VacuumDomain>
|
||||
*/
|
||||
CHECK_FALSE(validation.relationResults[2].valid());
|
||||
CHECK(
|
||||
validation.relationResults[2].result.failure ==
|
||||
schema_validation::RelationValidationFailure::DomainAbsent
|
||||
);
|
||||
|
||||
/*
|
||||
* Inscribed<StellarDomains, VacuumDomain>
|
||||
*/
|
||||
CHECK_FALSE(validation.relationResults[4].valid());
|
||||
CHECK(
|
||||
validation.relationResults[4].result.failure ==
|
||||
schema_validation::RelationValidationFailure::OuterDomainAbsent
|
||||
);
|
||||
}
|
||||
179
tests/discritization/domain/schema/validation/boundary.cpp
Normal file
179
tests/discritization/domain/schema/validation/boundary.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
#include <vector>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <mfem.hpp>
|
||||
|
||||
#include "serif/discretization/domain/mesh/topology.hpp"
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/relation/relations.hpp"
|
||||
#include "serif/discretization/domain/relation/validation/runtime.hpp"
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/schema/validation/boundary.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace relation = domain::relation;
|
||||
namespace schema = domain::schema;
|
||||
namespace validation = schema::validation;
|
||||
|
||||
using domain::mesh::MeshTopology;
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Accepts A Complete Internal Stellar Vacuum Interface",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
std::vector<domain_test_utils::BoundaryEdge> boundaries{{.firstVertexId = 1, .secondVertexId = 4, .attribute = 1}};
|
||||
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {2, 3}, boundaries);
|
||||
const MeshTopology topology{mesh};
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
CHECK(result);
|
||||
|
||||
/*
|
||||
* Interface ordering is intentionally semantic rather
|
||||
* than oriented.
|
||||
*/
|
||||
const auto reversedResult = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::VacuumDomain,
|
||||
domain::StellarDomains>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
CHECK(reversedResult);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Accepts A Complete Exterior Vacuum Boundary",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const std::vector<int> attributes{3};
|
||||
std::vector<domain_test_utils::BoundaryEdge> boundaries;
|
||||
|
||||
domain_test_utils::append_exterior_boundaries(
|
||||
boundaries, attributes, 1, 1, [](const int materialId) { return materialId == 3; }, 2
|
||||
);
|
||||
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(1, 1, attributes, boundaries);
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::InfinitySurfaceBoundary, domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK(result);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects A Tagged Internal Face For An Exterior Boundary",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {3, 3}, {{.firstVertexId = 1, .secondVertexId = 4, .attribute = 2}});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::InfinitySurfaceBoundary, domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(
|
||||
result.failure == validation::RelationValidationFailure::DomainBoundaryTaggedFaceHasWrongTopology
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects A Tagged Exterior Face Of The Wrong Material",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(1, 1, {2}, {{.firstVertexId = 0, .secondVertexId = 1, .attribute = 2}});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::InfinitySurfaceBoundary, domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(
|
||||
result.failure ==
|
||||
validation::RelationValidationFailure::DomainBoundaryTaggedFaceTouchesUnexpectedDomain
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects A Tagged Internal Interface With Unexpected "
|
||||
"Materials",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh =
|
||||
domain_test_utils::make_grid_mesh(2, 1, {1, 2}, {{.firstVertexId = 1, .secondVertexId = 4, .attribute = 1}});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
|
||||
CHECK(
|
||||
result.failure ==
|
||||
validation::RelationValidationFailure::DomainBoundaryTaggedFaceTouchesUnexpectedDomain
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects An Untagged Expected Interface",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {2, 3}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::DomainBoundaryExpectedFaceIsUntagged);
|
||||
REQUIRE(result.domainBoundaryDiagnostics.has_value());
|
||||
CHECK(result.domainBoundaryDiagnostics->faceID >= 0);
|
||||
CHECK(result.domainBoundaryDiagnostics->boundaryElementID == -1);
|
||||
CHECK_FALSE(result.domainBoundaryDiagnostics->actualBoundaryID.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects An Expected Interface With The Wrong Attribute",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {2, 3}, {{.firstVertexId = 1, .secondVertexId = 4, .attribute = 9}});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(
|
||||
result.failure ==
|
||||
validation::RelationValidationFailure::DomainBoundaryExpectedFaceHasWrongID
|
||||
);
|
||||
REQUIRE(result.domainBoundaryDiagnostics.has_value());
|
||||
REQUIRE(result.domainBoundaryDiagnostics->actualBoundaryID.has_value());
|
||||
CHECK(*result.domainBoundaryDiagnostics->actualBoundaryID == 9);
|
||||
CHECK(result.domainBoundaryDiagnostics->expectedBoundaryID == 1);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Domain Boundary Rejects A Relation That Is Not Realized Anywhere",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {2, 2}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::DomainBoundary<
|
||||
domain::StellarSurfaceBoundary, domain::StellarDomains,
|
||||
domain::VacuumDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::DomainBoundaryAbsent);
|
||||
}
|
||||
73
tests/discritization/domain/schema/validation/connected.cpp
Normal file
73
tests/discritization/domain/schema/validation/connected.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <mfem.hpp>
|
||||
|
||||
#include "serif/discretization/domain/mesh/topology.hpp"
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/relation/relations.hpp"
|
||||
#include "serif/discretization/domain/relation/validation/runtime.hpp"
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/schema/validation/connected.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace relation = domain::relation;
|
||||
namespace schema = domain::schema;
|
||||
namespace validation = schema::validation;
|
||||
|
||||
using domain::mesh::MeshTopology;
|
||||
|
||||
TEST_CASE(
|
||||
"Connected Accepts Face Connected Atomic And Composite Domains",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh();
|
||||
const MeshTopology topology{mesh};
|
||||
|
||||
const auto coreResult = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
REQUIRE(coreResult);
|
||||
REQUIRE(coreResult.connectedDiagnostics.has_value());
|
||||
CHECK(coreResult.connectedDiagnostics->domainElementCount == 1);
|
||||
CHECK(coreResult.connectedDiagnostics->visitedElementCount == 1);
|
||||
|
||||
const auto stellarResult = validation::RelationValidator<relation::FullyConnected<domain::StellarDomains>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
REQUIRE(stellarResult);
|
||||
REQUIRE(stellarResult.connectedDiagnostics.has_value());
|
||||
CHECK(stellarResult.connectedDiagnostics->domainElementCount == 9);
|
||||
CHECK(stellarResult.connectedDiagnostics->visitedElementCount == 9);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Connected Rejects An Absent Domain",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 1, {2, 2}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::DomainAbsent);
|
||||
REQUIRE(result.connectedDiagnostics.has_value());
|
||||
CHECK(result.connectedDiagnostics->domainElementCount == 0);
|
||||
CHECK(result.connectedDiagnostics->visitedElementCount == 0);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Connected Rejects Multiple Face Disconnected Components",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(3, 1, {1, 2, 1}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::DomainDisconnected);
|
||||
REQUIRE(result.connectedDiagnostics.has_value());
|
||||
CHECK(result.connectedDiagnostics->domainElementCount == 2);
|
||||
CHECK(result.connectedDiagnostics->visitedElementCount == 1);
|
||||
CHECK(result.connectedDiagnostics->elementID >= 0);
|
||||
}
|
||||
96
tests/discritization/domain/schema/validation/inscribed.cpp
Normal file
96
tests/discritization/domain/schema/validation/inscribed.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <vector>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <mfem.hpp>
|
||||
|
||||
#include "serif/discretization/domain/mesh/topology.hpp"
|
||||
#include "serif/discretization/domain/physical_domains.hpp"
|
||||
#include "serif/discretization/domain/relation/relations.hpp"
|
||||
#include "serif/discretization/domain/relation/validation/runtime.hpp"
|
||||
#include "serif/discretization/domain/schema/schemas.hpp"
|
||||
#include "serif/discretization/domain/schema/validation/inscribed.hpp"
|
||||
#include "serif/discretization/domain/types.hpp"
|
||||
|
||||
#include "serif/tests/test_tags.hpp"
|
||||
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
|
||||
|
||||
namespace domain = serif::discretization::domain;
|
||||
namespace relation = domain::relation;
|
||||
namespace schema = domain::schema;
|
||||
namespace validation = schema::validation;
|
||||
|
||||
using domain::mesh::MeshTopology;
|
||||
|
||||
TEST_CASE(
|
||||
"Inscribed Accepts Nested Atomic And Composite Domains",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh();
|
||||
const MeshTopology topology{mesh};
|
||||
|
||||
const auto coreResult = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
CHECK(coreResult);
|
||||
|
||||
const auto stellarResult = validation::RelationValidator<relation::Inscribed<domain::StellarDomains, domain::VacuumDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
|
||||
|
||||
CHECK(stellarResult);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Inscribed Rejects An Absent Inner Domain",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 2, {2, 2, 2, 2}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainAbsent);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Inscribed Rejects An Absent Outer Domain",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(1, 1, {1}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::OuterDomainAbsent);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Inscribed Rejects An Inner Domain Touching The Computational Boundary",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(2, 2, {1, 2, 2, 2}, {});
|
||||
|
||||
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainTouchesMeshBoundary);
|
||||
REQUIRE(result.inscribedDiagnostics.has_value());
|
||||
CHECK(result.inscribedDiagnostics->faceID >= 0);
|
||||
CHECK(result.inscribedDiagnostics->innerElementID >= 0);
|
||||
CHECK(result.inscribedDiagnostics->adjacentElementID == -1);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Inscribed Rejects An Inner Domain Touching An Unexpected Material",
|
||||
tags::unit &tags::mesh &tags::utils &tags::domain
|
||||
) {
|
||||
std::vector<int> attributes{2, 2, 2, 2, 1, 3, 2, 2, 2};
|
||||
|
||||
const mfem::Mesh mesh = domain_test_utils::make_grid_mesh(3, 3, attributes, {});
|
||||
|
||||
const auto result = validation::RelationValidator<
|
||||
relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::
|
||||
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
|
||||
|
||||
CHECK_FALSE(result);
|
||||
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainTouchesUnexpectedDomain);
|
||||
REQUIRE(result.inscribedDiagnostics.has_value());
|
||||
CHECK(result.inscribedDiagnostics->adjacentDomainID == 3);
|
||||
}
|
||||
Reference in New Issue
Block a user