#ifndef FESA_ANALYSIS_EIGEN_REDUCTION_H_ #define FESA_ANALYSIS_EIGEN_REDUCTION_H_ #include #include #include #include #include "fesa/analysis/eigen_analysis_state.h" #include "fesa/core/status.h" #include "fesa/math/matrix.h" #include "fesa/math/sparse_matrix.h" #include "fesa/math/vector.h" #include "fesa/model/model_types.h" namespace fesa::eigen_internal { /// @brief Stores one constraint-first nodal lift from whitened coordinates. struct NodalLift { Matrix positive_basis{6U, 0U}; Matrix scaled_lift{6U, 0U}; std::array null_vector{}; std::size_t offset{0U}; EigenNodalReductionRecord record{}; }; /// @brief Preserves the original sparse pencil and its checked nodal reduction. struct EigenReduction { SparseMatrix whitened_operator; std::vector nodes; std::size_t free_count; std::size_t null_count; double characteristic_length; double eta_mz; double eta_kz; double eta_pz; }; /// @brief Applies actual component constraints before analytic null removal. Result BuildEigenReduction( const SparseMatrix& full_stiffness, const std::vector& nodal_mass, const std::vector& frames, const std::vector& constraint_mask, const std::vector& nodal_drilling_stiffness, double characteristic_length); /// @brief Restores scaled global coordinates with constrained entries zero. Vector RestoreScaledMode(const EigenReduction& reduction, const Matrix& whitened_vectors, std::size_t column); /// @brief Applies the assembled nodal mass in physical global coordinates. Vector MultiplyNodalMass(const std::vector& nodal_mass, const Vector& vector); } // namespace fesa::eigen_internal #endif // FESA_ANALYSIS_EIGEN_REDUCTION_H_