feat(cpp-object-oriented-modular-refactoring): step 14 - runtime-element-factory

This commit is contained in:
KOKO\Mimi
2026-08-16 09:38:30 +09:00
parent ace493ee57
commit aaa488211b
14 changed files with 991 additions and 27 deletions
+99
View File
@@ -288,6 +288,16 @@ Result<Mitc4PhysicalRecovery> RecoveryFailure(const SourceLocation& location,
"*ELEMENT", identity, std::move(message)}}));
}
/// @brief Creates a structured failure at the runtime element boundary.
template <class T>
Result<T> RuntimeFailure(const SourceLocation& location,
const SourceEntityId& source_id, std::string message) {
return Result<T>::Failure(Status::Failure(
FailureCategory::kModel,
{{Severity::kError, "invalid-runtime-element", location, "*ELEMENT",
source_id.source_label_text, std::move(message)}}));
}
} // namespace
Result<Mitc4Shell> Mitc4Shell::Create(
@@ -794,6 +804,95 @@ Result<Mitc4PhysicalRecovery> Mitc4Shell::RecoverPhysical(
return Result<Mitc4PhysicalRecovery>::Success(std::move(recovery));
}
const ElementDofLayout& Mitc4Shell::DofLayout() const noexcept {
return dof_layout_;
}
Result<ElementStiffnessContribution> Mitc4Shell::ComputeStiffness() const {
if (dof_layout_.node_indices.size() != kNodeCount ||
dof_layout_.components_per_node.size() != kGlobalDofsPerNode) {
return RuntimeFailure<ElementStiffnessContribution>(
runtime_location_, dof_layout_.source_id,
"MITC4 runtime stiffness requires a bound four-node six-DOF layout.");
}
try {
auto stiffness = Stiffness();
if (!stiffness.HasValue()) {
return Result<ElementStiffnessContribution>::Failure(
stiffness.GetStatus());
}
return Result<ElementStiffnessContribution>::Success(
{dof_layout_, std::move(stiffness.Value().stabilized_global24)});
} catch (const std::exception& error) {
return RuntimeFailure<ElementStiffnessContribution>(
runtime_location_, dof_layout_.source_id, error.what());
}
}
Result<ElementResultBundle> Mitc4Shell::Recover(
const Vector& element_displacement) const {
if (dof_layout_.node_indices.size() != kNodeCount ||
dof_layout_.components_per_node.size() != kGlobalDofsPerNode ||
element_displacement.Size() != kGlobalDofCount) {
return RuntimeFailure<ElementResultBundle>(
runtime_location_, dof_layout_.source_id,
"MITC4 runtime recovery requires a bound four-node layout and 24 "
"DOFs.");
}
Result<Mitc4PhysicalRecovery> recovered = [&]() {
try {
return RecoverPhysical(element_displacement);
} catch (const std::exception& error) {
return RuntimeFailure<Mitc4PhysicalRecovery>(
runtime_location_, dof_layout_.source_id, error.what());
}
}();
if (!recovered.HasValue()) {
return Result<ElementResultBundle>::Failure(recovered.GetStatus());
}
constexpr std::array<ShellMidsurfaceLocation, kNodeCount> locations{
ShellMidsurfaceLocation::kGp1, ShellMidsurfaceLocation::kGp2,
ShellMidsurfaceLocation::kGp3, ShellMidsurfaceLocation::kGp4};
constexpr std::array<ShellSectionPosition, 3> positions{
ShellSectionPosition::kBottom, ShellSectionPosition::kMiddle,
ShellSectionPosition::kTop};
constexpr std::array<double, 3> zeta{-1.0, 0.0, 1.0};
ShellElementResultRows rows{};
rows.rows.reserve(kNodeCount);
rows.physical_strain_energy = recovered.Value().strain_energy;
for (std::size_t point = 0U; point < recovered.Value().points.size();
++point) {
const auto& physical_point = recovered.Value().points[point];
ShellResultRow row{};
row.element = element_index_;
row.location = locations[point];
row.natural_coordinates = physical_point.natural_coordinates;
row.local_frame = {physical_point.local_frame.e1,
physical_point.local_frame.e2,
physical_point.local_frame.e3};
row.generalized_strain = physical_point.generalized_strain;
row.section_resultant = physical_point.section_resultant;
for (std::size_t position = 0U; position < positions.size(); ++position) {
row.stress[position] = {positions[position], zeta[position],
physical_point.in_plane_stress[position]};
}
rows.rows.push_back(std::move(row));
}
return Result<ElementResultBundle>::Success(
{dof_layout_.source_id, std::move(rows)});
}
void Mitc4Shell::BindRuntime(ElementDofLayout layout,
const EntityIndex element_index,
SourceLocation location) {
dof_layout_ = std::move(layout);
element_index_ = element_index;
runtime_location_ = std::move(location);
}
Mitc4Shell::Mitc4Shell(std::array<Vector3, 4> coordinates,
std::array<Vector3, 4> directors,
std::array<Vector3, 4> tangent_a,