feat(analysis): execute solid generalized frequency pencil
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
#ifndef FESA_ANALYSIS_SOLID_FREQUENCY_PROCEDURE_H_
|
||||
#define FESA_ANALYSIS_SOLID_FREQUENCY_PROCEDURE_H_
|
||||
|
||||
#include "fesa/analysis/solid_frequency_state.h"
|
||||
|
||||
namespace fesa {
|
||||
class Domain;
|
||||
/// @brief Executes unloaded reference-state C3D8 generalized frequency
|
||||
/// analysis.
|
||||
class SolidFrequencyProcedureExecutor final {
|
||||
public:
|
||||
/// @brief Returns lowest requested modes after validating every returned
|
||||
/// pair.
|
||||
/// @note Domain is immutable and must remain alive during execution.
|
||||
Result<SolidFrequencyState> Execute(const Domain& domain) const;
|
||||
};
|
||||
} // namespace fesa
|
||||
#endif // FESA_ANALYSIS_SOLID_FREQUENCY_PROCEDURE_H_
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef FESA_ANALYSIS_SOLID_FREQUENCY_STATE_H_
|
||||
#define FESA_ANALYSIS_SOLID_FREQUENCY_STATE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/solvers/eigen/mkl_feast_eigen_solver.h"
|
||||
|
||||
namespace fesa {
|
||||
/// @brief Identifies a source-ordered physical Solid eigenmode.
|
||||
struct SolidEigenMode {
|
||||
std::size_t mode_id;
|
||||
double eigenvalue;
|
||||
std::uint8_t classification;
|
||||
std::size_t cluster_id;
|
||||
std::optional<double> frequency;
|
||||
};
|
||||
/// @brief Stores original free K/M validation for every backend pair.
|
||||
struct SolidEigenpairCheck {
|
||||
std::size_t sorted_rank;
|
||||
std::size_t solver_column;
|
||||
double eigenvalue;
|
||||
double modal_mass;
|
||||
double rayleigh_quotient;
|
||||
double eta_r;
|
||||
double eta_norm;
|
||||
double eta_energy;
|
||||
};
|
||||
/// @brief Owns a completed modal candidate, independent of response frames.
|
||||
/// @note Vectors are requested-mode by full source node/UX,UY,UZ order.
|
||||
struct SolidFrequencyState {
|
||||
explicit SolidFrequencyState(FeastEigenResult result)
|
||||
: backend{std::move(result)} {}
|
||||
std::size_t full_dof_count{0U};
|
||||
std::size_t free_dof_count{0U};
|
||||
double classification_scale{0.0};
|
||||
double mass_ideal_lower_bound{0.0};
|
||||
double mass_roundoff_guard{0.0};
|
||||
double mass_lower_bound{0.0};
|
||||
double eta_gram{0.0};
|
||||
double max_eta_orth{0.0};
|
||||
std::vector<std::uint8_t> constraint_mask;
|
||||
std::vector<double> prescribed_displacement;
|
||||
std::vector<SolidEigenMode> modes;
|
||||
Matrix vectors{0U, 0U};
|
||||
std::vector<SolidEigenpairCheck> eigenpair_checks;
|
||||
FeastEigenResult backend;
|
||||
};
|
||||
} // namespace fesa
|
||||
#endif // FESA_ANALYSIS_SOLID_FREQUENCY_STATE_H_
|
||||
@@ -47,6 +47,9 @@ class Hex8Element final : public Element {
|
||||
Result<Hex8Response> EvaluateNonlinear(const Vector& displacement) const;
|
||||
/// @brief Returns the constant reference consistent mass; density required.
|
||||
Result<ElementStiffnessContribution> ComputeMass() const;
|
||||
/// @brief Returns immutable positive reference Gauss volume weights.
|
||||
/// @note Order is the kernel's fixed eight-point integration order.
|
||||
std::array<double, 8> ReferenceWeights() const noexcept;
|
||||
|
||||
private:
|
||||
/// @brief Caches shape, reference gradients and positive volume weights.
|
||||
|
||||
@@ -58,7 +58,7 @@ struct FeastEigenResult {
|
||||
std::string upper_search_termination;
|
||||
};
|
||||
|
||||
/// @brief Solves a whitened real-symmetric eigenproblem with oneMKL FEAST.
|
||||
/// @brief Adapts standard and symmetric-definite sparse pencils to FEAST.
|
||||
class MklFeastEigenSolver final {
|
||||
public:
|
||||
/// @brief Computes all validated interval pairs for a requested lowest-mode
|
||||
@@ -76,6 +76,28 @@ class MklFeastEigenSolver final {
|
||||
Result<FeastEigenResult> Solve(const SparseMatrix& whitened_operator,
|
||||
std::size_t requested_modes,
|
||||
double zero_operator_scale) const;
|
||||
/// @brief Solves the original sparse symmetric definite K/M pencil.
|
||||
/// @param mass_lower_bound Certified positive lower spectral bound of M,
|
||||
/// including floating-point assembly uncertainty; never a diagonal estimate.
|
||||
/// @param classification_scale Positive max |Kii|/Mii in physical units.
|
||||
/// @note Eigenvectors are mass-normalized. For this API the historical
|
||||
/// whitened_residuals field contains original-pencil eta_r; no whitening
|
||||
/// is performed. Intervals/eigenvalues in normalized backend evidence use
|
||||
/// classification_scale, while eigenvalues are returned in physical units.
|
||||
Result<FeastEigenResult> SolveGeneralized(const SparseMatrix& stiffness,
|
||||
const SparseMatrix& mass,
|
||||
std::size_t requested_modes,
|
||||
double mass_lower_bound,
|
||||
double classification_scale) const;
|
||||
|
||||
private:
|
||||
/// @brief Shares deterministic count/search controls without changing
|
||||
/// pencils.
|
||||
Result<FeastEigenResult> SolveImpl(const SparseMatrix& stiffness,
|
||||
const SparseMatrix* mass,
|
||||
std::size_t requested_modes,
|
||||
double physical_scale,
|
||||
double mass_lower_bound) const;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
Reference in New Issue
Block a user