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.
60 lines
2.8 KiB
C++
60 lines
2.8 KiB
C++
#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);
|
|
}
|