204 lines
7.7 KiB
C++
204 lines
7.7 KiB
C++
#ifndef FESA_ANALYSIS_SOLID_DYNAMIC_ANALYSIS_STATE_H_
|
|
#define FESA_ANALYSIS_SOLID_DYNAMIC_ANALYSIS_STATE_H_
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "fesa/fem/dof_manager.h"
|
|
#include "fesa/results/solid_result_records.h"
|
|
|
|
namespace fesa {
|
|
|
|
/// @brief Dimensionally explicit translation-only Newton evidence.
|
|
struct SolidDynamicIterationEvidence {
|
|
std::uint32_t iteration_index{0};
|
|
double residual_numerator{0}; // Force infinity norm.
|
|
double residual_scale{0}; // Uncancelled force infinity scale.
|
|
double residual_metric{0}; // Maximum componentwise force ratio.
|
|
std::size_t worst_full_dof{0};
|
|
std::array<double, 5> worst_force_terms{}; // r,Ma,fint,F,uncancelled scale.
|
|
double weighted_residual_numerator{0}; // Original HHT force infinity norm.
|
|
double recombined_residual_numerator{
|
|
0}; // Actual solved weighted force norm.
|
|
double old_residual_numerator{0}; // Previous physical free force norm.
|
|
double weighted_equivalence_metric{0}; // Uncancelled force identity ratio.
|
|
std::array<double, 4>
|
|
worst_weighted_terms{}; // Original,recombined,old r,scale.
|
|
bool zero_scale_exact{true};
|
|
std::array<double, 4> correction_metrics{}; // du/L,h*dv/L,h²*da/L,h²*dA/L.
|
|
double update_metric{0}; // Maximum uncancelled update equality ratio.
|
|
bool residual_pass{false};
|
|
bool correction_pass{false};
|
|
bool update_pass{false};
|
|
};
|
|
|
|
/// @brief Failure-only shadow dot products; these never change force or
|
|
/// acceptance.
|
|
struct SolidDynamicLinearDotEvidence {
|
|
EntityIndex element_index{0};
|
|
std::size_t local_row{0};
|
|
double absolute_product_sum{0};
|
|
double kernel_force{0};
|
|
double compensated_force{
|
|
0}; // Shadow using rounded relative differences only.
|
|
};
|
|
|
|
/// @brief Failure-only coordinate arithmetic evidence, with length units.
|
|
struct SolidDynamicCoordinateEvidence {
|
|
EntityIndex element_index{0};
|
|
std::size_t local_row{0};
|
|
double displacement{0};
|
|
double previous_displacement{0};
|
|
double fresh_correction{0};
|
|
double reference_displacement{0};
|
|
double previous_reference_displacement{0};
|
|
double relative_high{0};
|
|
double previous_relative_high{0};
|
|
};
|
|
|
|
/// @brief Failure-only arithmetic shadow; never substitutes physical forces.
|
|
struct SolidDynamicForceSumEvidence {
|
|
double assembled_internal{0};
|
|
double compensated_internal{0};
|
|
double absolute_local_internal_sum{0};
|
|
double assembled_inertia{0};
|
|
double compensated_inertia{0};
|
|
double absolute_inertia_product_sum{0};
|
|
};
|
|
|
|
/// @brief Internal exact-candidate recurrence evidence, separate from gates.
|
|
struct SolidDynamicNewtonRepeatEvidence {
|
|
std::size_t history_entry_count{0};
|
|
std::uint32_t matched_entry_iteration{0};
|
|
std::size_t changed_translations{0};
|
|
std::size_t changed_holding_mask{0};
|
|
std::size_t changed_correction_metrics{0};
|
|
bool repeat{false};
|
|
};
|
|
|
|
/// @brief Keeps failed attempt evidence outside the accepted physical history.
|
|
struct SolidDynamicIterationRecord {
|
|
std::uint32_t increment_index{0};
|
|
double time{0};
|
|
std::string stage;
|
|
std::string outcome;
|
|
std::string failure_code;
|
|
SolidDynamicIterationEvidence evidence;
|
|
std::vector<SolidDynamicLinearDotEvidence> failure_linear_dot;
|
|
std::vector<SolidDynamicCoordinateEvidence> failure_coordinates;
|
|
std::optional<SolidDynamicForceSumEvidence> failure_force_sum;
|
|
std::optional<SolidDynamicNewtonRepeatEvidence> newton_repeat;
|
|
};
|
|
|
|
/// @brief Retains normalized physical low parts; never serialized as extra
|
|
/// result fields. Corresponding endpoint fields contain the nearest Float64
|
|
/// high parts. Both parts are copied and validated together at commit.
|
|
struct SolidDynamicFrameLowParts {
|
|
Vector displacement{0};
|
|
Vector velocity{0};
|
|
Vector acceleration{0};
|
|
Vector algorithmic_acceleration{0};
|
|
Vector inertia_force{0};
|
|
Vector internal_force{0};
|
|
Vector external_force{0};
|
|
Vector residual{0};
|
|
Vector reaction{0};
|
|
Vector residual_scale{0};
|
|
double strain_energy{0};
|
|
double kinetic_energy{0};
|
|
double external_work{0};
|
|
double energy_balance_error{0};
|
|
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, 6> global_equilibrium{};
|
|
std::array<double, 3> linearization_current_internal_moment{};
|
|
std::array<double, 3> reference_internal_moment{};
|
|
std::array<double, 3> current_free_residual_moment{};
|
|
};
|
|
|
|
/// @brief Owns one complete Solid endpoint; physical a differs from auxiliary
|
|
/// A.
|
|
struct SolidDynamicAcceptedFrameState {
|
|
std::uint32_t frame_index{0};
|
|
std::uint32_t increment_index{0};
|
|
std::uint32_t iteration_count{0};
|
|
double time{0};
|
|
bool is_initial{false};
|
|
std::vector<EntityIndex> nodal_internal_order;
|
|
std::vector<SourceEntityId> nodal_source_ids;
|
|
Vector displacement{0};
|
|
Vector velocity{0};
|
|
Vector acceleration{0};
|
|
Vector algorithmic_acceleration{0};
|
|
Vector inertia_force{0};
|
|
Vector internal_force{0};
|
|
Vector external_force{0};
|
|
Vector residual{0};
|
|
Vector reaction{0};
|
|
Vector residual_scale{0};
|
|
std::vector<SolidIntegrationPointRow> solid_results;
|
|
double strain_energy{0};
|
|
double kinetic_energy{0};
|
|
double external_work{0};
|
|
double energy_balance_error{0};
|
|
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, 6> global_equilibrium{};
|
|
// Internal evidence, not additional official output fields.
|
|
std::array<double, 3> linearization_current_internal_moment{};
|
|
std::array<double, 3> reference_internal_moment{};
|
|
std::array<double, 3> current_free_residual_moment{};
|
|
std::vector<SolidDynamicIterationEvidence> iterations;
|
|
SolidDynamicFrameLowParts low;
|
|
};
|
|
|
|
/// @brief Owns only validated accepted Solid history; rejects partial
|
|
/// candidates.
|
|
class SolidDynamicAnalysisState {
|
|
public:
|
|
/// @brief Creates an empty state for exactly one zero-BC fixed dynamic
|
|
/// schedule.
|
|
static Result<SolidDynamicAnalysisState> Create(const Domain& domain,
|
|
const DofManager& dofs);
|
|
/// @brief Validates shape, identity, schedule, finite values and Newton
|
|
/// evidence.
|
|
/// @note A failed candidate never changes accepted frames or current state.
|
|
Status CommitAcceptedFrame(const SolidDynamicAcceptedFrameState& frame);
|
|
/// @brief Returns an independent accepted endpoint copy for trial
|
|
/// preparation.
|
|
Result<SolidDynamicAcceptedFrameState> BeginTrialFromCommitted() const;
|
|
/// @brief Returns accepted endpoints in source increment order.
|
|
const std::vector<SolidDynamicAcceptedFrameState>& AcceptedFrames()
|
|
const noexcept;
|
|
/// @brief Returns the last endpoint; throws when no frame is accepted.
|
|
const SolidDynamicAcceptedFrameState& CommittedState() const;
|
|
/// @brief Reports whether schedule and inventory have been initialized.
|
|
bool IsInitialized() const noexcept;
|
|
/// @brief Appends attempt evidence without committing physical state.
|
|
void RecordIteration(SolidDynamicIterationRecord record);
|
|
/// @brief Returns attempt evidence, including a terminal failure if present.
|
|
const std::vector<SolidDynamicIterationRecord>& IterationRecords()
|
|
const noexcept;
|
|
|
|
private:
|
|
std::size_t full_dof_count_{0};
|
|
std::uint32_t increment_count_{0};
|
|
double time_increment_{0};
|
|
std::vector<std::size_t> constrained_dofs_;
|
|
std::vector<SourceEntityId> source_ids_;
|
|
std::vector<SolidIntegrationPointRow> point_inventory_;
|
|
std::vector<SolidDynamicAcceptedFrameState> accepted_frames_;
|
|
std::vector<SolidDynamicIterationRecord> iteration_records_;
|
|
bool initialized_{false};
|
|
};
|
|
} // namespace fesa
|
|
#endif // FESA_ANALYSIS_SOLID_DYNAMIC_ANALYSIS_STATE_H_
|