test(tests): added test suite

The test suite is extensive. Note that LLMs were used to aid in the development of the test suite. All LLM generated code was manually reviewed.
This commit is contained in:
2026-11-09 13:53:17 -05:00
parent 74e55a6859
commit cb20faeb3d
202 changed files with 35505 additions and 953 deletions

Binary file not shown.

View File

@@ -0,0 +1,59 @@
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include "serif/discretization/domain/mesh/topology.hpp"
#include "serif/discretization/domain/schema/schemas.hpp"
#include "serif/discretization/domain/schema/validation/all.hpp"
namespace {
namespace domain = serif::discretization::domain;
/** @brief Represent the core, envelope, vacuum and their interfaces without a finite-element backend. */
[[nodiscard]] domain::mesh::MeshTopologyData layered_topology() {
return {
.elementDomainIDs = {1, 2, 3},
.faceElements = {{.firstElementID = 0, .secondElementID = 1}, {.firstElementID = 1, .secondElementID = 2}, {.firstElementID = 2}},
.boundaryElementBoundaryIDs = {1, 2},
.boundaryElementFaceIDs = {1, 2}
};
}
}
TEST_CASE("Physical schema validation uses backend-independent mesh connectivity", "[unit][discretization][domain]") {
const domain::mesh::MeshTopology topology(layered_topology());
const auto result = domain::schema::validation::validate_schema<domain::schema::CoreEnvelopeVacuumDomainSchema>(topology);
REQUIRE(result);
CHECK(result.relation_count() == 7);
CHECK(topology.element_neighbors(0) == std::vector<int>{1});
CHECK((topology.element_neighbors(1) == std::vector<int>{0, 2}));
CHECK(topology.boundary_elements_on_face(1) == std::vector<int>{0});
CHECK(topology.boundary_element_face(1) == 2);
CHECK(topology.face_elements(2).secondElementID == -1);
}
TEST_CASE("Neutral topology rejects invalid indexing before deriving adjacency", "[unit][discretization][domain]") {
domain::mesh::MeshTopologyData data = layered_topology();
SECTION("A face names an absent volume element") {
data.faceElements.front().firstElementID = 3;
}
SECTION("Boundary labels and faces have different counts") {
data.boundaryElementFaceIDs.pop_back();
}
SECTION("A boundary names an absent face") {
data.boundaryElementFaceIDs.front() = 3;
}
CHECK_THROWS(domain::mesh::MeshTopology(data));
}
TEST_CASE("Neutral topology retains unresolved and multiply labelled boundary faces", "[unit][discretization][domain]") {
domain::mesh::MeshTopologyData data = layered_topology();
data.boundaryElementBoundaryIDs.insert(data.boundaryElementBoundaryIDs.end(), {7, 8});
data.boundaryElementFaceIDs.insert(data.boundaryElementFaceIDs.end(), {1, -1});
const domain::mesh::MeshTopology topology(data);
CHECK((topology.boundary_elements_on_face(1) == std::vector<int>{0, 2}));
CHECK(topology.boundary_element_face(3) == -1);
CHECK(topology.boundary_element_boundary_id(3) == 8);
CHECK(topology.element_neighbors(-1).empty());
CHECK(topology.boundary_elements_on_face(100).empty());
CHECK(topology.element_domain_id(100) == 0);
}

Binary file not shown.

View File

@@ -1,42 +0,0 @@
#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);
}

View File

@@ -3,11 +3,11 @@
#include <string_view>
#include <catch2/catch_test_macros.hpp>
#include <mfem.hpp>
#include "mfem/mesh/mesh.hpp"
#include <stroid/stroid.h>
#include "serif/discretization/domain/schema/schemas.hpp"
#include "serif/discretization/domain/schema/validation/all.hpp"
#include "serif/backend/mfem/discretization/schema.hpp"
#include "serif/tests/test_tags.hpp"
#include "serif/tests/discritization/domain/domain_test_utils.hpp"
@@ -23,7 +23,7 @@ TEST_CASE(
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh();
const auto validation =
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
serif::backend::mfem::discretization::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
REQUIRE(validation.valid());
REQUIRE(validation.relationResults.size() == 7);
@@ -53,7 +53,7 @@ TEST_CASE(
*/
const mfem::Mesh mesh = domain_test_utils::make_layered_mesh(false, true);
const auto validation =
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
serif::backend::mfem::discretization::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
CHECK_FALSE(validation.valid());
REQUIRE(validation.relationResults.size() == 7);
CHECK(validation.failed_relation_count() == 1);
@@ -145,7 +145,7 @@ TEST_CASE(
* accept a mesh generated under another numbering convention.
*/
const auto productionValidation =
schema_validation::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(*stroidMesh.mesh);
serif::backend::mfem::discretization::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(*stroidMesh.mesh);
CHECK_FALSE(productionValidation.valid());
CHECK(productionValidation.failed_relation_count() > 0);
@@ -157,7 +157,7 @@ TEST_CASE(
) {
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);
const auto validation = serif::backend::mfem::discretization::validate_schema<schema::CoreEnvelopeVacuumDomainSchema>(mesh);
CHECK_FALSE(validation.valid());
REQUIRE(validation.relationResults.size() == 7);

View File

@@ -1,9 +1,9 @@
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include <mfem.hpp>
#include "mfem/mesh/mesh.hpp"
#include "serif/discretization/domain/mesh/topology.hpp"
#include "serif/backend/mfem/discretization/topology.hpp"
#include "serif/discretization/domain/physical_domains.hpp"
#include "serif/discretization/domain/relation/relations.hpp"
#include "serif/discretization/domain/relation/validation/runtime.hpp"
@@ -20,6 +20,7 @@ namespace schema = domain::schema;
namespace validation = schema::validation;
using domain::mesh::MeshTopology;
using serif::backend::mfem::discretization::make_mesh_topology;
TEST_CASE(
"Domain Boundary Accepts A Complete Internal Stellar Vacuum Interface",
@@ -28,7 +29,7 @@ TEST_CASE(
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 MeshTopology topology = make_mesh_topology(mesh);
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::StellarSurfaceBoundary, domain::StellarDomains,
@@ -63,7 +64,7 @@ TEST_CASE(
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});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK(result);
}
@@ -76,7 +77,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::InfinitySurfaceBoundary, domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(
@@ -92,7 +93,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::InfinitySurfaceBoundary, domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(
@@ -112,7 +113,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::StellarSurfaceBoundary, domain::StellarDomains,
domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
@@ -131,7 +132,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::StellarSurfaceBoundary, domain::StellarDomains,
domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::DomainBoundaryExpectedFaceIsUntagged);
@@ -150,7 +151,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::StellarSurfaceBoundary, domain::StellarDomains,
domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(
@@ -172,7 +173,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<relation::DomainBoundary<
domain::StellarSurfaceBoundary, domain::StellarDomains,
domain::VacuumDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::DomainBoundaryAbsent);

View File

@@ -1,7 +1,7 @@
#include <catch2/catch_test_macros.hpp>
#include <mfem.hpp>
#include "mfem/mesh/mesh.hpp"
#include "serif/discretization/domain/mesh/topology.hpp"
#include "serif/backend/mfem/discretization/topology.hpp"
#include "serif/discretization/domain/physical_domains.hpp"
#include "serif/discretization/domain/relation/relations.hpp"
#include "serif/discretization/domain/relation/validation/runtime.hpp"
@@ -18,13 +18,14 @@ namespace schema = domain::schema;
namespace validation = schema::validation;
using domain::mesh::MeshTopology;
using serif::backend::mfem::discretization::make_mesh_topology;
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 MeshTopology topology = make_mesh_topology(mesh);
const auto coreResult = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
@@ -47,7 +48,7 @@ TEST_CASE(
) {
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});
const auto result = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::DomainAbsent);
@@ -62,7 +63,7 @@ TEST_CASE(
) {
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});
const auto result = validation::RelationValidator<relation::FullyConnected<domain::CoreDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::DomainDisconnected);

View File

@@ -1,9 +1,9 @@
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include <mfem.hpp>
#include "mfem/mesh/mesh.hpp"
#include "serif/discretization/domain/mesh/topology.hpp"
#include "serif/backend/mfem/discretization/topology.hpp"
#include "serif/discretization/domain/physical_domains.hpp"
#include "serif/discretization/domain/relation/relations.hpp"
#include "serif/discretization/domain/relation/validation/runtime.hpp"
@@ -20,13 +20,14 @@ namespace schema = domain::schema;
namespace validation = schema::validation;
using domain::mesh::MeshTopology;
using serif::backend::mfem::discretization::make_mesh_topology;
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 MeshTopology topology = make_mesh_topology(mesh);
const auto coreResult = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(topology);
@@ -43,7 +44,7 @@ TEST_CASE(
) {
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});
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainAbsent);
@@ -55,7 +56,7 @@ TEST_CASE(
) {
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});
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::OuterDomainAbsent);
@@ -67,7 +68,7 @@ TEST_CASE(
) {
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});
const auto result = validation::RelationValidator<relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainTouchesMeshBoundary);
@@ -87,7 +88,7 @@ TEST_CASE(
const auto result = validation::RelationValidator<
relation::Inscribed<domain::CoreDomain, domain::EnvelopeDomain>>::
template validate<schema::CoreEnvelopeVacuumDomainSchema>(MeshTopology{mesh});
template validate<schema::CoreEnvelopeVacuumDomainSchema>(make_mesh_topology(mesh));
CHECK_FALSE(result);
CHECK(result.failure == validation::RelationValidationFailure::InnerDomainTouchesUnexpectedDomain);