#ifndef FESA_ELEMENTS_HEX8_ELEMENT_H_ #define FESA_ELEMENTS_HEX8_ELEMENT_H_ #include #include #include "fesa/elements/element.h" #include "fesa/materials/isotropic_linear_elastic_material.h" #include "fesa/results/solid_result_records.h" namespace fesa { /// @brief Owns all local quantities from one validated linear or TL trial. struct Hex8Response { Vector internal_force{24U}; Matrix material_tangent{24U, 24U}; Matrix geometric_tangent{24U, 24U}; Matrix tangent{24U, 24U}; double strain_energy{0.0}; std::array points{}; }; /// @brief Normalized full-state response for Solid HHT high+low arithmetic. /// @note Point rows are rounded observables; forces, Hessian and energy retain /// their low components until global assembly and physical validation. struct Hex8HighLowResponse { Hex8Response high; Vector internal_force_low{24U}; Matrix tangent_low{24U, 24U}; double strain_energy_low{0.0}; }; /// @brief Implements C3D8 full deviatoric and mean-volume Green energy. /// @note Reference geometry is owned and immutable; no trial is committed. class Hex8Element final : public Element { public: using Coordinates = std::array, 8>; /// @brief Validates identity, isotropic material and whole reference cell. /// @param coordinates Reference global coordinates in source node order. /// @param density Optional reference mass per volume, positive if present. /// @note All inputs are copied; no Domain or section lifetime is required. static Result Create( EntityIndex element_index, ElementDofLayout layout, Coordinates coordinates, const LinearElasticMaterial& material, std::optional density = std::nullopt, SourceLocation location = {}); const ElementDofLayout& DofLayout() const noexcept override; Result ComputeStiffness() const override; Result Recover( const Vector& displacement) const override; /// @brief Returns f=K0*u and infinitesimal tensor strain at eight points. Result EvaluateLinear(const Vector& displacement) const; /// @brief Returns one certified mean-Green TL trial and its energy Hessian. Result EvaluateNonlinear(const Vector& displacement) const; /// @brief Evaluates linear energy/force/Hessian on the complete paired state. /// @note Uses the same reference-relative gradient operator as the paired TL /// path. Inputs must have 24 finite normalized high+low translations. Result EvaluateLinearHighLow( const Vector& high, const Vector& low) const; /// @brief Evaluates mean-Green TL mechanics without collapsing low state. /// @note Failure preserves immutable reference data and all caller state. Result EvaluateNonlinearHighLow( const Vector& high, const Vector& low) const; /// @brief Returns the constant reference consistent mass; density required. Result ComputeMass() const; /// @brief Returns immutable positive reference Gauss volume weights. /// @note Order is the kernel's fixed eight-point integration order. std::array ReferenceWeights() const noexcept; private: /// @brief Caches shape, reference gradients and positive volume weights. struct ReferencePoint { std::array shape{}; std::array, 8> gradients{}; std::array natural{}; std::array position{}; double weight{0.0}; }; /// @brief Constructs an owned candidate before reference validation. Hex8Element(EntityIndex element_index, ElementDofLayout layout, Coordinates coordinates, double kappa, double mu, std::optional density, SourceLocation location); /// @brief Evaluates without mutating the cached reference or previous values. Result Evaluate(const Vector& displacement, bool nonlinear) const; /// @brief Uses one paired gradient for energy, force and analytic Hessian. Result EvaluateHighLow( const Vector& high, const Vector& low, bool nonlinear) const; /// @brief Attaches stable source context to a model failure. Status Failure(const char* message) const; EntityIndex element_index_; ElementDofLayout layout_; Coordinates coordinates_; double kappa_; double mu_; std::optional density_; SourceLocation location_; std::array points_{}; Matrix stiffness_{24U, 24U}; // Optional immutable Hessian from the same paired quadrature graph. Failure // to build it does not reject models supported by the original F64 paths. bool paired_linear_tangent_ready_{false}; Matrix paired_linear_tangent_high_{24U, 24U}; Matrix paired_linear_tangent_low_{24U, 24U}; }; } // namespace fesa #endif // FESA_ELEMENTS_HEX8_ELEMENT_H_