11#include " geometrycentral/surface/vector_heat_method.h"
2+ #include " geometrycentral/numerical/linear_algebra_utilities.h"
23#include " geometrycentral/utilities/vector2.h"
34
45namespace geometrycentral {
@@ -55,7 +56,9 @@ void VectorHeatMethodSolver::ensureHaveVectorHeatSolver() {
5556 // PositiveDefiniteSolver. Otherwise, we must use a SquareSolver
5657 geom.requireEdgeCotanWeights ();
5758 bool isDelaunay = true ;
59+ double minCotanWeight = std::numeric_limits<double >::max ();
5860 for (Edge e : mesh.edges ()) {
61+ minCotanWeight = std::min (minCotanWeight, geom.edgeCotanWeights [e]);
5962 if (geom.edgeCotanWeights [e] < -1e-6 ) {
6063 isDelaunay = false ;
6164 break ;
@@ -64,7 +67,14 @@ void VectorHeatMethodSolver::ensureHaveVectorHeatSolver() {
6467 geom.unrequireEdgeCotanWeights ();
6568
6669 if (isDelaunay) {
67- vectorHeatSolver.reset (new PositiveDefiniteSolver<std::complex <double >>(vectorOp));
70+ // TODO we said the matrix should be SPD if Delaunay, but SuiteSparse is failing with non-SPD error
71+ // (observed by nsharp on intrinsic delaunay RamSkull100k.obj)
72+ // workaround with a try-catch for now
73+ try {
74+ vectorHeatSolver.reset (new PositiveDefiniteSolver<std::complex <double >>(vectorOp));
75+ } catch (const std::runtime_error&) {
76+ vectorHeatSolver.reset (new SquareSolver<std::complex <double >>(vectorOp));
77+ }
6878 } else {
6979 vectorHeatSolver.reset (new SquareSolver<std::complex <double >>(vectorOp)); // not necessarily SPD without Delaunay
7080 }
0 commit comments