#pragma once #include "fesa/Core/Core.hpp" #include #include #include #include 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 entity_ids; std::vector component_labels; std::vector> 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 field_outputs; }; struct ResultStep { std::string name; std::vector 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 node_ids; std::vector coordinates; std::vector element_ids; std::vector element_types; std::vector> connectivity; std::vector steps; }; class InMemoryResultsWriter { public: void writeLinearStatic(const Domain& domain, const DofManager& dofs, const std::vector& u_full, const std::vector& 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& u_full, const std::vector& 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& labels, const std::string& description, const Domain& domain, const DofManager& dofs, const std::vector& 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 values{}; for (Dof dof : allDofs()) { values[static_cast(dofIndex(dof))] = full_values[static_cast(dofs.fullIndex(node_id, dof))]; } field.values.push_back(values); } return field; } ResultFile result_; }; } // namespace fesa