#include #include #include #include #include #include #include "fesa/materials/isotropic_linear_elastic_material.h" namespace { fesa::SourceEntityId MaterialSourceId() { return {"", 7, "Steel"}; } fesa::SourceLocation MaterialLocation() { return {"models/material.inp", 30U}; } } // namespace TEST(Material, OwnsIsotropicElasticityThroughVirtualBase) { static_assert(std::has_virtual_destructor_v); auto candidate = fesa::IsotropicLinearElasticMaterial::Create( MaterialSourceId(), "Steel", 210.0e9, 0.3, MaterialLocation()); ASSERT_TRUE(candidate.HasValue()); std::unique_ptr material = std::make_unique( std::move(candidate.Value())); EXPECT_EQ(material->Kind(), fesa::MaterialKind::kIsotropicLinearElastic); EXPECT_EQ(material->SourceId().source_label, 7); EXPECT_EQ(material->SourceId().source_label_text, "Steel"); const auto& isotropic = static_cast(*material); EXPECT_EQ(isotropic.Name(), "Steel"); EXPECT_DOUBLE_EQ(isotropic.YoungsModulus(), 210.0e9); EXPECT_DOUBLE_EQ(isotropic.PoissonsRatio(), 0.3); EXPECT_EQ(isotropic.Location().file, "models/material.inp"); EXPECT_EQ(isotropic.Location().line, 30U); } TEST(Material, RejectsInvalidCurrentElasticFields) { const auto expect_rejected = [](double youngs_modulus, double poissons_ratio) { const auto result = fesa::IsotropicLinearElasticMaterial::Create( MaterialSourceId(), "Steel", youngs_modulus, poissons_ratio, MaterialLocation()); ASSERT_FALSE(result.HasValue()); EXPECT_EQ(result.GetStatus().Category(), fesa::FailureCategory::kModel); ASSERT_EQ(result.GetStatus().Diagnostics().size(), 1U); EXPECT_EQ(result.GetStatus().Diagnostics()[0].severity, fesa::Severity::kError); }; expect_rejected(0.0, 0.3); expect_rejected(std::numeric_limits::infinity(), 0.3); expect_rejected(210.0e9, -1.0); expect_rejected(210.0e9, std::numeric_limits::quiet_NaN()); const auto beam_compatible = fesa::IsotropicLinearElasticMaterial::Create( MaterialSourceId(), "Steel", 210.0e9, 0.75, MaterialLocation()); EXPECT_TRUE(beam_compatible.HasValue()); }