Source code for openmdao.solvers.backtracking

""" Line search using backtracking."""

from openmdao.solvers.solver_base import LineSearch
from openmdao.util.record_util import update_local_meta, create_local_meta


[docs]class BackTracking(LineSearch): """A line search subsolver using backtracking. Options ------- options['iprint'] : int(0) Set to 0 to disable printing, set to 1 to print the residual to stdout each iteration, set to 2 to print subiteration residuals as well. options['atol'] : float(1e-10) Absolute convergence tolerancee for line search. options['maxiter'] : int(10) Maximum number of line searches. options['rtol'] : float(0.9) Relative convergence tolerancee for line search. options['solve_subsystems'] : bool(True) Set to True to solve subsystems. You may need this for solvers nested under Newton. """ def __init__(self): super(BackTracking, self).__init__() opt = self.options opt.add_option('atol', 1e-10, lower=0.0, desc='Absolute convergence tolerancee for line search.') opt.add_option('rtol', 0.9, lower=0.0, desc='Relative convergence tolerancee for line search.') opt.add_option('maxiter', 10, lower=0, desc='Maximum number of line searches.') opt.add_option('solve_subsystems', True, desc='Set to True to solve subsystems. You may need this for solvers nested under Newton.')
[docs] def solve(self, params, unknowns, resids, system, solver, alpha, fnorm, fnorm0, metadata=None): """ Take the gradient calculated by the parent solver and figure out how far to go. Args ---- params : `VecWrapper` `VecWrapper` containing parameters. (p) unknowns : `VecWrapper` `VecWrapper` containing outputs and states. (u) resids : `VecWrapper` `VecWrapper` containing residuals. (r) system : `System` Parent `System` object. metadata : dict, optional Dictionary containing execution metadata (e.g. iteration coordinate). solver : `Solver` Parent solver instance. alpha : float Initial over-relaxation factor as used in parent solver. fnorm : float Initial norm of the residual for absolute tolerance check. fnorm0 : float Initial norm of the residual for relative tolerance check. """ atol = self.options['atol'] rtol = self.options['rtol'] maxiter = self.options['maxiter'] result = system.dumat[None] local_meta = create_local_meta(metadata, system.pathname) itercount = 0 ls_alpha = alpha # Backtracking Line Search while itercount < maxiter and \ fnorm > atol and \ fnorm/fnorm0 > rtol: ls_alpha *= 0.5 unknowns.vec -= ls_alpha*result.vec itercount += 1 # Metadata update update_local_meta(local_meta, (solver.iter_count, itercount)) # Just evaluate the model with the new points if self.options['solve_subsystems'] is True: system.children_solve_nonlinear(local_meta) system.apply_nonlinear(params, unknowns, resids, local_meta) solver.recorders.record_iteration(system, local_meta) fnorm = resids.norm() if self.options['iprint'] > 0: self.print_norm('BK_TKG', system.pathname, itercount, fnorm, fnorm0, indent=1, solver='LS')