feat(cpp-object-oriented-modular-refactoring): step 4 - model-element-google-style

This commit is contained in:
KOKO\Mimi
2026-08-16 05:37:40 +09:00
parent 34ab8b5bf1
commit 8bc0ea2f8e
46 changed files with 5184 additions and 5323 deletions
+29 -29
View File
@@ -146,7 +146,7 @@ Result<std::vector<EntityIndex>> resolveTarget(
const Domain& domain,
const NodalLoad& load) {
std::vector<const NodeSet*> matchingSets;
for (const auto& set : domain.nodeSets()) {
for (const auto& set : domain.NodeSets()) {
if (equalName(set.name, load.target)) {
matchingSets.push_back(&set);
}
@@ -155,8 +155,8 @@ Result<std::vector<EntityIndex>> resolveTarget(
std::vector<EntityIndex> matchingNodes;
std::int64_t label = 0;
if (tryPositiveInteger(load.target, label)) {
for (std::size_t index = 0U; index < domain.nodes().size(); ++index) {
if (domain.nodes()[index].sourceId.source_label == label) {
for (std::size_t index = 0U; index < domain.Nodes().size(); ++index) {
if (domain.Nodes()[index].source_id.source_label == label) {
matchingNodes.push_back(static_cast<EntityIndex>(index));
}
}
@@ -172,10 +172,10 @@ Result<std::vector<EntityIndex>> resolveTarget(
"The load target must resolve unambiguously to one node or one expanded node set."));
}
if (!matchingSets.empty()) {
const auto& nodes = matchingSets.front()->nodeIndices;
std::vector<unsigned char> seen(domain.nodes().size(), 0U);
const auto& nodes = matchingSets.front()->node_indices;
std::vector<unsigned char> seen(domain.Nodes().size(), 0U);
for (const EntityIndex node : nodes) {
if (node >= domain.nodes().size() || seen[node] != 0U) {
if (node >= domain.Nodes().size() || seen[node] != 0U) {
return Result<std::vector<EntityIndex>>::Failure(loadFailure(
"invalid-load-target",
load.location,
@@ -219,26 +219,26 @@ Status validateFiniteVector(
Status validateShellMoments(
const Domain& domain,
const Vector& fullLoad) {
if (domain.shellElements().empty()) {
if (domain.ShellElements().empty()) {
return Status::Ok();
}
std::vector<const ShellNodeInitialFrame*> frameByNode(
domain.nodes().size(), nullptr);
for (const auto& frame : domain.shellNodeInitialFrames()) {
if (frame.nodeIndex >= frameByNode.size() ||
frameByNode[frame.nodeIndex] != nullptr) {
domain.Nodes().size(), nullptr);
for (const auto& frame : domain.ShellNodeInitialFrames()) {
if (frame.node_index >= frameByNode.size() ||
frameByNode[frame.node_index] != nullptr) {
return loadFailure(
"invalid-shell-director",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
"NODE",
std::to_string(frame.nodeIndex),
std::to_string(frame.node_index),
"Shell nodal directors must have unique in-range node identities.");
}
frameByNode[frame.nodeIndex] = &frame;
frameByNode[frame.node_index] = &frame;
}
for (std::size_t node = 0U; node < domain.nodes().size(); ++node) {
for (std::size_t node = 0U; node < domain.Nodes().size(); ++node) {
const double momentX = fullLoad[node * dofsPerNode + 3U];
const double momentY = fullLoad[node * dofsPerNode + 4U];
const double momentZ = fullLoad[node * dofsPerNode + 5U];
@@ -250,9 +250,9 @@ Status validateShellMoments(
if (frame == nullptr) {
return loadFailure(
"invalid-shell-director",
domain.nodes()[node].location,
domain.Nodes()[node].location,
"NODE",
domain.nodes()[node].sourceId.source_label_text,
domain.Nodes()[node].source_id.source_label_text,
"A loaded shell node must have an approved initial director.");
}
@@ -271,9 +271,9 @@ Status validateShellMoments(
if (!(projectionRatio <= shellMomentProjectionTolerance)) {
return loadFailure(
"unsupported-drilling-load",
domain.nodes()[node].location,
domain.Nodes()[node].location,
"CLOAD",
domain.nodes()[node].sourceId.source_label_text,
domain.Nodes()[node].source_id.source_label_text,
"The aggregate nodal moment has an unsupported director-parallel component.");
}
}
@@ -286,23 +286,23 @@ Result<Vector> LoadAssembler::assembleFullNodalLoad(
const AnalysisModel& model,
const DofManager& dofs) {
const Domain& domain = model.domain();
if (domain.nodes().size() >
if (domain.Nodes().size() >
(std::numeric_limits<std::size_t>::max)() / dofsPerNode) {
return Result<Vector>::Failure(loadFailure(
"invalid-load-dimensions",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
"LOAD_ASSEMBLER",
domain.sourceContentIdentity(),
domain.SourceContentIdentity(),
"The semantic node count cannot be represented in full-DOF order."));
}
const std::size_t expectedFullCount =
domain.nodes().size() * dofsPerNode;
domain.Nodes().size() * dofsPerNode;
const Status dofStatus = validateDofOrder(
dofs, expectedFullCount, {domain.sourcePath(), 0U});
dofs, expectedFullCount, {domain.SourcePath(), 0U});
if (!dofStatus.IsOk()) {
return Result<Vector>::Failure(dofStatus);
}
for (std::size_t node = 0U; node < domain.nodes().size(); ++node) {
for (std::size_t node = 0U; node < domain.Nodes().size(); ++node) {
for (std::size_t component = 0U;
component < dofsPerNode;
++component) {
@@ -313,17 +313,17 @@ Result<Vector> LoadAssembler::assembleFullNodalLoad(
node * dofsPerNode + component) {
return Result<Vector>::Failure(loadFailure(
"invalid-load-order",
domain.nodes()[node].location,
domain.Nodes()[node].location,
"LOAD_ASSEMBLER",
domain.nodes()[node].sourceId.source_label_text,
domain.Nodes()[node].source_id.source_label_text,
"DofManager node/component identity must match full-DOF order."));
}
} catch (const std::out_of_range&) {
return Result<Vector>::Failure(loadFailure(
"invalid-load-dimensions",
domain.nodes()[node].location,
domain.Nodes()[node].location,
"LOAD_ASSEMBLER",
domain.nodes()[node].sourceId.source_label_text,
domain.Nodes()[node].source_id.source_label_text,
"DofManager must provide all six DOFs for every semantic node."));
}
}
+55 -55
View File
@@ -2,8 +2,8 @@
#include "fesa/analysis/analysis_model.hpp"
#include "fesa/assembly/parallel_for.hpp"
#include "fesa/elements/euler_beam_3d.hpp"
#include "fesa/elements/mitc4_shell.hpp"
#include "fesa/elements/euler_beam_3d.h"
#include "fesa/elements/mitc4_shell.h"
#include "fesa/fem/dof_manager.hpp"
#include <array>
@@ -52,46 +52,46 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
const DofManager& dofs,
const ParallelFor& parallelFor) {
const Domain& domain = model.domain();
if (domain.nodes().size() >
if (domain.Nodes().size() >
(std::numeric_limits<std::size_t>::max)() / kDofsPerNode ||
dofs.fullDofCount() != domain.nodes().size() * kDofsPerNode) {
dofs.fullDofCount() != domain.Nodes().size() * kDofsPerNode) {
return assemblyFailure(
"invalid-assembly-dimensions",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
std::to_string(dofs.fullDofCount()),
"DofManager dimensions do not match the active model nodes.");
}
if (!model.activeElements().empty() && !domain.shellElements().empty()) {
if (!model.activeElements().empty() && !domain.ShellElements().empty()) {
return assemblyFailure(
"unsupported-mixed-element-model",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
"B33:FESA-MITC4",
"Sparse assembly does not support mixed beam and shell models.");
}
if (!domain.shellElements().empty()) {
if (domain.shellElements().size() >
if (!domain.ShellElements().empty()) {
if (domain.ShellElements().size() >
(std::numeric_limits<std::size_t>::max)() /
kShellContributionCount) {
return assemblyFailure(
"invalid-assembly-dimensions",
{domain.sourcePath(), 0U},
std::to_string(domain.shellElements().size()),
{domain.SourcePath(), 0U},
std::to_string(domain.ShellElements().size()),
"Shell contribution storage exceeds the addressable range.");
}
std::vector<std::optional<std::array<double, 3>>> directorsByNode(
domain.nodes().size());
for (const auto& frame : domain.shellNodeInitialFrames()) {
if (frame.nodeIndex >= directorsByNode.size() ||
directorsByNode[frame.nodeIndex]) {
domain.Nodes().size());
for (const auto& frame : domain.ShellNodeInitialFrames()) {
if (frame.node_index >= directorsByNode.size() ||
directorsByNode[frame.node_index]) {
return assemblyFailure(
"invalid-assembly-element",
{domain.sourcePath(), 0U},
std::to_string(frame.nodeIndex),
{domain.SourcePath(), 0U},
std::to_string(frame.node_index),
"Shell initial frames must map uniquely to model nodes.");
}
directorsByNode[frame.nodeIndex] = frame.director;
directorsByNode[frame.node_index] = frame.director;
}
struct ShellInput {
@@ -102,23 +102,23 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
std::array<std::size_t, kShellElementDofCount> scatter;
};
std::vector<ShellInput> inputs;
inputs.reserve(domain.shellElements().size());
inputs.reserve(domain.ShellElements().size());
for (std::size_t elementOrder = 0U;
elementOrder < domain.shellElements().size();
elementOrder < domain.ShellElements().size();
++elementOrder) {
const auto& element = domain.shellElements()[elementOrder];
if (element.materialIndex >= domain.materials().size() ||
element.sectionIndex >= domain.shellSections().size()) {
const auto& element = domain.ShellElements()[elementOrder];
if (element.material_index >= domain.Materials().size() ||
element.section_index >= domain.ShellSections().size()) {
return assemblyFailure(
"invalid-assembly-element",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"Shell element references an entity outside the Domain.");
}
ShellInput input{};
input.section = &domain.shellSections()[element.sectionIndex];
input.material = &domain.materials()[element.materialIndex];
input.section = &domain.ShellSections()[element.section_index];
input.material = &domain.Materials()[element.material_index];
try {
input.scatter = dofs.shellElementScatter(
static_cast<EntityIndex>(elementOrder));
@@ -126,22 +126,22 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
return assemblyFailure(
"invalid-assembly-scatter",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"DofManager does not contain the active shell scatter.");
}
for (std::size_t nodePosition = 0U;
nodePosition < element.nodeIndices.size();
nodePosition < element.node_indices.size();
++nodePosition) {
const EntityIndex nodeIndex = element.nodeIndices[nodePosition];
if (nodeIndex >= domain.nodes().size() ||
const EntityIndex nodeIndex = element.node_indices[nodePosition];
if (nodeIndex >= domain.Nodes().size() ||
!directorsByNode[nodeIndex]) {
return assemblyFailure(
"invalid-assembly-element",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"Shell element requires a valid node and initial director.");
}
input.nodes[nodePosition] = &domain.nodes()[nodeIndex];
input.nodes[nodePosition] = &domain.Nodes()[nodeIndex];
input.directors[nodePosition] = *directorsByNode[nodeIndex];
for (std::size_t component = 0U;
component < kDofsPerNode;
@@ -156,7 +156,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
return assemblyFailure(
"invalid-assembly-scatter",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"Shell scatter does not match the active model topology.");
}
}
@@ -170,7 +170,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
inputs.size(),
[&](const std::size_t elementOrder) {
const auto& input = inputs[elementOrder];
const auto shell = Mitc4Shell::create(
const auto shell = Mitc4Shell::Create(
input.nodes,
input.directors,
*input.section,
@@ -179,7 +179,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
localFailures[elementOrder] = shell.GetStatus();
return;
}
const auto stiffness = shell.Value().stiffness();
const auto stiffness = shell.Value().Stiffness();
if (!stiffness.HasValue()) {
localFailures[elementOrder] = stiffness.GetStatus();
return;
@@ -197,7 +197,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
buffer[localOrder] = {
input.scatter[localRow],
input.scatter[localColumn],
stiffness.Value().stabilizedGlobal24(
stiffness.Value().stabilized_global24(
localRow, localColumn),
elementOrder,
localOrder};
@@ -235,7 +235,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
kBeamContributionCount) {
return assemblyFailure(
"invalid-assembly-dimensions",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
std::to_string(model.activeElements().size()),
"Element contribution storage exceeds the addressable range.");
}
@@ -243,22 +243,22 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
std::vector<std::array<std::size_t, kBeamElementDofCount>> scatters;
scatters.reserve(model.activeElements().size());
for (const EntityIndex elementIndex : model.activeElements()) {
if (elementIndex >= domain.elements().size()) {
if (elementIndex >= domain.Elements().size()) {
return assemblyFailure(
"invalid-assembly-element",
{domain.sourcePath(), 0U},
{domain.SourcePath(), 0U},
std::to_string(elementIndex),
"Active element index is outside the Domain.");
}
const auto& element = domain.elements()[elementIndex];
if (element.nodeIndices[0U] >= domain.nodes().size() ||
element.nodeIndices[1U] >= domain.nodes().size() ||
element.materialIndex >= domain.materials().size() ||
element.sectionIndex >= domain.sections().size()) {
const auto& element = domain.Elements()[elementIndex];
if (element.node_indices[0U] >= domain.Nodes().size() ||
element.node_indices[1U] >= domain.Nodes().size() ||
element.material_index >= domain.Materials().size() ||
element.section_index >= domain.Sections().size()) {
return assemblyFailure(
"invalid-assembly-element",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"Element references an entity outside the Domain.");
}
@@ -269,7 +269,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
return assemblyFailure(
"invalid-assembly-scatter",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"DofManager does not contain the active element scatter.");
}
for (std::size_t endpoint = 0U; endpoint < 2U; ++endpoint) {
@@ -278,7 +278,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
++component) {
const std::size_t local = endpoint * kDofsPerNode + component;
const std::size_t expected =
static_cast<std::size_t>(element.nodeIndices[endpoint]) *
static_cast<std::size_t>(element.node_indices[endpoint]) *
kDofsPerNode +
component;
if (scatter[local] != expected ||
@@ -286,7 +286,7 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
return assemblyFailure(
"invalid-assembly-scatter",
element.location,
element.sourceId.source_label_text,
element.source_id.source_label_text,
"Element scatter does not match the active model topology.");
}
}
@@ -301,18 +301,18 @@ Result<SparseMatrix> SparseAssembler::assembleStiffness(
model.activeElements().size(),
[&](const std::size_t elementOrder) {
const EntityIndex elementIndex = model.activeElements()[elementOrder];
const auto& definition = domain.elements()[elementIndex];
const auto beam = EulerBeam3D::create(
domain.nodes()[definition.nodeIndices[0U]],
domain.nodes()[definition.nodeIndices[1U]],
domain.sections()[definition.sectionIndex],
domain.materials()[definition.materialIndex]);
const auto& definition = domain.Elements()[elementIndex];
const auto beam = EulerBeam3D::Create(
domain.Nodes()[definition.node_indices[0U]],
domain.Nodes()[definition.node_indices[1U]],
domain.Sections()[definition.section_index],
domain.Materials()[definition.material_index]);
if (!beam.HasValue()) {
localFailures[elementOrder] = beam.GetStatus();
return;
}
const Matrix stiffness = beam.Value().globalStiffness();
const Matrix stiffness = beam.Value().GlobalStiffness();
auto& buffer = localBuffers[elementOrder];
const auto& scatter = scatters[elementOrder];
for (std::size_t localRow = 0U;