SuperDex Physics C++ API
Loading...
Searching...
No Matches
nonlinear_solver_params.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19// PLEASE DO NOT ADD OTHER INCLUDES HERE. This header is included in the mochi_physics public API.
23
24#include <limits>
25
26namespace superdex {
27/** @brief Convergence status of the non-linear solver. */
28enum struct ConvergenceStatus {
29 // WARNING: Values are ordered by severity: None < Converged < Stopped < Diverged. This ordering
30 // enables worst-status accumulation via Max.
31
32 /** @brief Convergence status has not been set. */
34
35 /** @brief Solver converged to the requested tolerance. */
37
38 /**
39 * @brief Solver met at least one stopping criterion without converging to the requested
40 * tolerance.
41 */
43
44 /** @brief Solver diverged. Some form of solution reset may have been used. */
46
47 /** @brief Number of convergence status enum values. */
49};
50static_assert(
51 static_cast<int>(ConvergenceStatus::Count) == 4 &&
55 "ConvergenceStatus must be ordered by severity.");
56} // namespace superdex
57
60MOCHI_ENUM_ITEM(Converged)
61MOCHI_ENUM_ITEM(Stopped)
62MOCHI_ENUM_ITEM(Diverged)
65
66namespace superdex {
67/** @brief Positive Semi-Definite (PSD) projection modes for the dresidual matrix. */
68// clang-format off
70 Never, ///< Never project to PSD.
71 Always, ///< Always project to PSD.
72 IfFailRetry, ///< If one non-linear iteration fails, retry the iteration projecting to PSD.
73 IfFailAlways, ///< If one non-linear iteration fails, retry the iteration projecting to PSD and continue projecting in all the remaining iterations of the solve.
74 Count, ///< Number of PSD projection mode enum values.
75 Default = Always ///< Default PSD projection mode.
76};
77// clang-format on
78} // namespace superdex
79
81MOCHI_ENUM_ITEM(Never)
82MOCHI_ENUM_ITEM(Always)
83MOCHI_ENUM_ITEM(IfFailRetry)
84MOCHI_ENUM_ITEM(IfFailAlways)
87
88namespace superdex {
89/** @brief Non-linear solver types. */
91 /** @brief Newton's method. */
93
94 /**
95 * @brief Broyden-Fletcher-Goldfarb-Shanno (BFGS) method.
96 *
97 * @note The initial approximation of the dresidual is the actual dresidual (i.e., the first
98 * iteration matches Newton's method).
99 * @note The algorithm is restarted with the actual dresidual every @ref
100 * NonLinearSolverParams::dResidualAssemblyPeriod iterations, or immediately if the line search
101 * fails to improve the figure of merit it monitors or the linear solver fails to converge.
102 *
103 * @see NonLinearSolverParams::dResidualAssemblyPeriod
104 */
106
107 /**
108 * @brief Symmetric Rank-One (SR1) method.
109 *
110 * @note The initial approximation of the dresidual is the actual dresidual (i.e., the first
111 * iteration matches Newton's method).
112 * @note The algorithm is restarted with the actual dresidual every @ref
113 * NonLinearSolverParams::dResidualAssemblyPeriod iterations, or immediately if the line search
114 * fails to improve the figure of merit it monitors or the linear solver fails to converge.
115 *
116 * @see NonLinearSolverParams::dResidualAssemblyPeriod
117 */
119
120 /** @brief Number of non-linear solver type enum values. */
122
123 /** @brief Default non-linear solver type. */
125};
126} // namespace superdex
127
129MOCHI_ENUM_ITEM(Newton)
130MOCHI_ENUM_ITEM(BFGS)
132MOCHI_ENUM_COUNT(Count)
134
135namespace superdex {
136/** @brief Line search methods for the non-linear solver. */
137enum struct LineSearchType {
138 /** @brief No line search. May substantially degrade stability. */
140
141 /**
142 * @brief Simple line search. Accepts a step if the objective function does not increase by more
143 * than a specified relative tolerance.
144 *
145 * @see NonLinearSolverParams::lineSearchMaxRelIncrease. */
147
148 /**
149 * @brief Line search with Armijo condition.
150 *
151 * @see NonLinearSolverParams::lineSearchWolfe1
152 */
154
155 /**
156 * @brief Line search with weak Wolfe conditions.
157 *
158 * @see NonLinearSolverParams::lineSearchWolfe1, NonLinearSolverParams::lineSearchWolfe2
159 */
161
162 /**
163 * @brief Line search with strong Wolfe conditions.
164 *
165 * @see NonLinearSolverParams::lineSearchWolfe1, NonLinearSolverParams::lineSearchWolfe2
166 */
168
169 /**
170 * @brief Line search with residual norm condition. Accepts a step if the residual norm decreases.
171 *
172 * @note More robust than objective-based line searches (@ref LineSearchType::Simple, @ref
173 * LineSearchType::Armijo, @ref LineSearchType::WolfeWeak, @ref LineSearchType::WolfeStrong) but
174 * may degrade non-linear solver convergence in non-convex problems. In highly non-convex regions
175 * where the residual norm cannot be reduced, it may cause objects to move at slower velocity than
176 * they should due to the inability to take valid steps. Consider using an objective-based line
177 * search in that case.
178 */
180
181 /**
182 * @brief Line search that accepts either the Armijo or the residual norm condition.
183 *
184 * @note It combines the robustness of objective-based criteria when the iteration is far from the
185 * solution, with residual-based criteria when it is near the solution (particularly useful with
186 * single precision). It requires slightly higher cost per line-search iteration.
187 */
189
190 /** @brief Number of line search type enum values. */
192
193 /** @brief Default line search type. */
195};
196} // namespace superdex
197
199MOCHI_ENUM_ITEM(None)
200MOCHI_ENUM_ITEM(Simple)
201MOCHI_ENUM_ITEM(Armijo)
202MOCHI_ENUM_ITEM(WolfeWeak)
203MOCHI_ENUM_ITEM(WolfeStrong)
204MOCHI_ENUM_ITEM(ResidualNorm)
205MOCHI_ENUM_ITEM(ArmijoOrResidualNorm)
206MOCHI_ENUM_COUNT(Count)
208
209namespace superdex {
210/** @brief Strategies to select the relative tolerance of the linear solver (aka forcing term). */
212 /** @brief Constant relative tolerance. */
214
215 /**
216 * @brief Eisenstat-Walker strategy no. 1.
217 *
218 * @note Should be used with @ref LinearSolverConvergenceNorm::ResidualL2. Other norms may yield
219 * suboptimal forcing terms.
220 * @note Not recommended for use with quasi-Newton methods (e.g., @ref NonLinearSolverType::BFGS,
221 * @ref NonLinearSolverType::SR1).
222 *
223 * @see [Choosing the Forcing Terms in an Inexact Newton Method, Choice 1 (Eisenstat and Walker,
224 * 1994)](https://softlib.rice.edu/pub/CRPC-TRs/reports/CRPC-TR94463.pdf)
225 */
227
228 /**
229 * @brief Eisenstat-Walker strategy no. 2.
230 *
231 * @note Not recommended for use with quasi-Newton methods (e.g., @ref NonLinearSolverType::BFGS,
232 * @ref NonLinearSolverType::SR1).
233 *
234 * @see [Choosing the Forcing Terms in an Inexact Newton Method, Choice 2 (Eisenstat and Walker,
235 * 1994)](https://softlib.rice.edu/pub/CRPC-TRs/reports/CRPC-TR94463.pdf)
236 */
238
239 /**
240 * @brief Custom Eisenstat-Walker strategy: eta = max(min(1/(2+k), sqrt(|r|)), eta_0), where `k`
241 * is the non-linear iteration number, `|r|` is the L2-norm of the nonlinear residual, and
242 * `eta_0` is @ref LinearSolverParams::relTol.
243 *
244 * @note Should be used with @ref LinearSolverConvergenceNorm::ResidualL2. Other norms may yield
245 * suboptimal forcing terms.
246 * @note Not recommended for use with quasi-Newton methods (e.g., @ref NonLinearSolverType::BFGS,
247 * @ref NonLinearSolverType::SR1).
248 */
250
251 /** @brief Number of linear tolerance strategy enum values. */
253
254 /** @brief Default linear tolerance strategy. */
256};
257} // namespace superdex
258
260MOCHI_ENUM_ITEM(Constant)
261MOCHI_ENUM_ITEM(EisenstatWalker1)
262MOCHI_ENUM_ITEM(EisenstatWalker2)
263MOCHI_ENUM_ITEM(EisenstatWalker3)
264MOCHI_ENUM_COUNT(Count)
266
267namespace superdex {
268/**
269 * @brief Convergence monitoring mode for the non-linear solver residual.
270 *
271 * @note Convergence is evaluated per simulation island, not scene-wide. Each island is solved
272 * independently, and the selected mode determines how convergence is assessed within that island.
273 * @note The norm used to monitor divergence via @ref NonLinearSolverParams::absDivTol and @ref
274 * NonLinearSolverParams::relDivTol is always the L2 norm, irrespective of this setting.
275 * @note The norm used to monitor stagnation via @ref NonLinearSolverParams::relStepTol is always
276 * the L2 norm, irrespective of this setting.
277 *
278 * @see NonLinearSolverParams::absTol, NonLinearSolverParams::relTol
279 */
281 /**
282 * @brief Use global, unweighted residual norm for convergence checks within each simulation
283 * island.
284 *
285 * @details Convergence is determined by the global residual norm within each simulation island:
286 * |r| <= absTol or |r| <= relTol * |r0|
287 */
289
290 /**
291 * @brief Use per-actor weighted residual norms for convergence checks.
292 *
293 * @details Each actor uses a per-actor weighted L2 norm |r_a|_W = sqrt(Σᵢ wᵢ·rᵢ²), where
294 * weights normalize force/torque residuals by characteristic force/torque. All actors must
295 * satisfy their individual criteria: |r_a|_W <= absTol or |r_a|_W <= relTol * |r0_a|_W
296 *
297 * @note Weights are derived from inertia properties. Actors with zero inertia receive uniform
298 * weights, which provide no physical normalization. For quasi-static problems, @ref
299 * NonLinearSolverConvergenceMode::Global mode is recommended.
300 */
302
303 /** @brief Number of convergence monitoring mode enum values. */
305
306 /** @brief Default convergence monitoring mode. */
308};
309} // namespace superdex
310
312MOCHI_ENUM_ITEM(Global)
313MOCHI_ENUM_ITEM(PerActorWeighted)
314MOCHI_ENUM_COUNT(Count)
316
317namespace superdex {
318/**
319 * @brief Default tolerance for the L2 norm of the non-linear solver's raw linear-solve increment.
320 * Avoids attempting to solve beyond the floating-point noise floor.
321 *
322 * @see NonLinearSolverParams::relStepTol.
323 */
324constexpr real kDefaultRelStepTol = 10_r * std::numeric_limits<real>::epsilon();
325
326/** @brief Parameters for the non-linear solver. */
328 /** @brief Non-linear solver type. */
330
331 /**
332 * @brief Every how many non-linear iterations to assemble the dresidual matrix.
333 *
334 * @note For Newton's method, set to >1 to reuse the dresidual across iterations.
335 * @note For quasi-Newton methods (e.g., BFGS, SR1), it must be >1 and indicates every how many
336 * iterations to restart the algorithm with the actual dresidual.
337 */
339
340 // Stopping criteria. The solver terminates when any of the criteria is satisfied.
341
342 /** @brief Maximum number of non-linear iterations. */
343 int maxIter = 4;
344
345 /**
346 * @brief Maximum elapsed time [s].
347 *
348 * @note The solve terminates if the elapsed time exceeds this threshold.
349 * @note 0 means no time limit.
350 */
352
353 /**
354 * @brief Convergence monitoring mode.
355 *
356 * @note Applies to @ref absTol and @ref relTol.
357 */
359
360 /** @brief Absolute residual norm tolerance for convergence. */
361 real absTol = 1e-3_r;
362
363 /** @brief Relative residual norm tolerance for convergence, relative to the initial residual. */
364 real relTol = 1e-6_r;
365
366 /**
367 * @brief Relative tolerance on the L2 norm of the raw linear-solve increment before line search
368 * scaling.
369 *
370 * @note The solve terminates with @ref ConvergenceStatus::Stopped status if |dx|/|x| is below
371 * this threshold (i.e., the step norm is below this fraction of the current solution norm).
372 * @note 0 disables this criterion.
373 * @note Default is @ref kDefaultRelStepTol.
374 */
376
377 /** @brief Stop the solve if the line search figure of merit does not improve from the previous
378 * iteration. */
380
381 // Retries and fallbacks
382
383 /** @brief Positive Semi-Definite (PSD) projection mode for the dresidual matrix. */
385
386 /** @brief Fall back to gradient descent direction if the solver search direction fails. */
388
389 // Explosion control
390
391 /** @brief Enable heuristic explosion prevention. */
392 bool explosionControl = true;
393
394 /**
395 * @brief Absolute divergence tolerance.
396 *
397 * @note Triggers explosion control if residual norm exceeds this value.
398 * @note Used only if @ref explosionControl is true.
399 */
401
402 /**
403 * @brief Relative divergence tolerance, relative to the initial residual.
404 *
405 * @note Triggers explosion control if relative residual norm exceeds this value.
406 * @note Used only if @ref explosionControl is true.
407 */
409
410 // Line search
411
412 /**
413 * @brief Maximum number of line search iterations.
414 *
415 * @note Must be >= 1 unless @ref lineSearchType is @ref LineSearchType::None.
416 */
418
419 /**
420 * @brief Step length reduction factor for line search.
421 *
422 * @note Must be in (0, 1).
423 */
425
426 /**
427 * @brief Wolfe condition parameter c1 (sufficient decrease).
428 *
429 * @note Must be in (0, 1).
430 * @note Used only by @ref LineSearchType::Armijo, @ref LineSearchType::WolfeWeak, @ref
431 * LineSearchType::WolfeStrong, and @ref LineSearchType::ArmijoOrResidualNorm line search types.
432 */
434
435 /**
436 * @brief Wolfe condition parameter c2 (curvature).
437 *
438 * @note Must be in (@ref lineSearchWolfe1, 1).
439 * @note Used only by @ref LineSearchType::WolfeWeak and @ref LineSearchType::WolfeStrong line
440 * search types.
441 */
443
444 /**
445 * @brief Maximum relative increase in the objective to accept the step.
446 *
447 * @note Only applies to @ref LineSearchType::Simple.
448 */
450
451 /** @brief Line search type. */
453
454 // Linear tolerance strategy
455
456 /** @brief Strategy for adaptive linear solver tolerance (forcing term). */
458
459 // Other
460
461 /** @brief Verbosity level for logging output. */
463
464#if MOCHI_LANGUAGE_CPP20
465 bool operator==(NonLinearSolverParams const&) const = default;
466#endif
467
492};
493
494} // namespace superdex
LinearToleranceStrategy
Strategies to select the relative tolerance of the linear solver (aka forcing term).
@ EisenstatWalker2
Eisenstat-Walker strategy no.
@ EisenstatWalker1
Eisenstat-Walker strategy no.
@ Default
Default linear tolerance strategy.
@ EisenstatWalker3
Custom Eisenstat-Walker strategy: eta = max(min(1/(2+k), sqrt(|r|)), eta_0), where k is the non-linea...
@ Constant
Constant relative tolerance.
VerbosityLevel
Verbosity levels for solvers and optimizers.
@ Warning
Errors and warnings.
ConvergenceStatus
Convergence status of the non-linear solver.
@ None
Convergence status has not been set.
@ Stopped
Solver met at least one stopping criterion without converging to the requested tolerance.
@ Converged
Solver converged to the requested tolerance.
@ Count
Number of convergence status enum values.
NonLinearSolverType
Non-linear solver types.
@ BFGS
Broyden-Fletcher-Goldfarb-Shanno (BFGS) method.
@ SR1
Symmetric Rank-One (SR1) method.
@ Default
Default non-linear solver type.
LineSearchType
Line search methods for the non-linear solver.
@ ArmijoOrResidualNorm
Line search that accepts either the Armijo or the residual norm condition.
@ WolfeStrong
Line search with strong Wolfe conditions.
@ ResidualNorm
Line search with residual norm condition.
@ Default
Default line search type.
@ Armijo
Line search with Armijo condition.
@ WolfeWeak
Line search with weak Wolfe conditions.
PsdProjectionMode
Positive Semi-Definite (PSD) projection modes for the dresidual matrix.
@ IfFailAlways
If one non-linear iteration fails, retry the iteration projecting to PSD and continue projecting in a...
@ IfFailRetry
If one non-linear iteration fails, retry the iteration projecting to PSD.
@ Default
Default PSD projection mode.
constexpr real kDefaultRelStepTol
Default tolerance for the L2 norm of the non-linear solver's raw linear-solve increment.
@ None
Invalid actor type.
Definition mochi_enums.h:26
@ Count
Number of actor type enum values.
Definition mochi_enums.h:38
NonLinearSolverConvergenceMode
Convergence monitoring mode for the non-linear solver residual.
@ PerActorWeighted
Use per-actor weighted residual norms for convergence checks.
@ Global
Use global, unweighted residual norm for convergence checks within each simulation island.
@ Default
Default convergence monitoring mode.
#define MOCHI_ENUM_COUNT(name)
Definition reflection.h:275
#define MOCHI_ENUM_END()
Definition reflection.h:276
#define MOCHI_STRUCT_END()
Definition reflection.h:279
#define MOCHI_ENUM_BEGIN(name)
Definition reflection.h:273
#define MOCHI_FIELD(name)
Definition reflection.h:293
#define MOCHI_STRUCT_BEGIN(name)
Definition reflection.h:278
#define MOCHI_ENUM_ITEM(name)
Definition reflection.h:274
Parameters for the non-linear solver.
real lineSearchMaxRelIncrease
Maximum relative increase in the objective to accept the step.
real lineSearchWolfe1
Wolfe condition parameter c1 (sufficient decrease).
bool operator==(NonLinearSolverParams const &) const =default
bool explosionControl
Enable heuristic explosion prevention.
real relDivTol
Relative divergence tolerance, relative to the initial residual.
double maxElapsedTimeSeconds
Maximum elapsed time [s].
real lineSearchWolfe2
Wolfe condition parameter c2 (curvature).
VerbosityLevel verbosity
Verbosity level for logging output.
PsdProjectionMode psdProjMode
Positive Semi-Definite (PSD) projection mode for the dresidual matrix.
real relTol
Relative residual norm tolerance for convergence, relative to the initial residual.
real absTol
Absolute residual norm tolerance for convergence.
NonLinearSolverType solverType
Non-linear solver type.
bool stopIfNoImprovement
Stop the solve if the line search figure of merit does not improve from the previous iteration.
real relStepTol
Relative tolerance on the L2 norm of the raw linear-solve increment before line search scaling.
real absDivTol
Absolute divergence tolerance.
NonLinearSolverConvergenceMode convergenceMode
Convergence monitoring mode.
real lineSearchAlpha
Step length reduction factor for line search.
bool gradientDescentFallback
Fall back to gradient descent direction if the solver search direction fails.
LinearToleranceStrategy linearToleranceStrategy
Strategy for adaptive linear solver tolerance (forcing term).
LineSearchType lineSearchType
Line search type.
int maxIter
Maximum number of non-linear iterations.
int lineSearchMaxIter
Maximum number of line search iterations.
int dResidualAssemblyPeriod
Every how many non-linear iterations to assemble the dresidual matrix.