From f9b33d524774ac53a7b92363b0efe77000c332b4 Mon Sep 17 00:00:00 2001 From: sdast9 Date: Fri, 11 Jul 2025 17:16:43 -0400 Subject: [PATCH] for new experimental branch --- src/polysolve/nonlinear/Solver.cpp | 6 +++++ src/polysolve/nonlinear/Solver.hpp | 8 +++++-- .../nonlinear/line_search/LineSearch.cpp | 23 +++++++++++++++---- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/polysolve/nonlinear/Solver.cpp b/src/polysolve/nonlinear/Solver.cpp index 1b98faa1..1977f190 100644 --- a/src/polysolve/nonlinear/Solver.cpp +++ b/src/polysolve/nonlinear/Solver.cpp @@ -481,6 +481,12 @@ namespace polysolve::nonlinear m_current.fDeltaCount = (m_current.fDelta < m_stop.fDelta) ? (m_current.fDeltaCount + 1) : 0; + if (m_iteration_callback && m_iteration_callback(m_current)) + { + m_status = Status::ObjectiveCustomStop; + m_logger.debug("[{}][{}] Iteration callback decided to stop", descent_strategy_name(), m_line_search->name()); + } + m_logger.debug( "[{}][{}] {} (stopping criteria: {})", descent_strategy_name(), m_line_search->name(), m_current.print_message(), m_stop.print_message()); diff --git a/src/polysolve/nonlinear/Solver.hpp b/src/polysolve/nonlinear/Solver.hpp index 211ea981..17be2e16 100644 --- a/src/polysolve/nonlinear/Solver.hpp +++ b/src/polysolve/nonlinear/Solver.hpp @@ -79,6 +79,8 @@ namespace polysolve::nonlinear void set_line_search(const json ¶ms); const json &info() const { return solver_info; } + void set_iteration_callback(std::function callback) { m_iteration_callback = callback; } + /// @brief If true the solver will not throw an error if the maximum number of iterations is reached bool allow_out_of_iterations = false; @@ -87,7 +89,7 @@ namespace polysolve::nonlinear const std::shared_ptr &line_search() const { return m_line_search; }; protected: - /// @brief Compute direction in which the argument should be updated + /// @brief Compute direction in which the argument should be updated /// @param objFunc Problem to be minimized /// @param x Current input (n x 1) /// @param grad Gradient at current step (n x 1) @@ -139,7 +141,7 @@ namespace polysolve::nonlinear // ==================================================================== // Solver state // ==================================================================== - + /// @brief Reset the solver at the start of a minimization /// @param ndof number of degrees of freedom void reset(const int ndof); @@ -151,6 +153,8 @@ namespace polysolve::nonlinear std::vector m_iter_per_strategy; + std::function m_iteration_callback = nullptr; + // ==================================================================== // Solver info // ==================================================================== diff --git a/src/polysolve/nonlinear/line_search/LineSearch.cpp b/src/polysolve/nonlinear/line_search/LineSearch.cpp index a9be577a..c2832edf 100644 --- a/src/polysolve/nonlinear/line_search/LineSearch.cpp +++ b/src/polysolve/nonlinear/line_search/LineSearch.cpp @@ -111,6 +111,23 @@ namespace polysolve::nonlinear::line_search } const double nan_free_step_size = step_size; + + // TODO: Fix this + const bool use_grad_norm = initial_grad.norm() < use_grad_norm_tol; + const double starting_step_size = step_size; + + // ---------------------- + // Find descent step size 1 + // ---------------------- + { + POLYSOLVE_SCOPED_STOPWATCH("energy min in LS", classical_line_search_time, m_logger); + step_size = compute_descent_step_size(x, delta_x, objFunc, use_grad_norm, initial_energy, initial_grad, step_size); + if (std::isnan(step_size)) + { + // Superclass::save_sampled_values("failed-line-search-values.csv", x, delta_x, objFunc); + return NaN; + } + } // ----------------------------- // Find collision-free step size // ----------------------------- @@ -133,12 +150,10 @@ namespace polysolve::nonlinear::line_search if (initial_grad.norm() < 1e-30) return step_size; - // TODO: Fix this - const bool use_grad_norm = initial_grad.norm() < use_grad_norm_tol; - const double starting_step_size = step_size; + // ---------------------- - // Find descent step size + // Find descent step size 2 // ---------------------- { POLYSOLVE_SCOPED_STOPWATCH("energy min in LS", classical_line_search_time, m_logger);