feat(cpp-object-oriented-modular-refactoring): step 14 - runtime-element-factory
This commit is contained in:
@@ -13,6 +13,7 @@ add_executable(
|
||||
unit/core/diagnostic_test.cpp
|
||||
unit/core/source_identity_test.cpp
|
||||
unit/core/status_test.cpp
|
||||
unit/elements/element_factory_test.cpp
|
||||
unit/elements/euler_beam_3d_test.cpp
|
||||
unit/elements/mitc4_shell_test.cpp
|
||||
unit/fem/dof_manager_test.cpp
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
#include "fesa/elements/element_factory.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/element.h"
|
||||
#include "fesa/elements/euler_beam_3d.h"
|
||||
#include "fesa/elements/mitc4_shell.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
namespace {
|
||||
|
||||
fesa::ModelDefinition BeamDefinition(
|
||||
std::array<fesa::EntityIndex, 2> node_indices = {0U, 1U},
|
||||
fesa::EntityIndex material_index = 0U,
|
||||
fesa::EntityIndex property_index = 0U) {
|
||||
fesa::ModelDefinition definition{};
|
||||
definition.source_path = "element-factory-beam.inp";
|
||||
definition.source_content_identity = "fnv1a64:beam";
|
||||
definition.nodes = {
|
||||
{{"Beam-1", 1, "1"}, {0.0, 0.0, 0.0}, {definition.source_path, 1U}},
|
||||
{{"Beam-1", 2, "2"}, {2.0, 0.0, 0.0}, {definition.source_path, 2U}}};
|
||||
definition.materials = {
|
||||
{"Steel", 100.0, 0.25, {definition.source_path, 10U}}};
|
||||
definition.sections = {{"BeamSection",
|
||||
2.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
{0.0, 1.0, 0.0},
|
||||
{},
|
||||
{definition.source_path, 20U}}};
|
||||
definition.elements = {{{"Beam-1", 7, "7"},
|
||||
node_indices,
|
||||
material_index,
|
||||
property_index,
|
||||
{definition.source_path, 30U}}};
|
||||
return definition;
|
||||
}
|
||||
|
||||
fesa::ModelDefinition ShellDefinition(
|
||||
fesa::EntityIndex definition_material_index = 0U,
|
||||
fesa::EntityIndex section_material_index = 0U) {
|
||||
fesa::ModelDefinition definition{};
|
||||
definition.source_path = "element-factory-shell.inp";
|
||||
definition.source_content_identity = "fnv1a64:shell";
|
||||
definition.nodes = {
|
||||
{{"Shell-1", 1, "1"}, {-1.0, -1.0, 0.0}, {definition.source_path, 1U}},
|
||||
{{"Shell-1", 2, "2"}, {1.0, -1.0, 0.0}, {definition.source_path, 2U}},
|
||||
{{"Shell-1", 3, "3"}, {1.0, 1.0, 0.0}, {definition.source_path, 3U}},
|
||||
{{"Shell-1", 4, "4"}, {-1.0, 1.0, 0.0}, {definition.source_path, 4U}}};
|
||||
definition.materials = {
|
||||
{"Steel-A", 120.0, 0.25, {definition.source_path, 10U}},
|
||||
{"Steel-B", 200.0, 0.30, {definition.source_path, 11U}}};
|
||||
definition.shell_sections = {{"ShellSection",
|
||||
0.2,
|
||||
section_material_index,
|
||||
{definition.source_path, 20U}}};
|
||||
definition.shell_elements = {{{"Shell-1", 9, "9"},
|
||||
fesa::ShellSourceElementType::kS4,
|
||||
{0U, 1U, 2U, 3U},
|
||||
definition_material_index,
|
||||
0U,
|
||||
{definition.source_path, 30U}}};
|
||||
for (fesa::EntityIndex node = 0U; node < 4U; ++node) {
|
||||
definition.shell_node_initial_frames.push_back(
|
||||
{node, {0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}});
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
||||
fesa::Domain MakeDomain(fesa::ModelDefinition definition) {
|
||||
auto candidate = fesa::Domain::Create(std::move(definition));
|
||||
if (!candidate.HasValue()) {
|
||||
throw std::runtime_error{"Expected a valid Domain fixture."};
|
||||
}
|
||||
return std::move(candidate.Value());
|
||||
}
|
||||
|
||||
void ExpectSameMatrix(const fesa::Matrix& actual,
|
||||
const fesa::Matrix& expected) {
|
||||
ASSERT_EQ(actual.Rows(), expected.Rows());
|
||||
ASSERT_EQ(actual.Columns(), expected.Columns());
|
||||
for (std::size_t row = 0U; row < actual.Rows(); ++row) {
|
||||
for (std::size_t column = 0U; column < actual.Columns(); ++column) {
|
||||
EXPECT_DOUBLE_EQ(actual(row, column), expected(row, column));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectModelFailure(
|
||||
const fesa::Result<std::unique_ptr<fesa::Element>>& candidate) {
|
||||
ASSERT_FALSE(candidate.HasValue());
|
||||
EXPECT_EQ(candidate.GetStatus().Category(), fesa::FailureCategory::kModel);
|
||||
ASSERT_EQ(candidate.GetStatus().Diagnostics().size(), 1U);
|
||||
EXPECT_EQ(candidate.GetStatus().Diagnostics()[0].severity,
|
||||
fesa::Severity::kError);
|
||||
}
|
||||
|
||||
class UnknownElementDefinition final : public fesa::ElementDefinition {
|
||||
public:
|
||||
fesa::ElementDefinitionKind Kind() const noexcept override {
|
||||
return static_cast<fesa::ElementDefinitionKind>(99);
|
||||
}
|
||||
|
||||
const fesa::SourceEntityId& SourceId() const noexcept override {
|
||||
return source_id_;
|
||||
}
|
||||
|
||||
std::string_view SourceElementType() const noexcept override {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
const std::vector<fesa::EntityIndex>& NodeIndices() const noexcept override {
|
||||
return node_indices_;
|
||||
}
|
||||
|
||||
fesa::EntityIndex MaterialIndex() const noexcept override { return 0U; }
|
||||
|
||||
fesa::EntityIndex PropertyIndex() const noexcept override { return 0U; }
|
||||
|
||||
private:
|
||||
fesa::SourceEntityId source_id_{"Unknown-1", 99, "99"};
|
||||
std::vector<fesa::EntityIndex> node_indices_{0U, 1U};
|
||||
};
|
||||
|
||||
class DestructionProbeElement final : public fesa::Element {
|
||||
public:
|
||||
explicit DestructionProbeElement(bool& destroyed) : destroyed_{&destroyed} {}
|
||||
|
||||
~DestructionProbeElement() override { *destroyed_ = true; }
|
||||
|
||||
const fesa::ElementDofLayout& DofLayout() const noexcept override {
|
||||
return layout_;
|
||||
}
|
||||
|
||||
fesa::Result<fesa::ElementStiffnessContribution> ComputeStiffness()
|
||||
const override {
|
||||
return fesa::Result<fesa::ElementStiffnessContribution>::Success(
|
||||
{layout_, fesa::Matrix{0U, 0U}});
|
||||
}
|
||||
|
||||
fesa::Result<fesa::ElementResultBundle> Recover(
|
||||
const fesa::Vector&) const override {
|
||||
return fesa::Result<fesa::ElementResultBundle>::Success(
|
||||
{layout_.source_id, fesa::BeamElementResultRows{}});
|
||||
}
|
||||
|
||||
private:
|
||||
bool* destroyed_;
|
||||
fesa::ElementDofLayout layout_{};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// C-ELEMENT-001
|
||||
TEST(ElementFactory, CreatesBeamWithStableLayoutStiffnessAndRecovery) {
|
||||
static_assert(std::has_virtual_destructor_v<fesa::Element>);
|
||||
|
||||
bool destroyed = false;
|
||||
{
|
||||
std::unique_ptr<fesa::Element> probe =
|
||||
std::make_unique<DestructionProbeElement>(destroyed);
|
||||
EXPECT_NE(probe, nullptr);
|
||||
}
|
||||
EXPECT_TRUE(destroyed);
|
||||
|
||||
const fesa::Domain domain = MakeDomain(BeamDefinition());
|
||||
const fesa::ElementFactory factory{};
|
||||
auto candidate = factory.Create(domain.Elements()[0U], domain);
|
||||
ASSERT_TRUE(candidate.HasValue());
|
||||
ASSERT_NE(candidate.Value(), nullptr);
|
||||
const std::unique_ptr<fesa::Element>& element = candidate.Value();
|
||||
|
||||
const auto& layout = element->DofLayout();
|
||||
EXPECT_EQ(layout.source_id.source_label_text, "7");
|
||||
EXPECT_EQ(layout.node_indices, (std::vector<fesa::EntityIndex>{0U, 1U}));
|
||||
EXPECT_EQ(layout.components_per_node,
|
||||
(std::vector<fesa::DofComponent>{
|
||||
fesa::DofComponent::kUx, fesa::DofComponent::kUy,
|
||||
fesa::DofComponent::kUz, fesa::DofComponent::kUrx,
|
||||
fesa::DofComponent::kUry, fesa::DofComponent::kUrz}));
|
||||
|
||||
auto stiffness = element->ComputeStiffness();
|
||||
ASSERT_TRUE(stiffness.HasValue());
|
||||
EXPECT_EQ(stiffness.Value().layout.node_indices, layout.node_indices);
|
||||
auto direct = fesa::EulerBeam3D::Create(
|
||||
domain.Nodes()[0U], domain.Nodes()[1U], domain.Sections()[0U],
|
||||
domain.LinearElasticMaterials()[0U]);
|
||||
ASSERT_TRUE(direct.HasValue());
|
||||
ExpectSameMatrix(stiffness.Value().values, direct.Value().GlobalStiffness());
|
||||
|
||||
fesa::Vector displacement{12U};
|
||||
displacement[6U] = 0.1;
|
||||
auto result = element->Recover(displacement);
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
EXPECT_EQ(result.Value().source_id.source_label_text, "7");
|
||||
ASSERT_TRUE(std::holds_alternative<fesa::BeamElementResultRows>(
|
||||
result.Value().payload));
|
||||
const auto& rows =
|
||||
std::get<fesa::BeamElementResultRows>(result.Value().payload);
|
||||
ASSERT_EQ(rows.endpoint_rows.size(), 2U);
|
||||
EXPECT_DOUBLE_EQ(rows.endpoint_rows[0U].end_action[0U], -10.0);
|
||||
EXPECT_DOUBLE_EQ(rows.endpoint_rows[1U].end_action[0U], 10.0);
|
||||
EXPECT_DOUBLE_EQ(rows.endpoint_rows[0U].section_resultant[0U], 10.0);
|
||||
EXPECT_EQ(rows.endpoint_rows[0U].node.source_label_text, "1");
|
||||
EXPECT_EQ(rows.endpoint_rows[1U].node.source_label_text, "2");
|
||||
EXPECT_EQ(rows.gauss_rows.size(), 2U);
|
||||
EXPECT_EQ(rows.stress_rows.size(), 2U);
|
||||
}
|
||||
|
||||
TEST(ElementFactory, CreatesMitc4WithStableLayoutStiffnessAndRecovery) {
|
||||
auto mixed_definition = ShellDefinition();
|
||||
mixed_definition.sections = {{"BeamSection",
|
||||
2.0,
|
||||
1.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
{0.0, 1.0, 0.0},
|
||||
{},
|
||||
{mixed_definition.source_path, 21U}}};
|
||||
mixed_definition.elements = {{{"Shell-1", 8, "8"},
|
||||
{0U, 1U},
|
||||
0U,
|
||||
0U,
|
||||
{mixed_definition.source_path, 29U}}};
|
||||
const fesa::Domain domain = MakeDomain(std::move(mixed_definition));
|
||||
const fesa::ElementFactory factory{};
|
||||
ASSERT_EQ(domain.Elements().Size(), 2U);
|
||||
auto candidate = factory.Create(domain.Elements()[1U], domain);
|
||||
ASSERT_TRUE(candidate.HasValue());
|
||||
ASSERT_NE(candidate.Value(), nullptr);
|
||||
const std::unique_ptr<fesa::Element>& element = candidate.Value();
|
||||
|
||||
EXPECT_EQ(element->DofLayout().node_indices,
|
||||
(std::vector<fesa::EntityIndex>{0U, 1U, 2U, 3U}));
|
||||
EXPECT_EQ(element->DofLayout().components_per_node.size(), 6U);
|
||||
auto stiffness = element->ComputeStiffness();
|
||||
ASSERT_TRUE(stiffness.HasValue());
|
||||
|
||||
std::array<const fesa::Node*, 4> nodes{
|
||||
&domain.Nodes()[0U], &domain.Nodes()[1U], &domain.Nodes()[2U],
|
||||
&domain.Nodes()[3U]};
|
||||
std::array<std::array<double, 3>, 4> directors{
|
||||
std::array<double, 3>{0.0, 0.0, 1.0},
|
||||
{0.0, 0.0, 1.0},
|
||||
{0.0, 0.0, 1.0},
|
||||
{0.0, 0.0, 1.0}};
|
||||
auto direct =
|
||||
fesa::Mitc4Shell::Create(nodes, directors, domain.ShellSections()[0U],
|
||||
domain.LinearElasticMaterials()[0U]);
|
||||
ASSERT_TRUE(direct.HasValue());
|
||||
auto direct_stiffness = direct.Value().Stiffness();
|
||||
ASSERT_TRUE(direct_stiffness.HasValue());
|
||||
ExpectSameMatrix(stiffness.Value().values,
|
||||
direct_stiffness.Value().stabilized_global24);
|
||||
|
||||
auto result = element->Recover(fesa::Vector{24U});
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
ASSERT_TRUE(std::holds_alternative<fesa::ShellElementResultRows>(
|
||||
result.Value().payload));
|
||||
const auto& rows =
|
||||
std::get<fesa::ShellElementResultRows>(result.Value().payload);
|
||||
ASSERT_EQ(rows.rows.size(), 4U);
|
||||
EXPECT_DOUBLE_EQ(rows.physical_strain_energy, 0.0);
|
||||
EXPECT_EQ(rows.rows[0U].location, fesa::ShellMidsurfaceLocation::kGp1);
|
||||
EXPECT_EQ(rows.rows[3U].location, fesa::ShellMidsurfaceLocation::kGp4);
|
||||
for (const auto& row : rows.rows) {
|
||||
EXPECT_EQ(row.element, fesa::EntityIndex{1U});
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ElementFactory, OwnerBuildsNonOwningViewInStableElementOrder) {
|
||||
const fesa::Domain beam_domain = MakeDomain(BeamDefinition());
|
||||
const fesa::Domain shell_domain = MakeDomain(ShellDefinition());
|
||||
const fesa::ElementFactory factory{};
|
||||
auto beam = factory.Create(beam_domain.Elements()[0U], beam_domain);
|
||||
auto shell = factory.Create(shell_domain.Elements()[0U], shell_domain);
|
||||
ASSERT_TRUE(beam.HasValue());
|
||||
ASSERT_TRUE(shell.HasValue());
|
||||
|
||||
std::vector<std::unique_ptr<fesa::Element>> owner;
|
||||
owner.push_back(std::move(beam.Value()));
|
||||
owner.push_back(std::move(shell.Value()));
|
||||
fesa::ElementView view;
|
||||
view.reserve(owner.size());
|
||||
for (const auto& element : owner) {
|
||||
view.push_back(std::cref(*element));
|
||||
}
|
||||
|
||||
ASSERT_EQ(view.size(), 2U);
|
||||
EXPECT_EQ(&view[0U].get(), owner[0U].get());
|
||||
EXPECT_EQ(&view[1U].get(), owner[1U].get());
|
||||
EXPECT_EQ(view[0U].get().DofLayout().source_id.source_label_text, "7");
|
||||
EXPECT_EQ(view[1U].get().DofLayout().source_id.source_label_text, "9");
|
||||
}
|
||||
|
||||
TEST(ElementFactory, RejectsUnknownAndIncompatibleDefinitions) {
|
||||
const fesa::ElementFactory factory{};
|
||||
const fesa::Domain beam_domain = MakeDomain(BeamDefinition());
|
||||
const UnknownElementDefinition unknown{};
|
||||
ExpectModelFailure(factory.Create(unknown, beam_domain));
|
||||
|
||||
auto property_mismatch_definition = BeamDefinition();
|
||||
property_mismatch_definition.shell_sections = {
|
||||
{"ShellSection",
|
||||
0.2,
|
||||
0U,
|
||||
{property_mismatch_definition.source_path, 21U}}};
|
||||
property_mismatch_definition.elements[0U].section_index = 1U;
|
||||
const fesa::Domain property_mismatch =
|
||||
MakeDomain(std::move(property_mismatch_definition));
|
||||
ExpectModelFailure(
|
||||
factory.Create(property_mismatch.Elements()[0U], property_mismatch));
|
||||
|
||||
const fesa::Domain material_mismatch = MakeDomain(ShellDefinition(0U, 1U));
|
||||
ExpectModelFailure(
|
||||
factory.Create(material_mismatch.Elements()[0U], material_mismatch));
|
||||
|
||||
const fesa::Domain invalid_node = MakeDomain(BeamDefinition({0U, 2U}));
|
||||
ExpectModelFailure(factory.Create(invalid_node.Elements()[0U], invalid_node));
|
||||
|
||||
auto missing_frame_definition = ShellDefinition();
|
||||
missing_frame_definition.shell_node_initial_frames.pop_back();
|
||||
const fesa::Domain missing_frame =
|
||||
MakeDomain(std::move(missing_frame_definition));
|
||||
auto missing_frame_result =
|
||||
factory.Create(missing_frame.Elements()[0U], missing_frame);
|
||||
ExpectModelFailure(missing_frame_result);
|
||||
EXPECT_EQ(missing_frame_result.GetStatus().Diagnostics()[0U].code,
|
||||
"missing-shell-frame");
|
||||
}
|
||||
@@ -535,7 +535,7 @@ TEST(EulerBeam3D, HermiteAndBMatrixMatchReviewedSigns) {
|
||||
displacement[10U] = -slope(w, length);
|
||||
displacement[11U] = slope(v, length);
|
||||
|
||||
const BeamRecovery recovery = beam.Recover(displacement);
|
||||
const BeamRecovery recovery = beam.RecoverBeam(displacement);
|
||||
const double inverse_sqrt_three = 1.0 / std::sqrt(3.0);
|
||||
const std::array<double, 2> gauss_xi = {-inverse_sqrt_three,
|
||||
inverse_sqrt_three};
|
||||
@@ -718,7 +718,7 @@ TEST(EulerBeam3D, RotatedTransformPreservesWorkAndEnergy) {
|
||||
ExpectScaledNear(global_variation.Dot(global_force),
|
||||
local_variation.Dot(local_force), kMatrixTolerance);
|
||||
|
||||
const BeamRecovery recovery = beam.Recover(global_displacement);
|
||||
const BeamRecovery recovery = beam.RecoverBeam(global_displacement);
|
||||
EXPECT_NEAR(recovery.gauss_generalized_strains[0U][0U],
|
||||
(local_displacement[6U] - local_displacement[0U]) / 3.0, 1.0e-14);
|
||||
}
|
||||
@@ -738,7 +738,7 @@ TEST(EulerBeam3D, PreservesExactRotatedResultsAcrossVector3Migration) {
|
||||
for (std::size_t index = 0U; index < displacement.Size(); ++index) {
|
||||
displacement[index] = 0.01 * static_cast<double>(index + 1U) - 0.04;
|
||||
}
|
||||
const BeamRecovery recovery = beam.Recover(displacement);
|
||||
const BeamRecovery recovery = beam.RecoverBeam(displacement);
|
||||
|
||||
EXPECT_DOUBLE_EQ(global(0U, 0U), 0x1.65f135da12f68p+28);
|
||||
EXPECT_DOUBLE_EQ(global(0U, 1U), 0x1.6261c084bda12p+28);
|
||||
@@ -829,7 +829,7 @@ TEST(EulerBeam3D, AnalyticalAxialTorsionAndTwoPlaneBendingRecover) {
|
||||
axial[6U],
|
||||
axial_force * length / (material.youngs_modulus * section.area),
|
||||
kAnalyticalTolerance);
|
||||
const BeamRecovery axial_recovery = beam.Recover(axial);
|
||||
const BeamRecovery axial_recovery = beam.RecoverBeam(axial);
|
||||
ExpectRelativeNear(axial_recovery.equilibrium_end_actions[0U][0U],
|
||||
-axial_force, kAnalyticalTolerance);
|
||||
ExpectRelativeNear(axial_recovery.equilibrium_end_actions[1U][0U],
|
||||
@@ -846,7 +846,7 @@ TEST(EulerBeam3D, AnalyticalAxialTorsionAndTwoPlaneBendingRecover) {
|
||||
torsion[9U],
|
||||
torque * length / (shear_modulus * section.torsional_constant),
|
||||
kAnalyticalTolerance);
|
||||
const BeamRecovery torsion_recovery = beam.Recover(torsion);
|
||||
const BeamRecovery torsion_recovery = beam.RecoverBeam(torsion);
|
||||
ExpectRelativeNear(torsion_recovery.equilibrium_end_actions[0U][3U], -torque,
|
||||
kAnalyticalTolerance);
|
||||
ExpectRelativeNear(torsion_recovery.equilibrium_end_actions[1U][3U], torque,
|
||||
@@ -865,7 +865,7 @@ TEST(EulerBeam3D, AnalyticalAxialTorsionAndTwoPlaneBendingRecover) {
|
||||
local_yforce * length * length /
|
||||
(2.0 * material.youngs_modulus * section.i22),
|
||||
kAnalyticalTolerance);
|
||||
const BeamRecovery local_yrecovery = beam.Recover(local_y);
|
||||
const BeamRecovery local_yrecovery = beam.RecoverBeam(local_y);
|
||||
ExpectRelativeNear(local_yrecovery.equilibrium_end_actions[0U][1U],
|
||||
-local_yforce, kAnalyticalTolerance);
|
||||
ExpectRelativeNear(local_yrecovery.equilibrium_end_actions[1U][1U],
|
||||
@@ -887,7 +887,7 @@ TEST(EulerBeam3D, AnalyticalAxialTorsionAndTwoPlaneBendingRecover) {
|
||||
-local_zforce * length * length /
|
||||
(2.0 * material.youngs_modulus * section.i11),
|
||||
kAnalyticalTolerance);
|
||||
const BeamRecovery local_zrecovery = beam.Recover(local_z);
|
||||
const BeamRecovery local_zrecovery = beam.RecoverBeam(local_z);
|
||||
ExpectRelativeNear(local_zrecovery.equilibrium_end_actions[0U][2U],
|
||||
-local_zforce, kAnalyticalTolerance);
|
||||
ExpectRelativeNear(local_zrecovery.equilibrium_end_actions[1U][2U],
|
||||
@@ -1028,7 +1028,7 @@ TEST(EulerBeam3D, RecoversSectionPointAndDefaultCentroidS11) {
|
||||
displacement[10U] = kappa_y * length;
|
||||
displacement[11U] = kappa_z * length;
|
||||
|
||||
const BeamRecovery recovery = beam.Recover(displacement);
|
||||
const BeamRecovery recovery = beam.RecoverBeam(displacement);
|
||||
ASSERT_EQ(recovery.stress_points.size(), 4U);
|
||||
for (std::size_t gauss_point = 0; gauss_point < 2U; ++gauss_point) {
|
||||
for (std::size_t point = 0; point < section.section_points.size();
|
||||
@@ -1050,7 +1050,7 @@ TEST(EulerBeam3D, RecoversSectionPointAndDefaultCentroidS11) {
|
||||
}
|
||||
|
||||
const auto default_beam = AlignedBeam(length, MakeSection(), material);
|
||||
const BeamRecovery default_recovery = default_beam.Recover(displacement);
|
||||
const BeamRecovery default_recovery = default_beam.RecoverBeam(displacement);
|
||||
ASSERT_EQ(default_recovery.stress_points.size(), 2U);
|
||||
for (std::size_t gauss_point = 0; gauss_point < 2U; ++gauss_point) {
|
||||
const BeamStressPoint& stress = default_recovery.stress_points[gauss_point];
|
||||
@@ -1091,7 +1091,7 @@ TEST(EulerBeam3D, ReproducesConstantStrainTwistAndCurvaturePatches) {
|
||||
shear_modulus * section.torsional_constant * twist,
|
||||
material.youngs_modulus * section.i11 * kappa_y,
|
||||
material.youngs_modulus * section.i22 * kappa_z};
|
||||
const BeamRecovery recovery = beam.Recover(displacement);
|
||||
const BeamRecovery recovery = beam.RecoverBeam(displacement);
|
||||
for (std::size_t point = 0; point < 2U; ++point) {
|
||||
for (std::size_t component = 0; component < 4U; ++component) {
|
||||
ExpectScaledNear(recovery.gauss_generalized_strains[point][component],
|
||||
|
||||
Reference in New Issue
Block a user