Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "fesa/elements/hex8_element.h"
|
||||
|
||||
#include "fesa/math/vector3.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -180,17 +182,46 @@ Result<Hex8Element> Hex8Element::Create(EntityIndex index,
|
||||
point.weight <= 0.0)
|
||||
return Result<Hex8Element>::Failure(candidate.Failure(
|
||||
"Reference quadrature Jacobian must be finite and positive."));
|
||||
const auto inverse = hex8_internal::Inverse(jacobian, point.weight);
|
||||
if (!Finite(inverse))
|
||||
const Vector3 c0{jacobian[0][0], jacobian[1][0], jacobian[2][0]};
|
||||
const Vector3 c1{jacobian[0][1], jacobian[1][1], jacobian[2][1]};
|
||||
const Vector3 c2{jacobian[0][2], jacobian[1][2], jacobian[2][2]};
|
||||
if (!c0.Cross(c1).IsFinite() || !c1.Cross(c2).IsFinite() ||
|
||||
!c2.Cross(c0).IsFinite())
|
||||
return Result<Hex8Element>::Failure(
|
||||
candidate.Failure("Reference Jacobian inverse is nonfinite."));
|
||||
Matrix coefficients{3U, 3U};
|
||||
Matrix natural_gradients{3U, 8U};
|
||||
for (std::size_t i = 0; i < 3U; ++i) {
|
||||
for (std::size_t d = 0; d < 3U; ++d)
|
||||
coefficients(i, d) = jacobian[i][d];
|
||||
for (std::size_t a = 0; a < 8U; ++a)
|
||||
natural_gradients(i, a) = derivatives[a][i];
|
||||
}
|
||||
const auto factor = dense_blas_internal::DenseFactor::Lu(coefficients);
|
||||
if (!factor.HasValue())
|
||||
return Result<Hex8Element>::Failure(
|
||||
candidate.Failure("Reference Jacobian inverse is nonfinite."));
|
||||
// The original geometry gate required every reciprocal action to be
|
||||
// finite, including entries not exposed by the smaller shape-gradient RHS.
|
||||
Matrix canonical{3U, 1U};
|
||||
for (std::size_t axis = 0; axis < 3U; ++axis) {
|
||||
if (axis != 0U) canonical(axis - 1U, 0U) = 0.0;
|
||||
canonical(axis, 0U) = 1.0;
|
||||
if (!factor.Value().Solve(canonical, true).HasValue())
|
||||
return Result<Hex8Element>::Failure(
|
||||
candidate.Failure("Reference Jacobian inverse is nonfinite."));
|
||||
}
|
||||
// J has Cartesian rows and natural columns: J^T grad_x N = grad_nat N.
|
||||
const auto gradients = factor.Value().Solve(natural_gradients, true);
|
||||
if (!gradients.HasValue())
|
||||
return Result<Hex8Element>::Failure(candidate.Failure(
|
||||
"Reference gradient or point coordinate is nonfinite."));
|
||||
point.position = coordinates[0];
|
||||
for (std::size_t a = 0; a < 8; ++a)
|
||||
for (std::size_t i = 0; i < 3; ++i) {
|
||||
point.position[i] +=
|
||||
point.shape[a] * (coordinates[a][i] - coordinates[0][i]);
|
||||
for (std::size_t d = 0; d < 3; ++d)
|
||||
point.gradients[a][i] += inverse[d][i] * derivatives[a][d];
|
||||
point.gradients[a][i] = gradients.Value()(i, a);
|
||||
if (!std::isfinite(point.gradients[a][i]) ||
|
||||
!std::isfinite(point.position[i]))
|
||||
return Result<Hex8Element>::Failure(candidate.Failure(
|
||||
|
||||
Reference in New Issue
Block a user