#ifndef FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_ #define FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_ #include #include #include #include #include #include "fesa/analysis/nonlinear_static_control.h" #include "fesa/core/status.h" namespace fesa { /// @brief Identifies the latest Newton procedure stage reached by a record. enum class NewtonIterationStage { kEntered, kKinematicsEvaluated, kInternalAssembled, kExternalAssembled, kSolvedCorrection, kConvergenceEvaluated, kAccepted, kFailed, }; /// @brief Carries the controlled failure that ended one Newton iteration. struct NewtonIterationFailure { bool present; NewtonIterationStage stage; std::string diagnostic_code; std::string reason; }; /// @brief Carries one fixed-schema Newton iteration diagnostic record. struct NewtonIterationLogRecord { std::string step_name; std::uint32_t increment_index; double load_factor; std::uint32_t iteration; NewtonIterationStage last_completed_stage; NewtonIterationFailure failure; std::string transition; std::string outcome; std::string diagnostic_code; NewtonChannelDecision force_residual; NewtonChannelDecision moment_residual; NewtonChannelDecision translation_correction; NewtonChannelDecision rotation_correction; bool combined_passed; }; /// @brief Carries two-channel HHT endpoint convergence evidence. /// @note Array entries are translation and rotation channels, respectively. /// Corrections are dimensionless N2 metrics; rate corrections already include /// h or h squared. Residual numerator and scale retain force/moment units. struct DynamicNewtonIterationLogRecord { std::uint32_t increment_index = 0U; std::uint32_t iteration_index = 0U; double time = 0.0; std::string stage; std::string outcome; std::string failure_code; std::array residual_numerator{}; std::array residual_scale{}; std::array coordinate_correction{}; std::array velocity_correction{}; std::array acceleration_correction{}; std::array algorithmic_correction{}; bool residual_pass = false; bool correction_pass = false; }; /// @brief Writes deterministic, line-oriented Newton iteration diagnostics. /// @note A write, flush, or close failure permanently prevents a successful /// log lifecycle for this writer instance. class NewtonIterationLogWriter { public: /// @brief Opens and truncates the diagnostic log before Newton execution. /// @param log_path Derived application-owned diagnostic-log path. /// @return Success when the writer owns an empty binary log, otherwise an /// output failure with code `log-output-failure`. Status Open(const std::filesystem::path& log_path); /// @brief Writes one complete LF-terminated Newton iteration record. /// @param record Explicit stage, outcome, and typed convergence decision. /// @return Success after writing a complete record, otherwise an output /// failure with code `log-output-failure`. Status Write(const NewtonIterationLogRecord& record); /// @brief Writes one complete HHT record using schema `hht-log-v1`. /// @return Success after the complete line is written; invalid numeric /// evidence or stream failure permanently fails this writer instance. Status Write(const DynamicNewtonIterationLogRecord& record); /// @brief Flushes every complete record written so far to the log. /// @return Success after the stream flush, otherwise an output failure with /// code `log-output-failure`. Status Flush(); /// @brief Closes the log before authoritative result finalization. /// @return Success after close, otherwise an output failure with code /// `log-output-failure`. Status Close(); private: enum class State { kReady, kOpen, kClosed, kFailed }; std::ofstream stream_; std::filesystem::path log_path_; State state_{State::kReady}; }; } // namespace fesa #endif // FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_