feat: implement consistent-mass HHT shell dynamics
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
#ifndef FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_
|
||||
#define FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/core/source_identity.h"
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/domain.h"
|
||||
#include "fesa/results/result_records.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores one accepted endpoint of an HHT dynamic step.
|
||||
struct DynamicAcceptedFrameState {
|
||||
std::uint32_t frame_index = 0U;
|
||||
std::uint32_t increment_index = 0U;
|
||||
std::uint32_t iteration_count = 0U;
|
||||
double time = 0.0;
|
||||
bool is_initial = false;
|
||||
std::vector<EntityIndex> nodal_internal_order;
|
||||
std::vector<SourceEntityId> nodal_source_ids;
|
||||
Vector generalized_coordinates{0U};
|
||||
Vector velocity{0U};
|
||||
Vector acceleration{0U};
|
||||
Vector algorithmic_acceleration{0U};
|
||||
std::vector<std::array<std::array<double, 3>, 3>> nodal_triad;
|
||||
std::vector<std::array<double, 3>> nodal_director;
|
||||
Vector angular_velocity{0U};
|
||||
Vector angular_acceleration{0U};
|
||||
Vector inertia_force{0U};
|
||||
Vector internal_force{0U};
|
||||
Vector external_force{0U};
|
||||
Vector residual{0U};
|
||||
Vector reaction{0U};
|
||||
Vector residual_scale{0U};
|
||||
std::vector<ShellResultRow> shell_results;
|
||||
double kinetic_energy = 0.0;
|
||||
double physical_strain_energy = 0.0;
|
||||
double drilling_energy = 0.0;
|
||||
double external_work = 0.0;
|
||||
double energy_defect = 0.0;
|
||||
std::array<double, 6> global_equilibrium{};
|
||||
std::array<double, 3> linear_momentum{};
|
||||
std::array<double, 3> angular_momentum{};
|
||||
std::array<double, 3> linear_momentum_rate{};
|
||||
std::array<double, 3> angular_momentum_rate{};
|
||||
std::array<double, 2> free_residual_metrics{};
|
||||
Vector hidden_constraint{0U};
|
||||
Vector hidden_velocity_defect{0U};
|
||||
Vector hidden_acceleration_defect{0U};
|
||||
Vector hidden_constraint_scale{0U};
|
||||
Vector hidden_velocity_defect_scale{0U};
|
||||
Vector hidden_acceleration_defect_scale{0U};
|
||||
};
|
||||
|
||||
/// @brief Owns accepted HHT frame history and the current committed endpoint.
|
||||
class DynamicAnalysisState {
|
||||
public:
|
||||
/// @brief Creates an uninitialized state that cannot be written or committed.
|
||||
DynamicAnalysisState() = default;
|
||||
|
||||
/// @brief Validates the immutable dynamic inventory and schedule.
|
||||
/// @return A state ready to accept the required frame zero.
|
||||
static Result<DynamicAnalysisState> Create(const Domain& domain,
|
||||
const DofManager& dofs);
|
||||
|
||||
/// @brief Returns an independent copy of the committed frame.
|
||||
/// @pre At least one frame has been committed.
|
||||
Result<DynamicAcceptedFrameState> BeginTrialFromCommitted() const;
|
||||
|
||||
/// @brief Atomically accepts one complete finite dynamic frame.
|
||||
Status CommitAcceptedFrame(const DynamicAcceptedFrameState& frame);
|
||||
|
||||
/// @brief Discards caller-owned trial data without mutating this state.
|
||||
void DiscardTrial() noexcept;
|
||||
|
||||
/// @brief Returns accepted frames in frame-index order.
|
||||
const std::vector<DynamicAcceptedFrameState>& AcceptedFrames() const noexcept;
|
||||
|
||||
/// @brief Returns the current committed frame.
|
||||
/// @pre At least one frame has been committed.
|
||||
const DynamicAcceptedFrameState& CommittedState() const;
|
||||
|
||||
/// @brief Reports whether Create has validated this state inventory.
|
||||
bool IsInitialized() const noexcept;
|
||||
|
||||
private:
|
||||
DynamicAnalysisState(std::size_t full_dof_count,
|
||||
std::uint32_t increment_count, double initial_increment,
|
||||
std::vector<EntityIndex> shell_element_order,
|
||||
std::vector<std::size_t> constrained_dofs,
|
||||
std::vector<SourceEntityId> nodal_source_ids,
|
||||
std::vector<ShellNodeInitialFrame> initial_frames);
|
||||
|
||||
std::size_t full_dof_count_ = 0U;
|
||||
std::uint32_t increment_count_ = 0U;
|
||||
double initial_increment_ = 0.0;
|
||||
std::vector<EntityIndex> shell_element_order_;
|
||||
std::vector<std::size_t> constrained_dofs_;
|
||||
std::vector<SourceEntityId> nodal_source_ids_;
|
||||
std::vector<ShellNodeInitialFrame> initial_frames_;
|
||||
std::vector<DynamicAcceptedFrameState> accepted_frames_;
|
||||
std::size_t hidden_constraint_count_ = 0U;
|
||||
bool initialized_ = false;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef FESA_ANALYSIS_HHT_DYNAMIC_PROCEDURE_H_
|
||||
#define FESA_ANALYSIS_HHT_DYNAMIC_PROCEDURE_H_
|
||||
|
||||
#include "fesa/analysis/prepared_analysis.h"
|
||||
|
||||
namespace fesa {
|
||||
class LinearSolver;
|
||||
class ParallelFor;
|
||||
class TangentSolver;
|
||||
|
||||
/// @brief Executes endpoint-equilibrium HHT with consistent shell inertia.
|
||||
class HhtDynamicProcedureExecutor {
|
||||
public:
|
||||
/// @brief Retains caller-owned deterministic execution and solve adapters.
|
||||
HhtDynamicProcedureExecutor(const ParallelFor& parallel_for,
|
||||
LinearSolver& positive_solver,
|
||||
TangentSolver& tangent_solver);
|
||||
|
||||
/// @brief Returns complete accepted history without opening result output.
|
||||
Result<DynamicExecutionResult> Execute(const Domain& domain,
|
||||
NewtonIterationLogWriter& log) const;
|
||||
|
||||
private:
|
||||
const ParallelFor& parallel_for_;
|
||||
LinearSolver& positive_solver_;
|
||||
TangentSolver& tangent_solver_;
|
||||
};
|
||||
} // namespace fesa
|
||||
#endif // FESA_ANALYSIS_HHT_DYNAMIC_PROCEDURE_H_
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef FESA_ANALYSIS_HHT_TIME_INTEGRATION_H_
|
||||
#define FESA_ANALYSIS_HHT_TIME_INTEGRATION_H_
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/vector.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores the coupled original negative-alpha HHT coefficients.
|
||||
struct HhtParameters {
|
||||
double alpha;
|
||||
double beta;
|
||||
double gamma;
|
||||
};
|
||||
|
||||
/// @brief Stores the displacement and velocity Newmark predictors.
|
||||
struct HhtPredictor {
|
||||
Vector coordinates;
|
||||
Vector velocity;
|
||||
};
|
||||
|
||||
/// @brief Separates physical chart rates from the auxiliary acceleration.
|
||||
struct HhtRates {
|
||||
Vector velocity;
|
||||
Vector acceleration;
|
||||
Vector algorithmic_acceleration;
|
||||
};
|
||||
|
||||
/// @brief Builds coupled coefficients for alpha in [-1/3, 0].
|
||||
/// @note The public INP subset uses only alpha=-0.05.
|
||||
Result<HhtParameters> MakeHhtParameters(double alpha);
|
||||
|
||||
/// @brief Predicts q and v using the old auxiliary acceleration.
|
||||
/// @param time_increment Finite positive duration in input time units.
|
||||
Result<HhtPredictor> PredictHht(const Vector& coordinates,
|
||||
const Vector& velocity,
|
||||
const Vector& algorithmic_acceleration,
|
||||
double time_increment,
|
||||
const HhtParameters& parameters);
|
||||
|
||||
/// @brief Recovers physical and auxiliary rates from one trial coordinate.
|
||||
/// @param old_acceleration Physical endpoint acceleration at the old time.
|
||||
Result<HhtRates> EvaluateHhtRates(const Vector& coordinates,
|
||||
const HhtPredictor& predictor,
|
||||
const Vector& old_acceleration,
|
||||
double time_increment,
|
||||
const HhtParameters& parameters);
|
||||
|
||||
} // namespace fesa
|
||||
#endif // FESA_ANALYSIS_HHT_TIME_INTEGRATION_H_
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_
|
||||
#define FESA_ANALYSIS_NEWTON_ITERATION_LOG_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
@@ -49,6 +50,27 @@ struct NewtonIterationLogRecord {
|
||||
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<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;
|
||||
};
|
||||
|
||||
/// @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.
|
||||
@@ -66,6 +88,11 @@ class NewtonIterationLogWriter {
|
||||
/// 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`.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/analysis/analysis_state.h"
|
||||
#include "fesa/analysis/dynamic_analysis_state.h"
|
||||
#include "fesa/analysis/eigen_analysis_state.h"
|
||||
#include "fesa/analysis/nonlinear_analysis_state.h"
|
||||
#include "fesa/core/diagnostic.h"
|
||||
@@ -21,6 +22,8 @@ class NewtonIterationLogWriter;
|
||||
class NonlinearResultsWriter;
|
||||
class NonlinearStaticProcedureExecutor;
|
||||
class ResultsWriter;
|
||||
class HhtDynamicProcedureExecutor;
|
||||
class DynamicResultsWriter;
|
||||
struct DerivedOutputPaths;
|
||||
|
||||
/// @brief Owns one parsed and semantically mapped analysis input.
|
||||
@@ -49,9 +52,15 @@ struct NonlinearStaticExecutionResult {
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
|
||||
/// @brief Stores a complete HHT history before atomic result finalization.
|
||||
struct DynamicExecutionResult {
|
||||
DynamicAnalysisState state;
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
|
||||
using PreparedAnalysisOutcome =
|
||||
std::variant<LinearStaticExecutionResult, NonlinearStaticExecutionResult,
|
||||
EigenAnalysisState>;
|
||||
EigenAnalysisState, DynamicExecutionResult>;
|
||||
|
||||
/// @brief Selects the approved procedure from a prepared Domain.
|
||||
/// @pre The executors and log outlive this call.
|
||||
@@ -60,7 +69,8 @@ Result<PreparedAnalysisOutcome> ExecutePreparedAnalysis(
|
||||
const Domain& domain, LinearStaticProcedureExecutor& linear_executor,
|
||||
NonlinearStaticProcedureExecutor& nonlinear_executor,
|
||||
const LinearFrequencyProcedureExecutor& frequency_executor,
|
||||
NewtonIterationLogWriter& log);
|
||||
NewtonIterationLogWriter& log,
|
||||
const HhtDynamicProcedureExecutor* dynamic_executor = nullptr);
|
||||
|
||||
/// @brief Writes an already computed outcome to its authoritative result file.
|
||||
/// @pre The Newton log has closed successfully before this function is called.
|
||||
@@ -69,7 +79,8 @@ Status FinalizePreparedAnalysisResult(
|
||||
const DerivedOutputPaths& paths, const Domain& domain,
|
||||
const PreparedAnalysisOutcome& outcome,
|
||||
const std::vector<Diagnostic>& diagnostics, ResultsWriter& linear_writer,
|
||||
NonlinearResultsWriter& nonlinear_writer, EigenResultsWriter& eigen_writer);
|
||||
NonlinearResultsWriter& nonlinear_writer, EigenResultsWriter& eigen_writer,
|
||||
DynamicResultsWriter* dynamic_writer = nullptr);
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef FESA_ELEMENTS_NONLINEAR_MITC4_INERTIA_H_
|
||||
#define FESA_ELEMENTS_NONLINEAR_MITC4_INERTIA_H_
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/elements/nonlinear_mitc4_shell.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/math/vector3.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores exact physical rotation-rate and drilling-null quantities.
|
||||
struct DynamicRotationKinematics {
|
||||
Vector3 director;
|
||||
Vector3 drill_null;
|
||||
Matrix null_gradient{3U, 3U};
|
||||
/// @brief Stores D2 drill_null[velocity, velocity], without Dn[a].
|
||||
Vector3 null_directional_second;
|
||||
Vector3 angular_velocity;
|
||||
Vector3 angular_acceleration;
|
||||
/// @brief Stores director derivatives in fixed-global chart directions.
|
||||
std::array<Vector3, 3> director_first;
|
||||
std::array<std::array<Vector3, 3>, 3> director_second;
|
||||
std::array<std::array<std::array<Vector3, 3>, 3>, 3> director_third;
|
||||
};
|
||||
|
||||
/// @brief Evaluates exact finite-rotation rates and the unit drilling null.
|
||||
/// @param phi Fixed-global principal-chart rotation coordinate.
|
||||
/// @param initial_director Unit director at zero rotation.
|
||||
/// @param velocity Fixed-chart rotation-coordinate rate.
|
||||
/// @param acceleration Fixed-chart rotation-coordinate acceleration.
|
||||
/// @return Finite director/rates/null derivatives or a structured failure.
|
||||
[[nodiscard]] Result<DynamicRotationKinematics> EvaluateDynamicRotation(
|
||||
const Vector3& phi, const Vector3& initial_director,
|
||||
const Vector3& velocity, const Vector3& acceleration);
|
||||
|
||||
/// @brief Stores the consistent kinetic-inertia quantities at one trial.
|
||||
struct NonlinearMitc4InertiaEvaluation {
|
||||
Matrix mass;
|
||||
Matrix position_tangent;
|
||||
Matrix velocity_tangent;
|
||||
Vector force;
|
||||
Vector convective_force;
|
||||
double kinetic_energy;
|
||||
Vector3 momentum;
|
||||
Vector3 angular_momentum;
|
||||
Vector3 momentum_rate;
|
||||
Vector3 angular_momentum_rate;
|
||||
/// @brief Stores uncancelled quadrature norm sums for balance checks.
|
||||
double momentum_rate_scale = 0.0;
|
||||
double angular_momentum_rate_scale = 0.0;
|
||||
};
|
||||
|
||||
/// @brief Evaluates finite-rotation consistent inertia for one MITC4 shell.
|
||||
/// @note This object owns immutable reference geometry only, never analysis
|
||||
/// trial state.
|
||||
class NonlinearMitc4Inertia {
|
||||
public:
|
||||
/// @brief Creates a checked consistent kinetic-mass evaluator.
|
||||
/// @param nodes Four non-owning nodes in source order.
|
||||
/// @param initial_frames Fixed proper node frames in source order.
|
||||
/// @param section Centered shell section with positive thickness.
|
||||
/// @param material Shell material used to retain the nonlinear-shell input
|
||||
/// contract.
|
||||
/// @param density Reference mass density, strictly positive and finite.
|
||||
/// @return A checked immutable evaluator or a structured model failure.
|
||||
static Result<NonlinearMitc4Inertia> Create(
|
||||
std::array<const Node*, 4> nodes,
|
||||
std::array<ShellNodeInitialFrame, 4> initial_frames,
|
||||
const ShellSection& section, const LinearElasticMaterial& material,
|
||||
double density);
|
||||
|
||||
/// @brief Evaluates physical consistent inertia at a complete trial.
|
||||
/// @param trial Fixed-global translation and rotation coordinates.
|
||||
/// @param velocity24 Fixed-chart generalized physical velocity.
|
||||
/// @param physical_acceleration24 Fixed-chart generalized physical
|
||||
/// acceleration.
|
||||
/// @return Current mass, inertia force and exact partial tangents, or a
|
||||
/// fail-closed diagnostic.
|
||||
[[nodiscard]] Result<NonlinearMitc4InertiaEvaluation> Evaluate(
|
||||
const NonlinearMitc4TrialDofs& trial, const Vector& velocity24,
|
||||
const Vector& physical_acceleration24) const;
|
||||
|
||||
private:
|
||||
NonlinearMitc4Inertia(std::array<Vector3, 4> coordinates,
|
||||
std::array<Matrix, 4> initial_frames,
|
||||
std::array<Vector3, 4> initial_directors,
|
||||
double thickness, double density,
|
||||
SourceLocation source_location, std::string identity);
|
||||
|
||||
std::array<Vector3, 4> coordinates_;
|
||||
std::array<Matrix, 4> initial_frames_;
|
||||
std::array<Vector3, 4> initial_directors_;
|
||||
double thickness_;
|
||||
double density_;
|
||||
SourceLocation source_location_;
|
||||
std::string identity_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ELEMENTS_NONLINEAR_MITC4_INERTIA_H_
|
||||
@@ -43,6 +43,16 @@ struct NonlinearMitc4InternalEquilibrium {
|
||||
Vector internal_force;
|
||||
NonlinearMitc4Recovery recovery;
|
||||
double physical_strain_energy;
|
||||
Vector physical_force{0U};
|
||||
Vector drilling_force{0U};
|
||||
Matrix drilling_tangent{0U, 0U};
|
||||
Matrix drilling_metric{0U, 0U};
|
||||
double drilling_energy = 0.0;
|
||||
Vector force_directional_second{0U};
|
||||
Vector drilling_constraint{0U};
|
||||
Matrix drilling_constraint_gradient{0U, 0U};
|
||||
std::array<Matrix, 4> drilling_constraint_hessian{
|
||||
Matrix{0U, 0U}, Matrix{0U, 0U}, Matrix{0U, 0U}, Matrix{0U, 0U}};
|
||||
};
|
||||
|
||||
class NonlinearMitc4Shell;
|
||||
@@ -50,11 +60,13 @@ class NonlinearMitc4Shell;
|
||||
/// @brief Evaluates the internal residual and tangent at one complete trial.
|
||||
/// @param element Immutable nonlinear MITC4 reference evaluator.
|
||||
/// @param trial Complete global translation and rotation trial coordinates.
|
||||
/// @param coordinate_direction Optional 24-vector for D2(f_int)[v,v].
|
||||
/// @return Internal force, consistent tangent and physical recovery, or
|
||||
/// failure.
|
||||
/// @note External load vectors and their tangents are intentionally excluded.
|
||||
Result<NonlinearMitc4InternalEquilibrium> EvaluateInternalResidualAndTangent(
|
||||
const NonlinearMitc4Shell& element, const NonlinearMitc4TrialDofs& trial);
|
||||
const NonlinearMitc4Shell& element, const NonlinearMitc4TrialDofs& trial,
|
||||
const Vector* coordinate_direction = nullptr);
|
||||
|
||||
/// @brief Evaluates fixed-reference Total Lagrangian MITC4 kinematics.
|
||||
/// @note This class owns no mutable trial or accepted analysis state.
|
||||
@@ -94,7 +106,8 @@ class NonlinearMitc4Shell {
|
||||
|
||||
friend Result<NonlinearMitc4InternalEquilibrium>
|
||||
EvaluateInternalResidualAndTangent(const NonlinearMitc4Shell& element,
|
||||
const NonlinearMitc4TrialDofs& trial);
|
||||
const NonlinearMitc4TrialDofs& trial,
|
||||
const Vector* coordinate_direction);
|
||||
|
||||
std::array<Vector3, 4> coordinates_;
|
||||
std::array<Matrix, 4> initial_frames_;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef FESA_IO_HDF5_DYNAMIC_HDF5_RESULTS_WRITER_H_
|
||||
#define FESA_IO_HDF5_DYNAMIC_HDF5_RESULTS_WRITER_H_
|
||||
|
||||
#include "fesa/results/dynamic_results_writer.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Writes schema-v1 HHT dynamic HDF5 results with atomic finalization.
|
||||
class DynamicHdf5ResultsWriter final : public DynamicResultsWriter {
|
||||
public:
|
||||
/// @brief Writes a validated dynamic result file and preserves a prior final
|
||||
/// file on failure.
|
||||
Status Write(const std::filesystem::path& output_path, const Domain& domain,
|
||||
const DynamicAnalysisState& state,
|
||||
const std::vector<Diagnostic>& diagnostics) override;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_IO_HDF5_DYNAMIC_HDF5_RESULTS_WRITER_H_
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef FESA_RESULTS_DYNAMIC_RESULTS_WRITER_H_
|
||||
#define FESA_RESULTS_DYNAMIC_RESULTS_WRITER_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/analysis/dynamic_analysis_state.h"
|
||||
#include "fesa/core/diagnostic.h"
|
||||
#include "fesa/core/status.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
class Domain;
|
||||
|
||||
/// @brief Writes complete HHT dynamic results to their official output file.
|
||||
class DynamicResultsWriter {
|
||||
public:
|
||||
virtual ~DynamicResultsWriter() = default;
|
||||
|
||||
/// @brief Persists every accepted dynamic frame and diagnostic atomically.
|
||||
virtual Status Write(const std::filesystem::path& output_path,
|
||||
const Domain& domain, const DynamicAnalysisState& state,
|
||||
const std::vector<Diagnostic>& diagnostics) = 0;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_RESULTS_DYNAMIC_RESULTS_WRITER_H_
|
||||
Reference in New Issue
Block a user