feat(nonlinear-static-newton-raphson): step 10 - prepared-analysis-flow-and-full-procedure
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
#include "fesa/analysis/linear_static_procedure.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/analysis/analysis_model.h"
|
||||
#include "fesa/assembly/load_assembler.h"
|
||||
#include "fesa/assembly/parallel_for.h"
|
||||
#include "fesa/assembly/sparse_assembler.h"
|
||||
#include "fesa/constraints/essential_constraint_policy.h"
|
||||
#include "fesa/elements/element.h"
|
||||
#include "fesa/elements/element_factory.h"
|
||||
#include "fesa/fem/dof_manager.h"
|
||||
#include "fesa/results/result_recovery.h"
|
||||
#include "fesa/solvers/linear/linear_solver.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
LinearStaticProcedureExecutor::LinearStaticProcedureExecutor(
|
||||
const ParallelFor& parallel_for, LinearSolver& linear_solver)
|
||||
: parallel_for_(parallel_for), linear_solver_(linear_solver) {}
|
||||
|
||||
Result<LinearStaticExecutionResult> LinearStaticProcedureExecutor::Execute(
|
||||
const Domain& domain) const {
|
||||
Result<AnalysisModel> model = AnalysisModel::Create(domain);
|
||||
if (!model.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(model.GetStatus());
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Element>> elements;
|
||||
ElementView element_view;
|
||||
elements.reserve(model.Value().ActiveElements().size());
|
||||
element_view.reserve(model.Value().ActiveElements().size());
|
||||
const ElementFactory factory;
|
||||
for (const EntityIndex element_index : model.Value().ActiveElements()) {
|
||||
Result<std::unique_ptr<Element>> element =
|
||||
factory.Create(domain.Elements()[element_index], domain);
|
||||
if (!element.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(element.GetStatus());
|
||||
}
|
||||
element_view.emplace_back(*element.Value());
|
||||
elements.push_back(std::move(element.Value()));
|
||||
}
|
||||
|
||||
DofManager dofs;
|
||||
const Status dof_status = dofs.Build(model.Value(), element_view);
|
||||
if (!dof_status.IsOk()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(dof_status);
|
||||
}
|
||||
|
||||
AnalysisState state = AnalysisState::Create(dofs, {"Step-1", 0U});
|
||||
Result<SparseMatrix> stiffness =
|
||||
SparseAssembler::Assemble(element_view, dofs, parallel_for_);
|
||||
if (!stiffness.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(stiffness.GetStatus());
|
||||
}
|
||||
|
||||
Result<PartitionedStiffness> partitions =
|
||||
EssentialConstraintPolicy{}.Partition(stiffness.Value(), dofs);
|
||||
if (!partitions.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(partitions.GetStatus());
|
||||
}
|
||||
|
||||
const Status factorized = linear_solver_.Factorize(partitions.Value().k_ff);
|
||||
if (!factorized.IsOk()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(factorized);
|
||||
}
|
||||
|
||||
Result<Vector> external =
|
||||
LoadAssembler::AssembleFullNodalLoad(model.Value(), dofs);
|
||||
if (!external.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(external.GetStatus());
|
||||
}
|
||||
state.ExternalForce() = std::move(external.Value());
|
||||
|
||||
Result<Vector> rhs = LoadAssembler::EffectiveFreeRhs(
|
||||
state.ExternalForce(), partitions.Value().k_fc, dofs.PrescribedValues(),
|
||||
dofs);
|
||||
if (!rhs.HasValue()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(rhs.GetStatus());
|
||||
}
|
||||
|
||||
Vector free_displacement{dofs.FreeDofCount()};
|
||||
const Status solved = linear_solver_.Solve(rhs.Value(), free_displacement);
|
||||
if (!solved.IsOk()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(solved);
|
||||
}
|
||||
state.Displacement() = EssentialConstraintPolicy{}.ReconstructFull(
|
||||
free_displacement, dofs.PrescribedValues(), dofs);
|
||||
|
||||
const Status recovered = ResultRecovery::Recover(
|
||||
model.Value(), element_view, dofs, stiffness.Value(),
|
||||
state.Displacement(), state.ExternalForce(), state);
|
||||
if (!recovered.IsOk()) {
|
||||
return Result<LinearStaticExecutionResult>::Failure(recovered);
|
||||
}
|
||||
|
||||
std::vector<Diagnostic> diagnostics = domain.Warnings();
|
||||
SortDiagnostics(diagnostics);
|
||||
return Result<LinearStaticExecutionResult>::Success(
|
||||
{std::move(state), std::move(diagnostics)});
|
||||
}
|
||||
|
||||
} // namespace fesa
|
||||
Reference in New Issue
Block a user