feat(analysis): implement Hex8 solid static procedures
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
#ifndef FESA_ANALYSIS_SOLID_STATIC_PROCEDURE_H_
|
||||
#define FESA_ANALYSIS_SOLID_STATIC_PROCEDURE_H_
|
||||
|
||||
#include "fesa/analysis/solid_static_state.h"
|
||||
|
||||
namespace fesa {
|
||||
class LinearSolver;
|
||||
class ParallelFor;
|
||||
class TangentSolver;
|
||||
|
||||
/// @brief Owns successful static frames and sorted model diagnostics.
|
||||
struct SolidStaticExecutionResult {
|
||||
SolidStaticState state;
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
|
||||
/// @brief Executes linear K0 or fixed-factor TL StVK static analysis.
|
||||
class SolidStaticProcedureExecutor {
|
||||
public:
|
||||
/// @brief Uses non-owned adapters, which must outlive this executor.
|
||||
/// @param tangent_solver Must support indefinite stressed tangents.
|
||||
SolidStaticProcedureExecutor(const ParallelFor& parallel_for,
|
||||
LinearSolver& linear_solver,
|
||||
TangentSolver& tangent_solver);
|
||||
/// @brief Returns validated results; no I/O or final-file replacement.
|
||||
Result<SolidStaticExecutionResult> Execute(const Domain& domain) const;
|
||||
/// @brief Executes into a fresh observer retaining accepted history on
|
||||
/// failure.
|
||||
/// @note A previously initialized observer is rejected without mutation.
|
||||
Status ExecuteInto(const Domain& domain, SolidStaticState& state) const;
|
||||
|
||||
private:
|
||||
const ParallelFor& parallel_for_;
|
||||
LinearSolver& linear_solver_;
|
||||
TangentSolver& tangent_solver_;
|
||||
};
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ANALYSIS_SOLID_STATIC_PROCEDURE_H_
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef FESA_ANALYSIS_SOLID_STATIC_STATE_H_
|
||||
#define FESA_ANALYSIS_SOLID_STATIC_STATE_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/analysis/nonlinear_static_control.h"
|
||||
#include "fesa/results/solid_result_records.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Keeps raw current-arm balance and its free-residual explanation.
|
||||
/// @note Internal evidence only; no additional persistent result fields.
|
||||
struct SolidStaticBalanceEvidence {
|
||||
std::array<double, 3> internal_force_sum{};
|
||||
std::array<double, 3> reference_internal_moment{};
|
||||
std::array<double, 3> current_internal_moment{};
|
||||
std::array<double, 3> free_residual_moment{};
|
||||
std::array<double, 3> linearization_moment{};
|
||||
std::array<double, 3> internal_force_scale{};
|
||||
std::array<double, 3> reference_moment_scale{};
|
||||
std::array<double, 3> current_moment_scale{};
|
||||
};
|
||||
|
||||
/// @brief Owns a complete accepted static frame in stable node/source order.
|
||||
/// @note Vectors are node-major UX/UY/UZ; reaction is constrained residual.
|
||||
struct SolidStaticFrame {
|
||||
std::uint32_t frame_index{0U};
|
||||
std::uint32_t increment_index{0U};
|
||||
double load_factor{0.0};
|
||||
std::uint32_t iteration_count{0U};
|
||||
bool is_factor_one{false};
|
||||
std::vector<EntityIndex> nodal_internal_order;
|
||||
std::vector<SourceEntityId> nodal_source_ids;
|
||||
Vector displacement{0U};
|
||||
Vector internal_force{0U};
|
||||
Vector external_force{0U};
|
||||
Vector residual{0U};
|
||||
Vector reaction{0U};
|
||||
std::vector<SolidIntegrationPointRow> solid_results;
|
||||
double physical_strain_energy{0.0};
|
||||
// Applied plus support forces, then moments about global zero at X+u.
|
||||
std::array<double, 6> global_equilibrium{};
|
||||
SolidStaticBalanceEvidence balance;
|
||||
};
|
||||
|
||||
/// @brief Records two physical static channels, including failed iterations.
|
||||
struct SolidStaticIterationRecord {
|
||||
std::uint32_t increment_index{0U};
|
||||
double load_factor{0.0};
|
||||
std::uint32_t iteration{0U};
|
||||
NewtonChannelDecision force_residual{"residual_force",
|
||||
0.0,
|
||||
0.0,
|
||||
NewtonConvergenceBranch::kZeroScale,
|
||||
kNewtonZeroScaleThreshold,
|
||||
NewtonChannelUnit::kForce,
|
||||
false};
|
||||
NewtonChannelDecision translation_correction{
|
||||
"correction_translation",
|
||||
0.0,
|
||||
0.0,
|
||||
NewtonConvergenceBranch::kZeroScale,
|
||||
kNewtonZeroScaleThreshold,
|
||||
NewtonChannelUnit::kLength,
|
||||
false};
|
||||
bool convergence_evaluated{false};
|
||||
bool accepted{false};
|
||||
std::string diagnostic_code;
|
||||
std::string stage;
|
||||
std::string failure_reason;
|
||||
};
|
||||
|
||||
/// @brief Evaluates translation-only static criteria with input force/length.
|
||||
/// @note Exact-zero external force selects the absolute residual branch.
|
||||
Result<SolidStaticIterationRecord> EvaluateSolidStaticConvergence(
|
||||
const Vector& residual, const Vector& internal, const Vector& external,
|
||||
const Vector& correction, const Vector& increment);
|
||||
|
||||
/// @brief Owns committed static state independently of caller trial work.
|
||||
class SolidStaticState {
|
||||
public:
|
||||
/// @brief Creates an uninitialized observer usable with ExecuteInto().
|
||||
SolidStaticState() = default;
|
||||
/// @brief Copies immutable source inventory and the zero-factor baseline.
|
||||
static Result<SolidStaticState> Create(const Domain& domain,
|
||||
const DofManager& dofs);
|
||||
/// @brief Validates complete recovery, then appends and replaces atomically.
|
||||
/// @note The executor certifies trial geometry before this state boundary.
|
||||
Status CommitAcceptedFrame(const SolidStaticFrame& frame);
|
||||
/// @brief Returns authoritative accepted frames; baseline is not a frame.
|
||||
const std::vector<SolidStaticFrame>& AcceptedFrames() const noexcept;
|
||||
/// @brief Returns baseline or the most recently accepted complete state.
|
||||
const SolidStaticFrame& CommittedState() const noexcept;
|
||||
/// @brief Returns all iteration evidence, including the final failed trial.
|
||||
const std::vector<SolidStaticIterationRecord>& IterationRecords()
|
||||
const noexcept;
|
||||
|
||||
private:
|
||||
friend class SolidStaticProcedureExecutor;
|
||||
bool initialized_{false};
|
||||
bool nonlinear_{false};
|
||||
std::vector<SolidIntegrationPointRow> reference_points_;
|
||||
std::vector<std::size_t> constrained_dofs_;
|
||||
Vector prescribed_values_{0U};
|
||||
SolidStaticFrame committed_;
|
||||
std::vector<SolidStaticFrame> accepted_frames_;
|
||||
std::vector<SolidStaticIterationRecord> iterations_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ANALYSIS_SOLID_STATIC_STATE_H_
|
||||
Reference in New Issue
Block a user