fix: enforce thermal boundary dof endpoints

This commit is contained in:
KOKO\Mimi
2026-09-29 18:47:23 +09:00
parent 254247efc1
commit 283628ecda
6 changed files with 188 additions and 5 deletions
+33 -1
View File
@@ -1,6 +1,8 @@
#include "fesa/analysis/analysis_model.h"
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <string>
#include <vector>
@@ -40,7 +42,10 @@ Result<AnalysisModel> AnalysisModel::Create(const Domain& domain) {
const Domain& AnalysisModel::GetDomain() const noexcept { return *domain_; }
const StepDefinition& AnalysisModel::Step() const noexcept {
const StepDefinition& AnalysisModel::Step() const {
if (is_thermal_) {
throw std::logic_error{"Thermal AnalysisModel requires ThermalStep()."};
}
return domain_->Steps()[0U];
}
@@ -92,6 +97,16 @@ const std::vector<EntityIndex>& AnalysisModel::ActiveThermalNodes()
return active_thermal_nodes_;
}
const std::vector<EntityIndex>& AnalysisModel::ActiveThermalMaterials()
const noexcept {
return active_thermal_materials_;
}
const std::vector<EntityIndex>& AnalysisModel::ActiveThermalSections()
const noexcept {
return active_thermal_sections_;
}
const std::vector<SurfacePressureLoadDefinition>&
AnalysisModel::ActiveSurfacePressureLoads() const noexcept {
static const std::vector<SurfacePressureLoadDefinition> kNoSurfacePressures;
@@ -109,6 +124,12 @@ AnalysisModel::AnalysisModel(const Domain& domain) : domain_{&domain} {
++index) {
active_thermal_elements_.push_back(
static_cast<EntityIndex>(first_element + index));
active_thermal_sections_.push_back(
domain.ThermalElements()[index].ThermalSectionIndex());
active_thermal_materials_.push_back(
domain.ThermalSections()[domain.ThermalElements()[index]
.ThermalSectionIndex()]
.material_index);
for (const EntityIndex node :
domain.ThermalElements()[index].NodeIndices()) {
active_nodes[node] = true;
@@ -119,6 +140,17 @@ AnalysisModel::AnalysisModel(const Domain& domain) : domain_{&domain} {
active_thermal_nodes_.push_back(static_cast<EntityIndex>(index));
}
}
std::sort(active_thermal_sections_.begin(), active_thermal_sections_.end());
active_thermal_sections_.erase(
std::unique(active_thermal_sections_.begin(),
active_thermal_sections_.end()),
active_thermal_sections_.end());
std::sort(active_thermal_materials_.begin(),
active_thermal_materials_.end());
active_thermal_materials_.erase(
std::unique(active_thermal_materials_.begin(),
active_thermal_materials_.end()),
active_thermal_materials_.end());
return;
}
std::vector<bool> reachable_materials(domain.Materials().Size(), false);
+1 -1
View File
@@ -20,7 +20,7 @@ Status InvalidThermalDefinition(const SourceLocation& location,
"THERMAL", identity, message}});
}
bool IsThermalDof(const int dof) { return dof >= 11 && dof <= 15; }
bool IsThermalDof(const int dof) { return dof == 11 || dof == 15; }
Status ValidateThermalTargets(
const std::vector<ThermalBoundaryConditionDefinition>& boundaries,