97 lines
3.2 KiB
C++
97 lines
3.2 KiB
C++
#include "fesa/analysis/analysis_model.hpp"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace fesa {
|
|
|
|
Result<AnalysisModel> AnalysisModel::create(const Domain& domain) {
|
|
if (domain.steps().empty()) {
|
|
return Result<AnalysisModel>::Failure(Status::Failure(
|
|
FailureCategory::kInput,
|
|
{{Severity::kError,
|
|
"invalid-model-cardinality",
|
|
{domain.sourcePath(), 0U},
|
|
"STEP",
|
|
"0",
|
|
"AnalysisModel requires exactly one static step."}}));
|
|
}
|
|
if (domain.steps().size() > 1U) {
|
|
const auto& secondStep = domain.steps()[1];
|
|
return Result<AnalysisModel>::Failure(Status::Failure(
|
|
FailureCategory::kInput,
|
|
{{Severity::kError,
|
|
"unsupported-multiple-step",
|
|
secondStep.location,
|
|
"STEP",
|
|
secondStep.name,
|
|
"AnalysisModel does not support multiple steps."}}));
|
|
}
|
|
return Result<AnalysisModel>::Success(AnalysisModel{domain});
|
|
}
|
|
|
|
const Domain& AnalysisModel::domain() const noexcept {
|
|
return *domain_;
|
|
}
|
|
|
|
const StaticStepDefinition& AnalysisModel::step() const noexcept {
|
|
return domain_->steps().front();
|
|
}
|
|
|
|
const std::vector<EntityIndex>& AnalysisModel::activeElements() const noexcept {
|
|
return activeElements_;
|
|
}
|
|
|
|
const std::vector<EntityIndex>& AnalysisModel::activeMaterials() const noexcept {
|
|
return activeMaterials_;
|
|
}
|
|
|
|
const std::vector<EntityIndex>& AnalysisModel::activeSections() const noexcept {
|
|
return activeSections_;
|
|
}
|
|
|
|
const std::vector<EntityIndex>&
|
|
AnalysisModel::activeBoundaryConditions() const noexcept {
|
|
return activeBoundaryConditions_;
|
|
}
|
|
|
|
const std::vector<EntityIndex>& AnalysisModel::activeLoads() const noexcept {
|
|
return activeLoads_;
|
|
}
|
|
|
|
AnalysisModel::AnalysisModel(const Domain& domain) : domain_{&domain} {
|
|
std::vector<bool> reachableMaterials(domain.materials().size(), false);
|
|
std::vector<bool> reachableSections(domain.sections().size(), false);
|
|
|
|
for (std::size_t index = 0U; index < domain.elements().size(); ++index) {
|
|
const auto& element = domain.elements()[index];
|
|
activeElements_.push_back(static_cast<EntityIndex>(index));
|
|
reachableMaterials[element.materialIndex] = true;
|
|
reachableSections[element.sectionIndex] = true;
|
|
}
|
|
|
|
// Ascending vector positions are the stable internal order, independent
|
|
// of first reachability or duplicate element assignments.
|
|
for (std::size_t index = 0U; index < reachableMaterials.size(); ++index) {
|
|
if (reachableMaterials[index]) {
|
|
activeMaterials_.push_back(static_cast<EntityIndex>(index));
|
|
}
|
|
}
|
|
for (std::size_t index = 0U; index < reachableSections.size(); ++index) {
|
|
if (reachableSections[index]) {
|
|
activeSections_.push_back(static_cast<EntityIndex>(index));
|
|
}
|
|
}
|
|
|
|
for (std::size_t index = 0U;
|
|
index < step().boundaries.size();
|
|
++index) {
|
|
activeBoundaryConditions_.push_back(static_cast<EntityIndex>(index));
|
|
}
|
|
for (std::size_t index = 0U; index < step().loads.size(); ++index) {
|
|
activeLoads_.push_back(static_cast<EntityIndex>(index));
|
|
}
|
|
}
|
|
|
|
} // namespace fesa
|