feat(newton): first newton solver implementation

This commit is contained in:
2026-09-08 06:36:39 -04:00
parent 76818f2f82
commit b3c04d507a
98 changed files with 20397 additions and 11040 deletions

View File

@@ -2,6 +2,7 @@
#include <catch2/matchers/catch_matchers_floating_point.hpp>
#include <cmath>
#include <mfem.hpp>
#include <stdexcept>
import mean_field;
import test_helpers;
@@ -10,6 +11,56 @@ using namespace mean_field;
using Catch::Matchers::WithinAbs;
namespace prepared_test = gravity_prepared_test_utils;
namespace {
[[nodiscard]] mfem::Vector make_folding_displacement(const mean_field::fem::FEM &f) {
mfem::ParGridFunction field(f.displacementFes.get());
mfem::VectorFunctionCoefficient coefficient(
f.mesh->Dimension(), [](const mfem::Vector &position, mfem::Vector &value) {
value.SetSize(position.Size());
for (int dimension = 0; dimension < position.Size(); ++dimension) {
value(dimension) = -2.0 * position(dimension);
}
}
);
field.ProjectCoefficient(coefficient);
mfem::Vector displacementTrue;
field.GetTrueDofs(displacementTrue);
return displacementTrue;
}
} // namespace
TEST_CASE(
"Prepared Mapped Hdiv Mass Reports Invalid Candidate Geometry Without Unwinding",
tags::gravity_prepared_unit &tags::geometry
) {
auto args = test_utils::setup_args();
fem::FEM f = fem::setup_fem(args.mesh_file, args, 0);
REQUIRE(f.okay());
operators::PreparedMappedHDivMassOperator preparedOperator(f, *f.domainMapperStateless);
mfem::Vector displacement = preparedOperator.GetDisplacementMap().gather(make_folding_displacement(f));
const auto rejected = preparedOperator.TryPrepare(displacement);
REQUIRE_FALSE(rejected.has_value());
CHECK(rejected.error().reason == operators::HDivMassPreparationRejectionReason::invalid_mapping);
CHECK(rejected.error().mappingStatus == mapping::MappingStatus::non_positive_determinant);
CHECK_FALSE(preparedOperator.IsPrepared());
CHECK_FALSE(preparedOperator.HasVariationData());
CHECK(preparedOperator.GetPreparationCount() == 0);
CHECK_THROWS_AS(preparedOperator.Prepare(displacement), std::domain_error);
CHECK_FALSE(preparedOperator.IsPrepared());
CHECK(preparedOperator.GetPreparationCount() == 0);
displacement = 0.0;
const auto recovered = preparedOperator.TryPrepare(displacement);
REQUIRE(recovered.has_value());
CHECK(preparedOperator.IsPrepared());
CHECK(preparedOperator.HasVariationData());
CHECK(preparedOperator.GetPreparationCount() == 1);
}
TEST_CASE(
"Prepared Mapped Hdiv Mass Matches Stateless Kernel",
tags::gravity_prepared