diff --git a/tests/unit/io/abaqus/thermal_domain_test.cpp b/tests/unit/io/abaqus/thermal_domain_test.cpp index 40106e5..90bb15f 100644 --- a/tests/unit/io/abaqus/thermal_domain_test.cpp +++ b/tests/unit/io/abaqus/thermal_domain_test.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -14,7 +15,8 @@ class TemporaryInput final { public: explicit TemporaryInput(const std::string& content) : path_{std::filesystem::temp_directory_path() / - "fesa-thermal-domain.inp"} { + ("fesa-thermal-domain-" + std::to_string(next_id_.fetch_add(1U)) + + ".inp")} { std::ofstream output{path_, std::ios::binary | std::ios::trunc}; output << content; if (!output) throw std::runtime_error{"Unable to write thermal fixture."}; @@ -26,9 +28,12 @@ class TemporaryInput final { const std::filesystem::path& Path() const noexcept { return path_; } private: + static std::atomic next_id_; std::filesystem::path path_; }; +std::atomic TemporaryInput::next_id_{0U}; + fesa::Result MapText(const std::string& text) { const TemporaryInput input{text}; const auto parsed = fesa::AbaqusInputReader{}.Read(input.Path()); @@ -117,6 +122,60 @@ TEST(ThermalDomainMapping, RejectsInteriorAndConflictingThermalBoundaries) { "conflicting-boundary-condition"); } +TEST(ThermalDomainMapping, + AcceptsSectionPointSpellingsAndRejectsUnsupportedForms) { + const std::vector> cases{ + {".5\n", true}, {".5, 5\n", true}, {".5, 05\n", true}, + {".5, 4\n", false}, {".5, 6\n", false}, {".5, 5, 0.\n", false}}; + for (const auto& test_case : cases) { + SCOPED_TRACE(test_case.first); + auto deck = ThermalDeck(); + const auto start = deck.find(".5, 5\n"); + deck.replace(start, std::string{".5, 5\n"}.size(), test_case.first); + EXPECT_EQ(MapText(deck).HasValue(), test_case.second); + } +} + +TEST(ThermalDomainMapping, RejectsThermalMaterialAndControlForms) { + struct Case { + std::string from; + std::string to; + }; + const std::vector cases{ + {"54.,\n", "54., 1.\n"}, + {"460.,\n", "460.\n461.\n"}, + {"7850.,\n", "-1.,\n"}, + {"*Conductivity\n", "*Conductivity, dependencies=1\n"}, + {"*Specific Heat\n460.,\n", ""}, + {"*Heat Transfer\n1., 100.\n", + "*Heat Transfer, steady state\n1., 100.\n"}, + {"*Heat Transfer\n1., 100.\n", "*Heat Transfer\n0., 100.\n"}, + {"inc=100", "inc=99"}, + {"*Step, name=Heat, inc=100", "*Step, name=Heat, nlgeom=YES, inc=100"}, + {"*Step, name=Heat, inc=100", "*Step, name=Heat, perturbation, inc=100"}}; + for (const auto& test_case : cases) { + SCOPED_TRACE(test_case.to); + auto deck = ThermalDeck(); + const auto position = deck.find(test_case.from); + ASSERT_NE(position, std::string::npos); + deck.replace(position, test_case.from.size(), test_case.to); + EXPECT_FALSE(MapText(deck).HasValue()); + } +} + +TEST(ThermalDomainMapping, AppliesSameDofStepOverrideAndDefaultValues) { + auto deck = ThermalDeck(); + const auto first = deck.find("Bottom, 15, 15, 30."); + deck.replace(first, std::string{"Bottom, 15, 15, 30."}.size(), + "Bottom, 11, 11, 30."); + const auto result = MapText(deck); + ASSERT_TRUE(result.HasValue()); + ASSERT_EQ(result.Value().ThermalModelBoundaries().size(), 2U); + ASSERT_EQ(result.Value().ThermalStep()->Boundaries().size(), 2U); + EXPECT_DOUBLE_EQ(result.Value().ThermalModelBoundaries()[0U].value, 0.0); + EXPECT_DOUBLE_EQ(result.Value().ThermalStep()->Boundaries()[0U].value, 30.0); +} + TEST(ThermalDomainMapping, MapsApprovedShellThermalReference) { auto path = std::filesystem::path{__FILE__}.parent_path(); for (int index = 0; index < 4; ++index) path = path.parent_path();