Repository navigation
Conversation
Kaiyao-Ge
force-pushed
the
nonsmooth-newton
branch
from
October 25, 2026 18:20
c835d82 to
c6c8281
Compare
Near convergence the true decrease of a path falls below what the energy can resolve, so the acceptance test can no longer verify it. Two options (spec and Options): - handoff (off | first | any, default any): after an outer iteration whose inner loop stopped at the noise floor or whose path is below the resolution (first: only if no inner step was accepted before), and when the gradient norm is below line_search/use_grad_norm_tol, the rest of the solve is left to the Newton chain. A declined direction is not counted as a failure. Counters handoff_noise_floor, handoff_grad_norm and handoff_iterations in the solver info. - resolution (default true): 32 eps |E| counts in the inner noise floor, and a path whose model decrease does not exceed it is not verified by the true energy (the Newton step is line searched instead). Tests: option parsing; the log-barrier problem with and without the handoff; fewer retractions and true energy evaluations with the resolution on an energy with a large constant.
Kaiyao-Ge
added a commit
to Kaiyao-Ge/polyfem
that referenced
this pull request
Oct 30, 2026
Pin polysolve to f39cb83 (polyfem/polysolve#123): NonsmoothNewton hands the rest of a solve to the Newton chain once the true energy no longer verifies the path (handoff "any" and the energy resolution by default). The five-cubes test now checks that Newton chain iterations of a reduced solve only follow a handoff or a failed direction, instead of requiring that the chain is never used.
NonsmoothNewton needs an LLT that reports indefinite matrices, which so far meant Eigen::CholmodSupernodalLLT only, so builds without CHOLMOD could not run the strategy at all. Eigen's SimplicialLLT reports a non-positive pivot as NumericalIssue, which EigenDirect turns into the same runtime_error the strategy already catches. Add it as a linear solver (factory, available_solvers, spec) and let NonsmoothNewton accept it. The log-term test now runs in every build, with CHOLMOD when available and SimplicialLLT otherwise, and also checks a solve with SimplicialLLT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NonsmoothNewton descent strategy
Adds
NonsmoothNewton, a Newton variant for objectives that split as f = s + n, with s smooth and n a stiff nonsmooth term such as a contact barrier.When the current iterate has active nonsmooth terms, the strategy minimizes a reduced model: a frozen quadratic of s plus the exact n. It does this with Levenberg–Marquardt steps in a growing subspace. Every segment of the resulting path is certified with
max_step_size. The end point, or a retraction along the path, is accepted by its true decrease. On other iterates the Newton direction is line searched as usual. If the strategy fails, the solver falls back to the existing Newton chain.Near convergence the true decrease of a step falls below what the energy can resolve in floating point, so the acceptance test can no longer verify the path. From then on the strategy hands the rest of the solve to the Newton chain, whose line search compares gradient norms instead of energies once the gradient is small (
line_search/use_grad_norm_tol). On a pin-cushion contact scene (steps 11–20), the handoff and the energy resolution cut the solve time from 205 s to 131 s.Changes
Problem: optional nonsmooth-split callbacks (has_nonsmooth_term,smooth_*,nonsmooth_*,metric_diagonal) andHessianBlock. The defaults report that the problem has no split, so existing problems are unaffected.DescentStrategy::take_step: a hook that lets a strategy return a step it has already verified.Solver::minimizethen appliesx += stepand skips the line search. The default returns false, so behaviour is unchanged for all existing strategies.Solver::minimizeevaluated the objective at the start point twice (once only for a debug message). It now evaluates it once.Solver::create("NonsmoothNewton"): builds the chain NonsmoothNewton → Newton chain (Newton::create_solver(true, ...)) → GD.nonlinear-solver-spec.json: theNonsmoothNewtonoptions (max_inner,relative_stop,fraction_to_boundary,rho_min,max_columns,handoff,resolution,guard/*) and internaldebug/*switches.handoff(off/first/any, defaultany): hand the solve to the Newton chain after an outer iteration whose inner loop stopped at the noise floor of the energy, or whose path is below the energy resolution (first: only if no inner step was accepted before). Except foroff, also when the gradient norm is belowline_search/use_grad_norm_tol.resolution(default true): count 32 eps |E| as the resolution of the true energy E, in the inner noise floor and in the acceptance. A path whose model decrease does not exceed it is not verified by the true energy; the Newton step is line searched instead.Eigen::SimplicialLLT(Eigen's simplicial Cholesky; in the factory,available_solversandlinear-solver-spec.json). LikeEigen::CholmodSupernodalLLT, it reports a non-positive pivot, soNonsmoothNewtonalso runs in builds without CHOLMOD.tests/test_nonsmooth_newton.cpp. They cover option parsing, a log-barrier problem (with and without the handoff, and the resolution on an energy with a large constant), and the no-split case, where the result is bitwise equal toNewton. The log-barrier test usesEigen::CholmodSupernodalLLTwhen CHOLMOD is available andEigen::SimplicialLLTotherwise, and also checks a solve withEigen::SimplicialLLT.When the problem provides the split, the linear solver must be an LLT that reports indefinite matrices:
Eigen::CholmodSupernodalLLTorEigen::SimplicialLLT. This is checked on first use.