#ifndef FESA_ELEMENTS_MITC4_SHELL_H_ #define FESA_ELEMENTS_MITC4_SHELL_H_ #include #include #include "fesa/core/status.h" #include "fesa/math/matrix.h" #include "fesa/math/vector.h" #include "fesa/model/model_types.h" namespace fesa { /// @brief Stores bilinear shape values and natural-coordinate derivatives. struct Mitc4ShapeFunctions { std::array values; std::array xi_derivatives; std::array eta_derivatives; }; /// @brief Stores a right-handed local shell frame at one location. struct Mitc4LocalFrame { std::array e1; std::array e2; std::array e3; }; /// @brief Stores canonical MITC4 covariant shear interpolation weights. struct Mitc4TyingWeights { std::array xi_zeta; std::array eta_zeta; }; /// @brief Stores one fixed 2-by-2-by-2 integration point and weight. struct Mitc4QuadraturePoint { std::array natural_coordinates; double weight; }; /// @brief Separates physical, drilling, and stabilized stiffness matrices. struct Mitc4Stiffness { Matrix physical_local20; Matrix physical_global24; Matrix drilling_global24; Matrix stabilized_global24; double drilling_stiffness; }; /// @brief Stores physical shell recovery at one midsurface Gauss location. struct Mitc4PhysicalRecoveryPoint { std::array natural_coordinates; Mitc4LocalFrame local_frame; std::array generalized_strain; std::array section_resultant; std::array, 3> in_plane_stress; }; /// @brief Stores physical-only recovery rows and strain energy. struct Mitc4PhysicalRecovery { std::array points; double strain_energy; }; /// @brief Implements the approved small-rotation FESA-MITC4 shell kernel. /// @note Physical and numerical drilling contributions remain separate. class Mitc4Shell { public: /// @brief Creates a validated shell kernel from four non-owning node /// pointers. /// @param nodes Node pointers valid for the duration of this call. /// @param initial_directors Validated unit initial directors in node order. /// @param section Centered constant-thickness shell section. /// @param material Supported isotropic elastic material. /// @return A validated shell or a structured model failure. static Result Create( std::array nodes, std::array, 4> initial_directors, const ShellSection& section, const LinearElasticMaterial& material); /// @brief Evaluates bilinear shape functions and derivatives. static Mitc4ShapeFunctions ShapeFunctions(double xi, double eta) noexcept; /// @brief Evaluates the canonical edge-midpoint tying weights. static Mitc4TyingWeights TyingWeights(double xi, double eta) noexcept; /// @brief Returns the fixed 2-by-2-by-2 quadrature inventory. static const std::array& VolumeQuadrature() noexcept; /// @brief Evaluates the right-handed local frame at a midsurface location. [[nodiscard]] Mitc4LocalFrame LocalFrame(double xi, double eta) const; /// @brief Returns the physical 24-to-20 transformation. [[nodiscard]] Matrix PhysicalTransformation20() const; /// @brief Returns the numerical drilling 24-to-4 transformation. [[nodiscard]] Matrix DrillingTransformation4() const; /// @brief Evaluates the direct five-component physical strain operator. [[nodiscard]] Matrix DirectStrainDisplacement20(double xi, double eta, double zeta) const; /// @brief Evaluates all four canonical covariant tying shear samples. [[nodiscard]] Matrix CovariantTyingShearSamples20() const; /// @brief Evaluates the MITC-projected five-component strain operator. [[nodiscard]] Matrix StrainDisplacement20(double xi, double eta, double zeta) const; /// @brief Returns the isotropic in-plane plane-stress matrix. [[nodiscard]] Matrix PlaneStressConstitutive() const; /// @brief Returns the five-component plane-stress and shear matrix. [[nodiscard]] Matrix MaterialConstitutive5() const; /// @brief Returns the centered membrane section matrix. [[nodiscard]] Matrix MembraneSectionMatrix() const; /// @brief Returns the centered bending section matrix. [[nodiscard]] Matrix BendingSectionMatrix() const; /// @brief Returns the corrected transverse-shear section matrix. [[nodiscard]] Matrix TransverseShearSectionMatrix() const; /// @brief Computes physical, drilling, and stabilized stiffness matrices. /// @return Finite stiffness matrices or a structured model failure. [[nodiscard]] Result Stiffness() const; /// @brief Recovers physical shell quantities without drilling results. /// @param global_element_displacement24 Global element DOFs in node order. /// @return Physical recovery rows or a structured model failure. [[nodiscard]] Result RecoverPhysical( const Vector& global_element_displacement24) const; private: using Vector3 = std::array; /// @brief Stores covariant, reciprocal, frame, and Jacobian data at one /// point. struct GeometryData { std::array covariant; std::array reciprocal; Mitc4LocalFrame frame; double jacobian; }; /// @brief Stores validated shell geometry and constitutive state. Mitc4Shell(std::array coordinates, std::array directors, std::array tangent_a, std::array tangent_b, Vector3 normal_candidate, double thickness, double youngs_modulus, double poisson_ratio, SourceLocation source_location, std::string identity); /// @brief Evaluates a finite positive Jacobian and right-handed frame. bool EvaluateGeometry(double xi, double eta, double zeta, GeometryData& result) const noexcept; /// @brief Evaluates displacement-basis derivatives in covariant directions. std::array, 20> BasisDerivatives( double xi, double eta, double zeta) const noexcept; /// @brief Builds direct or tied strain without changing projection order. Matrix StrainDisplacement(double xi, double eta, double zeta, const Matrix* tying_samples) const; std::array coordinates_; std::array directors_; std::array tangent_a_; std::array tangent_b_; Vector3 normal_candidate_; double thickness_; double youngs_modulus_; double poisson_ratio_; SourceLocation source_location_; std::string identity_; }; } // namespace fesa #endif // FESA_ELEMENTS_MITC4_SHELL_H_