#include #include #include #include #include #include #include #include #include "fesa/properties/general_beam_section.h" #include "fesa/properties/shell_section.h" namespace { fesa::SourceLocation PropertyLocation() { return {"models/property.inp", 40U}; } } // namespace TEST(ElementProperty, OwnsGeneralBeamSectionThroughVirtualBase) { static_assert(std::has_virtual_destructor_v); const fesa::SourceEntityId source_id{"", 4, "BeamSection"}; auto candidate = fesa::GeneralBeamSection::Create( source_id, "BeamSection", 0.02, 1.0e-5, 0.0, 2.0e-5, 5.0e-6, {0.0, 1.0, 0.0}, {{-0.1, 0.0}, {0.1, 0.0}}, PropertyLocation()); ASSERT_TRUE(candidate.HasValue()); std::unique_ptr property = std::make_unique(std::move(candidate.Value())); EXPECT_EQ(property->Kind(), fesa::ElementPropertyKind::kGeneralBeamSection); EXPECT_EQ(property->SourceId().source_label, 4); EXPECT_EQ(property->SourceId().source_label_text, "BeamSection"); const auto& section = static_cast(*property); EXPECT_EQ(section.Name(), "BeamSection"); EXPECT_DOUBLE_EQ(section.Area(), 0.02); EXPECT_DOUBLE_EQ(section.I11(), 1.0e-5); EXPECT_DOUBLE_EQ(section.I12(), 0.0); EXPECT_DOUBLE_EQ(section.I22(), 2.0e-5); EXPECT_DOUBLE_EQ(section.TorsionalConstant(), 5.0e-6); EXPECT_EQ(section.FirstAxis(), (std::array{0.0, 1.0, 0.0})); EXPECT_EQ(section.SectionPoints(), (std::vector>{{-0.1, 0.0}, {0.1, 0.0}})); EXPECT_EQ(section.Location().line, 40U); } TEST(ElementProperty, OwnsShellSectionThroughVirtualBase) { const fesa::SourceEntityId source_id{"", 8, "ShellSection"}; auto candidate = fesa::ShellSection::Create(source_id, "ShellSection", 0.01, fesa::EntityIndex{3}, PropertyLocation()); ASSERT_TRUE(candidate.HasValue()); std::unique_ptr property = std::make_unique(std::move(candidate.Value())); EXPECT_EQ(property->Kind(), fesa::ElementPropertyKind::kShellSection); EXPECT_EQ(property->SourceId().source_label, 8); const auto& section = static_cast(*property); EXPECT_EQ(section.Name(), "ShellSection"); EXPECT_DOUBLE_EQ(section.Thickness(), 0.01); EXPECT_EQ(section.MaterialIndex(), fesa::EntityIndex{3}); EXPECT_EQ(section.Location().file, "models/property.inp"); } TEST(ElementProperty, PreservesEmptyOptionalSectionPointInventory) { const auto section = fesa::GeneralBeamSection::Create( {"", 4, "BeamSection"}, "BeamSection", 0.02, 1.0e-5, 0.0, 2.0e-5, 5.0e-6, {0.0, 1.0, 0.0}, {}, PropertyLocation()); ASSERT_TRUE(section.HasValue()); EXPECT_TRUE(section.Value().SectionPoints().empty()); } TEST(ElementProperty, RejectsInvalidCurrentSectionFields) { const auto invalid_beam = fesa::GeneralBeamSection::Create( {"", 4, "BeamSection"}, "BeamSection", 0.0, 1.0e-5, 0.0, 2.0e-5, 5.0e-6, {0.0, 1.0, 0.0}, {}, PropertyLocation()); ASSERT_FALSE(invalid_beam.HasValue()); EXPECT_EQ(invalid_beam.GetStatus().Category(), fesa::FailureCategory::kModel); const auto coupled_beam = fesa::GeneralBeamSection::Create( {"", 4, "BeamSection"}, "BeamSection", 0.02, 1.0e-5, 1.0e-8, 2.0e-5, 5.0e-6, {0.0, 1.0, 0.0}, {}, PropertyLocation()); EXPECT_FALSE(coupled_beam.HasValue()); const auto nonfinite_point = fesa::GeneralBeamSection::Create( {"", 4, "BeamSection"}, "BeamSection", 0.02, 1.0e-5, 0.0, 2.0e-5, 5.0e-6, {0.0, 1.0, 0.0}, {{std::numeric_limits::quiet_NaN(), 0.0}}, PropertyLocation()); EXPECT_FALSE(nonfinite_point.HasValue()); const auto invalid_shell = fesa::ShellSection::Create({"", 8, "ShellSection"}, "ShellSection", 0.0, fesa::EntityIndex{3}, PropertyLocation()); ASSERT_FALSE(invalid_shell.HasValue()); EXPECT_EQ(invalid_shell.GetStatus().Category(), fesa::FailureCategory::kModel); }