feat(cpp-object-oriented-modular-refactoring): step 18 - load-hierarchy
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/element_factory.h"
|
||||
#include "fesa/loads/concentrated_nodal_load.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/source_target_resolver.h"
|
||||
|
||||
@@ -345,11 +346,12 @@ Status AppendShellRows(const SourceLocation& location,
|
||||
|
||||
Result<std::vector<EntityIndex>> ResolveLoadTarget(
|
||||
const SourceTargetResolver& resolver, const Domain& domain,
|
||||
const NodalLoad& load) {
|
||||
auto resolved = resolver.Resolve({SourceEntityKind::kNode, "", load.target});
|
||||
const ConcentratedNodalLoad& load) {
|
||||
auto resolved = resolver.Resolve(load.Target());
|
||||
if (!resolved.HasValue()) {
|
||||
return RecoveryResultFailure<std::vector<EntityIndex>>(
|
||||
"invalid-node-station-entity", load.location, load.target,
|
||||
"invalid-node-station-entity", load.Location(),
|
||||
load.Target().target_name_or_label,
|
||||
"A station-eligibility load target must resolve unambiguously.");
|
||||
}
|
||||
std::vector<EntityIndex> nodes;
|
||||
@@ -359,7 +361,8 @@ Result<std::vector<EntityIndex>> ResolveLoadTarget(
|
||||
const EntityIndex node = target.entity_index;
|
||||
if (node >= domain.Nodes().size() || seen[node] != 0U) {
|
||||
return RecoveryResultFailure<std::vector<EntityIndex>>(
|
||||
"invalid-node-station-entity", load.location, load.target,
|
||||
"invalid-node-station-entity", load.Location(),
|
||||
load.Target().target_name_or_label,
|
||||
"A station-eligibility node set must contain unique valid nodes.");
|
||||
}
|
||||
seen[node] = 1U;
|
||||
@@ -789,33 +792,46 @@ ResultRecovery::NormalizeSectionResultantsToNodeStations(
|
||||
}
|
||||
|
||||
std::vector<unsigned char> loaded_nodes(domain.Nodes().size(), 0U);
|
||||
if (model.ActiveLoads().size() != model.Step().loads.size()) {
|
||||
const auto& loads = model.Step().ConcentratedLoads();
|
||||
if (model.ActiveLoads().size() != loads.Size()) {
|
||||
return RecoveryResultFailure<std::vector<NodeStationResultRow>>(
|
||||
"invalid-node-station-entity", model.Step().location, model.Step().name,
|
||||
"invalid-node-station-entity", model.Step().Location(),
|
||||
model.Step().Name(),
|
||||
"The active load view must preserve every sole-step load.");
|
||||
}
|
||||
const SourceTargetIndex target_index = SourceTargetIndex::FromDomain(domain);
|
||||
const SourceTargetResolver target_resolver{target_index};
|
||||
for (std::size_t order = 0U; order < model.ActiveLoads().size(); ++order) {
|
||||
const EntityIndex load_index = model.ActiveLoads()[order];
|
||||
if (load_index != order || load_index >= model.Step().loads.size()) {
|
||||
if (load_index != order || load_index >= loads.Size()) {
|
||||
return RecoveryResultFailure<std::vector<NodeStationResultRow>>(
|
||||
"invalid-node-station-entity", model.Step().location,
|
||||
"invalid-node-station-entity", model.Step().Location(),
|
||||
std::to_string(load_index),
|
||||
"Active loads must remain in stable source order.");
|
||||
}
|
||||
const auto& load = model.Step().loads[load_index];
|
||||
if (!std::isfinite(load.magnitude)) {
|
||||
const auto& load = loads[load_index];
|
||||
if (load.SourceOrder() != order) {
|
||||
return RecoveryResultFailure<std::vector<NodeStationResultRow>>(
|
||||
"nonfinite-node-station-value", load.location, load.target,
|
||||
"Station eligibility requires finite concentrated loads.");
|
||||
"invalid-node-station-entity", load.Location(),
|
||||
std::to_string(load.SourceOrder()),
|
||||
"Station eligibility requires stable load source order.");
|
||||
}
|
||||
bool has_nonzero_component = false;
|
||||
for (const double component : load.GlobalComponents()) {
|
||||
if (!std::isfinite(component)) {
|
||||
return RecoveryResultFailure<std::vector<NodeStationResultRow>>(
|
||||
"nonfinite-node-station-value", load.Location(),
|
||||
load.Target().target_name_or_label,
|
||||
"Station eligibility requires finite concentrated loads.");
|
||||
}
|
||||
has_nonzero_component = has_nonzero_component || component != 0.0;
|
||||
}
|
||||
auto targets = ResolveLoadTarget(target_resolver, domain, load);
|
||||
if (!targets.HasValue()) {
|
||||
return Result<std::vector<NodeStationResultRow>>::Failure(
|
||||
targets.GetStatus());
|
||||
}
|
||||
if (load.magnitude != 0.0) {
|
||||
if (has_nonzero_component) {
|
||||
for (const EntityIndex node : targets.Value()) {
|
||||
loaded_nodes[node] = 1U;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user