Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "fesa/elements/hex8_element.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/math/sparse_matrix.h"
|
||||
#include "fesa/solvers/eigen/mkl_feast_eigen_solver.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
@@ -50,7 +51,8 @@ double Ratio(double numerator, double denominator) {
|
||||
return numerator / denominator;
|
||||
}
|
||||
/// @brief Builds an immutable candidate; all returns precede public commit.
|
||||
Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain,
|
||||
const EigenSolver& solver) {
|
||||
const auto* frequency = domain.Frequency();
|
||||
if (!domain.IsSolid() || frequency == nullptr ||
|
||||
frequency->requested_mode_count <= 0)
|
||||
@@ -76,6 +78,7 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
}
|
||||
ElementFactory factory;
|
||||
std::vector<std::unique_ptr<Element>> owned;
|
||||
std::vector<std::unique_ptr<SolidTrialElement>> trials;
|
||||
ElementView view;
|
||||
for (const auto index : model.Value().ActiveElements()) {
|
||||
const auto& definition = domain.Elements()[index];
|
||||
@@ -87,11 +90,13 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
auto element = factory.Create(definition, domain);
|
||||
if (!element.HasValue())
|
||||
return Result<SolidFrequencyState>::Failure(element.GetStatus());
|
||||
if (dynamic_cast<const Hex8Element*>(element.Value().get()) == nullptr)
|
||||
auto trial = factory.BindSolidTrial(*element.Value());
|
||||
if (trial == nullptr)
|
||||
return Result<SolidFrequencyState>::Failure(
|
||||
Failure("unsupported-frequency-element", "Only C3D8 is supported."));
|
||||
view.emplace_back(*element.Value());
|
||||
owned.push_back(std::move(element.Value()));
|
||||
trials.push_back(std::move(trial));
|
||||
}
|
||||
DofManager dofs;
|
||||
const Status mapping = dofs.Build(model.Value(), view);
|
||||
@@ -121,7 +126,7 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
std::vector<std::size_t> additions_by_dof(dofs.FullDofCount(), 0U);
|
||||
constexpr double eps = std::numeric_limits<double>::epsilon();
|
||||
for (std::size_t e = 0; e < owned.size(); ++e) {
|
||||
const auto& hex = static_cast<const Hex8Element&>(*owned[e]);
|
||||
const auto& hex = *trials[e];
|
||||
auto mass = hex.ComputeMass();
|
||||
if (!mass.HasValue())
|
||||
return Result<SolidFrequencyState>::Failure(mass.GetStatus());
|
||||
@@ -220,7 +225,7 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
return Result<SolidFrequencyState>::Failure(
|
||||
Failure("invalid-solid-eigen-scale",
|
||||
"A positive finite classification scale is required."));
|
||||
auto backend = MklFeastEigenSolver{}.SolveGeneralized(k, m, requested,
|
||||
auto backend = solver.SolveGeneralized(k, m, requested,
|
||||
mass_lower, scale);
|
||||
if (!backend.HasValue())
|
||||
return Result<SolidFrequencyState>::Failure(backend.GetStatus());
|
||||
@@ -269,11 +274,11 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
"Normalized modal vector is not finite."));
|
||||
}
|
||||
mv = m.Multiply(vector);
|
||||
const Vector kv = k.Multiply(vector);
|
||||
Vector kv = k.Multiply(vector);
|
||||
const double lambda = state.backend.eigenvalues[c];
|
||||
const double modal_mass = vector.Dot(mv);
|
||||
const double energy = vector.Dot(kv);
|
||||
Vector residual = kv;
|
||||
Vector residual = std::move(kv);
|
||||
residual.Axpy(-lambda, mv);
|
||||
const double norm_phi = vector.Norm();
|
||||
const double residual_norm = residual.Norm();
|
||||
@@ -355,7 +360,8 @@ Result<SolidFrequencyState> ExecuteCandidate(const Domain& domain) {
|
||||
Result<SolidFrequencyState> SolidFrequencyProcedureExecutor::Execute(
|
||||
const Domain& domain) const {
|
||||
try {
|
||||
auto result = ExecuteCandidate(domain);
|
||||
const MklFeastEigenSolver default_solver;
|
||||
auto result = ExecuteCandidate(domain, solver_ ? *solver_ : default_solver);
|
||||
if (result.HasValue()) return result;
|
||||
auto diagnostics = result.GetStatus().Diagnostics();
|
||||
for (auto& diagnostic : diagnostics)
|
||||
|
||||
Reference in New Issue
Block a user