feat(cpp-object-oriented-modular-refactoring): step 22 - result-recovery-modules
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#include "results/analysis_state_commit.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
namespace fesa::results_internal {
|
||||
|
||||
Status CommitRecoveryCandidate(RecoveryCandidate candidate,
|
||||
AnalysisState& state) {
|
||||
const std::size_t full_count = state.Displacement().Size();
|
||||
if (candidate.displacement.Size() != full_count ||
|
||||
candidate.external_force.Size() != full_count ||
|
||||
candidate.internal_force.Size() != full_count ||
|
||||
candidate.residual.Size() != full_count ||
|
||||
candidate.reaction.Size() != full_count) {
|
||||
return RecoveryFailure(
|
||||
"invalid-recovery-dimensions", {}, state.Identity().step_name,
|
||||
"Recovery candidate vectors must match the AnalysisState dimension.");
|
||||
}
|
||||
if (!IsFiniteVector(candidate.displacement) ||
|
||||
!IsFiniteVector(candidate.external_force) ||
|
||||
!IsFiniteVector(candidate.internal_force) ||
|
||||
!IsFiniteVector(candidate.residual) ||
|
||||
!IsFiniteVector(candidate.reaction)) {
|
||||
return RecoveryFailure(
|
||||
"nonfinite-recovery-value", {}, state.Identity().step_name,
|
||||
"Recovery candidate vectors must contain only finite values.");
|
||||
}
|
||||
|
||||
const bool has_any_beam_rows = !candidate.endpoint_rows.empty() ||
|
||||
!candidate.gauss_rows.empty() ||
|
||||
!candidate.stress_rows.empty();
|
||||
const bool has_complete_beam_rows = !candidate.endpoint_rows.empty() &&
|
||||
!candidate.gauss_rows.empty() &&
|
||||
!candidate.stress_rows.empty();
|
||||
if (candidate.has_beam_results != has_complete_beam_rows ||
|
||||
(has_any_beam_rows && !has_complete_beam_rows)) {
|
||||
return RecoveryFailure(
|
||||
"invalid-recovery-result-family", {}, state.Identity().step_name,
|
||||
"Beam recovery flags require endpoint, Gauss, and stress rows as one "
|
||||
"complete result family.");
|
||||
}
|
||||
|
||||
const std::array<double, 6> zero_equilibrium{};
|
||||
const std::array<double, 3> zero_metrics{};
|
||||
const bool has_any_shell_results =
|
||||
!candidate.expected_shell_elements.empty() ||
|
||||
!candidate.shell.rows.empty() ||
|
||||
candidate.shell.physical_strain_energy != 0.0 ||
|
||||
candidate.shell.equilibrium != zero_equilibrium ||
|
||||
candidate.shell.verification_metrics != zero_metrics;
|
||||
const bool has_complete_shell_inventory =
|
||||
!candidate.expected_shell_elements.empty() &&
|
||||
!candidate.shell.rows.empty();
|
||||
if (candidate.has_shell_results != has_complete_shell_inventory ||
|
||||
(has_any_shell_results && !has_complete_shell_inventory)) {
|
||||
return RecoveryFailure(
|
||||
"invalid-recovery-result-family", {}, state.Identity().step_name,
|
||||
"Shell recovery flags require expected elements and physical rows as "
|
||||
"one complete result family.");
|
||||
}
|
||||
if (candidate.has_beam_results && candidate.has_shell_results) {
|
||||
return RecoveryFailure(
|
||||
"unsupported-mixed-element-model", {}, "mixed-runtime-results",
|
||||
"Result recovery does not support mixed beam and shell models.");
|
||||
}
|
||||
|
||||
AnalysisState candidate_state = state;
|
||||
candidate_state.Displacement() = std::move(candidate.displacement);
|
||||
candidate_state.ExternalForce() = std::move(candidate.external_force);
|
||||
candidate_state.InternalForce() = std::move(candidate.internal_force);
|
||||
candidate_state.Residual() = std::move(candidate.residual);
|
||||
candidate_state.Reaction() = std::move(candidate.reaction);
|
||||
candidate_state.EndpointResults() = std::move(candidate.endpoint_rows);
|
||||
candidate_state.GaussResults() = std::move(candidate.gauss_rows);
|
||||
candidate_state.StressResults() = std::move(candidate.stress_rows);
|
||||
const Status shell_commit_status = candidate_state.CommitShellResults(
|
||||
candidate.expected_shell_elements, std::move(candidate.shell));
|
||||
if (!shell_commit_status.IsOk()) {
|
||||
return shell_commit_status;
|
||||
}
|
||||
state = std::move(candidate_state);
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
} // namespace fesa::results_internal
|
||||
Reference in New Issue
Block a user