feat(cpp-object-oriented-modular-refactoring): step 9 - result-io-vector3
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/io/abaqus/input_reader.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -239,6 +241,7 @@ RootAssembly, 6, -12.5
|
||||
|
||||
} // namespace
|
||||
|
||||
// C-DUP-002
|
||||
TEST(InpDomainMapping, MapsEverySupportedKeywordAndLegacyDeck) {
|
||||
auto result = MapText("supported-inventory", SupportedInventoryDeck(true));
|
||||
ASSERT_TRUE(result.HasValue());
|
||||
@@ -425,6 +428,17 @@ OnlySecond, 2, 5.
|
||||
"2, 1., 0., 0.", "2, 1e308, 1e297, 0."),
|
||||
"0., 1., 0.", "1e308, 0., 0."));
|
||||
ASSERT_TRUE(large_finite.HasValue());
|
||||
const auto& large_domain = large_finite.Value();
|
||||
ASSERT_EQ(large_domain.Nodes().size(), 2U);
|
||||
const fesa::Vector3 large_delta =
|
||||
fesa::Vector3{large_domain.Nodes()[1U].coordinates} -
|
||||
fesa::Vector3{large_domain.Nodes()[0U].coordinates};
|
||||
EXPECT_TRUE(large_delta.IsFinite());
|
||||
EXPECT_TRUE(std::isfinite(large_delta.Norm()));
|
||||
EXPECT_DOUBLE_EQ(large_delta.Y(), 1.0e297);
|
||||
const fesa::Vector3 large_guide{large_domain.Sections()[0U].first_axis};
|
||||
EXPECT_TRUE(large_guide.IsFinite());
|
||||
EXPECT_TRUE(std::isfinite(large_guide.Norm()));
|
||||
}
|
||||
|
||||
TEST(InpDomainMapping, KeepsNodeAndElementSetNamesInSeparateNamespaces) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "fesa/analysis/analysis_state.h"
|
||||
#include "fesa/build_info.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
namespace {
|
||||
@@ -1114,7 +1115,7 @@ TEST(Hdf5ResultsWriter, SuccessfullyReplacesExistingFinal) {
|
||||
EXPECT_EQ(ReadUint64Attribute(metadata.Get(), "schema_version"), 0U);
|
||||
}
|
||||
|
||||
// MITC4-H5-001
|
||||
// MITC4-H5-001, C-DUP-002
|
||||
TEST(Hdf5ResultsWriter, WritesExactShellMetadataAndModelIdentity) {
|
||||
TempDirectory directory{"shell-model"};
|
||||
const auto source = directory.Path() / "shell.inp";
|
||||
@@ -1150,9 +1151,15 @@ TEST(Hdf5ResultsWriter, WritesExactShellMetadataAndModelIdentity) {
|
||||
|
||||
EXPECT_EQ(DatasetDimensions(file.Get(), "/model/shell/nodal_director"),
|
||||
std::vector<hsize_t>({4U, 3U}));
|
||||
constexpr fesa::Vector3 director{0.0, 0.0, 1.0};
|
||||
std::vector<double> expected_directors;
|
||||
for (std::size_t node = 0U; node < 4U; ++node) {
|
||||
expected_directors.insert(expected_directors.end(),
|
||||
director.Components().begin(),
|
||||
director.Components().end());
|
||||
}
|
||||
EXPECT_EQ(ReadDoubleDataset(file.Get(), "/model/shell/nodal_director"),
|
||||
std::vector<double>(
|
||||
{0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0}));
|
||||
expected_directors);
|
||||
EXPECT_EQ(DatasetDimensions(file.Get(), "/model/shell/nodal_frame"),
|
||||
std::vector<hsize_t>({4U, 3U, 3U}));
|
||||
ExpectCompoundMemberNames(file.Get(), "/model/shell/materials",
|
||||
@@ -1305,3 +1312,31 @@ TEST(Hdf5ResultsWriter, InvalidShellInventoryPreservesExistingFinal) {
|
||||
EXPECT_EQ(ReadBytes(final), sentinel);
|
||||
EXPECT_EQ(EntryCount(directory.Path()), 1U);
|
||||
}
|
||||
|
||||
// C-DUP-002
|
||||
TEST(Hdf5ResultsWriter,
|
||||
Vector3ShellSerializationRejectsNonfiniteWithoutReplacingFinal) {
|
||||
TempDirectory directory{"shell-vector3-atomic"};
|
||||
auto fixture = MakeShellFixture(directory.Path() / "shell.inp");
|
||||
const auto final = directory.Path() / "results.h5";
|
||||
fesa::Hdf5ResultsWriter writer;
|
||||
|
||||
ASSERT_TRUE(writer.Write(final, *fixture.domain, *fixture.state, {}).IsOk());
|
||||
const std::vector<char> valid_bytes = ReadBytes(final);
|
||||
const auto file = OpenFile(final);
|
||||
const auto directors =
|
||||
ReadDoubleDataset(file.Get(), "/model/shell/nodal_director");
|
||||
ASSERT_EQ(directors.size(), 12U);
|
||||
for (std::size_t offset = 0U; offset < directors.size(); offset += 3U) {
|
||||
const fesa::Vector3 director{directors[offset], directors[offset + 1U],
|
||||
directors[offset + 2U]};
|
||||
EXPECT_TRUE(director.IsFinite());
|
||||
EXPECT_EQ(director, (fesa::Vector3{0.0, 0.0, 1.0}));
|
||||
}
|
||||
|
||||
fixture.state->Displacement()[0U] = std::numeric_limits<double>::quiet_NaN();
|
||||
ExpectOutputFailure(writer.Write(final, *fixture.domain, *fixture.state, {}),
|
||||
"invalid-result-state");
|
||||
EXPECT_EQ(ReadBytes(final), valid_bytes);
|
||||
EXPECT_EQ(EntryCount(directory.Path()), 1U);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "fesa/assembly/parallel_for.h"
|
||||
#include "fesa/assembly/sparse_assembler.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
namespace {
|
||||
@@ -719,14 +720,14 @@ TEST(ResultRecovery, KeepsFullResidualAndComputesGlobalShellEquilibrium) {
|
||||
}
|
||||
}
|
||||
|
||||
// MITC4-REC-004
|
||||
// MITC4-REC-004, C-DUP-002
|
||||
TEST(ResultRecovery, UsesGlobalOriginForShellMomentBalance) {
|
||||
auto centered_definition = MakeShellDefinition();
|
||||
auto translated_definition = centered_definition;
|
||||
constexpr std::array<double, 3> translation{7.0, 11.0, 0.0};
|
||||
constexpr fesa::Vector3 translation{7.0, 11.0, 0.0};
|
||||
for (auto& node : translated_definition.nodes) {
|
||||
for (std::size_t component = 0U; component < translation.size();
|
||||
++component) {
|
||||
for (std::size_t component = 0U;
|
||||
component < translation.Components().size(); ++component) {
|
||||
node.coordinates[component] += translation[component];
|
||||
}
|
||||
}
|
||||
@@ -753,13 +754,8 @@ TEST(ResultRecovery, UsesGlobalOriginForShellMomentBalance) {
|
||||
EXPECT_NEAR(translated.Equilibrium()[component], centered_force[component],
|
||||
1.0e-12);
|
||||
}
|
||||
const std::array<double, 3> translated_moment_delta{
|
||||
translation[1U] * centered_force[2U] -
|
||||
translation[2U] * centered_force[1U],
|
||||
translation[2U] * centered_force[0U] -
|
||||
translation[0U] * centered_force[2U],
|
||||
translation[0U] * centered_force[1U] -
|
||||
translation[1U] * centered_force[0U]};
|
||||
const fesa::Vector3 translated_moment_delta =
|
||||
translation.Cross(fesa::Vector3{centered_force});
|
||||
for (std::size_t component = 0U; component < 3U; ++component) {
|
||||
EXPECT_NEAR(translated.Equilibrium()[3U + component] -
|
||||
centered.Equilibrium()[3U + component],
|
||||
|
||||
Reference in New Issue
Block a user