refactor: extract results reference comparison

This commit is contained in:
NINI
2026-05-05 01:38:04 +09:00
parent 339bf1cbb9
commit 421ad5a707
9 changed files with 469 additions and 257 deletions
+123
View File
@@ -0,0 +1,123 @@
#pragma once
#include "fesa/Core/Core.hpp"
#include <array>
#include <map>
#include <string>
#include <vector>
namespace fesa {
struct FieldOutput {
std::string name;
std::string position = "NODAL";
std::string entity_type = "node";
std::string basis = "GLOBAL";
std::string description;
std::vector<GlobalId> entity_ids;
std::vector<std::string> component_labels;
std::vector<std::array<Real, 6>> values;
};
struct ResultFrame {
LocalIndex frame_id = 0;
LocalIndex increment = 1;
LocalIndex iteration = 0;
Real step_time = 1.0;
Real total_time = 1.0;
bool converged = true;
std::string description = "Phase 1 linear static frame";
std::map<std::string, FieldOutput> field_outputs;
};
struct ResultStep {
std::string name;
std::vector<ResultFrame> frames;
};
struct ResultFile {
std::string schema_name = "FESA_RESULTS";
LocalIndex schema_version = 1;
std::string solver_name = "FESA";
std::string dof_convention = "UX,UY,UZ,RX,RY,RZ";
std::string sign_convention = "Abaqus-compatible";
std::string precision = "double";
std::string index_type = "int64";
std::vector<GlobalId> node_ids;
std::vector<Vec3> coordinates;
std::vector<GlobalId> element_ids;
std::vector<std::string> element_types;
std::vector<std::array<GlobalId, 4>> connectivity;
std::vector<ResultStep> steps;
};
class InMemoryResultsWriter {
public:
void writeLinearStatic(const Domain& domain,
const DofManager& dofs,
const std::vector<Real>& u_full,
const std::vector<Real>& rf_full) {
const auto model = buildLinearStaticAnalysisModel(domain);
writeLinearStatic(domain, model, dofs, u_full, rf_full);
}
void writeLinearStatic(const Domain& domain,
const AnalysisModel& model,
const DofManager& dofs,
const std::vector<Real>& u_full,
const std::vector<Real>& rf_full) {
result_ = ResultFile{};
for (const auto& [node_id, node] : domain.nodes) {
result_.node_ids.push_back(node_id);
result_.coordinates.push_back(node.coordinates);
}
for (const auto& [element_id, element] : domain.elements) {
result_.element_ids.push_back(element_id);
result_.element_types.push_back(elementTypeLabel(element.type));
result_.connectivity.push_back(element.node_ids);
}
ResultStep step;
step.name = model.step.name.empty() ? "Step-1" : model.step.name;
ResultFrame frame;
frame.frame_id = 0;
frame.field_outputs["U"] = buildNodalField("U", displacementComponentLabels(), "Nodal displacement and rotation", domain, dofs, u_full);
frame.field_outputs["RF"] = buildNodalField("RF", reactionComponentLabels(), "Nodal reaction force and moment", domain, dofs, rf_full);
step.frames.push_back(frame);
result_.steps.push_back(step);
}
const ResultFile& result() const {
return result_;
}
private:
static FieldOutput buildNodalField(const std::string& name,
const std::vector<std::string>& labels,
const std::string& description,
const Domain& domain,
const DofManager& dofs,
const std::vector<Real>& full_values) {
FieldOutput field;
field.name = name;
field.position = "NODAL";
field.entity_type = "node";
field.basis = "GLOBAL";
field.description = description;
field.component_labels = labels;
for (const auto& [node_id, node] : domain.nodes) {
(void)node;
field.entity_ids.push_back(node_id);
std::array<Real, 6> values{};
for (Dof dof : allDofs()) {
values[static_cast<std::size_t>(dofIndex(dof))] = full_values[static_cast<std::size_t>(dofs.fullIndex(node_id, dof))];
}
field.values.push_back(values);
}
return field;
}
ResultFile result_;
};
} // namespace fesa