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_
|
||||
Reference in New Issue
Block a user