#include "fesa/analysis/analysis_model.hpp" #include #include namespace fesa { Result AnalysisModel::create(const Domain& domain) { if (domain.steps().empty()) { return Result::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::Failure(Status::Failure( FailureCategory::kInput, {{Severity::kError, "unsupported-multiple-step", secondStep.location, "STEP", secondStep.name, "AnalysisModel does not support multiple steps."}})); } return Result::Success(AnalysisModel{domain}); } const Domain& AnalysisModel::domain() const noexcept { return *domain_; } const StaticStepDefinition& AnalysisModel::step() const noexcept { return domain_->steps().front(); } const std::vector& AnalysisModel::activeElements() const noexcept { return activeElements_; } const std::vector& AnalysisModel::activeMaterials() const noexcept { return activeMaterials_; } const std::vector& AnalysisModel::activeSections() const noexcept { return activeSections_; } const std::vector& AnalysisModel::activeBoundaryConditions() const noexcept { return activeBoundaryConditions_; } const std::vector& AnalysisModel::activeLoads() const noexcept { return activeLoads_; } AnalysisModel::AnalysisModel(const Domain& domain) : domain_{&domain} { std::vector reachableMaterials(domain.materials().size(), false); std::vector 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(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(index)); } } for (std::size_t index = 0U; index < reachableSections.size(); ++index) { if (reachableSections[index]) { activeSections_.push_back(static_cast(index)); } } for (std::size_t index = 0U; index < step().boundaries.size(); ++index) { activeBoundaryConditions_.push_back(static_cast(index)); } for (std::size_t index = 0U; index < step().loads.size(); ++index) { activeLoads_.push_back(static_cast(index)); } } } // namespace fesa