feat(cpp-object-oriented-modular-refactoring): step 13 - element-definition-domain
This commit is contained in:
@@ -307,7 +307,7 @@ class CapturingResultsWriter final : public fesa::ResultsWriter {
|
||||
const std::vector<fesa::Diagnostic>& diagnostics) override {
|
||||
output_path_ = output_path;
|
||||
node_count_ = domain.Nodes().size();
|
||||
shell_element_count_ = domain.ShellElements().size();
|
||||
shell_element_count_ = domain.ShellElements().Size();
|
||||
state_ = std::make_unique<fesa::AnalysisState>(state);
|
||||
diagnostics_ = diagnostics;
|
||||
return fesa::Status::Ok();
|
||||
|
||||
@@ -815,7 +815,7 @@ HdfProjection ReadHdfProjection(const std::filesystem::path& results,
|
||||
projection.nodes = ReadNodeRows(file.Get());
|
||||
projection.elements = ReadElementRows(file.Get());
|
||||
if (projection.nodes.size() != domain.Nodes().size() ||
|
||||
projection.elements.size() != domain.Elements().size()) {
|
||||
projection.elements.size() != domain.BeamElements().Size()) {
|
||||
Fail("schema-mismatch",
|
||||
"HDF5 model identity counts do not match the input.");
|
||||
}
|
||||
@@ -834,7 +834,7 @@ HdfProjection ReadHdfProjection(const std::filesystem::path& results,
|
||||
for (std::size_t element = 0U; element < projection.elements.size();
|
||||
++element) {
|
||||
const auto& actual = projection.elements[element];
|
||||
const auto& expected = domain.Elements()[element];
|
||||
const auto& expected = domain.BeamElements()[element];
|
||||
if (actual.internal_element_id != element ||
|
||||
actual.instance_name != expected.source_id.instance_name ||
|
||||
actual.source_element_label != expected.source_id.source_label ||
|
||||
|
||||
@@ -77,6 +77,19 @@ fesa::ModelDefinition MakeDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
fesa::ModelDefinition MakeMixedDefinition() {
|
||||
auto definition = MakeDefinition();
|
||||
const auto source = definition.source_path;
|
||||
definition.shell_sections = {{"ShellSection", 0.01, 1U, {source, 35U}}};
|
||||
definition.shell_elements = {{{"Shell-1", 5, "5"},
|
||||
fesa::ShellSourceElementType::kS4,
|
||||
{0U, 1U, 2U, 3U},
|
||||
1U,
|
||||
0U,
|
||||
{source, 45U}}};
|
||||
return definition;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(AnalysisModel, ClassifiesActiveEntitiesInStableOrder) {
|
||||
@@ -102,9 +115,9 @@ TEST(AnalysisModel, ReferencesWithoutCopyingOrMutatingDomain) {
|
||||
auto domain_result = fesa::Domain::Create(MakeDefinition());
|
||||
ASSERT_TRUE(domain_result.HasValue());
|
||||
const fesa::Domain& domain = domain_result.Value();
|
||||
const auto* const element_address = domain.Elements().data();
|
||||
const auto* const material_address = domain.Materials().data();
|
||||
const auto* const section_address = domain.Sections().data();
|
||||
const auto* const element_address = &domain.Elements()[0U];
|
||||
const auto* const material_address = &domain.Materials()[0U];
|
||||
const auto* const section_address = &domain.Sections()[0U];
|
||||
const std::string step_name = domain.Steps()[0].name;
|
||||
const double first_load_magnitude = domain.Steps()[0].loads[0].magnitude;
|
||||
|
||||
@@ -114,9 +127,9 @@ TEST(AnalysisModel, ReferencesWithoutCopyingOrMutatingDomain) {
|
||||
|
||||
EXPECT_EQ(&model.GetDomain(), &domain);
|
||||
EXPECT_EQ(&model.Step(), &domain.Steps()[0]);
|
||||
EXPECT_EQ(model.GetDomain().Elements().data(), element_address);
|
||||
EXPECT_EQ(model.GetDomain().Materials().data(), material_address);
|
||||
EXPECT_EQ(model.GetDomain().Sections().data(), section_address);
|
||||
EXPECT_EQ(&model.GetDomain().Elements()[0U], element_address);
|
||||
EXPECT_EQ(&model.GetDomain().Materials()[0U], material_address);
|
||||
EXPECT_EQ(&model.GetDomain().Sections()[0U], section_address);
|
||||
EXPECT_EQ(&model.GetDomain().Elements()[model.ActiveElements()[1]],
|
||||
&domain.Elements()[1]);
|
||||
EXPECT_EQ(&model.GetDomain().Materials()[model.ActiveMaterials()[2]],
|
||||
@@ -127,6 +140,31 @@ TEST(AnalysisModel, ReferencesWithoutCopyingOrMutatingDomain) {
|
||||
EXPECT_DOUBLE_EQ(domain.Steps()[0].loads[0].magnitude, first_load_magnitude);
|
||||
}
|
||||
|
||||
// C-MODEL-002
|
||||
TEST(AnalysisModel, KeepsNonOwningMixedDefinitionAndPropertyIndices) {
|
||||
auto domain_result = fesa::Domain::Create(MakeMixedDefinition());
|
||||
ASSERT_TRUE(domain_result.HasValue());
|
||||
const fesa::Domain& domain = domain_result.Value();
|
||||
|
||||
auto model_result = fesa::AnalysisModel::Create(domain);
|
||||
ASSERT_TRUE(model_result.HasValue());
|
||||
const fesa::AnalysisModel& model = model_result.Value();
|
||||
|
||||
EXPECT_EQ(&model.GetDomain(), &domain);
|
||||
EXPECT_EQ(model.ActiveElements(),
|
||||
(std::vector<fesa::EntityIndex>{0U, 1U, 2U, 3U, 4U}));
|
||||
EXPECT_EQ(model.ActiveMaterials(),
|
||||
(std::vector<fesa::EntityIndex>{0U, 1U, 2U}));
|
||||
EXPECT_EQ(model.ActiveProperties(),
|
||||
(std::vector<fesa::EntityIndex>{0U, 1U, 2U, 4U}));
|
||||
EXPECT_EQ(&model.GetDomain().Elements()[model.ActiveElements()[4U]],
|
||||
&domain.Elements()[4U]);
|
||||
EXPECT_EQ(&model.GetDomain().Materials()[model.ActiveMaterials()[1U]],
|
||||
&domain.Materials()[1U]);
|
||||
EXPECT_EQ(&model.GetDomain().Properties()[model.ActiveProperties()[3U]],
|
||||
&domain.Properties()[4U]);
|
||||
}
|
||||
|
||||
TEST(AnalysisModel, RejectsMissingOrMultipleStep) {
|
||||
auto missing_definition = MakeDefinition();
|
||||
missing_definition.steps.clear();
|
||||
|
||||
@@ -103,7 +103,7 @@ fesa::ModelDefinition MakeShellDefinition(
|
||||
|
||||
fesa::Result<fesa::Mitc4Stiffness> DirectShellStiffness(
|
||||
const fesa::Domain& domain, const fesa::EntityIndex element_index) {
|
||||
const auto& definition = domain.ShellElements().at(element_index);
|
||||
const auto& definition = domain.ShellElements().At(element_index);
|
||||
std::array<const fesa::Node*, 4> nodes{};
|
||||
std::array<std::array<double, 3>, 4> directors{};
|
||||
for (std::size_t node = 0U; node < definition.node_indices.size(); ++node) {
|
||||
@@ -112,8 +112,8 @@ fesa::Result<fesa::Mitc4Stiffness> DirectShellStiffness(
|
||||
directors[node] = domain.ShellNodeInitialFrames().at(node_index).director;
|
||||
}
|
||||
auto shell = fesa::Mitc4Shell::Create(
|
||||
nodes, directors, domain.ShellSections().at(definition.section_index),
|
||||
domain.Materials().at(definition.material_index));
|
||||
nodes, directors, domain.ShellSections().At(definition.section_index),
|
||||
domain.LinearElasticMaterials().At(definition.material_index));
|
||||
if (!shell.HasValue()) {
|
||||
return fesa::Result<fesa::Mitc4Stiffness>::Failure(shell.GetStatus());
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/element_definition.h"
|
||||
#include "fesa/io/abaqus/input_reader.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
@@ -242,6 +243,7 @@ RootAssembly, 6, -12.5
|
||||
} // namespace
|
||||
|
||||
// C-DUP-002
|
||||
// C-MODEL-002
|
||||
TEST(InpDomainMapping, MapsEverySupportedKeywordAndLegacyDeck) {
|
||||
auto result = MapText("supported-inventory", SupportedInventoryDeck(true));
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
@@ -254,17 +256,23 @@ TEST(InpDomainMapping, MapsEverySupportedKeywordAndLegacyDeck) {
|
||||
EXPECT_EQ(domain.Nodes()[1].source_id.source_label_text, "0002");
|
||||
EXPECT_DOUBLE_EQ(domain.Nodes()[1].coordinates[0], 2.0);
|
||||
|
||||
ASSERT_EQ(domain.Elements().size(), 1U);
|
||||
EXPECT_EQ(domain.Elements()[0].source_id.source_label_text, "0007");
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices[0], 0U);
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices[1], 1U);
|
||||
ASSERT_EQ(domain.Elements().Size(), 1U);
|
||||
const fesa::ElementDefinition& element = domain.Elements()[0U];
|
||||
EXPECT_EQ(element.Kind(), fesa::ElementDefinitionKind::kEulerBeam3D);
|
||||
EXPECT_EQ(element.SourceId().source_label_text, "0007");
|
||||
EXPECT_EQ(element.SourceElementType(), "B33");
|
||||
EXPECT_EQ(element.NodeIndices(), (std::vector<fesa::EntityIndex>{0U, 1U}));
|
||||
EXPECT_EQ(&element, &domain.BeamElements()[0U]);
|
||||
|
||||
ASSERT_EQ(domain.Materials().size(), 1U);
|
||||
EXPECT_EQ(domain.Materials()[0].name, "Steel");
|
||||
EXPECT_DOUBLE_EQ(domain.Materials()[0].youngs_modulus, 210000.0);
|
||||
EXPECT_DOUBLE_EQ(domain.Materials()[0].poisson_ratio, 0.75);
|
||||
ASSERT_EQ(domain.Materials().Size(), 1U);
|
||||
EXPECT_EQ(domain.Materials()[0U].Kind(),
|
||||
fesa::MaterialKind::kIsotropicLinearElastic);
|
||||
EXPECT_EQ(domain.LinearElasticMaterials()[0U].name, "Steel");
|
||||
EXPECT_DOUBLE_EQ(domain.LinearElasticMaterials()[0U].youngs_modulus,
|
||||
210000.0);
|
||||
EXPECT_DOUBLE_EQ(domain.LinearElasticMaterials()[0U].poisson_ratio, 0.75);
|
||||
|
||||
ASSERT_EQ(domain.Sections().size(), 1U);
|
||||
ASSERT_EQ(domain.Sections().Size(), 1U);
|
||||
const auto& section = domain.Sections()[0];
|
||||
EXPECT_DOUBLE_EQ(section.area, 2.0);
|
||||
EXPECT_DOUBLE_EQ(section.i11, 3.0);
|
||||
@@ -274,8 +282,8 @@ TEST(InpDomainMapping, MapsEverySupportedKeywordAndLegacyDeck) {
|
||||
EXPECT_EQ(section.first_axis, (std::array<double, 3>{0.0, 1.0, 0.0}));
|
||||
EXPECT_EQ(section.section_points,
|
||||
(std::vector<std::array<double, 2>>{{-0.5, 0.25}, {0.5, -0.25}}));
|
||||
EXPECT_EQ(domain.Elements()[0].material_index, 0U);
|
||||
EXPECT_EQ(domain.Elements()[0].section_index, 0U);
|
||||
EXPECT_EQ(domain.BeamElements()[0U].material_index, 0U);
|
||||
EXPECT_EQ(domain.BeamElements()[0U].section_index, 0U);
|
||||
|
||||
ASSERT_EQ(domain.Steps().size(), 1U);
|
||||
const auto& step = domain.Steps()[0];
|
||||
@@ -305,9 +313,9 @@ TEST(InpDomainMapping, MapsEverySupportedKeywordAndLegacyDeck) {
|
||||
auto legacy = fesa::AbaqusDomainMapper{}.Map(parsed_legacy.Value());
|
||||
ASSERT_TRUE(legacy.HasValue());
|
||||
EXPECT_EQ(legacy.Value().Nodes().size(), 11U);
|
||||
EXPECT_EQ(legacy.Value().Elements().size(), 10U);
|
||||
EXPECT_EQ(legacy.Value().Materials().size(), 1U);
|
||||
EXPECT_EQ(legacy.Value().Sections().size(), 1U);
|
||||
EXPECT_EQ(legacy.Value().Elements().Size(), 10U);
|
||||
EXPECT_EQ(legacy.Value().Materials().Size(), 1U);
|
||||
EXPECT_EQ(legacy.Value().Sections().Size(), 1U);
|
||||
EXPECT_EQ(legacy.Value().Steps().size(), 1U);
|
||||
EXPECT_EQ(legacy.Value().Warnings().size(), 7U);
|
||||
EXPECT_EQ(ReadExactBytes(legacy_path), bytes_before);
|
||||
@@ -367,12 +375,12 @@ OnlySecond, 2, 5.
|
||||
EXPECT_EQ(domain.Nodes()[3].source_id.instance_name, "Second");
|
||||
EXPECT_EQ(domain.Nodes()[3].source_id.source_label, 20);
|
||||
|
||||
ASSERT_EQ(domain.Elements().size(), 2U);
|
||||
EXPECT_EQ(domain.Elements()[0].source_id.instance_name, "First");
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices,
|
||||
ASSERT_EQ(domain.BeamElements().Size(), 2U);
|
||||
EXPECT_EQ(domain.BeamElements()[0].source_id.instance_name, "First");
|
||||
EXPECT_EQ(domain.BeamElements()[0].node_indices,
|
||||
(std::array<fesa::EntityIndex, 2>{0U, 1U}));
|
||||
EXPECT_EQ(domain.Elements()[1].source_id.instance_name, "Second");
|
||||
EXPECT_EQ(domain.Elements()[1].node_indices,
|
||||
EXPECT_EQ(domain.BeamElements()[1].source_id.instance_name, "Second");
|
||||
EXPECT_EQ(domain.BeamElements()[1].node_indices,
|
||||
(std::array<fesa::EntityIndex, 2>{2U, 3U}));
|
||||
|
||||
ASSERT_EQ(domain.NodeSets().size(), 3U);
|
||||
@@ -525,12 +533,12 @@ TEST(InpDomainMapping, NoOpAllowlistWarnsWithoutSemanticEffect) {
|
||||
}
|
||||
|
||||
EXPECT_EQ(with_no_ops.Value().Nodes().size(), plain.Value().Nodes().size());
|
||||
EXPECT_EQ(with_no_ops.Value().Elements().size(),
|
||||
plain.Value().Elements().size());
|
||||
EXPECT_EQ(with_no_ops.Value().Materials().size(),
|
||||
plain.Value().Materials().size());
|
||||
EXPECT_EQ(with_no_ops.Value().Sections().size(),
|
||||
plain.Value().Sections().size());
|
||||
EXPECT_EQ(with_no_ops.Value().Elements().Size(),
|
||||
plain.Value().Elements().Size());
|
||||
EXPECT_EQ(with_no_ops.Value().Materials().Size(),
|
||||
plain.Value().Materials().Size());
|
||||
EXPECT_EQ(with_no_ops.Value().Sections().Size(),
|
||||
plain.Value().Sections().Size());
|
||||
EXPECT_EQ(with_no_ops.Value().NodeSets().size(),
|
||||
plain.Value().NodeSets().size());
|
||||
EXPECT_EQ(with_no_ops.Value().ElementSets().size(),
|
||||
@@ -543,13 +551,20 @@ TEST(InpDomainMapping, NoOpAllowlistWarnsWithoutSemanticEffect) {
|
||||
}
|
||||
|
||||
// MITC4-MAP-001
|
||||
// C-MODEL-002
|
||||
TEST(InpDomainMapping, MapsS4AndS4rThroughOneMitc4Identity) {
|
||||
auto result = MapText("mitc4-map-001", ShellDeck());
|
||||
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
const fesa::Domain& domain = result.Value();
|
||||
EXPECT_TRUE(domain.Elements().empty());
|
||||
ASSERT_EQ(domain.ShellElements().size(), 4U);
|
||||
EXPECT_TRUE(domain.BeamElements().Empty());
|
||||
ASSERT_EQ(domain.Elements().Size(), 4U);
|
||||
EXPECT_EQ(domain.Elements()[0U].Kind(),
|
||||
fesa::ElementDefinitionKind::kMitc4Shell);
|
||||
EXPECT_EQ(domain.Elements()[0U].SourceElementType(), "S4");
|
||||
EXPECT_EQ(domain.Elements()[1U].SourceElementType(), "S4R");
|
||||
EXPECT_EQ(&domain.Elements()[0U], &domain.ShellElements()[0U]);
|
||||
ASSERT_EQ(domain.ShellElements().Size(), 4U);
|
||||
EXPECT_EQ(domain.ShellElements()[0].source_id.instance_name, "First");
|
||||
EXPECT_EQ(domain.ShellElements()[0].source_id.source_label_text, "0010");
|
||||
EXPECT_EQ(domain.ShellElements()[0].source_type,
|
||||
@@ -573,7 +588,7 @@ TEST(InpDomainMapping, MapsS4AndS4rThroughOneMitc4Identity) {
|
||||
EXPECT_EQ(domain.ShellElements()[3].source_id.instance_name, "Second");
|
||||
EXPECT_EQ(fesa::kMitc4InternalFormulation, std::string_view{"FESA-MITC4"});
|
||||
|
||||
ASSERT_EQ(domain.ShellSections().size(), 2U);
|
||||
ASSERT_EQ(domain.ShellSections().Size(), 2U);
|
||||
EXPECT_EQ(domain.ShellSections()[0].name, "ShellS4");
|
||||
EXPECT_DOUBLE_EQ(domain.ShellSections()[0].thickness, 0.1);
|
||||
EXPECT_EQ(domain.ShellSections()[0].material_index, 0U);
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/element_definition.h"
|
||||
|
||||
namespace {
|
||||
|
||||
fesa::ModelDefinition MakeOwnedDefinition() {
|
||||
@@ -63,6 +65,90 @@ fesa::ModelDefinition MakeOwnedDefinition() {
|
||||
|
||||
} // namespace
|
||||
|
||||
// C-MODEL-002
|
||||
TEST(ElementDefinition, DomainOwnsMixedDefinitionsInStableBaseOrder) {
|
||||
static_assert(std::has_virtual_destructor_v<fesa::ElementDefinition>);
|
||||
static_assert(!std::is_copy_constructible_v<fesa::Domain>);
|
||||
static_assert(!std::is_copy_assignable_v<fesa::Domain>);
|
||||
static_assert(std::is_move_constructible_v<fesa::Domain>);
|
||||
static_assert(std::is_move_assignable_v<fesa::Domain>);
|
||||
|
||||
fesa::ModelDefinition definition{};
|
||||
definition.source_path = "models/mixed-owned.inp";
|
||||
definition.source_content_identity = "fnv1a64:mixed";
|
||||
definition.materials = {
|
||||
{"Steel", 210.0e9, 0.3, {definition.source_path, 30U}}};
|
||||
definition.sections = {{"BeamSection",
|
||||
0.02,
|
||||
1.0e-5,
|
||||
0.0,
|
||||
2.0e-5,
|
||||
5.0e-6,
|
||||
{0.0, 1.0, 0.0},
|
||||
{},
|
||||
{definition.source_path, 40U}}};
|
||||
definition.shell_sections = {
|
||||
{"ShellSection", 0.01, 0U, {definition.source_path, 41U}}};
|
||||
definition.elements = {
|
||||
{{"Beam-1", 7, "0007"}, {0U, 1U}, 0U, 0U, {definition.source_path, 20U}}};
|
||||
definition.shell_elements = {{{"Shell-1", 9, "0009"},
|
||||
fesa::ShellSourceElementType::kS4r,
|
||||
{2U, 3U, 4U, 5U},
|
||||
0U,
|
||||
0U,
|
||||
{definition.source_path, 21U}}};
|
||||
|
||||
auto result = fesa::Domain::Create(definition);
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
fesa::Domain domain = std::move(result.Value());
|
||||
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().Elements()[0U]),
|
||||
const fesa::ElementDefinition&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().Materials()[0U]),
|
||||
const fesa::Material&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().Properties()[0U]),
|
||||
const fesa::ElementProperty&>);
|
||||
|
||||
ASSERT_EQ(domain.Elements().Size(), 2U);
|
||||
const fesa::ElementDefinition& beam = domain.Elements()[0U];
|
||||
EXPECT_EQ(beam.Kind(), fesa::ElementDefinitionKind::kEulerBeam3D);
|
||||
EXPECT_EQ(beam.SourceId().source_label_text, "0007");
|
||||
EXPECT_EQ(beam.SourceElementType(), "B33");
|
||||
EXPECT_EQ(beam.NodeIndices(), (std::vector<fesa::EntityIndex>{0U, 1U}));
|
||||
EXPECT_EQ(beam.MaterialIndex(), fesa::EntityIndex{0U});
|
||||
EXPECT_EQ(beam.PropertyIndex(), fesa::EntityIndex{0U});
|
||||
|
||||
const fesa::ElementDefinition& shell = domain.Elements()[1U];
|
||||
EXPECT_EQ(shell.Kind(), fesa::ElementDefinitionKind::kMitc4Shell);
|
||||
EXPECT_EQ(shell.SourceId().source_label_text, "0009");
|
||||
EXPECT_EQ(shell.SourceElementType(), "S4R");
|
||||
EXPECT_EQ(shell.NodeIndices(),
|
||||
(std::vector<fesa::EntityIndex>{2U, 3U, 4U, 5U}));
|
||||
EXPECT_EQ(shell.MaterialIndex(), fesa::EntityIndex{0U});
|
||||
EXPECT_EQ(shell.PropertyIndex(), fesa::EntityIndex{1U});
|
||||
|
||||
ASSERT_EQ(domain.BeamElements().Size(), 1U);
|
||||
ASSERT_EQ(domain.ShellElements().Size(), 1U);
|
||||
EXPECT_EQ(&domain.BeamElements()[0U], &beam);
|
||||
EXPECT_EQ(&domain.ShellElements()[0U], &shell);
|
||||
|
||||
ASSERT_EQ(domain.Materials().Size(), 1U);
|
||||
EXPECT_EQ(domain.Materials()[0U].Kind(),
|
||||
fesa::MaterialKind::kIsotropicLinearElastic);
|
||||
EXPECT_EQ(&domain.LinearElasticMaterials()[0U], &domain.Materials()[0U]);
|
||||
|
||||
ASSERT_EQ(domain.Properties().Size(), 2U);
|
||||
EXPECT_EQ(domain.Properties()[0U].Kind(),
|
||||
fesa::ElementPropertyKind::kGeneralBeamSection);
|
||||
EXPECT_EQ(domain.Properties()[1U].Kind(),
|
||||
fesa::ElementPropertyKind::kShellSection);
|
||||
EXPECT_EQ(&domain.Sections()[0U], &domain.Properties()[0U]);
|
||||
EXPECT_EQ(&domain.ShellSections()[0U], &domain.Properties()[1U]);
|
||||
}
|
||||
|
||||
TEST(DomainModel, ImmutableOwnershipPreservesStableOrder) {
|
||||
auto definition = MakeOwnedDefinition();
|
||||
auto result = fesa::Domain::Create(definition);
|
||||
@@ -81,9 +167,9 @@ TEST(DomainModel, ImmutableOwnershipPreservesStableOrder) {
|
||||
static_assert(
|
||||
std::is_same_v<decltype(std::declval<const fesa::Domain&>().Nodes()),
|
||||
const std::vector<fesa::Node>&>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(std::declval<const fesa::Domain&>().Elements()),
|
||||
const std::vector<fesa::EulerBeam3DDefinition>&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().Elements()),
|
||||
const fesa::DomainCollectionView<fesa::ElementDefinition>&>);
|
||||
|
||||
EXPECT_EQ(domain.SourcePath(), std::filesystem::path{"models/owned.inp"});
|
||||
EXPECT_EQ(domain.SourceContentIdentity(), "fnv1a64:fedcba9876543210");
|
||||
@@ -94,11 +180,11 @@ TEST(DomainModel, ImmutableOwnershipPreservesStableOrder) {
|
||||
EXPECT_EQ(domain.Nodes()[1].source_id.source_label, 10);
|
||||
EXPECT_EQ(domain.Nodes().data(), first_node_address);
|
||||
|
||||
ASSERT_EQ(domain.Elements().size(), 1U);
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices[0], 1U);
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices[1], 0U);
|
||||
ASSERT_EQ(domain.Materials().size(), 1U);
|
||||
ASSERT_EQ(domain.Sections().size(), 1U);
|
||||
ASSERT_EQ(domain.BeamElements().Size(), 1U);
|
||||
EXPECT_EQ(domain.BeamElements()[0].node_indices[0], 1U);
|
||||
EXPECT_EQ(domain.BeamElements()[0].node_indices[1], 0U);
|
||||
ASSERT_EQ(domain.Materials().Size(), 1U);
|
||||
ASSERT_EQ(domain.Sections().Size(), 1U);
|
||||
EXPECT_DOUBLE_EQ(domain.Sections()[0].section_points[0][0], -0.1);
|
||||
ASSERT_EQ(domain.NodeSets().size(), 1U);
|
||||
EXPECT_EQ(domain.NodeSets()[0].node_indices[0], 0U);
|
||||
@@ -189,13 +275,13 @@ TEST(DomainModel, MultipleIdentityInstancesDoNotMerge) {
|
||||
EXPECT_NE(domain.Nodes()[0].source_id.instance_name,
|
||||
domain.Nodes()[2].source_id.instance_name);
|
||||
|
||||
ASSERT_EQ(domain.Elements().size(), 2U);
|
||||
EXPECT_EQ(domain.Elements()[0].source_id.source_label, 1);
|
||||
EXPECT_EQ(domain.Elements()[1].source_id.source_label, 1);
|
||||
EXPECT_EQ(domain.Elements()[0].source_id.instance_name, "Instance-A");
|
||||
EXPECT_EQ(domain.Elements()[1].source_id.instance_name, "Instance-B");
|
||||
EXPECT_EQ(domain.Elements()[0].node_indices[0], 0U);
|
||||
EXPECT_EQ(domain.Elements()[1].node_indices[0], 2U);
|
||||
ASSERT_EQ(domain.BeamElements().Size(), 2U);
|
||||
EXPECT_EQ(domain.BeamElements()[0].source_id.source_label, 1);
|
||||
EXPECT_EQ(domain.BeamElements()[1].source_id.source_label, 1);
|
||||
EXPECT_EQ(domain.BeamElements()[0].source_id.instance_name, "Instance-A");
|
||||
EXPECT_EQ(domain.BeamElements()[1].source_id.instance_name, "Instance-B");
|
||||
EXPECT_EQ(domain.BeamElements()[0].node_indices[0], 0U);
|
||||
EXPECT_EQ(domain.BeamElements()[1].node_indices[0], 2U);
|
||||
}
|
||||
|
||||
// MITC4-MODEL-002
|
||||
@@ -235,16 +321,16 @@ TEST(DomainModel, ShellOwnershipPreservesResolvedAssignmentsAndOptionalFrames) {
|
||||
const fesa::Domain& domain = result.Value();
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().ShellElements()),
|
||||
const std::vector<fesa::Mitc4ShellDefinition>&>);
|
||||
const fesa::DomainCollectionView<fesa::Mitc4ShellDefinition>&>);
|
||||
static_assert(std::is_same_v<
|
||||
decltype(std::declval<const fesa::Domain&>().ShellSections()),
|
||||
const std::vector<fesa::ShellSection>&>);
|
||||
const fesa::DomainCollectionView<fesa::ShellSection>&>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(std::declval<const fesa::Domain&>()
|
||||
.ShellNodeInitialFrames()),
|
||||
const std::vector<fesa::ShellNodeInitialFrame>&>);
|
||||
|
||||
ASSERT_EQ(domain.ShellElements().size(), 2U);
|
||||
ASSERT_EQ(domain.ShellElements().Size(), 2U);
|
||||
EXPECT_EQ(domain.ShellElements()[0].source_id.source_label, 20);
|
||||
EXPECT_EQ(domain.ShellElements()[0].source_id.source_label_text, "0020");
|
||||
EXPECT_EQ(domain.ShellElements()[1].source_id.source_label, 10);
|
||||
@@ -256,7 +342,7 @@ TEST(DomainModel, ShellOwnershipPreservesResolvedAssignmentsAndOptionalFrames) {
|
||||
EXPECT_EQ(domain.ShellElements()[0].material_index, 0U);
|
||||
EXPECT_EQ(domain.ShellElements()[0].section_index, 0U);
|
||||
|
||||
ASSERT_EQ(domain.ShellSections().size(), 2U);
|
||||
ASSERT_EQ(domain.ShellSections().Size(), 2U);
|
||||
EXPECT_EQ(domain.ShellSections()[0].name, "Section-B");
|
||||
EXPECT_DOUBLE_EQ(domain.ShellSections()[0].thickness, 0.02);
|
||||
EXPECT_EQ(domain.ShellSections()[0].material_index, 0U);
|
||||
|
||||
@@ -318,7 +318,7 @@ void ExpectScaledNear(const double actual, const double expected,
|
||||
std::vector<fesa::EndpointResultRow> MakeStationRows(
|
||||
const RecoveryFixture& fixture) {
|
||||
const auto& nodes = fixture.domain->Nodes();
|
||||
const auto& elements = fixture.domain->Elements();
|
||||
const auto& elements = fixture.domain->BeamElements();
|
||||
return {{0U,
|
||||
0,
|
||||
nodes[elements[0U].node_indices[0U]].source_id,
|
||||
|
||||
Reference in New Issue
Block a user