feat(cpp-object-oriented-modular-refactoring): step 11 - source-target-resolver

This commit is contained in:
KOKO\Mimi
2026-08-16 08:34:09 +09:00
parent 5430fffd62
commit a6324a9004
12 changed files with 714 additions and 273 deletions
+15 -40
View File
@@ -1,56 +1,29 @@
#include "fesa/fem/dof_manager.h"
#include <algorithm>
#include <charconv>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include "fesa/model/source_target_resolver.h"
namespace fesa {
namespace {
constexpr std::size_t kDofsPerNode = 6U;
char AsciiLower(char value) {
if (value >= 'A' && value <= 'Z') {
return static_cast<char>(value + ('a' - 'A'));
}
return value;
}
bool EqualName(const std::string& left, const std::string& right) {
return left.size() == right.size() &&
std::equal(left.begin(), left.end(), right.begin(),
[](char left_value, char right_value) {
return AsciiLower(left_value) == AsciiLower(right_value);
});
}
bool TryPositiveInteger(const std::string& text, std::int64_t& value) {
const char* const first = text.data();
const char* const last = first + text.size();
const auto parsed = std::from_chars(first, last, value);
return parsed.ec == std::errc{} && parsed.ptr == last && value > 0;
}
std::vector<EntityIndex> ExpandBoundaryTarget(
const Domain& domain, const BoundaryCondition& boundary) {
for (const auto& set : domain.NodeSets()) {
if (EqualName(set.name, boundary.target)) {
return set.node_indices;
}
const SourceTargetResolver& resolver, const BoundaryCondition& boundary) {
auto resolved =
resolver.Resolve({SourceEntityKind::kNode, "", boundary.target});
if (!resolved.HasValue()) {
return {};
}
std::int64_t source_label = 0;
if (TryPositiveInteger(boundary.target, source_label)) {
for (std::size_t node = 0U; node < domain.Nodes().size(); ++node) {
if (domain.Nodes()[node].source_id.source_label == source_label) {
return {static_cast<EntityIndex>(node)};
}
}
std::vector<EntityIndex> indices;
indices.reserve(resolved.Value().size());
for (const auto& target : resolved.Value()) {
indices.push_back(target.entity_index);
}
return {};
return indices;
}
template <std::size_t scatter_size>
@@ -94,12 +67,14 @@ SparsePattern BuildSparsePattern(
Result<DofManager> DofManager::Create(const AnalysisModel& model) {
const Domain& domain = model.GetDomain();
const SourceTargetIndex target_index = SourceTargetIndex::FromDomain(domain);
const SourceTargetResolver target_resolver{target_index};
const std::size_t full_count = domain.Nodes().size() * kDofsPerNode;
std::vector<std::optional<double>> prescribed_by_full_dof(full_count);
for (const EntityIndex boundary_index : model.ActiveBoundaryConditions()) {
const auto& boundary = model.Step().boundaries.at(boundary_index);
const auto target = ExpandBoundaryTarget(domain, boundary);
const auto target = ExpandBoundaryTarget(target_resolver, boundary);
for (const EntityIndex node : target) {
for (int component = boundary.first_dof; component <= boundary.last_dof;
++component) {