Files
FESADev/include/fesa/analysis/newton_iteration_log.h
T

145 lines
5.2 KiB
C++

#ifndef FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_
#define FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_
#include <array>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <optional>
#include <string>
#include "fesa/analysis/nonlinear_static_control.h"
#include "fesa/core/status.h"
namespace fesa {
struct SolidStaticIterationRecord;
struct SolidDynamicIterationRecord;
/// @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 Vendor-neutral field evidence in full global u/total-phi coordinates.
/// @note Missing quantities serialize as literal not-evaluated. Force uses
/// force/length units; generalized moment uses moment/rad units.
struct DynamicFieldLogEvidence {
std::optional<double> residual_numerator, residual_scale, spatial_flux;
std::optional<double> time_average_flux, correction_numerator, increment_norm;
std::optional<double> estimated_correction, residual_threshold, correction_threshold;
std::string branch = "not-evaluated";
std::optional<bool> residual_pass, correction_pass, field_pass;
};
/// @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<double, 2U> residual_numerator{};
std::array<double, 2U> residual_scale{};
std::array<double, 2U> coordinate_correction{};
std::array<double, 2U> velocity_correction{};
std::array<double, 2U> acceleration_correction{};
std::array<double, 2U> algorithmic_correction{};
bool residual_pass = false;
bool correction_pass = false;
// Absent policy preserves the historical v1 direct-writer/frame-zero contract.
std::string policy_id;
std::string step_name;
std::array<DynamicFieldLogEvidence, 2U> fields;
std::optional<bool> field_pass;
bool accepted = false;
bool strict_residual_evaluated = false;
bool strict_correction_evaluated = 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 HHT v1 evidence, or v2 when the field policy is identified.
/// @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 Writes the two actual Solid static convergence channels.
Status Write(const SolidStaticIterationRecord& record,
const std::string& step_name);
/// @brief Writes scalar full-pair Solid HHT convergence evidence.
Status Write(const SolidDynamicIterationRecord& 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_