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

@@ -1,5 +1,6 @@
#include <catch2/catch_test_macros.hpp>
#include <mfem.hpp>
#include <stdexcept>
import mean_field;
import test_helpers;
@@ -288,3 +289,75 @@ TEST_CASE(
CHECK(displacementEffect > 1.0e-8);
}
TEST_CASE(
"Prepared Hydrostatic Equilibrium Reports Candidate Mapping And Arithmetic Failures Without Unwinding",
tags::barotrope_hydrostatic_prepared_residual &tags::unit
) {
auto args = test_utils::setup_args();
mean_field::fem::FEM f = mean_field::fem::setup_fem(args.mesh_file, args, 0);
REQUIRE(f.okay());
mean_field::operators::PreparedHydrostaticEquilibriumOperator preparedOperator(f, *f.domainMapperStateless);
mfem::Vector enthalpy = prepared_hydrostatic_test_utils::make_enthalpy(f);
mfem::Vector gravityPotential = prepared_hydrostatic_test_utils::make_gravity_potential(f);
mfem::Vector displacement = field_dof_test_utils::make_supported_displacement(f, 0.73);
displacement *= 1.0e200;
auto dependencies = prepared_hydrostatic_test_utils::make_dependencies();
const auto rotation = prepared_hydrostatic_test_utils::make_rotation();
const auto mappingRejection = preparedOperator.TryPrepare(
prepared_hydrostatic_test_utils::make_state(enthalpy, gravityPotential, displacement, 0.41), dependencies,
rotation
);
REQUIRE_FALSE(mappingRejection.has_value());
CHECK(
(mappingRejection.error().reason ==
mean_field::operators::HydrostaticEquilibriumPreparationRejectionReason::inverted_geometry ||
mappingRejection.error().reason ==
mean_field::operators::HydrostaticEquilibriumPreparationRejectionReason::non_finite_geometry)
);
CHECK(mappingRejection.error().mappingStatus != mean_field::mapping::MappingStatus::valid);
CHECK_FALSE(preparedOperator.IsPrepared());
CHECK_THROWS_AS(
preparedOperator.Prepare(
prepared_hydrostatic_test_utils::make_state(enthalpy, gravityPotential, displacement, 0.41), dependencies,
rotation
),
std::domain_error
);
displacement = 0.0;
++dependencies.displacement.revision;
++dependencies.rotation.revision;
const auto enormousRotation = prepared_hydrostatic_test_utils::make_rotation(1.0e200);
const auto arithmeticRejection = preparedOperator.TryPrepare(
prepared_hydrostatic_test_utils::make_state(enthalpy, gravityPotential, displacement, 0.41), dependencies,
enormousRotation
);
REQUIRE_FALSE(arithmeticRejection.has_value());
CHECK(
arithmeticRejection.error().reason ==
mean_field::operators::HydrostaticEquilibriumPreparationRejectionReason::non_finite_residual
);
CHECK_FALSE(preparedOperator.IsPrepared());
CHECK_THROWS_AS(
preparedOperator.Prepare(
prepared_hydrostatic_test_utils::make_state(enthalpy, gravityPotential, displacement, 0.41), dependencies,
enormousRotation
),
std::domain_error
);
++dependencies.rotation.revision;
const auto recovered = preparedOperator.TryPrepare(
prepared_hydrostatic_test_utils::make_state(enthalpy, gravityPotential, displacement, 0.41), dependencies,
rotation
);
REQUIRE(recovered.has_value());
CHECK(recovered->preparedResidual);
CHECK(preparedOperator.IsPrepared());
}