perf(hex8): prepare guarded private four-column paired tangent packet

This commit is contained in:
KOKO\Mimi
2026-10-14 20:12:20 +09:00
parent b474d127d8
commit 9b8e53dcfd
6 changed files with 498 additions and 5 deletions
+39 -5
View File
@@ -9,6 +9,7 @@
#include "hex8_geometry.h"
#include "hex8_linear_tangent_cache.h"
#include "hex8_pair_arithmetic.h"
#include "hex8_pair_simd.h"
namespace fesa {
namespace {
@@ -163,6 +164,11 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
return Result<Hex8HighLowResponse>::Failure(
Failure("Hex8 high+low constitutive coefficients are unsupported."));
energy = HighLow{0.5} * HighLow{kappa_} * volume * mean_trace * mean_trace;
const auto packet_evaluator = nonlinear
? hex8_internal::SelectMaterialPacketEvaluator()
: hex8_internal::EvaluateMaterialPacketScalar;
const bool use_packets =
packet_evaluator != hex8_internal::EvaluateMaterialPacketScalar;
for (std::size_t g = 0; g < 8; ++g) {
const auto& point = points_[g];
const auto& gradients = point_gradients[g];
@@ -238,9 +244,11 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
for (std::size_t j = 0; j < 3; ++j)
for (std::size_t l = 0; l < 3; ++l)
gradient_stress[a][j][l] = gradients[a][j] * s[l][j];
for (std::size_t a = 0; a < 8; ++a)
for (std::size_t a = 0; a < 8; ++a) {
std::array<HighLow, 8> dots{};
for (std::size_t b = 0; b < 8; ++b) {
const auto dot = Dot(gradients[a], gradients[b]);
dots[b] = dot;
HighLow geo;
if (nonlinear)
for (std::size_t j = 0; j < 3; ++j)
@@ -250,14 +258,40 @@ Result<Hex8HighLowResponse> Hex8Element::EvaluateHighLow(
for (std::size_t k = 0; k < 3; ++k) {
const auto row = 3U * a + i;
const auto column = 3U * b + k;
const auto mat = deviatoric_fg[a][i] * fg[b][k] +
shear_fg[b][i] * fg[a][k] +
shear_fft[i][k] * dot;
material[row][column] += mat * HighLow{point.weight};
if (!use_packets) {
const auto mat = deviatoric_fg[a][i] * fg[b][k] +
shear_fg[b][i] * fg[a][k] +
shear_fft[i][k] * dot;
material[row][column] += mat * HighLow{point.weight};
}
if (i == k)
geometric[row][column] += geo * HighLow{point.weight};
}
}
if (use_packets)
for (std::size_t i = 0; i < 3; ++i)
for (std::size_t first = 0; first < 24; first += 4) {
hex8_internal::MaterialPacketInput input;
input.weight = HighLow{point.weight};
const auto row = 3U * a + i;
for (std::size_t lane = 0; lane < 4; ++lane) {
const auto column = first + lane;
const auto b = column / 3U;
const auto k = column % 3U;
input.deviatoric_left[lane] = deviatoric_fg[a][i];
input.deviatoric_right[lane] = fg[b][k];
input.shear_left[lane] = shear_fg[b][i];
input.shear_right[lane] = fg[a][k];
input.tensor_left[lane] = shear_fft[i][k];
input.gradient_dot[lane] = dots[b];
input.accumulated[lane] = material[row][column];
}
hex8_internal::PairPacket output;
packet_evaluator(input, &output);
for (std::size_t lane = 0; lane < 4; ++lane)
material[row][first + lane] = output[lane];
}
}
}
if (nonlinear || !paired_linear_tangent_->ready) {
std::array<Triple, 8> bulk_fg{};