feat(cpp-object-oriented-modular-refactoring): step 15 - generic-dof-manager
This commit is contained in:
@@ -22,71 +22,6 @@ Status ConstraintFailure(const std::string& code, const std::string& identity,
|
||||
message}});
|
||||
}
|
||||
|
||||
bool IsStrictlyIncreasing(const std::vector<std::size_t>& values) {
|
||||
return std::adjacent_find(
|
||||
values.begin(), values.end(),
|
||||
[](const std::size_t left, const std::size_t right) {
|
||||
return left >= right;
|
||||
}) == values.end();
|
||||
}
|
||||
|
||||
/// @brief Validates the stable full/free/constrained numbering invariant.
|
||||
Status ValidateDofOrder(const DofManager& dofs) {
|
||||
const std::size_t full_count = dofs.FullDofCount();
|
||||
const auto& free_dofs = dofs.FreeDofs();
|
||||
const auto& constrained_dofs = dofs.ConstrainedDofs();
|
||||
if (free_dofs.size() != dofs.FreeDofCount() ||
|
||||
constrained_dofs.size() != dofs.ConstrainedDofCount() ||
|
||||
dofs.PrescribedValues().Size() != constrained_dofs.size() ||
|
||||
constrained_dofs.size() > full_count ||
|
||||
free_dofs.size() != full_count - constrained_dofs.size()) {
|
||||
return ConstraintFailure("invalid-constraint-dimensions",
|
||||
std::to_string(full_count),
|
||||
"DofManager full, free, constrained, and "
|
||||
"prescribed dimensions must agree.");
|
||||
}
|
||||
if (!IsStrictlyIncreasing(free_dofs) ||
|
||||
!IsStrictlyIncreasing(constrained_dofs)) {
|
||||
return ConstraintFailure(
|
||||
"invalid-constraint-order", std::to_string(full_count),
|
||||
"Free and constrained DOFs must use stable increasing full-DOF order.");
|
||||
}
|
||||
|
||||
std::vector<unsigned char> ownership(full_count, 0U);
|
||||
try {
|
||||
for (std::size_t equation = 0U; equation < free_dofs.size(); ++equation) {
|
||||
const std::size_t full_dof = free_dofs[equation];
|
||||
if (full_dof >= full_count || ownership[full_dof] != 0U ||
|
||||
dofs.FreeEquation(full_dof) != equation) {
|
||||
return ConstraintFailure(
|
||||
"invalid-constraint-order", std::to_string(full_dof),
|
||||
"Free equation numbering must match the stable free-DOF order.");
|
||||
}
|
||||
ownership[full_dof] = 1U;
|
||||
}
|
||||
for (const std::size_t full_dof : constrained_dofs) {
|
||||
if (full_dof >= full_count || ownership[full_dof] != 0U ||
|
||||
dofs.FreeEquation(full_dof).has_value()) {
|
||||
return ConstraintFailure(
|
||||
"invalid-constraint-order", std::to_string(full_dof),
|
||||
"Constrained DOFs must be unique and absent from free equations.");
|
||||
}
|
||||
ownership[full_dof] = 2U;
|
||||
}
|
||||
} catch (const std::out_of_range&) {
|
||||
return ConstraintFailure(
|
||||
"invalid-constraint-dimensions", std::to_string(full_count),
|
||||
"DofManager equation storage does not cover every full DOF.");
|
||||
}
|
||||
if (std::find(ownership.begin(), ownership.end(), 0U) != ownership.end()) {
|
||||
return ConstraintFailure("invalid-constraint-order",
|
||||
std::to_string(full_count),
|
||||
"Free and constrained DOFs must partition the "
|
||||
"complete full-DOF range.");
|
||||
}
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
/// @brief Extracts one partition without changing the supplied DOF order.
|
||||
Result<SparseMatrix> ExtractBlock(const SparseMatrix& full,
|
||||
const std::vector<std::size_t>& row_dofs,
|
||||
@@ -123,7 +58,7 @@ Result<SparseMatrix> ExtractBlock(const SparseMatrix& full,
|
||||
}
|
||||
|
||||
void RequireDofOrder(const DofManager& dofs) {
|
||||
if (!ValidateDofOrder(dofs).IsOk()) {
|
||||
if (!dofs.ValidateInvariants().IsOk()) {
|
||||
throw std::invalid_argument{
|
||||
"DofManager constraint dimensions or order are invalid."};
|
||||
}
|
||||
@@ -144,7 +79,7 @@ Result<PartitionedStiffness> EssentialConstraints::Partition(
|
||||
"Full stiffness must be square and match the DofManager full "
|
||||
"dimension."));
|
||||
}
|
||||
const Status dof_status = ValidateDofOrder(dofs);
|
||||
const Status dof_status = dofs.ValidateInvariants();
|
||||
if (!dof_status.IsOk()) {
|
||||
return Result<PartitionedStiffness>::Failure(dof_status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user