feat(linear-static-mitc4-shell): step 6 - shell-dof-scatter

This commit is contained in:
KOKO\Mimi
2026-08-12 20:10:16 +09:00
parent 98d8ed6e4e
commit f845f780fa
4 changed files with 223 additions and 7 deletions
+49 -7
View File
@@ -54,17 +54,28 @@ std::vector<EntityIndex> expandBoundaryTarget(
return {};
}
template <std::size_t scatterSize>
void appendScatter(
std::vector<std::vector<std::size_t>>& columnsByRow,
const std::array<std::size_t, scatterSize>& scatter) {
for (const std::size_t row : scatter) {
auto& columns = columnsByRow[row];
columns.insert(columns.end(), scatter.begin(), scatter.end());
}
}
SparsePattern buildSparsePattern(
std::size_t fullDofCount,
const std::vector<EntityIndex>& activeElements,
const std::vector<std::array<std::size_t, 12>>& elementScatters) {
const std::vector<std::array<std::size_t, 12>>& elementScatters,
const std::vector<std::array<std::size_t, 24>>& shellElementScatters) {
std::vector<std::vector<std::size_t>> columnsByRow(fullDofCount);
for (const EntityIndex element : activeElements) {
const auto& scatter = elementScatters.at(element);
for (const std::size_t row : scatter) {
auto& columns = columnsByRow[row];
columns.insert(columns.end(), scatter.begin(), scatter.end());
}
appendScatter(columnsByRow, elementScatters.at(element));
}
// Every shell in the approved single-step shell subset is active.
for (const auto& scatter : shellElementScatters) {
appendScatter(columnsByRow, scatter);
}
SparsePattern pattern;
@@ -152,12 +163,36 @@ Result<DofManager> DofManager::create(const AnalysisModel& model) {
}
}
std::vector<std::array<std::size_t, 24>> shellElementScatters(
domain.shellElements().size());
for (std::size_t elementIndex = 0U;
elementIndex < domain.shellElements().size();
++elementIndex) {
const auto& element = domain.shellElements()[elementIndex];
auto& scatter = shellElementScatters[elementIndex];
for (std::size_t nodePosition = 0U;
nodePosition < element.nodeIndices.size();
++nodePosition) {
const std::size_t node = element.nodeIndices[nodePosition];
for (std::size_t component = 0U;
component < dofsPerNode;
++component) {
scatter[nodePosition * dofsPerNode + component] =
node * dofsPerNode + component;
}
}
}
auto pattern = buildSparsePattern(
fullCount, model.activeElements(), elementScatters);
fullCount,
model.activeElements(),
elementScatters,
shellElementScatters);
return Result<DofManager>::success(DofManager{
fullCount,
std::move(freeEquations),
std::move(elementScatters),
std::move(shellElementScatters),
std::move(freeDofs),
std::move(constrainedDofs),
std::move(prescribedValues),
@@ -195,6 +230,11 @@ const std::array<std::size_t, 12>& DofManager::elementScatter(
return elementScatters_.at(element);
}
const std::array<std::size_t, 24>& DofManager::shellElementScatter(
EntityIndex element) const {
return shellElementScatters_.at(element);
}
const std::vector<std::size_t>& DofManager::freeDofs() const noexcept {
return freeDofs_;
}
@@ -215,6 +255,7 @@ DofManager::DofManager(
std::size_t fullDofCount,
std::vector<std::optional<std::size_t>> freeEquations,
std::vector<std::array<std::size_t, 12>> elementScatters,
std::vector<std::array<std::size_t, 24>> shellElementScatters,
std::vector<std::size_t> freeDofs,
std::vector<std::size_t> constrainedDofs,
Vector prescribedValues,
@@ -222,6 +263,7 @@ DofManager::DofManager(
: fullDofCount_{fullDofCount},
freeEquations_{std::move(freeEquations)},
elementScatters_{std::move(elementScatters)},
shellElementScatters_{std::move(shellElementScatters)},
freeDofs_{std::move(freeDofs)},
constrainedDofs_{std::move(constrainedDofs)},
prescribedValues_{std::move(prescribedValues)},