Snapshot optimized solver and audit diagnostics before numerical experiments

This commit is contained in:
2026-09-16 14:34:06 -04:00
parent 75cc638739
commit 80cc3d83d7
64 changed files with 11969 additions and 267 deletions

View File

@@ -2870,3 +2870,80 @@ TEST_CASE(
CHECK_THROWS_AS(evaluator.Refresh(), std::invalid_argument);
CHECK_THROWS_AS(evaluator.EvaluatePoint(*transformation, integration_point, context), std::invalid_argument);
}
TEST_CASE("Fixed Mesh Geometry Cache Reuses Factors And Invalidates On Mesh Updates", "[mapping][geometry-cache]") {
SingleElementFixture fixture;
mapping::DomainMapper mapper({.dimension = dimension, .vacuum_element_attribute = 3}, make_kelvin_compactification());
mapping::DomainMapper::Workspace workspace(dimension);
const auto &rule = mfem::IntRules.Get(mfem::Geometry::CUBE, 5);
const auto &point = rule.IntPoint(0);
auto zero = fixture.MakeZeroElementDofs();
mapping::ElementDisplacementData displacement(fixture.GetElement(), zero);
ElementMappingDataOwner data(displacement);
auto compare = [&](const mfem::IntegrationPoint &ip) {
auto &transformation = *fixture.mesh.GetElementTransformation(0);
mapping::VolumeMappingContext fast, reference;
mapper.SetGeometryCacheEnabled(true);
REQUIRE(mapper.EvaluateVolume(data.Get(), transformation, ip, workspace, fast) == mapping::MappingStatus::valid);
mapper.SetGeometryCacheEnabled(false);
REQUIRE(mapper.EvaluateVolume(data.Get(), transformation, ip, workspace, reference) == mapping::MappingStatus::valid);
check_vector(fast.mapping.physical_position, reference.mapping.physical_position);
check_matrix(fast.mapping.mapping_jacobian, reference.mapping.mapping_jacobian);
check_matrix(fast.quadrature.J_inv, reference.quadrature.J_inv);
CHECK_THAT(fast.quadrature.weight, WithinAbs(reference.quadrature.weight, 1.0e-12));
mapper.SetGeometryCacheEnabled(true);
return fast.quadrature.weight;
};
const double originalWeight = compare(point);
CHECK(mapper.GetGeometryCacheStatistics().misses == 1);
compare(point);
CHECK(mapper.GetGeometryCacheStatistics().hits == 1);
auto changedPoint = point;
changedPoint.x += 0.013;
compare(changedPoint);
CHECK(mapper.GetGeometryCacheStatistics().points == 2);
changedPoint.weight *= 0.5;
compare(changedPoint);
CHECK(mapper.GetGeometryCacheStatistics().points == 2); // weights are supplied by the caller
fixture.mesh.Transform([](const mfem::Vector &x, mfem::Vector &y) {
y = x; y(0) *= 1.2; y(1) += 0.17;
});
const double newWeight = compare(point);
CHECK(newWeight > originalWeight);
CHECK(mapper.GetGeometryCacheStatistics().points == 1);
CHECK(mapper.GetGeometryCacheStatistics().misses == 3);
mapper.ClearGeometryCache();
CHECK(mapper.GetGeometryCacheStatistics().points == 0);
compare(point);
CHECK(mapper.GetGeometryCacheStatistics().misses == 1);
}
TEST_CASE("Geometry Cache Does Not Freeze Displacement Or Compactification State", "[mapping][geometry-cache]") {
SingleElementFixture fixture;
mapping::DomainMapper mapper({.dimension = dimension, .vacuum_element_attribute = 3}, make_kelvin_compactification());
mapping::DomainMapper::Workspace workspace(dimension);
const auto &point = mfem::IntRules.Get(mfem::Geometry::CUBE, 3).IntPoint(0);
for (double scale : {0.0, 0.02, -0.01}) {
auto &transformation = *fixture.mesh.GetElementTransformation(0);
auto dofs = fixture.MakeZeroElementDofs(); dofs = scale;
mapping::ElementDisplacementData displacement(fixture.GetElement(), dofs);
auto compactificationDofs = make_constant_compactification_dofs(fixture.GetElement(), 0.1 + scale);
mapping::ElementCompactificationData compactification(fixture.GetElement(), compactificationDofs);
mapping::ElementMappingData data{displacement, compactification};
for (int attribute : {1, 3}) {
transformation.Attribute = attribute;
mapping::VolumeMappingContext fast, reference;
mapper.SetGeometryCacheEnabled(true);
const auto fastStatus = mapper.EvaluateVolume(data, transformation, point, workspace, fast);
mapper.SetGeometryCacheEnabled(false);
const auto referenceStatus = mapper.EvaluateVolume(data, transformation, point, workspace, reference);
REQUIRE(fastStatus == referenceStatus);
if (fastStatus == mapping::MappingStatus::valid) {
check_vector(fast.mapping.physical_position, reference.mapping.physical_position);
check_matrix(fast.mapping.mapping_jacobian, reference.mapping.mapping_jacobian);
check_matrix(fast.quadrature.J_inv, reference.quadrature.J_inv);
}
}
}
CHECK(mapper.GetGeometryCacheStatistics().points == 1);
}