feat(euclidean): block-FD edge-DOF Hessian → cyclic Newton + Java convergence oracle
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m1s
Markdown link check / check (pull_request) Successful in 1m3s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m13s
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m1s
Markdown link check / check (pull_request) Successful in 1m3s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m13s
Implements the edge-DOF (cyclic) Euclidean Hessian, unblocking the full cyclic
Newton solve, and enables the Java EuclideanCyclicConvergenceTest cross-validation.
- euclidean_hessian.hpp: `euclidean_hessian_block_fd` / `_sym` — per-face 6×6
block FD over (u1,u2,u3,λ12,λ23,λ31), mirroring hyper_ideal_hessian_block_fd.
Per-face outputs carry the gradient signs (−α vertex, +α_opp edge), so the
result equals ∂G/∂x by construction (locality lemma). Analytic vertex-only
cotangent Hessian unchanged (still used for vertex-only layouts).
- newton_solver.hpp: newton_euclidean routes cyclic layouts (edge DOFs present)
through the block-FD Hessian; vertex-only path unchanged.
- tests:
* CyclicCircularEdge_CatHead_JavaXVal (now GREEN) — prescribe φ=π−0.1 on one
interior edge, solve, assert realised α_opp+α_opp = π−0.1 @1e-9.
* CyclicCircularEdge_PhiEntersGradient_CatHead — solver-free φ-wiring check.
* CyclicHessian_BlockFD_MatchesGradientFD_Tetrahedron — Hessian correctness.
243/243 cgal tests pass; vertex-only Euclidean Newton unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -258,7 +258,14 @@ inline NewtonResult newton_euclidean(
|
||||
}
|
||||
|
||||
// ── Hessian + solve H·Δx = −G (SparseQR fallback for singular H) ──
|
||||
auto H = euclidean_hessian(mesh, x, m);
|
||||
// Cyclic layout (edge DOFs present) → block-FD Hessian, which covers the
|
||||
// vertex-edge / edge-edge blocks the analytic cotangent Laplacian omits.
|
||||
// Vertex-only layout → analytic cotangent Laplacian (cheaper, exact).
|
||||
bool has_edge_dof = false;
|
||||
for (auto e : mesh.edges())
|
||||
if (m.e_idx[e] >= 0) { has_edge_dof = true; break; }
|
||||
auto H = has_edge_dof ? euclidean_hessian_block_fd_sym(mesh, x, m)
|
||||
: euclidean_hessian(mesh, x, m);
|
||||
bool ok = false;
|
||||
Eigen::VectorXd dx = detail::solve_with_fallback(H, -G, ok);
|
||||
if (!ok) break;
|
||||
|
||||
Reference in New Issue
Block a user