#include "fesa/analysis/analysis_model.h" #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& second_step = domain.Steps()[1]; return Result::Failure( Status::Failure(FailureCategory::kInput, {{Severity::kError, "unsupported-multiple-step", second_step.Location(), "STEP", second_step.Name(), "AnalysisModel does not support multiple steps."}})); } return Result::Success(AnalysisModel{domain}); } const Domain& AnalysisModel::GetDomain() const noexcept { return *domain_; } const StepDefinition& AnalysisModel::Step() const noexcept { return domain_->Steps()[0U]; } const std::vector& AnalysisModel::ActiveElements() const noexcept { return active_elements_; } const std::vector& AnalysisModel::ActiveBeamElements() const noexcept { return active_beam_elements_; } const std::vector& AnalysisModel::ActiveMaterials() const noexcept { return active_materials_; } const std::vector& AnalysisModel::ActiveProperties() const noexcept { return active_properties_; } const std::vector& AnalysisModel::ActiveSections() const noexcept { return active_sections_; } const std::vector& AnalysisModel::ActiveBoundaryConditions() const noexcept { return active_boundary_conditions_; } const std::vector& AnalysisModel::ActiveLoads() const noexcept { return active_loads_; } const std::vector& AnalysisModel::ActiveSurfacePressureLoads() const noexcept { return Step().SurfacePressureLoads(); } AnalysisModel::AnalysisModel(const Domain& domain) : domain_{&domain} { std::vector reachable_materials(domain.Materials().Size(), false); std::vector reachable_properties(domain.Properties().Size(), false); std::vector reachable_sections(domain.Sections().Size(), false); for (std::size_t index = 0U; index < domain.Elements().Size(); ++index) { const auto& element = domain.Elements()[index]; active_elements_.push_back(static_cast(index)); reachable_materials[element.MaterialIndex()] = true; reachable_properties[element.PropertyIndex()] = true; } for (std::size_t index = 0U; index < domain.BeamElements().Size(); ++index) { const auto& element = domain.BeamElements()[index]; active_beam_elements_.push_back(static_cast(index)); reachable_sections[element.section_index] = true; } // Ascending vector positions are the stable internal order, independent // of first reachability or duplicate element assignments. for (std::size_t index = 0U; index < reachable_materials.size(); ++index) { if (reachable_materials[index]) { active_materials_.push_back(static_cast(index)); } } for (std::size_t index = 0U; index < reachable_properties.size(); ++index) { if (reachable_properties[index]) { active_properties_.push_back(static_cast(index)); } } for (std::size_t index = 0U; index < reachable_sections.size(); ++index) { if (reachable_sections[index]) { active_sections_.push_back(static_cast(index)); } } for (std::size_t index = 0U; index < Step().BoundaryConditions().size(); ++index) { active_boundary_conditions_.push_back(static_cast(index)); } for (std::size_t index = 0U; index < Step().Loads().size(); ++index) { active_loads_.push_back(static_cast(index)); } } } // namespace fesa