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
183 lines
7.1 KiB
C++
183 lines
7.1 KiB
C++
#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
|
|
);
|
|
}
|