Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -7,9 +7,15 @@
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
#include "math/dense_blas_internal.h"
|
||||
#include "math/vector3_operations.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
|
||||
using math_internal::DerivativeSum;
|
||||
using math_internal::WeightedSum;
|
||||
|
||||
constexpr std::array<double, 4> kXiSigns{-1.0, 1.0, 1.0, -1.0};
|
||||
constexpr std::array<double, 4> kEtaSigns{-1.0, -1.0, 1.0, 1.0};
|
||||
|
||||
@@ -38,27 +44,6 @@ ShapeData ShapeDataAt(double xi, double eta) {
|
||||
return data;
|
||||
}
|
||||
|
||||
Vector3 WeightedSum(const std::array<double, 4>& weights,
|
||||
const std::array<Vector3, 4>& values) {
|
||||
Vector3 result{};
|
||||
for (std::size_t node = 0U; node < values.size(); ++node) {
|
||||
result = result + weights[node] * values[node];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief Forms a translation-invariant covariant tangent in node order.
|
||||
Vector3 DerivativeSum(const std::array<double, 4>& derivatives,
|
||||
const std::array<Vector3, 4>& coordinates) {
|
||||
// Shape derivatives sum to zero, so translating by node 1 improves the
|
||||
// numerical cancellation without changing the covariant tangent.
|
||||
std::array<Vector3, 4> relative{};
|
||||
for (std::size_t node = 0U; node < coordinates.size(); ++node) {
|
||||
relative[node] = coordinates[node] - coordinates[0];
|
||||
}
|
||||
return WeightedSum(derivatives, relative);
|
||||
}
|
||||
|
||||
Result<ShellGeometry> GeometryFailure(std::string code,
|
||||
const SourceLocation& location,
|
||||
std::string keyword, std::string identity,
|
||||
@@ -405,14 +390,27 @@ Result<ShellGeometry> PreprocessShellGeometry(
|
||||
element.source_id.source_label_text,
|
||||
"Shell Jacobian is nonfinite or nonpositive at a required point.");
|
||||
}
|
||||
const Vector3 reciprocal_xi =
|
||||
(1.0 / jacobian) * covariant_eta.Cross(covariant_zeta);
|
||||
const Vector3 reciprocal_eta =
|
||||
(1.0 / jacobian) * covariant_zeta.Cross(covariant_xi);
|
||||
const Vector3 reciprocal_zeta =
|
||||
(1.0 / jacobian) * covariant_xi.Cross(covariant_eta);
|
||||
if (!reciprocal_xi.IsFinite() || !reciprocal_eta.IsFinite() ||
|
||||
!reciprocal_zeta.IsFinite()) {
|
||||
bool finite_actions = std::isfinite(1.0 / jacobian) &&
|
||||
covariant_eta.Cross(covariant_zeta).IsFinite() &&
|
||||
covariant_zeta.Cross(covariant_xi).IsFinite() &&
|
||||
covariant_xi.Cross(covariant_eta).IsFinite();
|
||||
if (finite_actions) {
|
||||
Matrix coefficients{3U, 3U};
|
||||
for (std::size_t i = 0; i < 3U; ++i) {
|
||||
coefficients(i, 0) = covariant_xi[i];
|
||||
coefficients(i, 1) = covariant_eta[i];
|
||||
coefficients(i, 2) = covariant_zeta[i];
|
||||
}
|
||||
const auto factor = dense_blas_internal::DenseFactor::Lu(coefficients);
|
||||
finite_actions = factor.HasValue();
|
||||
Matrix rhs{3U, 1U};
|
||||
for (std::size_t axis = 0; finite_actions && axis < 3U; ++axis) {
|
||||
if (axis != 0U) rhs(axis - 1U, 0U) = 0.0;
|
||||
rhs(axis, 0U) = 1.0;
|
||||
finite_actions = factor.Value().Solve(rhs, true).HasValue();
|
||||
}
|
||||
}
|
||||
if (!finite_actions) {
|
||||
return GeometryFailure(
|
||||
"invalid-shell-jacobian", element.location, "ELEMENT",
|
||||
element.source_id.source_label_text,
|
||||
|
||||
Reference in New Issue
Block a user