fix(abaqus): map inline DS4 sets and reject beam sections

This commit is contained in:
KOKO\Mimi
2026-09-29 20:47:08 +09:00
parent 360f8df01d
commit 203d068951
2 changed files with 136 additions and 2 deletions
@@ -936,4 +936,115 @@ TEST(ThermalDomainMapping, RejectsMixedElementsAndWrongThermalMaterialScopes) {
}
}
TEST(ThermalDomainMapping, InlineElementSetResolvesSectionCaseInsensitively) {
auto deck = Replace(ThermalDeck(), "*Element, type=DS4",
"*Element, type=ds4, elset=inlineShells");
deck = Replace(deck, "*Elset, elset=E\n1\n", "");
deck = Replace(deck, "*Shell Section, elset=E",
"*Shell Section, elset=INLINESHELLS");
const TemporaryInput input{deck};
const auto parsed = fesa::AbaqusInputReader{}.Read(input.Path());
ASSERT_TRUE(parsed.HasValue());
const auto result = fesa::AbaqusDomainMapper{}.Map(parsed.Value());
ASSERT_TRUE(result.HasValue())
<< result.GetStatus().Diagnostics().front().message;
const auto& domain = result.Value();
ASSERT_EQ(domain.ElementSets().size(), 1U);
const auto& set = domain.ElementSets()[0];
EXPECT_EQ(set.name, "inlineShells");
EXPECT_EQ(set.instance_name, "I");
EXPECT_EQ(set.element_indices, std::vector<fesa::EntityIndex>{0U});
EXPECT_EQ(set.location.file, input.Path());
EXPECT_EQ(set.location.line, LineOf(deck, "*Element"));
ASSERT_EQ(domain.ThermalElements().Size(), 1U);
EXPECT_EQ(domain.ThermalElements()[0].ThermalSectionIndex(), 0U);
EXPECT_EQ(domain.ThermalSections()[0].name, "INLINESHELLS");
EXPECT_EQ(domain.ThermalSections()[0].location.line,
LineOf(deck, "*Shell Section"));
}
TEST(ThermalDomainMapping, InlineElementSetPreservesElementRowOrder) {
auto deck = Replace(ThermalDeck(), "*Element, type=DS4\n1, 1, 2, 3, 4",
"5,2,0,0\n6,3,0,0\n7,3,1,0\n8,2,1,0\n"
"*Element, type=DS4, elset=E\n7,1,2,3,4\n3,5,6,7,8");
deck = Replace(deck, "*Elset, elset=E\n1\n", "");
const auto result = MapText(deck);
ASSERT_TRUE(result.HasValue())
<< result.GetStatus().Diagnostics().front().message;
const auto& domain = result.Value();
ASSERT_EQ(domain.ElementSets().size(), 1U);
ASSERT_EQ(domain.ElementSets()[0].element_indices.size(), 2U);
EXPECT_EQ(domain.ElementSets()[0].element_indices,
(std::vector<fesa::EntityIndex>{0U, 1U}));
EXPECT_EQ(domain.ThermalElements()[0].SourceId().source_label, 7);
EXPECT_EQ(domain.ThermalElements()[1].SourceId().source_label, 3);
EXPECT_EQ(domain.ThermalElements()[0].ThermalSectionIndex(), 0U);
EXPECT_EQ(domain.ThermalElements()[1].ThermalSectionIndex(), 0U);
}
TEST(ThermalDomainMapping,
InlineElementSetRejectsInvalidAndDuplicateDefinitions) {
auto deck = Replace(ThermalDeck(), "*Elset, elset=E\n1\n", "");
for (const std::string option :
{"elset", "elset=", "elset=E, unknown=1", "elset=E, elset=e"}) {
SCOPED_TRACE(option);
const auto result = MapText(
Replace(deck, "*Element, type=DS4", "*Element, type=DS4, " + option));
ASSERT_FALSE(result.HasValue());
EXPECT_EQ(result.GetStatus().Diagnostics()[0].keyword, "ELEMENT");
EXPECT_EQ(result.GetStatus().Diagnostics()[0].location.line,
LineOf(deck, "*Element"));
}
ExpectRejected(Replace(ThermalDeck(), "*Element, type=DS4",
"*Element, type=DS4, elset=e"),
"ELSET");
deck = Replace(deck, "*Element, type=DS4", "*Element, type=DS4, elset=E");
ExpectRejected(
Replace(deck, "*Shell Section",
"*Element, type=DS4, elset=e\n2,1,2,3,4\n*Shell Section"),
"ELEMENT");
auto conflicting =
Replace(deck, "*Shell Section", "*Elset, elset=Other\n1\n*Shell Section");
conflicting =
Replace(conflicting, "*End Part",
"*Shell Section, elset=Other, material=M\n.5\n*End Part");
ExpectRejected(conflicting, "SHELL SECTION");
}
TEST(ThermalDomainMapping, RejectsBeamSectionAndBeamOnlyChildrenAtTheirSource) {
const std::string beam =
"*Beam General Section, elset=E, material=M, "
"section=GENERAL\n1,1,0,1,1\n1,0,0\n";
for (const std::string suffix :
{"", "*Section Points\n0,0\n", "*Transverse Shear Stiffness\n1,1,1\n"}) {
const auto deck =
Replace(ThermalDeck(), "*End Part", beam + suffix + "*End Part");
const auto result = MapText(deck);
ASSERT_FALSE(result.HasValue());
EXPECT_EQ(result.GetStatus().Diagnostics()[0].keyword,
"BEAM GENERAL SECTION");
EXPECT_EQ(result.GetStatus().Diagnostics()[0].location.line,
LineOf(deck, "*Beam General Section"));
}
ExpectRejected(
Replace(ThermalDeck(), "*End Part", "*Section Points\n0,0\n*End Part"),
"SECTION POINTS");
ExpectRejected(Replace(ThermalDeck(), "*End Part",
"*Transverse Shear Stiffness\n1,1,1\n*End Part"),
"TRANSVERSE SHEAR STIFFNESS");
}
TEST(ThermalDomainMapping, RejectsMalformedDs4ConnectivityAndElementOptions) {
for (const std::string row :
{"1,1,2,3", "1,1,2,3,4,1", "1,1,2,3,3", "1,0,2,3,4", "1,-1,2,3,4",
"1,1.5,2,3,4", "1,1,2,3,99", "0,1,2,3,4", "1.5,1,2,3,4",
"1,1,2,3,4\n1,1,2,3,4"}) {
SCOPED_TRACE(row);
ExpectRejected(Replace(ThermalDeck(), "1, 1, 2, 3, 4", row), "ELEMENT");
}
ExpectRejected(Replace(ThermalDeck(), "*Element, type=DS4",
"*Element, type=DS4, unknown=1"),
"ELEMENT");
}
} // namespace