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:
@@ -90,7 +90,16 @@ double GradientIntegral(std::size_t a, std::size_t b, std::size_t i,
|
||||
}
|
||||
std::vector<double> DenseOracle(const std::vector<std::size_t>& free) {
|
||||
const auto n = free.size();
|
||||
std::vector<double> k(n * n, 0.0), m(n * n, 0.0), eigen(n, 0.0);
|
||||
std::vector<double> k(n * n, 0.0), full_mass(24U * 24U, 0.0),
|
||||
m(n * n, 0.0), eigen(n, 0.0);
|
||||
for (std::size_t a = 0; a < 8; ++a)
|
||||
for (std::size_t b = 0; b < 8; ++b)
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
double value = 2.0 * 48.0 / 64.0;
|
||||
for (std::size_t d = 0; d < 3; ++d)
|
||||
value *= 1.0 + kSigns[a][d] * kSigns[b][d] / 3.0;
|
||||
full_mass[(3U * a + i) * 24U + 3U * b + i] = value;
|
||||
}
|
||||
for (std::size_t row = 0; row < n; ++row)
|
||||
for (std::size_t col = 0; col < n; ++col) {
|
||||
const auto a = free[row] / 3U, b = free[col] / 3U;
|
||||
@@ -104,12 +113,12 @@ std::vector<double> DenseOracle(const std::vector<std::size_t>& free) {
|
||||
GradientIntegral(a, b, j, i) + (i == j ? gradient_dot : 0.0)) +
|
||||
(80.0 / 48.0) * (48.0 * kSigns[a][i] / (8.0 * (i + 1))) *
|
||||
(48.0 * kSigns[b][j] / (8.0 * (j + 1)));
|
||||
if (i == j) {
|
||||
m[row * n + col] = 2.0 * 48.0 / 64.0;
|
||||
for (std::size_t d = 0; d < 3; ++d)
|
||||
m[row * n + col] *= 1.0 + kSigns[a][d] * kSigns[b][d] / 3.0;
|
||||
}
|
||||
}
|
||||
for (std::size_t row = 0; row < n; ++row) {
|
||||
const auto full_row = free[row];
|
||||
for (std::size_t col = 0; col < 24U; ++col)
|
||||
m[row * n + row] += full_mass[full_row * 24U + col];
|
||||
}
|
||||
EXPECT_EQ(
|
||||
LAPACKE_dsygv(LAPACK_ROW_MAJOR, 1, 'N', 'U', static_cast<MKL_INT>(n),
|
||||
k.data(), static_cast<MKL_INT>(n), m.data(),
|
||||
@@ -126,7 +135,7 @@ std::vector<std::size_t> FaceFree() {
|
||||
}
|
||||
} // namespace
|
||||
TEST(SolidFrequencyProcedure,
|
||||
OriginalConsistentPencilMatchesIndependentDenseOracle) {
|
||||
RowSumLumpedPencilMatchesIndependentDenseOracle) {
|
||||
for (const bool constrained : {false, true}) {
|
||||
const std::size_t count = constrained ? 12U : 24U;
|
||||
auto domain = Brick(count, constrained ? kFaceFixed : "");
|
||||
@@ -282,9 +291,9 @@ TEST(SolidFrequencyProcedure,
|
||||
|
||||
TEST(SolidFrequencyProcedure, RejectsOverflowingOriginalPencilValidationScale) {
|
||||
// Every local K entry, eigenvalue, and spectral enclosure is representable.
|
||||
// The all-odd x Walsh mode still overflows the original residual/energy
|
||||
// denominators: finite / infinity must never become passing zero evidence.
|
||||
auto domain = Brick(24U, "", 1.0, 2.0, 3e306);
|
||||
// With M_L=12*I, the highest mode makes ||K||_F+|lambda|*||M||_F
|
||||
// overflow: finite / infinity must never become passing zero evidence.
|
||||
auto domain = Brick(24U, "", 1.0, 2.0, 4e306);
|
||||
ASSERT_TRUE(domain.HasValue()) << StatusText(domain.GetStatus());
|
||||
const auto result =
|
||||
fesa::SolidFrequencyProcedureExecutor{}.Execute(domain.Value());
|
||||
|
||||
Reference in New Issue
Block a user