Files
FESADev/tests/integration/app/eigen_application_test.cpp
T
KOKO\Mimi 22c9d4435c feat: add eigen2 frequency pipeline and fail-closed validation
Implement MITC4 mass, constrained whitening, MKL FEAST, modal HDF5, and deterministic Value comparison. MSVC Debug builds; 394 of 395 tests pass. Original-model all-c residual and the documented S3 static contract conflict remain unresolved; this is an implementation checkpoint, not feature acceptance.
2026-09-09 03:14:30 +09:00

112 lines
2.9 KiB
C++

#include <gtest/gtest.h>
#include <hdf5.h>
#include <atomic>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <stdexcept>
#include <string>
#include "fesa/app/fesa_application.h"
namespace {
class EigenApplicationTest : public ::testing::Test {
protected:
void SetUp() override {
static std::atomic<unsigned long long> sequence{0U};
folder_ =
std::filesystem::temp_directory_path() /
("fesa-eigen-app-" +
std::to_string(
std::chrono::steady_clock::now().time_since_epoch().count()) +
"-" + std::to_string(sequence.fetch_add(1U)));
ASSERT_TRUE(std::filesystem::create_directory(folder_));
input_ = folder_ / "Panel.Modes.inp";
output_ = folder_ / "Panel.Modes_results.h5";
log_ = folder_ / "Panel.Modes_log.txt";
}
void TearDown() override {
std::error_code ignored;
std::filesystem::remove_all(folder_, ignored);
}
void WriteDeck(const bool empty = false) {
std::ofstream file{input_};
file << R"inp(*Part, name=Panel
*Node
11,0,0,0
22,1,0,0
33,1,1,0
44,0,1,0
*Element,type=S4
71,11,22,33,44
*Elset,elset=Shell
71
*Shell Section,elset=Shell,material=Steel
0.5
*End Part
*Assembly,name=Assembly
*Instance,name=Panel-1,part=Panel
*End Instance
*Nset,nset=Fixed,instance=Panel-1
11,22,33
*Nset,nset=Tip,instance=Panel-1
44
*End Assembly
*Material,name=Steel
*Density
1.
*Elastic
12.,0.
*Boundary
Fixed,1,6
Tip,1,2
Tip,4,6
)inp";
if (empty) file << "Tip,3,3\n";
file << R"inp(*Step,name=Step-2,nlgeom=NO,perturbation
*Frequency,eigensolver=Lanczos,normalization=mass
1
*End Step
)inp";
ASSERT_TRUE(file.good());
}
std::filesystem::path folder_, input_, output_, log_;
};
TEST_F(EigenApplicationTest, DispatchesFrequencyAndWritesModalSibling) {
WriteDeck();
ASSERT_EQ(fesa::FesaApplication{}.Run({input_.string()}), 0);
ASSERT_TRUE(std::filesystem::exists(output_));
ASSERT_TRUE(std::filesystem::exists(log_));
EXPECT_EQ(std::filesystem::file_size(log_), 0U);
const hid_t file =
H5Fopen(output_.string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
ASSERT_GE(file, 0);
EXPECT_GT(H5Lexists(file, "/steps/Step-1/eigen/modes", H5P_DEFAULT), 0);
EXPECT_GT(H5Lexists(file, "/steps/Step-1/eigen/vectors", H5P_DEFAULT), 0);
EXPECT_EQ(H5Lexists(file, "/steps/Step-1/frames", H5P_DEFAULT), 0);
EXPECT_GE(H5Fclose(file), 0);
}
TEST_F(EigenApplicationTest, EmptyPencilPreservesPreviousFinalAndEmptyLog) {
WriteDeck(true);
const std::string original = "previous authoritative file";
{
std::ofstream previous{output_, std::ios::binary};
previous << original;
}
EXPECT_EQ(fesa::FesaApplication{}.Run({input_.string()}), 4);
std::ifstream previous{output_, std::ios::binary};
EXPECT_TRUE(std::string(std::istreambuf_iterator<char>{previous}, {}) ==
original);
EXPECT_EQ(std::filesystem::file_size(log_), 0U);
}
} // namespace