feat(cpp-object-oriented-modular-refactoring): step 20 - analysis-hierarchy
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "fesa/assembly/load_assembler.h"
|
||||
#include "fesa/assembly/parallel_for.h"
|
||||
#include "fesa/assembly/sparse_assembler.h"
|
||||
#include "fesa/elements/element_factory.h"
|
||||
#include "fesa/io/abaqus/domain_mapper.h"
|
||||
#include "fesa/io/abaqus/input_reader.h"
|
||||
#include "fesa/results/result_recovery.h"
|
||||
@@ -13,8 +14,8 @@
|
||||
|
||||
namespace fesa {
|
||||
|
||||
Status Analysis::Run(const AnalysisRequest& request) {
|
||||
Status status = Initialize(request);
|
||||
Status LinearStaticAnalysis::Run(const AnalysisRequest& request) {
|
||||
Status status = InitializeCandidate(request);
|
||||
if (!status.IsOk()) {
|
||||
return status;
|
||||
}
|
||||
@@ -30,7 +31,7 @@ Status Analysis::Run(const AnalysisRequest& request) {
|
||||
if (!status.IsOk()) {
|
||||
return status;
|
||||
}
|
||||
status = Factorize();
|
||||
status = FactorizeFreeSystem();
|
||||
if (!status.IsOk()) {
|
||||
return status;
|
||||
}
|
||||
@@ -42,7 +43,7 @@ Status Analysis::Run(const AnalysisRequest& request) {
|
||||
if (!status.IsOk()) {
|
||||
return status;
|
||||
}
|
||||
return RecoverAndWriteResults();
|
||||
return RecoverAndWrite();
|
||||
}
|
||||
|
||||
LinearStaticAnalysis::LinearStaticAnalysis(const ParallelFor& parallel_for,
|
||||
@@ -52,7 +53,8 @@ LinearStaticAnalysis::LinearStaticAnalysis(const ParallelFor& parallel_for,
|
||||
linear_solver_{linear_solver},
|
||||
results_writer_{results_writer} {}
|
||||
|
||||
Status LinearStaticAnalysis::Initialize(const AnalysisRequest& request) {
|
||||
Status LinearStaticAnalysis::InitializeCandidate(
|
||||
const AnalysisRequest& request) {
|
||||
// Clear dependent objects in reverse ownership order so a reused analysis
|
||||
// never exposes a view into a Domain from an earlier run.
|
||||
effective_rhs_.reset();
|
||||
@@ -60,6 +62,8 @@ Status LinearStaticAnalysis::Initialize(const AnalysisRequest& request) {
|
||||
full_stiffness_.reset();
|
||||
state_.reset();
|
||||
dofs_.reset();
|
||||
element_view_.clear();
|
||||
elements_.clear();
|
||||
model_.reset();
|
||||
domain_.reset();
|
||||
diagnostics_.clear();
|
||||
@@ -90,11 +94,29 @@ Status LinearStaticAnalysis::BuildAnalysisModel() {
|
||||
}
|
||||
|
||||
Status LinearStaticAnalysis::BuildDofMapAndSparsePattern() {
|
||||
auto dofs = DofManager::Create(*model_);
|
||||
if (!dofs.HasValue()) {
|
||||
return dofs.GetStatus();
|
||||
std::vector<std::unique_ptr<Element>> elements;
|
||||
ElementView element_view;
|
||||
elements.reserve(model_->ActiveElements().size());
|
||||
element_view.reserve(model_->ActiveElements().size());
|
||||
const ElementFactory factory;
|
||||
for (const EntityIndex element_index : model_->ActiveElements()) {
|
||||
auto element = factory.Create(domain_->Elements()[element_index], *domain_);
|
||||
if (!element.HasValue()) {
|
||||
return element.GetStatus();
|
||||
}
|
||||
element_view.emplace_back(*element.Value());
|
||||
elements.push_back(std::move(element.Value()));
|
||||
}
|
||||
dofs_ = std::make_unique<DofManager>(std::move(dofs.Value()));
|
||||
|
||||
DofManager dofs;
|
||||
const Status dof_status = dofs.Build(*model_, element_view);
|
||||
if (!dof_status.IsOk()) {
|
||||
return dof_status;
|
||||
}
|
||||
|
||||
elements_ = std::move(elements);
|
||||
element_view_ = std::move(element_view);
|
||||
dofs_ = std::make_unique<DofManager>(std::move(dofs));
|
||||
state_ = std::make_unique<AnalysisState>(
|
||||
AnalysisState::Create(*dofs_, {"Step-1", 0U}));
|
||||
return Status::Ok();
|
||||
@@ -102,7 +124,7 @@ Status LinearStaticAnalysis::BuildDofMapAndSparsePattern() {
|
||||
|
||||
Status LinearStaticAnalysis::AssembleAndPartitionStiffness() {
|
||||
auto stiffness =
|
||||
SparseAssembler::AssembleStiffness(*model_, *dofs_, parallel_for_);
|
||||
SparseAssembler::Assemble(element_view_, *dofs_, parallel_for_);
|
||||
if (!stiffness.HasValue()) {
|
||||
return stiffness.GetStatus();
|
||||
}
|
||||
@@ -119,8 +141,8 @@ Status LinearStaticAnalysis::AssembleAndPartitionStiffness() {
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Status LinearStaticAnalysis::Factorize() {
|
||||
// This call intentionally precedes all load assembly in Analysis::Run.
|
||||
Status LinearStaticAnalysis::FactorizeFreeSystem() {
|
||||
// This call intentionally precedes all load assembly in Run.
|
||||
return linear_solver_.Factorize(partitioned_stiffness_->k_ff);
|
||||
}
|
||||
|
||||
@@ -154,9 +176,10 @@ Status LinearStaticAnalysis::SubstituteAndReconstruct() {
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Status LinearStaticAnalysis::RecoverAndWriteResults() {
|
||||
const Status recovery_status =
|
||||
ResultRecovery::Recover(*model_, *dofs_, *full_stiffness_, *state_);
|
||||
Status LinearStaticAnalysis::RecoverAndWrite() {
|
||||
const Status recovery_status = ResultRecovery::Recover(
|
||||
*model_, element_view_, *dofs_, *full_stiffness_, state_->Displacement(),
|
||||
state_->ExternalForce(), *state_);
|
||||
if (!recovery_status.IsOk()) {
|
||||
return recovery_status;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/analysis/analysis.h"
|
||||
#include "fesa/analysis/linear_static_analysis.h"
|
||||
#include "fesa/assembly/parallel_for.h"
|
||||
#include "fesa/core/diagnostic.h"
|
||||
@@ -91,8 +93,9 @@ int FesaApplication::Run(const std::vector<std::string>& arguments) {
|
||||
TbbParallelFor parallel_for;
|
||||
MklPardisoSolver linear_solver;
|
||||
Hdf5ResultsWriter results_writer;
|
||||
LinearStaticAnalysis analysis{parallel_for, linear_solver, results_writer};
|
||||
const Status status = analysis.Run(request);
|
||||
std::unique_ptr<Analysis> analysis = std::make_unique<LinearStaticAnalysis>(
|
||||
parallel_for, linear_solver, results_writer);
|
||||
const Status status = analysis->Run(request);
|
||||
if (status.IsOk()) {
|
||||
return kSuccessExitCode;
|
||||
}
|
||||
|
||||
@@ -57,13 +57,6 @@ Result<SparseMatrix> ExtractBlock(const SparseMatrix& full,
|
||||
std::move(contributions), pattern);
|
||||
}
|
||||
|
||||
void RequireDofOrder(const DofManager& dof_manager) {
|
||||
if (!dof_manager.ValidateInvariants().IsOk()) {
|
||||
throw std::invalid_argument{
|
||||
"DofManager constraint dimensions or order are invalid."};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Result<PartitionedStiffness> EssentialConstraintPolicy::Partition(
|
||||
@@ -114,7 +107,6 @@ Result<PartitionedStiffness> EssentialConstraintPolicy::Partition(
|
||||
|
||||
Vector EssentialConstraintPolicy::GatherFree(
|
||||
const Vector& full_values, const DofManager& dof_manager) const {
|
||||
RequireDofOrder(dof_manager);
|
||||
if (full_values.Size() != dof_manager.FullDofCount()) {
|
||||
throw std::invalid_argument{
|
||||
"Full vector size must match the DofManager full dimension."};
|
||||
@@ -129,7 +121,6 @@ Vector EssentialConstraintPolicy::GatherFree(
|
||||
|
||||
Vector EssentialConstraintPolicy::GatherConstrained(
|
||||
const Vector& full_values, const DofManager& dof_manager) const {
|
||||
RequireDofOrder(dof_manager);
|
||||
if (full_values.Size() != dof_manager.FullDofCount()) {
|
||||
throw std::invalid_argument{
|
||||
"Full vector size must match the DofManager full dimension."};
|
||||
@@ -145,7 +136,6 @@ Vector EssentialConstraintPolicy::GatherConstrained(
|
||||
Vector EssentialConstraintPolicy::ReconstructFull(
|
||||
const Vector& free_values, const Vector& constrained_values,
|
||||
const DofManager& dof_manager) const {
|
||||
RequireDofOrder(dof_manager);
|
||||
if (free_values.Size() != dof_manager.FreeDofCount() ||
|
||||
constrained_values.Size() != dof_manager.ConstrainedDofCount()) {
|
||||
throw std::invalid_argument{
|
||||
|
||||
Reference in New Issue
Block a user