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
+58 -25
View File
@@ -12,6 +12,7 @@
#include <vector>
#include "fesa/model/model_types.h"
#include "math/dense_blas_internal.h"
namespace fesa {
namespace thermal_internal {
@@ -136,10 +137,20 @@ Result<Geometry> BuildGeometry(const std::array<Vector3, 4>& coordinates,
const double uv = u.Dot(v);
const double determinant = uu * vv - uv * uv;
if (determinant > 0 && std::isfinite(determinant)) {
const double xi = (uv * v.Dot(w0) - vv * u.Dot(w0)) / determinant;
const double eta = (uv * u.Dot(w0) - uu * v.Dot(w0)) / determinant;
if (std::abs(xi) <= 1 && std::abs(eta) <= 1) {
candidates.push_back(w0 + xi * u + eta * v);
Matrix metric{2, 2};
metric(0,0) = uu; metric(0,1) = uv;
metric(1,0) = uv; metric(1,1) = vv;
Matrix rhs{2, 1};
rhs(0,0) = -u.Dot(w0); rhs(1,0) = -v.Dot(w0);
const auto factor = dense_blas_internal::DenseFactor::Lu(metric);
if (factor.HasValue()) {
const auto stationary = factor.Value().Solve(rhs);
if (stationary.HasValue()) {
const double xi = stationary.Value()(0,0);
const double eta = stationary.Value()(1,0);
if (std::abs(xi) <= 1 && std::abs(eta) <= 1)
candidates.push_back(w0 + xi * u + eta * v);
}
}
}
// The center is also useful for affine or rank-one normal images.
@@ -169,30 +180,39 @@ Result<SurfacePoint> EvaluateSurface(const Geometry& geometry, double xi,
const double jacobian = w.Norm();
const Interval determinant_interval = NormSquared(wi);
const double determinant = w.Dot(w);
// |a1 x a2|^2 is the Gram determinant identity, avoiding subtraction of
// nearly equal g11*g22 and g12*g12. This is still the actual-point metric.
const Interval inverse11 = Dot(a2i, a2i) / determinant_interval;
const Interval inverse12 =
(Interval{0} - Dot(a1i, a2i)) / determinant_interval;
const Interval inverse22 = Dot(a1i, a1i) / determinant_interval;
if (!(determinant_interval.lower > 0) || !inverse11.IsFinite() ||
!inverse12.IsFinite() || !inverse22.IsFinite() || !(jacobian > 0) ||
// Retain the original scalar range/scale certificate. Each canonical
// metric action is consumed immediately by its finite gate, never retained
// as inverse coefficients or used to compute a physical gradient.
const auto finite_metric_action = [&](Interval numerator) {
const Interval action = numerator / determinant_interval;
return action.IsFinite() &&
Scale(action, -2 * geometry.length_exponent).IsFinite();
};
if (!(determinant_interval.lower > 0) ||
!finite_metric_action(Dot(a2i, a2i)) ||
!finite_metric_action(Interval{0} - Dot(a1i, a2i)) ||
!finite_metric_action(Dot(a1i, a1i)) || !(jacobian > 0) ||
!std::isfinite(determinant) || determinant <= 0 ||
!Scale(inverse11, -2 * geometry.length_exponent).IsFinite() ||
!Scale(inverse12, -2 * geometry.length_exponent).IsFinite() ||
!Scale(inverse22, -2 * geometry.length_exponent).IsFinite() ||
!Scale(Dot(a1i, a1i), 2 * geometry.length_exponent).IsFinite() ||
!Scale(Dot(a2i, a2i), 2 * geometry.length_exponent).IsFinite()) {
return Result<SurfacePoint>::Failure(GeometryFailure(
source, location, "uncertain-thermal-shell-metric",
"Metric inverse enclosure is not finite or excludes no zero divisor."));
}
const Vector3 reciprocal1 = a2.Cross(w) / determinant;
const Vector3 reciprocal2 = w.Cross(a1) / determinant;
const auto reciprocal1i =
(Interval{1} / determinant_interval) * Cross(a2i, wi);
const auto reciprocal2i =
(Interval{1} / determinant_interval) * Cross(wi, a1i);
// Factor the physical tangent constraints rather than the rounded Gram
// matrix, which can lose rank while the certified patch is still regular.
Matrix constraints{3, 3};
for (std::size_t j = 0; j < 3; ++j) {
constraints(0,j) = a1[j];
constraints(1,j) = a2[j];
constraints(2,j) = w[j] / jacobian;
}
const auto factor = dense_blas_internal::DenseFactor::Lu(constraints);
if (!factor.HasValue())
return Result<SurfacePoint>::Failure(GeometryFailure(
source, location, "uncertain-thermal-shell-metric",
"Surface gradient enclosure is not finite."));
const Interval reciprocal_determinant = Interval{1} / determinant_interval;
SurfacePoint point{};
point.jacobian = std::ldexp(jacobian, 2 * geometry.length_exponent);
point.jacobian_interval =
@@ -213,13 +233,26 @@ Result<SurfacePoint> EvaluateSurface(const Geometry& geometry, double xi,
(Interval{1} + Interval{kEta[i]} * eta_interval);
const Interval dyi = Interval{.25 * kEta[i]} *
(Interval{1} + Interval{kXi[i]} * xi_interval);
const Vector3 gradient = dx * reciprocal1 + dy * reciprocal2;
const auto gradient_interval = dxi * reciprocal1i + dyi * reciprocal2i;
Matrix rhs{3, 1};
rhs(0,0) = dx; rhs(1,0) = dy;
const auto gradient = factor.Value().Solve(rhs);
if (!gradient.HasValue())
return Result<SurfacePoint>::Failure(GeometryFailure(
source, location, "uncertain-thermal-shell-metric",
"Surface gradient enclosure is not finite."));
// The real solution obeys a1.g=dx, a2.g=dy, w.g=0. Its exterior-product
// identity encloses the solution directly. The original outward endpoint
// graph is retained component by component; no interval factor pivot or
// interval inverse/basis is introduced and no low-order term is discarded.
const auto first_numerator = Cross(a2i, wi);
const auto second_numerator = Cross(wi, a1i);
std::array<double, 3> components{};
for (std::size_t j = 0; j < 3; ++j) {
components[j] = std::ldexp(gradient[j], -geometry.length_exponent);
components[j] = std::ldexp(gradient.Value()(j,0), -geometry.length_exponent);
point.gradient_interval[i][j] =
Scale(gradient_interval[j], -geometry.length_exponent);
Scale(dxi * (reciprocal_determinant * first_numerator[j]) +
dyi * (reciprocal_determinant * second_numerator[j]),
-geometry.length_exponent);
}
point.gradient[i] = Vector3{components};
if (!point.gradient[i].IsFinite() ||