From ac8d24a2cfe02009d66c443f8c6ccc6d92132663 Mon Sep 17 00:00:00 2001 From: "KOKO\\Mimi" Date: Sat, 1 Aug 2026 23:40:56 +0900 Subject: [PATCH] test(assembly): cover deterministic kernel failures --- .../unit/assembly/parallel_assembler_test.cpp | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tests/unit/assembly/parallel_assembler_test.cpp b/tests/unit/assembly/parallel_assembler_test.cpp index e10ff15..baaa3c2 100644 --- a/tests/unit/assembly/parallel_assembler_test.cpp +++ b/tests/unit/assembly/parallel_assembler_test.cpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include @@ -123,6 +125,59 @@ fesa::Domain build_beam_domain(const bool branched) { }); } +fesa::Domain build_multiple_kernel_failure_domain() { + fesa::DomainBuilder builder; + builder.add_node({ + fesa::NodeId{0}, + fesa::EntityOrigin{"BeamPart", "Beam-1", 1}, + fesa::Vec3{0.0, 0.0, 0.0}, + }); + builder.add_node({ + fesa::NodeId{1}, + fesa::EntityOrigin{"BeamPart", "Beam-1", 2}, + fesa::Vec3{1.0, 0.0, 0.0}, + }); + + auto material = fesa::IsotropicElastic{ + fesa::MaterialId{0}, + "Invalid", + std::numeric_limits::max(), + 0.3, + }; + builder.add_material(std::move(material)); + auto section = fesa::BeamSection{ + fesa::SectionId{0}, + "Invalid", + std::numeric_limits::max(), + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + fesa::ShearPropertySource::input, + fesa::Vec3{0.0, 1.0, 0.0}, + {}, + }; + builder.add_section(std::move(section)); + + builder.add_beam_element({ + fesa::ElementId{0}, + fesa::EntityOrigin{"BeamPart", "Beam-1", 20}, + {fesa::NodeId{0}, fesa::NodeId{1}}, + fesa::MaterialId{0}, + fesa::SectionId{0}, + }); + builder.add_beam_element({ + fesa::ElementId{1}, + fesa::EntityOrigin{"BeamPart", "Beam-1", 10}, + {fesa::NodeId{0}, fesa::NodeId{1}}, + fesa::MaterialId{0}, + fesa::SectionId{0}, + }); + + return finish_domain(std::move(builder), {"Load", {}, {}}); +} + std::vector bits(const std::vector& values) { std::vector result; result.reserve(values.size()); @@ -186,4 +241,26 @@ TEST(TbbElementEvaluation, RejectsZeroExecutionLimits) { std::invalid_argument); } +TEST(TbbElementEvaluation, ReportsFirstFailureByCanonicalElementOrigin) { + const fesa::Domain domain = build_multiple_kernel_failure_domain(); + const fesa::DofManager dofs = fesa::DofManager::build(domain); + + for (const std::size_t threads : {std::size_t{1}, std::size_t{4}}) { + SCOPED_TRACE(::testing::Message{} << "threads=" << threads); + try { + static_cast( + fesa::assemble_parallel(domain, dofs, {threads, 1})); + FAIL() << "Expected a Beam kernel failure."; + } catch (const std::runtime_error& error) { + const std::string message{error.what()}; + EXPECT_NE( + message.find("Beam element 10 kernel failed"), + std::string::npos); + EXPECT_EQ( + message.find("Beam element 20 kernel failed"), + std::string::npos); + } + } +} + } // namespace