Integrate Refactor solver sources and dual MSVC CMake builds

This commit is contained in:
KOKO\Mimi
2026-10-18 02:10:51 +09:00
parent 7ee32e5837
commit 12d51480de
218 changed files with 17842 additions and 9689 deletions
@@ -20,6 +20,7 @@
#include "fesa/elements/mitc4_shell.h"
#include "fesa/fem/dof_manager.h"
#include "fesa/math/sparse_matrix.h"
#include "fesa/solvers/eigen/mkl_feast_eigen_solver.h"
namespace fesa {
namespace {
@@ -84,7 +85,8 @@ double MaximumEdgeLength(const Domain& domain) {
return maximum;
}
Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain,
const EigenSolver& solver) {
const FrequencyStepDefinition* frequency = domain.Frequency();
if (frequency == nullptr || domain.Steps().Size() != 1U) {
return Result<EigenAnalysisState>::Failure(
@@ -101,6 +103,7 @@ Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
return Result<EigenAnalysisState>::Failure(model.GetStatus());
const ElementFactory factory;
std::vector<std::unique_ptr<Element>> owned;
std::vector<std::unique_ptr<ShellReferenceElement>> references;
ElementView view;
owned.reserve(model.Value().ActiveElements().size());
view.reserve(model.Value().ActiveElements().size());
@@ -108,13 +111,15 @@ Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
auto element = factory.Create(domain.Elements()[index], domain);
if (!element.HasValue())
return Result<EigenAnalysisState>::Failure(element.GetStatus());
if (dynamic_cast<const Mitc4Shell*>(element.Value().get()) == nullptr) {
auto reference = factory.BindShellReference(*element.Value());
if (reference == nullptr) {
return Result<EigenAnalysisState>::Failure(Failure(
"unsupported-frequency-element", std::to_string(index),
"The frequency procedure supports MITC4 shell elements only."));
}
view.emplace_back(*element.Value());
owned.push_back(std::move(element.Value()));
references.push_back(std::move(reference));
}
DofManager dofs;
const Status dof_status = dofs.Build(model.Value(), view);
@@ -158,7 +163,7 @@ Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
std::to_string(definition.MaterialIndex()),
"Every active shell material requires a positive density."));
}
const auto* element = dynamic_cast<const Mitc4Shell*>(owned[shell].get());
const auto& element = references[shell];
auto mass = element->Mass(density[definition.MaterialIndex()]);
auto shell_stiffness = element->Stiffness();
if (!mass.HasValue())
@@ -207,7 +212,7 @@ Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
(material->YoungsModulus() / density[material_id]) /
length / length);
}
auto backend = MklFeastEigenSolver{}.Solve(
auto backend = solver.Solve(
reduction.Value().whitened_operator, request, zero_scale);
if (!backend.HasValue())
return Result<EigenAnalysisState>::Failure(backend.GetStatus());
@@ -403,7 +408,8 @@ Result<EigenAnalysisState> ExecuteCandidate(const Domain& domain) {
Result<EigenAnalysisState> LinearFrequencyProcedureExecutor::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()) {
auto diagnostics = result.GetStatus().Diagnostics();
for (auto& diagnostic : diagnostics) {