feat(cpp-object-oriented-modular-refactoring): step 4 - model-element-google-style
This commit is contained in:
@@ -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."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user