#ifndef FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_ #define FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_ #include #include #include #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 Identifies the update and the meaning of a frame's full auxiliary A. enum class DynamicTimeIntegrationFormulation { kFullCoordinateHht, kReducedCoordinateHht }; /// @brief Stores one accepted endpoint of an HHT dynamic step. struct DynamicAcceptedFrameState { DynamicTimeIntegrationFormulation time_integration_formulation = DynamicTimeIntegrationFormulation::kFullCoordinateHht; 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 nodal_internal_order; std::vector nodal_source_ids; Vector generalized_coordinates{0U}; Vector velocity{0U}; Vector acceleration{0U}; /// Full-coordinate history stores the predictor driver. Reduced-coordinate /// history stores (1+alpha)*a_n-alpha*a_previous; frame zero stores a0. Vector algorithmic_acceleration{0U}; std::vector, 3>> nodal_triad; std::vector> 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 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 global_equilibrium{}; std::array linear_momentum{}; std::array angular_momentum{}; std::array linear_momentum_rate{}; std::array angular_momentum_rate{}; std::array 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 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 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& 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 shell_element_order, std::vector constrained_dofs, std::vector nodal_source_ids, std::vector initial_frames); std::size_t full_dof_count_ = 0U; std::uint32_t increment_count_ = 0U; double initial_increment_ = 0.0; std::vector shell_element_order_; std::vector constrained_dofs_; std::vector nodal_source_ids_; std::vector initial_frames_; std::vector accepted_frames_; std::size_t hidden_constraint_count_ = 0U; bool initialized_ = false; }; } // namespace fesa #endif // FESA_ANALYSIS_DYNAMIC_ANALYSIS_STATE_H_