99
1010@define (kw_only = True )
1111class SLCSolverOptionsConfig (BaseConfig ):
12+ """Configuration for the nonlinear solver used by the system-level controller.
13+
14+ Controls which OpenMDAO nonlinear solver is applied to the plant group and
15+ how it converges. The ``convergence_tolerance`` sets both ``atol`` and ``rtol``
16+ by default; either can be overridden individually.
17+
18+ Attributes:
19+ solver_name: Solver type. One of ``"gauss_seidel"``, ``"newton"``, or
20+ ``"block_jacobi"``.
21+ max_iter: Maximum number of nonlinear iterations.
22+ atol: Absolute convergence tolerance. Defaults to ``convergence_tolerance``.
23+ rtol: Relative convergence tolerance. Defaults to ``convergence_tolerance``.
24+ convergence_tolerance: Convenience value used to set both ``atol`` and ``rtol``
25+ when they are not specified individually.
26+ iprint: Solver print level (0 = silent, 2 = verbose).
27+ solver_option_kwargs: Additional keyword arguments passed directly to the
28+ solver's ``options`` dict.
29+ """
30+
1231 solver_name : str = field (
1332 default = "gauss_seidel" , validator = contains (["gauss_seidel" , "newton" , "block_jacobi" ])
1433 )
@@ -19,20 +38,31 @@ class SLCSolverOptionsConfig(BaseConfig):
1938 iprint : int = field (default = 2 )
2039 solver_option_kwargs : dict = field (default = {})
2140
41+ # Maps user-facing solver names to OpenMDAO solver classes
2242 solver_map : ClassVar = {
2343 "gauss_seidel" : om .NonlinearBlockGS ,
2444 "newton" : om .NewtonSolver ,
2545 "block_jacobi" : om .NonlinearBlockJac ,
2646 }
2747
2848 def __attrs_post_init__ (self ):
49+ # Default atol/rtol to the shared convergence_tolerance if not set
2950 if self .atol is None :
3051 self .atol = self .convergence_tolerance
3152 if self .rtol is None :
3253 self .rtol = self .convergence_tolerance
3354
3455 def get_solver_options (self ):
56+ """Build the options dict to apply to the nonlinear solver.
57+
58+ Merges config attributes with any extra ``solver_option_kwargs`` and
59+ renames ``max_iter`` to ``maxiter`` (the OpenMDAO option name).
60+
61+ Returns:
62+ dict: Keyword arguments suitable for ``solver.options[k] = v``.
63+ """
3564 d = self .as_dict ()
65+ # These attrs configure *which* solver or are handled separately
3666 non_solver_option_attrs = [
3767 "solver_name" ,
3868 "solver_map" ,
@@ -41,10 +71,12 @@ def get_solver_options(self):
4171 "max_iter" ,
4272 ]
4373 solver_options = {k : v for k , v in d .items () if k not in non_solver_option_attrs }
74+ # Merge extra kwargs and translate max_iter → maxiter for OpenMDAO
4475 solver_options_full = (
4576 solver_options | self .solver_option_kwargs | {"maxiter" : self .max_iter }
4677 )
4778 return solver_options_full
4879
4980 def return_nonlinear_solver (self ):
81+ """Return the OpenMDAO nonlinear solver class for ``solver_name``."""
5082 return self .solver_map [self .solver_name ]
0 commit comments