test(tests): added test suite
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.
This commit is contained in:
82
tests/model/runtime_volume.cpp
Normal file
82
tests/model/runtime_volume.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#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());
|
||||
}
|
||||
Reference in New Issue
Block a user