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:
2026-11-09 13:53:17 -05:00
parent 74e55a6859
commit cb20faeb3d
202 changed files with 35505 additions and 953 deletions

View File

@@ -0,0 +1,102 @@
#include <array>
#include <limits>
#include <catch2/catch_test_macros.hpp>
#include "serif/discretization/blocks/vector_view.hpp"
#include "serif/operators/linearized_system_view.hpp"
#include "serif/utils/dependencies/dependencies.hpp"
namespace
{
namespace blocks = serif::discretization::blocks;
namespace dependencies = serif::utils::dependencies;
using Kind = blocks::RepresentedValueKind;
struct Density
{
};
struct Shape
{
};
struct Gradient
{
};
struct Potential
{
};
struct Enthalpy
{
};
struct MassConstraint
{
};
struct CentralConstraint
{
};
using Values = dependencies::KeyList<Density, Shape, Gradient, Potential, Enthalpy, MassConstraint, CentralConstraint>;
using Residuals = dependencies::KeyList<Gradient, Potential, Density, Shape, Enthalpy, MassConstraint, CentralConstraint>;
using Layout = blocks::SystemLayout<Values, Residuals>;
} // namespace
TEST_CASE("System layout preserves every uneven physical block in independent state and residual orders", "[preconditioner][layout][unit]")
{
// The original equilibrium_coordinates.cpp fixture deliberately totals 22 on both sides with different orders.
const Layout layout{.state_sizes = {2, 3, 4, 5, 6, 1, 1}, .residual_sizes = {4, 5, 2, 3, 6, 1, 1}};
CHECK(layout.total_size<Kind::value>() == 22);
CHECK(layout.total_size<Kind::residual>() == 22);
CHECK(layout.offset<Kind::value, Density>() == 0);
CHECK(layout.offset<Kind::residual, Density>() == 9);
CHECK(layout.offset<Kind::value, Enthalpy>() == 14);
CHECK(layout.offset<Kind::residual, Enthalpy>() == 14);
CHECK(layout.offset<Kind::value, MassConstraint>() == 20);
CHECK(layout.offset<Kind::value, CentralConstraint>() == 21);
std::array<double, 22> values{}, residuals{};
for (std::size_t index = 0; index < values.size(); ++index)
{
values[index] = 100.0 + index;
residuals[index] = -200.0 - index;
}
const blocks::StateView<Layout> state(layout, values);
const blocks::ResidualView<Layout, const double> residual(layout, residuals);
CHECK(state.get<Density>().data() == values.data());
CHECK(state.get<Enthalpy>().data() == values.data() + 14);
CHECK(residual.get<Density>().data() == residuals.data() + 9);
CHECK(residual.get<Gradient>().data() == residuals.data());
state.get<MassConstraint>()[0] = 5.0;
state.get<CentralConstraint>()[0] = 7.0;
CHECK(values[20] == 5.0);
CHECK(values[21] == 7.0);
CHECK(residual.get<Density>()[0] == -209.0);
}
TEST_CASE("Block vector views reject mismatched storage and overflowing coordinate metadata", "[preconditioner][layout][validation]")
{
Layout layout{.state_sizes = {2, 3, 4, 5, 6, 1, 1}, .residual_sizes = {4, 5, 2, 3, 6, 1, 1}};
std::array<double, 21> short_values{};
CHECK_THROWS(blocks::StateView<Layout>(layout, short_values));
std::array<double, 22> values{};
blocks::StateView<Layout> state(layout, values);
layout.state_sizes[0] = 23;
CHECK_THROWS(state.get<Density>());
layout.state_sizes[0] = std::numeric_limits<std::size_t>::max();
CHECK_THROWS(layout.total_size<Kind::value>());
CHECK_THROWS(layout.offset<Kind::value, Gradient>());
CHECK_THROWS(blocks::StateView<Layout>(layout, values));
const blocks::SystemLayout<dependencies::KeyList<>, dependencies::KeyList<>> empty{};
CHECK(empty.total_size<Kind::value>() == 0);
CHECK(empty.total_size<Kind::residual>() == 0);
}
TEST_CASE("Linearized system views borrow the declared physical blocks without changing their identity", "[preconditioner][layout][unit]")
{
using DensityBlock = serif::operators::PhysicalBlock<Density, Density>;
using SurfaceBlock = serif::operators::PhysicalBlock<Shape, Enthalpy>;
const Layout layout{.state_sizes = {2, 3, 4, 5, 6, 1, 1}, .residual_sizes = {4, 5, 2, 3, 6, 1, 1}};
const auto sources = dependencies::make_dependency_context(dependencies::own<DensityBlock>(std::array{2.0, 3.0}), dependencies::own<SurfaceBlock>(std::array{5.0, 7.0}));
const serif::operators::LinearizedSystemView system(layout, sources);
CHECK(&system.layout() == &layout);
CHECK(&system.blocks() == &sources);
CHECK(&system.block<Density, Density>() == &sources.get<DensityBlock>());
CHECK(&system.block<Shape, Enthalpy>() == &sources.get<SurfaceBlock>());
}