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.
83 lines
4.8 KiB
C++
83 lines
4.8 KiB
C++
#include <memory>
|
|
#include <catch2/catch_test_macros.hpp>
|
|
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
|
#include "serif/backend/mfem/model/discretization.hpp"
|
|
#include "serif/backend/mfem/model/inputs.hpp"
|
|
#include "serif/backend/mfem/model/system.hpp"
|
|
#include "serif/backend/mfem/model/volume.hpp"
|
|
#include "serif/tests/equations/fixture.hpp"
|
|
|
|
namespace {
|
|
namespace backend = serif::model::backend::mfem;
|
|
namespace equation_tests = serif::tests::equations;
|
|
namespace execution = serif::operators::backend::mfem;
|
|
using Catch::Matchers::WithinAbs;
|
|
} // namespace
|
|
|
|
TEST_CASE("Model and standalone volume inputs reject missing compactification spaces before access", "[model][runtime][equations][unit]") {
|
|
namespace dependencies = serif::utils::dependencies;
|
|
namespace blocks = serif::discretization::blocks;
|
|
using Registry = serif::equations::EquationRegistry<equation_tests::Closure>;
|
|
|
|
auto fixture = std::make_shared<equation_tests::Fixture>();
|
|
const auto density = fixture->density(), enthalpy = fixture->enthalpy();
|
|
const auto coefficients = fixture->state(density, enthalpy);
|
|
const ::mfem::GridFunction unbound_compactification;
|
|
const auto bindings = dependencies::make_dependency_context(
|
|
dependencies::borrow<blocks::density::mass>(fixture->density_binding),
|
|
dependencies::borrow<::serif::tests::equations::Enthalpy>(fixture->enthalpy_binding),
|
|
dependencies::borrow<blocks::displacement::vector>(fixture->displacement_binding));
|
|
const auto discretization = backend::make_stellar_discretization(fixture, bindings, unbound_compactification, fixture->mapper);
|
|
CHECK_THROWS_AS(backend::make_model_inputs<Registry>(discretization, coefficients), std::logic_error);
|
|
CHECK_THROWS_AS(execution::make_volume_inputs<equation_tests::Closure>(discretization.equation_discretization<blocks::density::mass>(), coefficients), std::logic_error);
|
|
}
|
|
|
|
TEST_CASE("Model volume geometry adapters retain the accepted equation and complete coordinate transpose", "[model][runtime][equations][integration]") {
|
|
auto fixture = std::make_shared<equation_tests::Fixture>();
|
|
std::weak_ptr<equation_tests::Fixture> lifetime = fixture;
|
|
const auto density = fixture->density();
|
|
auto enthalpy = fixture->enthalpy();
|
|
const auto displacement = fixture->displacement(0.35);
|
|
const auto direction = fixture->displacement(0.23);
|
|
const auto dual = equation_tests::deterministic(density.Size(), 0.47);
|
|
std::shared_ptr<const backend::PhysicalSystem> system;
|
|
::mfem::Vector expected_action, expected_transpose; {
|
|
equation_tests::PreparedClosure prepared(equation_tests::Closure{serif::eos::models::Polytrope{3.0, 1.5}}, fixture->density_binding, fixture->displacement_binding, fixture->compactification, fixture->mapper);
|
|
prepared.prepare(fixture->state(density, enthalpy), displacement, fixture->workspace);
|
|
const auto accepted = prepared.cache().share<execution::volume_keys::Linearization>();
|
|
const auto geometry = backend::volume_geometry_block(accepted);
|
|
system = backend::make_physical_system(density.Size(), displacement.Size(), {{0, backend::volume_residual_values(accepted)}}, {{0, 0, geometry}}, {}, fixture);
|
|
geometry.action()->Mult(direction, expected_action);
|
|
geometry.action()->MultTranspose(dual, expected_transpose);
|
|
CHECK_THAT(dual * expected_action, WithinAbs(direction * expected_transpose, 2.0e-12));
|
|
REQUIRE(expected_action.Norml2() > 0.0);
|
|
|
|
constexpr double step = 1.0e-6;
|
|
::mfem::Vector perturbed(displacement);
|
|
perturbed.Add(step, direction);
|
|
prepared.prepare(fixture->state(density, enthalpy), perturbed, fixture->workspace);
|
|
::mfem::Vector difference(prepared.data().residual);
|
|
perturbed = displacement;
|
|
perturbed.Add(-step, direction);
|
|
prepared.prepare(fixture->state(density, enthalpy), perturbed, fixture->workspace);
|
|
difference -= prepared.data().residual;
|
|
difference *= 0.5 / step;
|
|
CHECK(equation_tests::relative_error(expected_action, difference) < 2.0e-8);
|
|
|
|
enthalpy = -1.0;
|
|
CHECK_FALSE(prepared.try_prepare(fixture->state(density, enthalpy), displacement, fixture->workspace));
|
|
::mfem::Vector repeated;
|
|
geometry.action()->Mult(direction, repeated);
|
|
CHECK(equation_tests::relative_error(repeated, expected_action) == 0.0);
|
|
}
|
|
fixture.reset();
|
|
CHECK_FALSE(lifetime.expired());
|
|
::mfem::Vector action, transpose;
|
|
system->jacobian().action()->Mult(direction, action);
|
|
system->jacobian().action()->MultTranspose(dual, transpose);
|
|
CHECK(equation_tests::relative_error(action, expected_action) == 0.0);
|
|
CHECK(equation_tests::relative_error(transpose, expected_transpose) == 0.0);
|
|
system.reset();
|
|
CHECK(lifetime.expired());
|
|
}
|