Files
FESADev/src/fesa/results/beam_result_recovery.cpp
T

107 lines
4.5 KiB
C++

#include "results/beam_result_recovery.h"
#include <array>
#include <cmath>
#include <cstddef>
#include <iterator>
#include <tuple>
namespace fesa::results_internal {
Status BeamResultRecovery(const SourceLocation& location,
const SourceEntityId& source_id,
const EntityIndex expected_element,
const std::array<SourceEntityId, 2>& expected_nodes,
const BeamElementResultRows& rows,
RecoveryCandidate& candidate) {
if (rows.endpoint_rows.size() != expected_nodes.size()) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam endpoint rows must preserve endpoint 0 and 1 source order.");
}
for (std::size_t endpoint = 0U; endpoint < expected_nodes.size();
++endpoint) {
const auto& row = rows.endpoint_rows[endpoint];
if (row.element != expected_element ||
row.endpoint != static_cast<int>(endpoint) ||
!SameSourceIdentity(row.node, expected_nodes[endpoint])) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam endpoint rows must preserve active element, endpoint, and "
"source-node order.");
}
if (!IsFiniteArray(row.end_action) ||
!IsFiniteArray(row.section_resultant)) {
return RecoveryFailure(
"nonfinite-recovery-value", location, source_id.source_label_text,
"Beam endpoint actions and section resultants must remain finite.");
}
}
constexpr std::array<int, 2> expected_gauss_points{1, 2};
if (rows.gauss_rows.size() != expected_gauss_points.size()) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam Gauss rows must preserve GP1 and GP2 source order.");
}
for (std::size_t point = 0U; point < expected_gauss_points.size(); ++point) {
const auto& row = rows.gauss_rows[point];
if (row.element != expected_element ||
row.gauss_point != expected_gauss_points[point]) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam Gauss rows must preserve active element and GP1 through GP2 "
"order.");
}
if (!IsFiniteArray(row.generalized_strain) ||
!IsFiniteArray(row.generalized_resultant)) {
return RecoveryFailure(
"nonfinite-recovery-value", location, source_id.source_label_text,
"Beam generalized recovery values must remain finite.");
}
}
if (rows.stress_rows.empty() || rows.stress_rows.front().gauss_point != 1 ||
rows.stress_rows.back().gauss_point != 2) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam stress rows must preserve GP and section-point source order.");
}
for (std::size_t order = 0U; order < rows.stress_rows.size(); ++order) {
const auto& row = rows.stress_rows[order];
if (row.element != expected_element || row.gauss_point < 1 ||
row.gauss_point > 2 ||
(order != 0U && std::tie(rows.stress_rows[order - 1U].gauss_point,
rows.stress_rows[order - 1U].section_point) >=
std::tie(row.gauss_point, row.section_point))) {
return RecoveryFailure(
"invalid-element-result-identity", location,
source_id.source_label_text,
"Beam stress rows must preserve active element, GP, and "
"section-point order.");
}
if (!std::isfinite(row.x1) || !std::isfinite(row.x2) ||
!std::isfinite(row.s11)) {
return RecoveryFailure(
"nonfinite-recovery-value", location, source_id.source_label_text,
"Beam section-point stress values must remain finite.");
}
}
candidate.has_beam_results = true;
candidate.endpoint_rows.insert(candidate.endpoint_rows.end(),
rows.endpoint_rows.begin(),
rows.endpoint_rows.end());
candidate.gauss_rows.insert(candidate.gauss_rows.end(),
rows.gauss_rows.begin(), rows.gauss_rows.end());
candidate.stress_rows.insert(candidate.stress_rows.end(),
rows.stress_rows.begin(),
rows.stress_rows.end());
return Status::Ok();
}
} // namespace fesa::results_internal