Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#include "fesa/io/hdf5/nonlinear_hdf5_results_writer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
@@ -14,17 +13,20 @@
|
||||
|
||||
#include "fesa/analysis/analysis_model.h"
|
||||
#include "fesa/build_info.h"
|
||||
#include "fesa/elements/finite_rotation.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "io/hdf5/hdf5_atomic_file.h"
|
||||
#include "io/hdf5/hdf5_primitives.h"
|
||||
#include "io/hdf5/hdf5_raii.h"
|
||||
#include "io/hdf5/hdf5_self_check.h"
|
||||
#include "math/finite_values.h"
|
||||
#include "results/shell_result_recovery.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
|
||||
using math_internal::IsFinite;
|
||||
|
||||
using hdf5_internal::Hdf5Failure;
|
||||
using hdf5_internal::Hdf5Handle;
|
||||
|
||||
@@ -90,43 +92,9 @@ struct DiagnosticWriteRow {
|
||||
const char* message;
|
||||
};
|
||||
|
||||
template <std::size_t Size>
|
||||
bool IsFinite(const std::array<double, Size>& values) {
|
||||
return std::all_of(values.begin(), values.end(),
|
||||
[](const double value) { return std::isfinite(value); });
|
||||
}
|
||||
|
||||
bool IsFinite(const Vector& values) {
|
||||
for (std::size_t index = 0U; index < values.Size(); ++index) {
|
||||
if (!std::isfinite(values[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SameIdentity(const SourceEntityId& left, const SourceEntityId& right) {
|
||||
return left.instance_name == right.instance_name &&
|
||||
left.source_label == right.source_label &&
|
||||
left.source_label_text == right.source_label_text;
|
||||
}
|
||||
|
||||
bool IsFinite(const ShellResultRow& row) {
|
||||
if (!IsFinite(row.natural_coordinates) || !IsFinite(row.generalized_strain) ||
|
||||
!IsFinite(row.section_resultant)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& axis : row.local_frame) {
|
||||
if (!IsFinite(axis)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (const auto& stress : row.stress) {
|
||||
if (!std::isfinite(stress.zeta) || !IsFinite(stress.components)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
bool SameIdentity(const SourceEntityId& left,
|
||||
const SourceEntityId& right) {
|
||||
return fesa::SourceIdentityEquals(left, right);
|
||||
}
|
||||
|
||||
Status Failure(const char* code, const std::string& message) {
|
||||
@@ -300,7 +268,8 @@ Status ValidateState(const Domain& domain, const NonlinearAnalysisState& state)
|
||||
const std::size_t element = row_index / kShellLocationsPerElement;
|
||||
const std::size_t location = row_index % kShellLocationsPerElement;
|
||||
if (row.element != element || row.location != locations[location] ||
|
||||
row.natural_coordinates != coordinates[location] || !IsFinite(row)) {
|
||||
row.natural_coordinates != coordinates[location] ||
|
||||
!results_internal::IsFiniteShellRow(row)) {
|
||||
return Failure("invalid-result-state",
|
||||
"Accepted shell rows must preserve element and GP order.");
|
||||
}
|
||||
@@ -315,13 +284,8 @@ void WriteCommonNumericAttributes(const hid_t dataset,
|
||||
const std::string& coordinate_system,
|
||||
const std::string& location) {
|
||||
hdf5_internal::WriteUint64Attribute(dataset, "schema_version", 1U);
|
||||
hdf5_internal::WriteStringAttribute(dataset, "component_names",
|
||||
component_names);
|
||||
hdf5_internal::WriteStringAttribute(dataset, "component_unit_dimensions",
|
||||
component_units);
|
||||
hdf5_internal::WriteStringAttribute(dataset, "coordinate_system",
|
||||
coordinate_system);
|
||||
hdf5_internal::WriteStringAttribute(dataset, "location", location);
|
||||
hdf5_internal::WriteQuantityAttributes(
|
||||
dataset, component_names, component_units, coordinate_system, location);
|
||||
}
|
||||
|
||||
void WriteFrameAttributes(const hid_t dataset, const AcceptedFrameState& frame) {
|
||||
@@ -660,12 +624,7 @@ void WriteModelData(const hid_t file, const Domain& domain,
|
||||
std::vector<double> frames;
|
||||
directors.reserve(domain.Nodes().size() * 3U);
|
||||
frames.reserve(domain.Nodes().size() * 9U);
|
||||
for (const auto& frame : domain.ShellNodeInitialFrames()) {
|
||||
directors.insert(directors.end(), frame.director.begin(), frame.director.end());
|
||||
frames.insert(frames.end(), frame.tangent_a.begin(), frame.tangent_a.end());
|
||||
frames.insert(frames.end(), frame.tangent_b.begin(), frame.tangent_b.end());
|
||||
frames.insert(frames.end(), frame.director.begin(), frame.director.end());
|
||||
}
|
||||
hdf5_internal::AppendShellReferenceFrames(domain, directors, frames);
|
||||
const hsize_t node_count = static_cast<hsize_t>(domain.Nodes().size());
|
||||
(void)WriteModelDoubleDataset(file, "/model/shell/nodal_director",
|
||||
{node_count, 3U}, directors.data(),
|
||||
@@ -772,14 +731,6 @@ void WriteAcceptedFrameTable(const hid_t file,
|
||||
hdf5_internal::WriteUint64Attribute(dataset.Get(), "schema_version", 1U);
|
||||
}
|
||||
|
||||
std::vector<double> CopyVector(const Vector& source) {
|
||||
std::vector<double> values(source.Size());
|
||||
for (std::size_t index = 0U; index < source.Size(); ++index) {
|
||||
values[index] = source[index];
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
std::vector<double> NodalDisplacement(const AcceptedFrameState& frame) {
|
||||
std::vector<double> values(frame.displacement.Size());
|
||||
for (std::size_t node = 0U; node < frame.nodal_internal_order.size(); ++node) {
|
||||
@@ -793,47 +744,6 @@ std::vector<double> NodalDisplacement(const AcceptedFrameState& frame) {
|
||||
return values;
|
||||
}
|
||||
|
||||
std::vector<double> FlattenTriads(const AcceptedFrameState& frame) {
|
||||
std::vector<double> values;
|
||||
values.reserve(frame.nodal_triad.size() * 9U);
|
||||
for (const auto& triad : frame.nodal_triad) {
|
||||
for (const auto& axis : triad) {
|
||||
values.insert(values.end(), axis.begin(), axis.end());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
std::vector<double> FlattenDirectors(const AcceptedFrameState& frame) {
|
||||
std::vector<double> values;
|
||||
values.reserve(frame.nodal_director.size() * 3U);
|
||||
for (const auto& director : frame.nodal_director) {
|
||||
values.insert(values.end(), director.begin(), director.end());
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
std::vector<double> SpatialReaction(const AcceptedFrameState& frame) {
|
||||
std::vector<double> values = CopyVector(frame.reaction);
|
||||
for (std::size_t node = 0U; node < frame.nodal_internal_order.size(); ++node) {
|
||||
const std::size_t offset = kDofsPerNode * node;
|
||||
const Vector3 phi{frame.rotation_vector[offset + 3U],
|
||||
frame.rotation_vector[offset + 4U],
|
||||
frame.rotation_vector[offset + 5U]};
|
||||
const Matrix transform = InverseTransposeLeftJacobianSO3(phi);
|
||||
const std::array<double, 3> generalized{
|
||||
frame.reaction[offset + 3U], frame.reaction[offset + 4U],
|
||||
frame.reaction[offset + 5U]};
|
||||
for (std::size_t row = 0U; row < 3U; ++row) {
|
||||
values[offset + 3U + row] = 0.0;
|
||||
for (std::size_t column = 0U; column < 3U; ++column) {
|
||||
values[offset + 3U + row] += transform(row, column) * generalized[column];
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
void WriteShellIdentity(const hid_t dataset, const bool has_section_positions,
|
||||
const std::string& local_frame_path) {
|
||||
hdf5_internal::WriteStringAttribute(dataset, "source_element_type_dataset",
|
||||
@@ -864,35 +774,36 @@ void WriteFrame(const hid_t file, const Domain& domain,
|
||||
file, root + "/nodal/displacement", nodal_dimensions, displacement.data(),
|
||||
displacement.size(), "UX,UY,UZ,URX,URY,URZ", "length,length,length,1,1,1",
|
||||
"global-cartesian", "nodal", frame);
|
||||
const auto triads = FlattenTriads(frame);
|
||||
const auto triads = hdf5_internal::FlattenNodalTriads(frame.nodal_triad);
|
||||
(void)WriteFrameDoubleDataset(file, root + "/nodal/triad",
|
||||
{node_count, 3U, 3U}, triads.data(), triads.size(),
|
||||
"X,Y,Z", "1,1,1", "global-cartesian",
|
||||
"nodal-triad", frame);
|
||||
const auto directors = FlattenDirectors(frame);
|
||||
const auto directors = hdf5_internal::FlattenNodalDirectors(frame.nodal_director);
|
||||
(void)WriteFrameDoubleDataset(file, root + "/nodal/director", {node_count, 3U},
|
||||
directors.data(), directors.size(), "D1,D2,D3",
|
||||
"1,1,1", "global-cartesian", "nodal-director",
|
||||
frame);
|
||||
const auto internal = CopyVector(frame.internal_force);
|
||||
const auto internal = hdf5_internal::CopyVectorValues(frame.internal_force);
|
||||
(void)WriteFrameDoubleDataset(
|
||||
file, root + "/nodal/generalized_internal_force", nodal_dimensions,
|
||||
internal.data(), internal.size(), "FI1,FI2,FI3,MI_PHI1,MI_PHI2,MI_PHI3",
|
||||
"force,force,force,force*length,force*length,force*length",
|
||||
"global-cartesian", "nodal", frame);
|
||||
const auto external = CopyVector(frame.external_force);
|
||||
const auto external = hdf5_internal::CopyVectorValues(frame.external_force);
|
||||
(void)WriteFrameDoubleDataset(
|
||||
file, root + "/nodal/generalized_external_force", nodal_dimensions,
|
||||
external.data(), external.size(), "FE1,FE2,FE3,ME_PHI1,ME_PHI2,ME_PHI3",
|
||||
"force,force,force,force*length,force*length,force*length",
|
||||
"global-cartesian", "nodal", frame);
|
||||
const auto residual = CopyVector(frame.residual);
|
||||
const auto residual = hdf5_internal::CopyVectorValues(frame.residual);
|
||||
(void)WriteFrameDoubleDataset(
|
||||
file, root + "/nodal/generalized_residual", nodal_dimensions,
|
||||
residual.data(), residual.size(), "RU1,RU2,RU3,RPHI1,RPHI2,RPHI3",
|
||||
"force,force,force,force*length,force*length,force*length",
|
||||
"global-cartesian", "nodal", frame);
|
||||
const auto reaction = SpatialReaction(frame);
|
||||
const auto reaction = hdf5_internal::SpatialReactionValues(
|
||||
frame.rotation_vector, frame.reaction, frame.nodal_internal_order.size());
|
||||
(void)WriteFrameDoubleDataset(
|
||||
file, root + "/nodal/reaction", nodal_dimensions, reaction.data(),
|
||||
reaction.size(), "RF1,RF2,RF3,RM1,RM2,RM3",
|
||||
|
||||
Reference in New Issue
Block a user