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

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_