feat(linear-static-3d-euler-beam): step 16 - euler-beam-element-review-fix

This commit is contained in:
KOKO\Mimi
2026-08-09 18:37:41 +09:00
parent c4ffe13477
commit cfdac70756
3 changed files with 431 additions and 30 deletions
+61 -4
View File
@@ -3,6 +3,7 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <limits>
#include <stdexcept>
#include <string>
#include <utility>
@@ -149,14 +150,30 @@ double normalizedMatrixError(const Matrix& lhs, const Matrix& rhs) {
double scale = 1.0;
for (std::size_t row = 0; row < lhs.rows(); ++row) {
for (std::size_t column = 0; column < lhs.columns(); ++column) {
const double lhsValue = lhs(row, column);
const double rhsValue = rhs(row, column);
if (!std::isfinite(lhsValue) || !std::isfinite(rhsValue)) {
return std::numeric_limits<double>::infinity();
}
const double difference = std::abs(lhsValue - rhsValue);
if (!std::isfinite(difference)) {
return std::numeric_limits<double>::infinity();
}
maximumDifference = (std::max)(
maximumDifference,
std::abs(lhs(row, column) - rhs(row, column)));
scale = (std::max)(scale, std::abs(lhs(row, column)));
scale = (std::max)(scale, std::abs(rhs(row, column)));
difference);
scale = (std::max)(scale, std::abs(lhsValue));
scale = (std::max)(scale, std::abs(rhsValue));
}
}
return maximumDifference / scale;
if (!std::isfinite(maximumDifference) || !std::isfinite(scale) ||
!(scale > 0.0)) {
return std::numeric_limits<double>::infinity();
}
const double normalizedError = maximumDifference / scale;
return std::isfinite(normalizedError)
? normalizedError
: std::numeric_limits<double>::infinity();
}
std::array<double, kGeneralizedComponentCount> generalizedStrain(
@@ -288,6 +305,46 @@ Result<EulerBeam3D> EulerBeam3D::create(
"E, G, A, Iy, Iz, and J must be finite and positive.");
}
const auto derivedRigidity = constitutiveDiagonal(
material.youngsModulus,
shearModulus,
section.area,
section.i11,
section.i22,
section.torsionalConstant);
const double lengthSquared = length * length;
const double lengthCubed = lengthSquared * length;
// These are every distinct positive magnitude used by the exact axial,
// torsion, and two bending closed-form blocks. Reject arithmetic
// overflow/underflow without introducing a conditioning threshold.
const std::array<double, 14> requiredStiffnessMagnitudes = {
derivedRigidity[0U],
derivedRigidity[1U],
derivedRigidity[2U],
derivedRigidity[3U],
derivedRigidity[0U] / length,
derivedRigidity[1U] / length,
12.0 * derivedRigidity[2U] / lengthCubed,
6.0 * derivedRigidity[2U] / lengthSquared,
4.0 * derivedRigidity[2U] / length,
2.0 * derivedRigidity[2U] / length,
12.0 * derivedRigidity[3U] / lengthCubed,
6.0 * derivedRigidity[3U] / lengthSquared,
4.0 * derivedRigidity[3U] / length,
2.0 * derivedRigidity[3U] / length};
if (std::any_of(
requiredStiffnessMagnitudes.begin(),
requiredStiffnessMagnitudes.end(),
[](double magnitude) {
return !std::isfinite(magnitude) || !(magnitude > 0.0);
})) {
return modelFailure(
"invalid-beam-property",
section.location,
identity,
"Derived beam stiffness coefficients must be finite and positive.");
}
const Vector3 ey = {
eyTrial[0] / eyTrialNorm,
eyTrial[1] / eyTrialNorm,