feat: adopt lumped mass and reduced-coordinate shell HHT

Integrate Hex8 mass verification and fixed-null-basis shell dynamics with numerical and physics handoff evidence. Preserve interrupted reference and full-validation status; full integration validation is deferred until after performance optimization.
This commit is contained in:
KOKO\Mimi
2026-10-13 16:57:19 +09:00
parent ede137c6b4
commit eaa5cbeb21
110 changed files with 15274 additions and 971 deletions
@@ -304,7 +304,7 @@ TEST(SolidHhtPairedKinematics, InvalidLowInputsFailWithoutChangingPredictor) {
.HasValue());
}
TEST(SolidHhtPairedKinematics, ConsistentMassKeepsSubUlpActionAndCancellation) {
TEST(SolidHhtPairedKinematics, MassMultiplyKeepsSubUlpActionAndCancellation) {
fesa::SparsePattern pattern;
pattern.row_offsets = {0, 2, 4};
pattern.column_indices = {0, 1, 0, 1};
@@ -569,7 +569,7 @@ TEST(SolidHhtDynamics, RampStartsAtZeroAndAuxiliaryAccelerationIsDistinct) {
}
TEST(SolidHhtDynamics,
OneFreeTranslationHasAnalyticConsistentInertialSupportReactions) {
OneFreeTranslationHasAnalyticLumpedInertialSupportReactions) {
auto result = RunDynamics(OneFree());
ASSERT_TRUE(result.HasValue()) << solid_hht_test::Message(result.GetStatus());
const auto d = solid_hht_test::Brick();
@@ -581,12 +581,11 @@ TEST(SolidHhtDynamics,
const auto& f = frames[n];
for (unsigned b = 0; b < 8; ++b) {
std::array<double, 3> product{}, sign{};
double scalar_mass = 2.0 / 216;
double scalar_mass = b == 0 ? .25 : 0.0;
for (unsigned c = 0; c < 3; ++c) {
const bool same = d.nodes[b].coordinates[c] == 0;
product[c] = same ? 1.0 / 3 : 1.0 / 6;
sign[c] = same ? -1 : 1;
scalar_mass *= same ? 2 : 1;
}
for (unsigned c = 0; c < 3; ++c) {
double stiffness;
@@ -620,7 +619,7 @@ TEST(SolidHhtDynamics,
}
if (n != 0) {
const auto& old = frames[n - 1];
const double mass = 2.0 / 27;
const double mass = .25;
const double weighted =
mass * f.algorithmic_acceleration[0] +
.95 * (f.internal_force[0] - f.external_force[0]) +
@@ -665,7 +664,7 @@ TEST(SolidHhtDynamics,
EXPECT_EQ(state.Value().CommittedState().increment_index, 0U);
EXPECT_DOUBLE_EQ(state.Value().CommittedState().displacement[0], 0);
EXPECT_NEAR(state.Value().CommittedState().acceleration[0],
.01 / (2.0 / 27.0), 1e-14);
.01 / .25, 1e-14);
ASSERT_FALSE(state.Value().IterationRecords().empty());
EXPECT_EQ(state.Value().IterationRecords().back().stage, "failed");
EXPECT_FALSE(state.Value().IterationRecords().back().failure_code.empty());