feat(cpp-object-oriented-modular-refactoring): step 11 - source-target-resolver
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user