107 lines
4.5 KiB
C++
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
|