Integrate Refactor solver sources and dual MSVC CMake builds

This commit is contained in:
KOKO\Mimi
2026-10-18 02:10:51 +09:00
parent 7ee32e5837
commit 12d51480de
218 changed files with 17842 additions and 9689 deletions
+57 -104
View File
@@ -9,6 +9,9 @@
#include "fesa/model/model_types.h"
#include "math/dense_blas_internal.h"
#include "math/finite_values.h"
#include "math/vector3_operations.h"
#include "elements/shell_kernel_values.h"
namespace fesa {
@@ -63,6 +66,13 @@ void Mitc4ShellDefinition::SynchronizeNodeIndices() {
namespace {
using shell_kernel_internal::FrameComponent;
using shell_kernel_internal::LocalEngineeringComponents;
using shell_kernel_internal::ElementIdentity;
using math_internal::DerivativeSum;
using math_internal::WeightedSum;
using math_internal::IsFinite;
constexpr std::size_t kNodeCount = 4U;
constexpr std::size_t kPhysicalDofsPerNode = 5U;
constexpr std::size_t kGlobalDofsPerNode = 6U;
@@ -71,24 +81,6 @@ constexpr std::size_t kGlobalDofCount = 24U;
constexpr double kShearCorrection = 5.0 / 6.0;
constexpr double kFrameTolerance = 1.0e-12;
Vector3 WeightedSum(const std::array<double, kNodeCount>& weights,
const std::array<Vector3, kNodeCount>& values) {
Vector3 result{};
for (std::size_t node = 0U; node < kNodeCount; ++node) {
result = result + weights[node] * values[node];
}
return result;
}
Vector3 DerivativeSum(const std::array<double, kNodeCount>& derivatives,
const std::array<Vector3, kNodeCount>& values) {
std::array<Vector3, kNodeCount> relative{};
for (std::size_t node = 0U; node < kNodeCount; ++node) {
relative[node] = values[node] - values[0];
}
return WeightedSum(derivatives, relative);
}
bool SameCoordinates(const Vector3& left, const Vector3& right) {
return left == right;
}
@@ -129,20 +121,6 @@ std::array<Vector3, kNodeCount> NodalTangentsB(
return tangents;
}
std::string ElementIdentity(const std::array<const Node*, kNodeCount>& nodes) {
std::string identity;
for (const Node* node : nodes) {
if (node == nullptr) {
continue;
}
if (!identity.empty()) {
identity += "-";
}
identity += node->source_id.source_label_text;
}
return identity;
}
Result<Mitc4Shell> ModelFailure(std::string code,
const SourceLocation& location,
const std::string& identity,
@@ -169,58 +147,36 @@ std::array<std::array<double, 3>, 3> CovariantStrainColumn(
return strain;
}
/// @brief Reconstructs Cartesian strain in the approved reciprocal-basis
/// reduction order.
/// @brief Solves C^T E C = E_cov for the actual strain tensor.
std::array<std::array<double, 3>, 3> ReconstructCartesianStrain(
const std::array<std::array<double, 3>, 3>& covariant_strain,
const std::array<Vector3, 3>& reciprocal) {
const dense_blas_internal::DenseFactor& factor) {
Matrix rhs{3U, 3U};
for (std::size_t i = 0; i < 3U; ++i)
for (std::size_t j = 0; j < 3U; ++j) rhs(i, j) = covariant_strain[i][j];
const auto left = factor.Solve(rhs, true);
if (!left.HasValue())
throw std::invalid_argument{"MITC4 Cartesian strain is nonfinite."};
const auto solved = factor.SolveRight(left.Value());
if (!solved.HasValue())
throw std::invalid_argument{"MITC4 Cartesian strain is nonfinite."};
std::array<std::array<double, 3>, 3> tensor{};
for (std::size_t row = 0U; row < 3U; ++row) {
for (std::size_t column = 0U; column < 3U; ++column) {
for (std::size_t first = 0U; first < 3U; ++first) {
for (std::size_t second = 0U; second < 3U; ++second) {
tensor[row][column] += covariant_strain[first][second] *
reciprocal[first][row] *
reciprocal[second][column];
}
}
}
}
for (std::size_t i = 0; i < 3U; ++i)
for (std::size_t j = 0; j < 3U; ++j) tensor[i][j] = solved.Value()(i, j);
return tensor;
}
double FrameComponent(const Vector3& left,
const std::array<std::array<double, 3>, 3>& tensor,
const Vector3& right) {
double value = 0.0;
for (std::size_t row = 0U; row < 3U; ++row) {
for (std::size_t column = 0U; column < 3U; ++column) {
value += left[row] * tensor[row][column] * right[column];
}
}
return value;
}
/// @brief Projects tensor strain into signed local engineering components.
std::array<double, 5> LocalEngineeringComponents(
const std::array<std::array<double, 3>, 3>& tensor,
const Mitc4LocalFrame& frame) {
const Vector3 e1{frame.e1};
const Vector3 e2{frame.e2};
const Vector3 e3{frame.e3};
return {FrameComponent(e1, tensor, e1), FrameComponent(e2, tensor, e2),
2.0 * FrameComponent(e1, tensor, e2),
2.0 * FrameComponent(e1, tensor, e3),
2.0 * FrameComponent(e2, tensor, e3)};
/// @brief Packs covariant columns without constructing reciprocal vectors.
Matrix CovariantMatrix(const std::array<Vector3, 3>& covariant) {
Matrix coefficients{3U, 3U};
for (std::size_t i = 0; i < 3U; ++i)
for (std::size_t j = 0; j < 3U; ++j) coefficients(i, j) = covariant[j][i];
return coefficients;
}
Matrix ScaledMatrix(const Matrix& source, double factor) {
Matrix result{source.Rows(), source.Columns()};
for (std::size_t row = 0U; row < source.Rows(); ++row) {
for (std::size_t column = 0U; column < source.Columns(); ++column) {
result(row, column) = factor * source(row, column);
}
}
Matrix result{source};
result.Scale(factor);
return result;
}
@@ -241,26 +197,6 @@ Matrix Congruence(const Matrix& local, const Matrix& transformation) {
return result;
}
bool IsFinite(const Matrix& matrix) {
for (std::size_t row = 0U; row < matrix.Rows(); ++row) {
for (std::size_t column = 0U; column < matrix.Columns(); ++column) {
if (!std::isfinite(matrix(row, column))) {
return false;
}
}
}
return true;
}
bool IsFinite(const Vector& vector) {
for (std::size_t index = 0U; index < vector.Size(); ++index) {
if (!std::isfinite(vector[index])) {
return false;
}
}
return true;
}
Result<Mitc4Stiffness> StiffnessFailure(const SourceLocation& location,
const std::string& identity,
std::string message) {
@@ -1092,12 +1028,25 @@ bool Mitc4Shell::EvaluateGeometry(double xi, double eta, double zeta,
return false;
}
result.reciprocal[0] =
(1.0 / result.jacobian) * result.covariant[1].Cross(result.covariant[2]);
result.reciprocal[1] =
(1.0 / result.jacobian) * result.covariant[2].Cross(result.covariant[0]);
result.reciprocal[2] =
(1.0 / result.jacobian) * result.covariant[0].Cross(result.covariant[1]);
if (!std::isfinite(1.0 / result.jacobian) ||
!result.covariant[1].Cross(result.covariant[2]).IsFinite() ||
!result.covariant[2].Cross(result.covariant[0]).IsFinite() ||
!result.covariant[0].Cross(result.covariant[1]).IsFinite()) return false;
// Preserve the reciprocal finiteness gate, streaming each action directly
// into validation rather than retaining a reciprocal-basis matrix.
try {
const auto factor = dense_blas_internal::DenseFactor::Lu(
CovariantMatrix(result.covariant));
if (!factor.HasValue()) return false;
Matrix rhs{3U, 1U};
for (std::size_t axis = 0; axis < 3U; ++axis) {
if (axis != 0U) rhs(axis - 1U, 0U) = 0.0;
rhs(axis, 0U) = 1.0;
if (!factor.Value().Solve(rhs, true).HasValue()) return false;
}
} catch (const std::exception&) {
return false;
}
const Vector3 area = midsurface_xi.Cross(midsurface_eta);
const double director_norm = director_value.Norm();
@@ -1120,8 +1069,7 @@ bool Mitc4Shell::EvaluateGeometry(double xi, double eta, double zeta,
const Vector3 e2 = e3.Cross(e1);
result.frame.e1 = e1.Components();
result.frame.e2 = e2.Components();
return result.reciprocal[0].IsFinite() && result.reciprocal[1].IsFinite() &&
result.reciprocal[2].IsFinite() && e2.IsFinite();
return e2.IsFinite();
}
std::array<std::array<Vector3, 3>, 20> Mitc4Shell::BasisDerivatives(
@@ -1165,6 +1113,11 @@ Matrix Mitc4Shell::StrainDisplacement(double xi, double eta, double zeta,
throw std::invalid_argument{
"MITC4 strain geometry is invalid at the requested point."};
}
const auto factor = dense_blas_internal::DenseFactor::Lu(
CovariantMatrix(geometry.covariant));
if (!factor.HasValue())
throw std::invalid_argument{
"MITC4 strain geometry is invalid at the requested point."};
const auto derivatives = BasisDerivatives(xi, eta, zeta);
const Mitc4TyingWeights weights = TyingWeights(xi, eta);
Matrix result{5U, kPhysicalDofCount};
@@ -1180,7 +1133,7 @@ Matrix Mitc4Shell::StrainDisplacement(double xi, double eta, double zeta,
covariant[2U][1U] = covariant[1U][2U];
}
const auto engineering = LocalEngineeringComponents(
ReconstructCartesianStrain(covariant, geometry.reciprocal),
ReconstructCartesianStrain(covariant, factor.Value()),
geometry.frame);
for (std::size_t component = 0U; component < engineering.size();
++component) {