#ifndef FESA_ELEMENTS_NONLINEAR_MITC4_SHELL_H_ #define FESA_ELEMENTS_NONLINEAR_MITC4_SHELL_H_ #include #include #include #include "fesa/core/status.h" #include "fesa/elements/mitc4_shell.h" #include "fesa/math/matrix.h" #include "fesa/math/vector.h" #include "fesa/math/vector3.h" #include "fesa/model/model_types.h" #include "fesa/results/result_records.h" namespace fesa { /// @brief Stores one four-node nonlinear shell trial in global coordinates. struct NonlinearMitc4TrialDofs { std::array displacement; std::array rotation_vector; }; /// @brief Stores physical shell recovery at one midsurface Gauss location. struct NonlinearMitc4RecoveryPoint { ShellMidsurfaceLocation location; std::array natural_coordinates; Mitc4LocalFrame local_frame; std::array generalized_strain; std::array section_resultant; std::array stress; }; /// @brief Stores the fixed four-row nonlinear physical recovery inventory. struct NonlinearMitc4Recovery { std::array gauss_points; double physical_strain_energy; }; /// @brief Stores complete internal equilibrium data for one nonlinear trial. struct NonlinearMitc4InternalEquilibrium { Vector internal_residual; Matrix internal_tangent; Vector internal_force; NonlinearMitc4Recovery recovery; double physical_strain_energy; Vector physical_force{0U}; Vector drilling_force{0U}; Matrix drilling_tangent{0U, 0U}; Matrix drilling_metric{0U, 0U}; double drilling_energy = 0.0; Vector force_directional_second{0U}; Vector drilling_constraint{0U}; Matrix drilling_constraint_gradient{0U, 0U}; std::array drilling_constraint_hessian{ Matrix{0U, 0U}, Matrix{0U, 0U}, Matrix{0U, 0U}, Matrix{0U, 0U}}; std::array drilling_constraint_third_directional_gradient{ Vector{0U}, Vector{0U}, Vector{0U}, Vector{0U}}; }; /// @brief Stores one nodal external drilling-null scalar and its variations. /// @note The scalar is `-n(phi)^T F`, where `n` is the normalized physical /// drill-null direction. Directional fields use `W=(phi_dot, 1)` and include /// the supplied force time derivatives. struct NonlinearMitc4ExternalDrillingConstraint { double value = 0.0; Vector gradient{0U}; Matrix hessian{0U, 0U}; double directional_first = 0.0; double directional_second = 0.0; Vector gradient_directional_first{0U}; Vector gradient_directional_second{0U}; }; class NonlinearMitc4Shell; /// @brief Evaluates the internal residual and tangent at one complete trial. /// @param element Immutable nonlinear MITC4 reference evaluator. /// @param trial Complete global translation and rotation trial coordinates. /// @param coordinate_direction Optional 24-vector for D2(f_int)[v,v]. /// @return Internal force, consistent tangent and physical recovery, or /// failure. /// @note External load vectors and their tangents are intentionally excluded. Result EvaluateInternalResidualAndTangent( const NonlinearMitc4Shell& element, const NonlinearMitc4TrialDofs& trial, const Vector* coordinate_direction = nullptr); /// @brief Evaluates fixed-reference Total Lagrangian MITC4 kinematics. /// @note This class owns no mutable trial or accepted analysis state. class NonlinearMitc4Shell { public: /// @brief Creates one checked nonlinear MITC4 element kinematics object. /// @param nodes Four non-owning source nodes in natural source order. /// @param initial_frames Matching fixed initial node frames in source order. /// @param section Centered positive-thickness shell section. /// @param material Homogeneous isotropic material with shell-valid constants. /// @return A checked evaluator or a structured model failure. static Result Create( std::array nodes, std::array initial_frames, const ShellSection& section, const LinearElasticMaterial& material); /// @brief Evaluates trial physical kinematics and fixed recovery rows. /// @param trial Global nodal translation and fixed-global rotation vectors. /// @return Physical recovery or a fail-closed trial diagnostic. [[nodiscard]] Result EvaluateKinematics( const NonlinearMitc4TrialDofs& trial) const; /// @brief Recovers the same physical quantities for one complete trial. /// @param trial Global nodal translation and fixed-global rotation vectors. /// @return Four ordered Gauss rows without nodal stress projection. [[nodiscard]] Result RecoverState( const NonlinearMitc4TrialDofs& trial) const; /// @brief Evaluates the external nodal drill-null scalar through W. /// @param node Source-local node index in `[0, 4)`. /// @param phi Fixed-global principal-chart rotation in radians. /// @param phi_dot Fixed-global chart rate in radians per time. /// @param force Nodal external generalized moment. /// @param force_rate First time derivative of force. /// @param force_acceleration Second time derivative of force. /// @return The scalar `-n(phi)^T force` and exact coordinate/time /// derivatives, or a fail-closed diagnostic. [[nodiscard]] Result EvaluateExternalDrillingConstraint(std::size_t node, const Vector3& phi, const Vector3& phi_dot, const Vector3& force, const Vector3& force_rate, const Vector3& force_acceleration) const; private: /// @brief Retains validated fixed-reference data without analysis ownership. NonlinearMitc4Shell(std::array coordinates, std::array initial_frames, std::array initial_directors, double thickness, double youngs_modulus, double poisson_ratio, double drilling_stiffness, SourceLocation source_location, std::string identity); friend Result EvaluateInternalResidualAndTangent(const NonlinearMitc4Shell& element, const NonlinearMitc4TrialDofs& trial, const Vector* coordinate_direction); std::array coordinates_; std::array initial_frames_; std::array initial_directors_; double thickness_; double youngs_modulus_; double poisson_ratio_; double drilling_stiffness_; SourceLocation source_location_; std::string identity_; }; } // namespace fesa #endif // FESA_ELEMENTS_NONLINEAR_MITC4_SHELL_H_