feat(stroid): added command line and tests

This commit is contained in:
2026-01-30 13:21:43 -05:00
parent 58f59516ec
commit ce69b91fde
30 changed files with 975 additions and 46 deletions

View File

@@ -1 +1,27 @@
subdir('stroid_sandbox')
gtest_dep = dependency('gtest', main: true, required : true)
gtest_main = dependency('gtest_main', required: true)
gtest_nomain_dep = dependency('gtest', main: false, required : true)
# Test files for const
test_sources = [
'stroidTest.cpp'
]
foreach test_file : test_sources
exe_name = test_file.split('.')[0]
test_exe = executable(
exe_name,
test_file,
dependencies: [
stroid_dep,
gtest_dep,
gtest_main
],
)
test(
exe_name,
test_exe,
env: ['MESON_SOURCE_ROOT=' + meson.project_source_root(), 'MESON_BUILD_ROOT=' + meson.project_build_root()])
endforeach

220
tests/stroidTest.cpp Normal file
View File

@@ -0,0 +1,220 @@
#include <gtest/gtest.h>
#include "fourdst/config/config.h"
#include "stroid/config/config.h"
#include "stroid/IO/mesh.h"
#include "stroid/topology/curvilinear.h"
#include "stroid/topology/mapping.h"
#include "stroid/topology/topology.h"
#include <cmath>
#include <filesystem>
#include <cstdlib>
#include <string>
namespace {
constexpr double kPi = 3.14159265358979323846;
using Config = fourdst::config::Config<stroid::config::MeshConfig>;
std::filesystem::path GetSourceRoot() {
if (const char* env = std::getenv("MESON_SOURCE_ROOT")) {
return std::filesystem::path(env);
}
return std::filesystem::current_path();
}
Config LoadConfigFromRepo(const std::filesystem::path& relative_path) {
Config cfg;
cfg.load((GetSourceRoot() / relative_path).string());
return cfg;
}
bool IsFiniteMeshNodes(const mfem::Mesh& mesh) {
const mfem::GridFunction* nodes = mesh.GetNodes();
if (!nodes) {
return false;
}
const int vdim = nodes->FESpace()->GetVDim();
const int ndofs = nodes->FESpace()->GetNDofs();
for (int i = 0; i < ndofs; ++i) {
for (int d = 0; d < vdim; ++d) {
const double val = (*nodes)(nodes->FESpace()->DofToVDof(i, d));
if (!std::isfinite(val)) {
return false;
}
}
}
return true;
}
} // namespace
/**
* @brief Test suite for the Stroid library
*/
class stroidTest : public ::testing::Test {};
TEST_F(stroidTest, BuildSkeleton_DefaultCounts) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
ASSERT_NE(mesh, nullptr);
EXPECT_EQ(mesh->Dimension(), 3);
EXPECT_EQ(mesh->GetNV(), 16);
EXPECT_EQ(mesh->GetNE(), 7);
EXPECT_EQ(mesh->GetNBE(), 6);
}
TEST_F(stroidTest, Finalize_RefinementIncreasesElements) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
const int initial_elements = mesh->GetNE();
stroid::topology::Finalize(*mesh, cfg);
EXPECT_GT(mesh->GetNE(), initial_elements);
EXPECT_TRUE(mesh->Conforming());
}
TEST_F(stroidTest, PromoteToHighOrder_SetsNodes) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
stroid::topology::Finalize(*mesh, cfg);
stroid::topology::PromoteToHighOrder(*mesh, cfg);
EXPECT_NE(mesh->GetNodes(), nullptr);
EXPECT_TRUE(IsFiniteMeshNodes(*mesh));
}
TEST_F(stroidTest, ProjectMesh_ProducesFiniteNodes) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
stroid::topology::Finalize(*mesh, cfg);
stroid::topology::PromoteToHighOrder(*mesh, cfg);
stroid::topology::ProjectMesh(*mesh, cfg);
EXPECT_TRUE(IsFiniteMeshNodes(*mesh));
}
TEST_F(stroidTest, ApplyEquiangular_BasicTransform) {
mfem::Vector pos(3);
pos(0) = 1.0;
pos(1) = 0.5;
pos(2) = -0.25;
stroid::topology::ApplyEquiangular(pos);
const double expected_y = 1.0 * std::tan(kPi / 4.0 * (0.5 / 1.0));
const double expected_z = 1.0 * std::tan(kPi / 4.0 * (-0.25 / 1.0));
EXPECT_NEAR(pos(1), expected_y, 1e-12);
EXPECT_NEAR(pos(2), expected_z, 1e-12);
}
TEST_F(stroidTest, ApplySpheroidal_FlattensZ) {
const Config cfg = LoadConfigFromRepo("configs/test_flattening.toml");
mfem::Vector pos(3);
pos(0) = 0.0;
pos(1) = 0.0;
pos(2) = 10.0;
stroid::topology::ApplySpheroidal(pos, cfg);
EXPECT_NEAR(pos(2), 8.0, 1e-12);
}
TEST_F(stroidTest, ApplyKelvin_ExpandsOutsideStar) {
const Config cfg;
mfem::Vector pos(3);
pos(0) = 5.5;
pos(1) = 0.0;
pos(2) = 0.0;
stroid::topology::ApplyKelvin(pos, cfg);
EXPECT_NEAR(pos(0), 6.0, 1e-12);
EXPECT_NEAR(pos(1), 0.0, 1e-12);
EXPECT_NEAR(pos(2), 0.0, 1e-12);
}
TEST_F(stroidTest, TransformPoint_AxisInsideCore_NoChange) {
const Config cfg;
mfem::Vector pos(3);
pos(0) = 1.0;
pos(1) = 0.0;
pos(2) = 0.0;
stroid::topology::TransformPoint(pos, cfg, 0);
EXPECT_NEAR(pos(0), 1.0, 1e-12);
EXPECT_NEAR(pos(1), 0.0, 1e-12);
EXPECT_NEAR(pos(2), 0.0, 1e-12);
}
TEST_F(stroidTest, TransformPoint_AxisEnvelope_NoChange) {
const Config cfg;
mfem::Vector pos(3);
pos(0) = 3.0;
pos(1) = 0.0;
pos(2) = 0.0;
stroid::topology::TransformPoint(pos, cfg, 0);
EXPECT_NEAR(pos(0), 3.0, 1e-12);
EXPECT_NEAR(pos(1), 0.0, 1e-12);
EXPECT_NEAR(pos(2), 0.0, 1e-12);
}
TEST_F(stroidTest, TransformPoint_AxisOutsideStar_KelvinExpands) {
const Config cfg;
mfem::Vector pos(3);
pos(0) = 5.5;
pos(1) = 0.0;
pos(2) = 0.0;
stroid::topology::TransformPoint(pos, cfg, 0);
EXPECT_NEAR(pos(0), 6.0, 1e-12);
EXPECT_NEAR(pos(1), 0.0, 1e-12);
EXPECT_NEAR(pos(2), 0.0, 1e-12);
}
TEST_F(stroidTest, SaveMesh_WritesFile) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
stroid::topology::Finalize(*mesh, cfg);
const std::filesystem::path tmp_dir = std::filesystem::temp_directory_path();
const std::filesystem::path mesh_path = tmp_dir / "stroid_test_mesh.mesh";
stroid::IO::SaveMesh(*mesh, mesh_path.string());
ASSERT_TRUE(std::filesystem::exists(mesh_path));
EXPECT_GT(std::filesystem::file_size(mesh_path), 0u);
std::error_code ec;
std::filesystem::remove(mesh_path, ec);
}
TEST_F(stroidTest, EndToEnd_BuildFinalizePromoteProject) {
const Config cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
stroid::topology::Finalize(*mesh, cfg);
stroid::topology::PromoteToHighOrder(*mesh, cfg);
stroid::topology::ProjectMesh(*mesh, cfg);
EXPECT_GT(mesh->GetNE(), 0);
EXPECT_NE(mesh->GetNodes(), nullptr);
EXPECT_TRUE(IsFiniteMeshNodes(*mesh));
}

View File

@@ -1,27 +0,0 @@
#include <print>
#include "stroid/topology/topology.h"
#include "stroid/config/config.h"
#include "stroid/IO/mesh.h"
#include <memory>
#include "mfem.hpp"
#include "stroid/topology/curvilinear.h"
#include "stroid/utils/mesh_utils.h"
#include "fourdst/config/config.h"
int main() {
const fourdst::config::Config<stroid::config::MeshConfig> cfg;
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
stroid::topology::Finalize(*mesh, cfg);
stroid::topology::PromoteToHighOrder(*mesh, cfg);
stroid::topology::ProjectMesh(*mesh, cfg);
//
// stroid::utils::MarkFlippedElements(*mesh);
// stroid::utils::MarkFlippedBoundaryElements(*mesh);
stroid::IO::ViewMesh(*mesh, "Spheroidal Mesh", stroid::IO::VISUALIZATION_MODE::BOUNDARY_ELEMENT_ID);
// stroid::IO::VisualizeFaceValence(*mesh);
// stroid::IO::SaveVTU(*mesh, "SpheroidalMesh");
}

View File

@@ -1 +0,0 @@
executable('stroid_sandbox', 'main.cpp', dependencies: stroid_dep)