perf(math): route ordinary products through MKL and preserve arithmetic

This commit is contained in:
KOKO\Mimi
2026-10-14 15:09:53 +09:00
parent b4fc1bb54b
commit 59c8e93b07
18 changed files with 793 additions and 169 deletions
+18 -23
View File
@@ -12,6 +12,7 @@
#include "fesa/math/vector3.h"
#include "fesa/model/model_types.h"
#include "math/dense_blas_internal.h"
namespace fesa {
@@ -228,10 +229,9 @@ double NormalizedMatrixError(const Matrix& lhs, const Matrix& rhs) {
std::array<double, kGeneralizedComponentCount> GeneralizedStrain(
const Matrix& b, const Vector& local_displacement) {
std::array<double, kGeneralizedComponentCount> strain{};
const auto product = b.Multiply(local_displacement);
for (std::size_t component = 0; component < strain.size(); ++component) {
for (std::size_t dof = 0; dof < local_displacement.Size(); ++dof) {
strain[component] += b(component, dof) * local_displacement[dof];
}
strain[component] = product[component];
}
return strain;
}
@@ -395,13 +395,15 @@ Matrix EulerBeam3D::LocalStiffness() const {
// Both Gauss points are required: a one-point bending rule loses two ranks.
for (const double xi : gauss_points) {
const Matrix b = StrainDisplacement(xi, length_);
Matrix weighted_b = b;
for (std::size_t component = 0; component < diagonal.size(); ++component)
for (std::size_t column = 0; column < kElementDofCount; ++column)
weighted_b(component, column) *= diagonal[component];
const auto contribution =
dense_blas_internal::MultiplyTransposeLeft(b, weighted_b);
for (std::size_t row = 0; row < kElementDofCount; ++row) {
for (std::size_t column = 0; column < kElementDofCount; ++column) {
for (std::size_t component = 0; component < diagonal.size();
++component) {
stiffness(row, column) += b(component, row) * diagonal[component] *
b(component, column) * jacobian;
}
stiffness(row, column) += contribution(row, column) * jacobian;
}
}
}
@@ -418,22 +420,17 @@ Matrix EulerBeam3D::GlobalStiffness() const {
const Matrix local = LocalStiffness();
const Matrix transform = Transformation(rotation_);
const Matrix local_times_transform = local.Multiply(transform);
Matrix global{kElementDofCount, kElementDofCount};
// Kg=T^T*Kl*T while dl=T*dg.
for (std::size_t row = 0; row < kElementDofCount; ++row) {
for (std::size_t column = 0; column < kElementDofCount; ++column) {
for (std::size_t inner = 0; inner < kElementDofCount; ++inner) {
global(row, column) +=
transform(inner, row) * local_times_transform(inner, column);
}
}
}
return global;
return dense_blas_internal::MultiplyTransposeLeft(transform,
local_times_transform);
}
Vector EulerBeam3D::LocalEquivalentLoad(
const ConstantLocalLineLoad& load) const {
const std::array<double, 4> components = {load.px, load.py, load.pz, load.mx};
Matrix component_column{components.size(), 1U};
for (std::size_t component = 0; component < components.size(); ++component)
component_column(component, 0U) = components[component];
Vector equivalent{kElementDofCount};
const double inverse_sqrt_three = 1.0 / std::sqrt(3.0);
const std::array<double, 2> gauss_points = {-inverse_sqrt_three,
@@ -441,12 +438,10 @@ Vector EulerBeam3D::LocalEquivalentLoad(
const double jacobian = 0.5 * length_;
for (const double xi : gauss_points) {
const Matrix interpolation = KinematicInterpolation(xi, length_);
const auto contribution = dense_blas_internal::MultiplyTransposeLeft(
interpolation, component_column);
for (std::size_t dof = 0; dof < equivalent.Size(); ++dof) {
for (std::size_t component = 0; component < components.size();
++component) {
equivalent[dof] +=
interpolation(component, dof) * components[component] * jacobian;
}
equivalent[dof] += contribution(dof, 0U) * jacobian;
}
}
return equivalent;