feat(phase3d+3e): port EuclideanCyclicFunctional + add SphericalFunctional gauge-fix

Phase 3d — EuclideanCyclicFunctional:
  • euclidean_geometry.hpp: t-value / atan2 corner-angle formula with
    centering trick (μ = (Λ̃₁₂+Λ̃₂₃+Λ̃₃₁)/6) for numerical stability
  • euclidean_functional.hpp: EuclideanMaps bundle, gradient (G_v = Θ_v − Σα_v,
    G_e = α_opp⁺ + α_opp⁻ − φ_e), 10-point GL path-integral energy,
    gradient_check_euclidean — identical halfedge convention to SphericalFunctional
  • test_euclidean_functional.cpp: 11 tests (1 skip) covering angle formula,
    right-isosceles triangle, angle sum = π, degenerate detection, gradient
    checks on triangle/quad-strip/tetrahedron/fan-5/mixed-pinned, NaN check

Phase 3e — Spherical gauge-fix:
  • spherical_gauge_shift(): Newton + backtracking line search to find t*
    where ΣG_v(x + t·1) = 0 (maximises E along the global scale direction);
    bisection used when sign change is detectable, Newton+backtrack otherwise
  • apply_spherical_gauge(): in-place wrapper
  • 3 new tests: GaugeFix_SpherTetVertexZerosSumGv, GaugeFix_ApplyInPlace,
    GaugeFix_AlreadyAtGaugeReturnsTNearZero

Total: 45 cgal tests pass, 3 skipped (@Ignore Hessian stubs, one per functional)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tarik Moussa
2026-05-12 07:39:14 +02:00
parent dc0d3ca005
commit 8c353bb884
7 changed files with 924 additions and 21 deletions

View File

@@ -4,7 +4,7 @@ conformallab++ is a modern C++ reimplementation of the [ConformalLab](https://gi
The long-term goal is a **CGAL package** that brings discrete conformal maps (hyper-ideal, spherical, Euclidean) to the CGAL ecosystem using `CGAL::Surface_mesh` as the underlying half-edge data structure.
> **Status:** Phase 3 abgeschlossen. Kern-Geometrie (Clausen, Hyper-Ideal, Sphärisch) und CGAL-Mesh-Infrastruktur sind vorhanden. Zum Abschluss von Phase 3 und als Vorbereitung für Phase 4 stehen noch sechs konkrete Schritte aus — siehe [Roadmap](#roadmap).
> **Status:** Phasen 3d + 3e abgeschlossen. Alle drei Kern-Geometrien (Hyper-Ideal, Sphärisch, Euklidisch) plus Sphärischer Gauge-Fix sind auf `ConformalMesh` portiert. **45 Tests, 3 skipped** (Hessian-Stubs). Nächster Schritt: Phase 3f (Hessian) → Phase 4 (Newton-Solver) — siehe [Roadmap](#roadmap).
---
@@ -17,7 +17,8 @@ The long-term goal is a **CGAL package** that brings discrete conformal maps (hy
| Hyper-ideal functional (energy + gradient, CGAL mesh) | ✅ Phase 3b |
| Spherical functional (energy + gradient, CGAL mesh) | ✅ Phase 3c |
| CGAL `Surface_mesh` infrastructure + mesh builders | ✅ Phase 3a |
| Euclidean functional | 🔜 Phase 4 |
| Euclidean functional (energy + gradient, CGAL mesh) | Phase 3d |
| Spherical gauge-fix (scale gauge for closed surfaces) | ✅ Phase 3e |
| Solvers (Newton, gradient flow) | 🔜 Phase 4 |
| XML serialisation / mesh I/O | 🔜 Phase 5 |
| Full CLI app | 🔜 Phase 5 |
@@ -72,7 +73,7 @@ cmake --build build --target conformallab_cgal_tests -j$(nproc)
ctest --test-dir build -R "^cgal\." --output-on-failure
```
Expected output: **30 tests pass, 2 skipped** (the two `@Ignore` Hessian stubs).
Expected output: **45 tests pass, 3 skipped** (the three `@Ignore` Hessian stubs, one per functional).
### Full CLI app (CGAL + viewer)
@@ -93,7 +94,9 @@ cmake --build build -j$(nproc)
| `hyper_ideal_utility.hpp` | Tetrahedron volume (Meyerhoff / KolpakovMednykh) |
| `hyper_ideal_functional.hpp` | Hyper-ideal energy + gradient on `ConformalMesh` |
| `spherical_geometry.hpp` | Spherical arc length, half-angle angle formula |
| `spherical_functional.hpp` | Spherical energy + gradient on `ConformalMesh` |
| `spherical_functional.hpp` | Spherical energy + gradient + gauge-fix on `ConformalMesh` |
| `euclidean_geometry.hpp` | Euclidean corner-angle formula (t-value / atan2) |
| `euclidean_functional.hpp` | Euclidean energy + gradient on `ConformalMesh` |
| `conformal_mesh.hpp` | `ConformalMesh` = `CGAL::Surface_mesh<Point3>`, index types, property-map helpers |
| `mesh_builder.hpp` | Factory meshes: triangle, tetrahedron, quad strip, fan, spherical tetrahedron, octahedron face |
| `discrete_elliptic_utility.hpp` | Discrete elliptic integrals |
@@ -112,7 +115,9 @@ code/
│ ├── hyper_ideal_geometry.hpp # ζ, lᵢⱼ, αᵢⱼ — pure math
│ ├── hyper_ideal_functional.hpp # HyperIdealFunctional on ConformalMesh
│ ├── spherical_geometry.hpp # spherical arc length + angles
│ ├── spherical_functional.hpp # SphericalFunctional on ConformalMesh
│ ├── spherical_functional.hpp # SphericalFunctional + gauge-fix on ConformalMesh
│ ├── euclidean_geometry.hpp # Euclidean corner-angle formula (t-value)
│ ├── euclidean_functional.hpp # EuclideanCyclicFunctional on ConformalMesh
│ ├── clausen.hpp # Clausen / Lobachevsky / ImLi₂
│ └── hyper_ideal_utility.hpp # Tetrahedron volumes
├── src/
@@ -125,7 +130,8 @@ code/
│ ├── CMakeLists.txt
│ ├── test_conformal_mesh.cpp # 14 mesh infrastructure tests
│ ├── test_hyper_ideal_functional.cpp # 6 hyper-ideal gradient checks
── test_spherical_functional.cpp # 8 spherical gradient checks
── test_spherical_functional.cpp # 11 spherical gradient + gauge-fix checks
│ └── test_euclidean_functional.cpp # 11 Euclidean gradient checks
└── deps/
├── tarballs/ # bundled dependency archives
├── eigen-3.4.0/ # header-only linear algebra (always extracted)
@@ -159,7 +165,8 @@ CGAL `Surface_mesh` tests (test prefix `cgal.`):
| `ConformalMeshProperties` | 5 | Property maps: λ, θ, idx, α, geometry type |
| `ConformalMeshValidity` | 1 | CGAL validity check for all factory meshes |
| `HyperIdealFunctional` | 6 | Finite-difference gradient checks on triangle, tetrahedron, quad strip, fan |
| `SphericalFunctional` | 8 | Angle formula correctness + gradient checks on spherical meshes |
| `SphericalFunctional` | 11 | Angle formula + gradient checks on spherical meshes + 3 gauge-fix tests |
| `EuclideanFunctional` | 11 | Angle formula + gradient checks on Euclidean meshes (triangle, quad strip, fan, tetrahedron) |
---
@@ -200,19 +207,15 @@ bereiten Phase 4 (Solver) vor. Die Zeitangaben sind grobe Schätzungen.
---
```
Phase 3d EuclideanCyclicFunctional portieren (23 Tage)
Wichtigster fehlender Baustein: Euklidische Uniformisierung
(genus-0 Flachparameterisierung, Kotangenten-Laplace)
Energie + Gradient auf ConformalMesh
→ Entsperrt die verbleibenden HDS-blockierten Tests
→ Voraussetzung für jeden end-to-end Optimiererlauf
Phase 3d EuclideanCyclicFunctional portieren ✅ abgeschlossen
euclidean_geometry.hpp: t-Wert / atan2 Winkelformel
→ euclidean_functional.hpp: Energie + Gradient auf ConformalMesh
11 Tests: Winkelformel, Gradient-Checks, NaN-Test, Fan, Mixed-Pinned
Phase 3e Gauge-Fix für SphericalFunctional (1 Tag)
Java-Äquivalent: maximizeInNegativeDirection() vor jeder
Auswertung — 1D-Liniensuche (Brent) entlang der
globalen Additionskonstante in u_v
→ Ohne Gauge-Fix ist die Energie auf geschlossenen Flächen
nach unten unbeschränkt; kein Optimierer kann konvergieren
Phase 3e Gauge-Fix für SphericalFunctional ✅ abgeschlossen
spherical_gauge_shift() + apply_spherical_gauge() in
spherical_functional.hpp — Newton + Backtracking
→ 3 neue Tests: ZerosSumGv, ApplyInPlace, AlreadyAtGauge
Phase 3f Hessian (Sphärisch → Euklidisch) (23 Tage)
→ Analytischer Hessian = Kotangenten-Laplace-Operator