예제 #1
0
class FakeSolver(NonLinearSolver):
    """ Does nothing but invoke a line search."""
    def __init__(self):
        super(FakeSolver, self).__init__()
        self.sub = BackTracking()

    def solve(self, params, unknowns, resids, system, metadata=None):
        """ Calc deriv then do line search."""

        # Perform an initial run to propagate srcs to targets.
        system.children_solve_nonlinear(None)
        system.apply_nonlinear(params, unknowns, resids)

        # Linearize Model with partial derivatives
        system._sys_linearize(params, unknowns, resids, total_derivs=False)

        # Calculate direction to take step
        arg = system.drmat[None]
        result = system.dumat[None]

        # Step waaaaay to far so we have to backtrack
        arg.vec[:] = resids.vec * 100
        system.solve_linear(system.dumat, system.drmat, [None], mode='fwd')

        unknowns.vec += result.vec

        self.sub.solve(params, unknowns, resids, system, self, 1.0, 1.0, 1.0)
예제 #2
0
class FakeSolver(NonLinearSolver):
    """ Does nothing but invoke a line search."""

    def __init__(self):
        super(FakeSolver, self).__init__()
        self.sub = BackTracking()

    def solve(self, params, unknowns, resids, system, metadata=None):
        """ Calc deriv then do line search."""

        # Perform an initial run to propagate srcs to targets.
        system.children_solve_nonlinear(None)
        system.apply_nonlinear(params, unknowns, resids)

        # Linearize Model with partial derivatives
        system._sys_linearize(params, unknowns, resids, total_derivs=False)

        # Calculate direction to take step
        arg = system.drmat[None]
        result = system.dumat[None]

        # Step waaaaay to far so we have to backtrack
        arg.vec[:] = resids.vec*100
        system.solve_linear(system.dumat, system.drmat, [None], mode='fwd')

        unknowns.vec += result.vec

        self.sub.solve(params, unknowns, resids, system, self, 1.0, 1.0, 1.0)
예제 #3
0
    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol',
                       1e-12,
                       lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol',
                       1e-10,
                       lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter',
                       20,
                       lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0, desc='Initial over-relaxation factor.')
        opt.add_option(
            'solve_subsystems',
            True,
            desc=
            'Set to True to solve subsystems. You may need this for solvers nested under Newton.'
        )

        self.print_name = 'NEWTON'

        # Only one choice, but you can set this to None if you want.
        self.line_search = BackTracking()
예제 #4
0
    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol',
                       1e-12,
                       lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol',
                       1e-10,
                       lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter',
                       20,
                       lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0, desc='Initial over-relaxation factor.')
        opt.add_option(
            'solve_subsystems',
            True,
            desc=
            'Set to True to solve subsystems. You may need this for solvers nested under Newton.'
        )

        self.print_name = 'NEWTON'

        # Only one choice, but the user could write their own.
        self.line_search = BackTracking()

        # User can specify a different linear solver for Newton. Default is
        # to use the parent's solver.
        self.ln_solver = None
예제 #5
0
파일: newton.py 프로젝트: relf/OpenMDAO
    def __init__(self):
        super(Newton, self).__init__()

        # What we support
        self.supports["uses_derivatives"] = True

        opt = self.options
        opt.add_option("atol", 1e-12, lower=0.0, desc="Absolute convergence tolerance.")
        opt.add_option("rtol", 1e-10, lower=0.0, desc="Relative convergence tolerance.")
        opt.add_option("maxiter", 20, lower=0, desc="Maximum number of iterations.")
        opt.add_option("alpha", 1.0, desc="Initial over-relaxation factor.")
        opt.add_option(
            "solve_subsystems",
            True,
            desc="Set to True to solve subsystems. You may need this for solvers nested under Newton.",
        )

        self.print_name = "NEWTON"

        # Only one choice, but the user could write their own.
        self.line_search = BackTracking()

        # User can specify a different linear solver for Newton. Default is
        # to use the parent's solver.
        self.ln_solver = None
예제 #6
0
파일: newton.py 프로젝트: fzahle/OpenMDAO
    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol', 1e-12, lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol', 1e-10, lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter', 20, lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0,
                       desc='Initial over-relaxation factor.')
        opt.add_option('solve_subsystems', True,
                       desc='Set to True to solve subsystems. You may need this for solvers nested under Newton.')

        # Only one choice, but you can set this to None if you want.
        self.line_search = BackTracking()
예제 #7
0
    def test_newton_with_backtracking_analysis_error(self):

        top = Problem()
        top.root = SellarStateConnection()
        top.root.nl_solver.line_search = BackTracking()
        top.root.nl_solver.line_search.options['maxiter'] = 2
        top.root.nl_solver.line_search.options['err_on_maxiter'] = True
        top.root.nl_solver.line_search.options['c'] = 1.0
        top.root.nl_solver.options['alpha'] = 10.0

        top.setup(check=False)

        try:
            top.run()
        except AnalysisError as err:
            self.assertEqual(
                str(err),
                "Solve in '': BackTracking failed to converge after 2 iterations."
            )
        else:
            self.fail("AnalysisError expected")
예제 #8
0
    def test_newton_with_backtracking(self):

        top = Problem()
        root = top.root = Group()
        root.add('comp', TrickyComp())
        root.add('p', IndepVarComp('y', 1.2278849186466743))
        root.connect('p.y', 'comp.y')

        root.nl_solver = Newton()
        root.ln_solver = ScipyGMRES()
        root.nl_solver.line_search = BackTracking()
        root.nl_solver.line_search.options['maxiter'] = 100
        root.nl_solver.line_search.options['c'] = 0.5
        root.nl_solver.options['alpha'] = 10.0

        top.setup(check=False)
        top['comp.x'] = 1.0
        top.print_all_convergence(level=1)
        top.run()

        assert_rel_error(self, top['comp.x'], .3968459, .0001)
예제 #9
0
파일: newton.py 프로젝트: cephdon/OpenMDAO
    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol', 1e-12, lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol', 1e-10, lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter', 20, lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0,
                       desc='Initial over-relaxation factor.')
        opt.add_option('solve_subsystems', True,
                       desc='Set to True to solve subsystems. You may need this for solvers nested under Newton.')

        self.print_name = 'NEWTON'

        # Only one choice, but the user could write their own.
        self.line_search = BackTracking()

        # User can slot a linear solver into Newton. Default is to use the
        # parent's solver.
        self.ln_solver = None
예제 #10
0
 def __init__(self):
     super(FakeSolver, self).__init__()
     self.sub = BackTracking()
예제 #11
0
파일: newton.py 프로젝트: fzahle/OpenMDAO
class Newton(NonLinearSolver):
    """A python Newton solver that solves a linear system to determine the
    next direction to step. Also uses `Backtracking` as the default line
    search algorithm, but you can choose a different one by specifying
    `self.line_search`.

    Options
    -------
    options['alpha'] :  float(1.0)
        Initial over-relaxation factor.
    options['atol'] :  float(1e-12)
        Absolute convergence tolerance.
    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['maxiter'] :  int(20)
        Maximum number of iterations.
    options['rtol'] :  float(1e-10)
        Relative convergence tolerance.
    options['solve_subsystems'] :  bool(True)
        Set to True to solve subsystems. You may need this for solvers nested under Newton.
    """

    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol', 1e-12, lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol', 1e-10, lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter', 20, lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0,
                       desc='Initial over-relaxation factor.')
        opt.add_option('solve_subsystems', True,
                       desc='Set to True to solve subsystems. You may need this for solvers nested under Newton.')

        # Only one choice, but you can set this to None if you want.
        self.line_search = BackTracking()

    def solve(self, params, unknowns, resids, system, metadata=None):
        """ Solves the system using a Netwon's Method.

        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).
        """

        atol = self.options['atol']
        rtol = self.options['rtol']
        maxiter = self.options['maxiter']
        alpha = self.options['alpha']

        # Metadata setup
        self.iter_count = 0
        local_meta = create_local_meta(metadata, system.pathname)
        system.ln_solver.local_meta = local_meta
        update_local_meta(local_meta, (self.iter_count, 0))

        # Perform an initial run to propagate srcs to targets.
        system.children_solve_nonlinear(local_meta)
        system.apply_nonlinear(params, unknowns, resids)

        f_norm = resids.norm()
        f_norm0 = f_norm

        if self.options['iprint'] > 0:
            self.print_norm('NEWTON', system.pathname, 0, f_norm, f_norm0)

        arg = system.drmat[None]
        result = system.dumat[None]

        while self.iter_count < maxiter and f_norm > atol and \
                f_norm/f_norm0 > rtol:

            # Linearize Model with partial derivatives
            system._sys_linearize(params, unknowns, resids, total_derivs=False)

            # Calculate direction to take step
            arg.vec[:] = resids.vec
            system.solve_linear(system.dumat, system.drmat, [None], mode='fwd')

            unknowns.vec += alpha*result.vec

            # Metadata update
            self.iter_count += 1
            update_local_meta(local_meta, (self.iter_count, 0))

            # 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)

            self.recorders.record_iteration(system, local_meta)

            f_norm = resids.norm()
            if self.options['iprint'] > 0:
                self.print_norm('NEWTON', system.pathname, self.iter_count, f_norm, f_norm0)

            # Backtracking Line Search
            if self.line_search is not None:
                self.line_search.solve(params, unknowns, resids, system, self,
                                       alpha, f_norm, f_norm0, metadata)

        # Need to make sure the whole workflow is executed at the final
        # point, not just evaluated.
        #self.iter_count += 1
        #update_local_meta(local_meta, (self.iter_count, 0))
        #system.children_solve_nonlinear(local_meta)

        if self.options['iprint'] > 0:

            if self.iter_count == maxiter or isnan(f_norm):
                msg = 'FAILED to converge after max iterations'
            else:
                msg = 'converged'

            self.print_norm('NEWTON', system.pathname, self.iter_count, f_norm,
                            f_norm0, msg=msg)

    def print_all_convergence(self):
        """ Turns on iprint for this solver and all subsolvers. Override if
        your solver has subsolvers."""
        self.options['iprint'] = 1
        if self.line_search is not None:
            self.line_search.options['iprint'] = 1
예제 #12
0
class Newton(NonLinearSolver):
    """A python Newton solver that solves a linear system to determine the
    next direction to step. Also uses `Backtracking` as the default line
    search algorithm, but you can choose a different one by specifying
    `self.line_search`.

    Options
    -------
    options['alpha'] :  float(1.0)
        Initial over-relaxation factor.
    options['atol'] :  float(1e-12)
        Absolute convergence tolerance.
    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['maxiter'] :  int(20)
        Maximum number of iterations.
    options['rtol'] :  float(1e-10)
        Relative convergence tolerance.
    options['solve_subsystems'] :  bool(True)
        Set to True to solve subsystems. You may need this for solvers nested under Newton.
    """
    def __init__(self):
        super(Newton, self).__init__()

        opt = self.options
        opt.add_option('atol',
                       1e-12,
                       lower=0.0,
                       desc='Absolute convergence tolerance.')
        opt.add_option('rtol',
                       1e-10,
                       lower=0.0,
                       desc='Relative convergence tolerance.')
        opt.add_option('maxiter',
                       20,
                       lower=0,
                       desc='Maximum number of iterations.')
        opt.add_option('alpha', 1.0, desc='Initial over-relaxation factor.')
        opt.add_option(
            'solve_subsystems',
            True,
            desc=
            'Set to True to solve subsystems. You may need this for solvers nested under Newton.'
        )

        self.print_name = 'NEWTON'

        # Only one choice, but you can set this to None if you want.
        self.line_search = BackTracking()

    def solve(self, params, unknowns, resids, system, metadata=None):
        """ Solves the system using a Netwon's Method.

        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).
        """

        atol = self.options['atol']
        rtol = self.options['rtol']
        maxiter = self.options['maxiter']
        alpha = self.options['alpha']

        # Metadata setup
        self.iter_count = 0
        local_meta = create_local_meta(metadata, system.pathname)
        system.ln_solver.local_meta = local_meta
        update_local_meta(local_meta, (self.iter_count, 0))

        # Perform an initial run to propagate srcs to targets.
        system.children_solve_nonlinear(local_meta)
        system.apply_nonlinear(params, unknowns, resids)

        f_norm = resids.norm()
        f_norm0 = f_norm

        if self.options['iprint'] > 0:
            self.print_norm(self.print_name, system.pathname, 0, f_norm,
                            f_norm0)

        arg = system.drmat[None]
        result = system.dumat[None]

        while self.iter_count < maxiter and f_norm > atol and \
                f_norm/f_norm0 > rtol:

            # Linearize Model with partial derivatives
            system._sys_linearize(params, unknowns, resids, total_derivs=False)

            # Calculate direction to take step
            arg.vec[:] = resids.vec
            system.solve_linear(system.dumat, system.drmat, [None], mode='fwd')

            # Step in that direction,
            self.iter_count += 1
            f_norm = self.line_search.solve(params, unknowns, resids, system,
                                            self, alpha, f_norm0, metadata)

        # Need to make sure the whole workflow is executed at the final
        # point, not just evaluated.
        #self.iter_count += 1
        #update_local_meta(local_meta, (self.iter_count, 0))
        #system.children_solve_nonlinear(local_meta)

        if self.options['iprint'] > 0:

            if self.iter_count == maxiter or isnan(f_norm):
                msg = 'FAILED to converge after max iterations'
            else:
                msg = 'converged'

            self.print_norm(self.print_name,
                            system.pathname,
                            self.iter_count,
                            f_norm,
                            f_norm0,
                            msg=msg)

    def print_all_convergence(self):
        """ Turns on iprint for this solver and all subsolvers. Override if
        your solver has subsolvers."""
        self.options['iprint'] = 1
        self.line_search.options['iprint'] = 1
예제 #13
0
 def __init__(self):
     super(FakeSolver, self).__init__()
     self.sub = BackTracking()
예제 #14
0
파일: newton.py 프로젝트: relf/OpenMDAO
class Newton(NonLinearSolver):
    """A python Newton solver that solves a linear system to determine the
    next direction to step. Also uses `Backtracking` as the default line
    search algorithm, but you can choose a different one by specifying
    `self.line_search`. A linear solver can also be specified by assigning it
    to `self.ln_solver` to use a different solver than the one in the
    parent system.

    Options
    -------
    options['alpha'] :  float(1.0)
        Initial over-relaxation factor.
    options['atol'] :  float(1e-12)
        Absolute convergence tolerance.
    options['err_on_maxiter'] : bool(False)
        If True, raise an AnalysisError if not converged at maxiter.
    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['maxiter'] :  int(20)
        Maximum number of iterations.
    options['rtol'] :  float(1e-10)
        Relative convergence tolerance.
    options['solve_subsystems'] :  bool(True)
        Set to True to solve subsystems. You may need this for solvers nested under Newton.
    """

    def __init__(self):
        super(Newton, self).__init__()

        # What we support
        self.supports["uses_derivatives"] = True

        opt = self.options
        opt.add_option("atol", 1e-12, lower=0.0, desc="Absolute convergence tolerance.")
        opt.add_option("rtol", 1e-10, lower=0.0, desc="Relative convergence tolerance.")
        opt.add_option("maxiter", 20, lower=0, desc="Maximum number of iterations.")
        opt.add_option("alpha", 1.0, desc="Initial over-relaxation factor.")
        opt.add_option(
            "solve_subsystems",
            True,
            desc="Set to True to solve subsystems. You may need this for solvers nested under Newton.",
        )

        self.print_name = "NEWTON"

        # Only one choice, but the user could write their own.
        self.line_search = BackTracking()

        # User can specify a different linear solver for Newton. Default is
        # to use the parent's solver.
        self.ln_solver = None

    def setup(self, sub):
        """ Initialize sub solvers.

        Args
        ----
        sub: `System`
            System that owns this solver.
        """
        if self.line_search:
            self.line_search.setup(sub)
        if self.ln_solver:
            self.ln_solver.setup(sub)

    def solve(self, params, unknowns, resids, system, metadata=None):
        """ Solves the system using a Netwon's Method.

        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).
        """

        atol = self.options["atol"]
        rtol = self.options["rtol"]
        maxiter = self.options["maxiter"]
        alpha = self.options["alpha"]

        # Metadata setup
        self.iter_count = 0
        local_meta = create_local_meta(metadata, system.pathname)
        system.ln_solver.local_meta = local_meta
        update_local_meta(local_meta, (self.iter_count, 0))

        # Perform an initial run to propagate srcs to targets.
        system.children_solve_nonlinear(local_meta)
        system.apply_nonlinear(params, unknowns, resids)

        f_norm = resids.norm()
        f_norm0 = f_norm

        if self.options["iprint"] > 0:
            self.print_norm(self.print_name, system.pathname, 0, f_norm, f_norm0)

        arg = system.drmat[None]
        result = system.dumat[None]

        while self.iter_count < maxiter and f_norm > atol and f_norm / f_norm0 > rtol:

            # Linearize Model with partial derivatives
            system._sys_linearize(params, unknowns, resids, total_derivs=False)

            # Calculate direction to take step
            arg.vec[:] = -resids.vec
            with system._dircontext:
                system.solve_linear(system.dumat, system.drmat, [None], mode="fwd", solver=self.ln_solver)

            # Step in that direction,
            self.iter_count += 1
            f_norm = self.line_search.solve(params, unknowns, resids, system, self, alpha, f_norm0, metadata)

        # Need to make sure the whole workflow is executed at the final
        # point, not just evaluated.
        # self.iter_count += 1
        # update_local_meta(local_meta, (self.iter_count, 0))
        # system.children_solve_nonlinear(local_meta)

        if self.iter_count >= maxiter or isnan(f_norm):
            msg = "FAILED to converge after %d iterations" % self.iter_count
            fail = True
        else:
            fail = False

        if self.options["iprint"] > 0:

            if not fail:
                msg = "converged"

            self.print_norm(self.print_name, system.pathname, self.iter_count, f_norm, f_norm0, msg=msg)

        if fail and self.options["err_on_maxiter"]:
            raise AnalysisError("Solve in '%s': Newton %s" % (system.pathname, msg))

    def print_all_convergence(self):
        """ Turns on iprint for this solver and all subsolvers. Override if
        your solver has subsolvers."""
        self.options["iprint"] = 1
        self.line_search.options["iprint"] = 1