feat(domain-and-input-skeleton): step 1 — domain-validation

This commit is contained in:
KOKO\Mimi
2026-07-30 17:08:07 +09:00
parent 96f3f3230e
commit 5a5af9c64b
8 changed files with 1202 additions and 50 deletions
+34 -38
View File
@@ -1,8 +1,11 @@
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <map>
#include <span>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -15,23 +18,14 @@
namespace fesa {
class DomainBuilder;
class Domain final {
public:
Domain(
std::vector<Node> nodes,
std::vector<BeamElement> beam_elements,
std::vector<IsotropicElastic> materials,
std::vector<BeamSection> sections,
std::vector<NodeSet> node_sets,
std::vector<ElementSet> element_sets,
StepDefinition step)
: nodes_{std::move(nodes)},
beam_elements_{std::move(beam_elements)},
materials_{std::move(materials)},
sections_{std::move(sections)},
node_sets_{std::move(node_sets)},
element_sets_{std::move(element_sets)},
step_{std::move(step)} {}
Domain(const Domain&) = default;
Domain(Domain&&) noexcept = default;
Domain& operator=(const Domain&) = default;
Domain& operator=(Domain&&) noexcept = default;
[[nodiscard]] std::span<const Node> nodes() const noexcept {
return nodes_;
@@ -61,29 +55,25 @@ public:
return step_;
}
[[nodiscard]] const Node& node(const NodeId id) const {
const auto found = std::find_if(
nodes_.begin(), nodes_.end(),
[id](const Node& candidate) { return candidate.id == id; });
if (found == nodes_.end()) {
throw std::out_of_range{"Node ID is not present in the Domain."};
}
return *found;
}
[[nodiscard]] const Node& node(const EntityOrigin& origin) const {
const auto found = std::find_if(
nodes_.begin(), nodes_.end(), [&origin](const Node& candidate) {
return candidate.origin == origin;
});
if (found == nodes_.end()) {
throw std::out_of_range{
"Node origin is not present in the Domain."};
}
return *found;
}
[[nodiscard]] const Node& node(NodeId id) const;
[[nodiscard]] const Node& node(const EntityOrigin& origin) const;
private:
friend class DomainBuilder;
using OriginKey = std::pair<std::string, std::int64_t>;
Domain(
std::vector<Node> nodes,
std::vector<BeamElement> beam_elements,
std::vector<IsotropicElastic> materials,
std::vector<BeamSection> sections,
std::vector<NodeSet> node_sets,
std::vector<ElementSet> element_sets,
StepDefinition step);
[[nodiscard]] static OriginKey origin_key(const EntityOrigin& origin);
std::vector<Node> nodes_;
std::vector<BeamElement> beam_elements_;
std::vector<IsotropicElastic> materials_;
@@ -91,6 +81,12 @@ private:
std::vector<NodeSet> node_sets_;
std::vector<ElementSet> element_sets_;
StepDefinition step_;
std::unordered_map<std::int64_t, std::size_t> node_indices_;
std::map<OriginKey, std::size_t> node_origin_indices_;
std::unordered_map<std::int64_t, std::size_t> beam_element_indices_;
std::map<OriginKey, std::size_t> beam_element_origin_indices_;
std::unordered_map<std::int64_t, std::size_t> material_indices_;
std::unordered_map<std::int64_t, std::size_t> section_indices_;
};
} // namespace fesa
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include <optional>
#include <vector>
#include <fesa/core/diagnostic.hpp>
#include <fesa/model/domain.hpp>
namespace fesa {
struct DomainBuildResult final {
std::optional<Domain> domain;
std::vector<Diagnostic> diagnostics;
};
class DomainBuilder final {
public:
void add_node(Node value);
void add_material(IsotropicElastic value);
void add_section(BeamSection value);
void add_beam_element(BeamElement value);
void add_node_set(NodeSet value);
void add_element_set(ElementSet value);
void set_step(StepDefinition value);
[[nodiscard]] DomainBuildResult build() &&;
private:
std::vector<Node> nodes_;
std::vector<BeamElement> beam_elements_;
std::vector<IsotropicElastic> materials_;
std::vector<BeamSection> sections_;
std::vector<NodeSet> node_sets_;
std::vector<ElementSet> element_sets_;
std::optional<StepDefinition> step_;
};
} // namespace fesa