#ifndef FESA_ANALYSIS_LINEAR_STATIC_ANALYSIS_H_ #define FESA_ANALYSIS_LINEAR_STATIC_ANALYSIS_H_ #include #include #include #include "fesa/analysis/analysis_model.h" #include "fesa/analysis/analysis_state.h" #include "fesa/constraints/essential_constraints.h" #include "fesa/core/status.h" #include "fesa/fem/dof_manager.h" #include "fesa/math/sparse_matrix.h" #include "fesa/math/vector.h" #include "fesa/model/domain.h" namespace fesa { class LinearSolver; class ParallelFor; class ResultsWriter; /// @brief Carries input and authoritative output paths for one analysis run. struct AnalysisRequest { std::filesystem::path input_path; std::filesystem::path output_path; }; /// @brief Executes the current approved V0 analysis lifecycle. class Analysis { public: virtual ~Analysis() = default; /// @brief Runs the eight current lifecycle stages in their approved order. /// @param request Input and output paths for this run. /// @return The first stage failure or successful result finalization. Status Run(const AnalysisRequest& request); protected: /// @brief Initializes owned input and Domain state for a run. virtual Status Initialize(const AnalysisRequest& request) = 0; /// @brief Builds the non-owning active-model view. virtual Status BuildAnalysisModel() = 0; /// @brief Builds stable DOF numbering and the sparse structural pattern. virtual Status BuildDofMapAndSparsePattern() = 0; /// @brief Assembles full stiffness and stable constraint partitions. virtual Status AssembleAndPartitionStiffness() = 0; /// @brief Factorizes Kff before any load assembly. virtual Status Factorize() = 0; /// @brief Assembles loads and forms Ff-Kfc*dc without solving. virtual Status AssembleLoadsAndEffectiveRhs() = 0; /// @brief Substitutes the retained factorization and reconstructs full d. virtual Status SubstituteAndReconstruct() = 0; /// @brief Recovers a complete candidate and writes authoritative results. virtual Status RecoverAndWriteResults() = 0; }; /// @brief Orchestrates the single-step linear-static procedure. /// @note Factorization, substitution, recovery, and writing remain separately /// observable through injected backend boundaries. class LinearStaticAnalysis final : public Analysis { public: /// @brief Creates a procedure using non-owned backend adapters. /// @note All three adapters must outlive this analysis object. LinearStaticAnalysis(const ParallelFor& parallel_for, LinearSolver& linear_solver, ResultsWriter& results_writer); protected: /// @copydoc Analysis::Initialize Status Initialize(const AnalysisRequest& request) override; /// @copydoc Analysis::BuildAnalysisModel Status BuildAnalysisModel() override; /// @copydoc Analysis::BuildDofMapAndSparsePattern Status BuildDofMapAndSparsePattern() override; /// @copydoc Analysis::AssembleAndPartitionStiffness Status AssembleAndPartitionStiffness() override; /// @copydoc Analysis::Factorize Status Factorize() override; /// @copydoc Analysis::AssembleLoadsAndEffectiveRhs Status AssembleLoadsAndEffectiveRhs() override; /// @copydoc Analysis::SubstituteAndReconstruct Status SubstituteAndReconstruct() override; /// @copydoc Analysis::RecoverAndWriteResults Status RecoverAndWriteResults() override; private: const ParallelFor& parallel_for_; LinearSolver& linear_solver_; ResultsWriter& results_writer_; AnalysisRequest request_; std::unique_ptr domain_; std::unique_ptr model_; std::unique_ptr dofs_; std::unique_ptr state_; std::unique_ptr full_stiffness_; std::unique_ptr partitioned_stiffness_; std::unique_ptr effective_rhs_; std::vector diagnostics_; }; } // namespace fesa #endif // FESA_ANALYSIS_LINEAR_STATIC_ANALYSIS_H_