def __init__(self):

        super(BroydenSolver, self).__init__()
        self.workflow = CyclicWorkflow()

        self.xin = numpy.zeros(0, 'd')
        self.F = numpy.zeros(0, 'd')
    def __init__(self):
        super(FixedPointIterator, self).__init__()

        self.history = zeros(0)
        self.current_iteration = 0

        self.workflow = CyclicWorkflow()
Exemple #3
0
 def setUp(self):
     """ Called before each test. """
     self.model = Assembly()
     self.model.add('c1', MyComp())
     self.model.add('c2', MyComp())
     self.model.add('driver', SimpleDriver())
     self.model.driver.workflow = CyclicWorkflow()
     self.model.driver.workflow.add(['c1', 'c2'])
Exemple #4
0
    def configure(self):
        """ set it up """
        self.add('c1', MyComp())
        self.add('c2', MyComp())
        self.add('driver', SimpleDriver())

        self.driver.workflow = CyclicWorkflow()
        self.driver.workflow.add(['c1', 'c2'])

        self.connect('c1.y', 'c2.x')
        self.connect('c2.y', 'c1.x')
Exemple #5
0
    def configure(self):
        """ set it up """
        self.add('c1', MyComp())
        self.add('c2', MyComp())
        self.add('c3', MyComp())
        self.add('c4', MyComp())

        self.driver.workflow = CyclicWorkflow()
        self.driver.workflow.add(['c1', 'c2', 'c3', 'c4'])

        self.connect('c1.y', 'c2.x')
        self.connect('c2.y', 'c3.x')
        self.connect('c3.y', 'c4.x')
        self.connect('c4.y', 'c1.x')
        self.connect('c1.yy', 'c3.xx')
        self.connect('c3.yy', 'c1.xx')
Exemple #6
0
 def __init__(self):
     super(MySolver, self).__init__()
     self.workflow = CyclicWorkflow()
Exemple #7
0
class MDASolver(Driver):

    tolerance = Float(1.0e-8, iotype='in', desc='Global convergence tolerance')

    max_iteration = Int(30, iotype='in', desc='Maximum number of iterations')

    newton = Bool(False, iotype='in', desc='Set to True to use a ' + \
                    'Newton-Krylov method. Defaults to False for ' + \
                    'Gauss-Siedel.')

    def __init__(self):

        super(MDASolver, self).__init__()
        self.workflow = CyclicWorkflow()

    def check_config(self):
        """ This solver requires a CyclicWorkflow. """

        super(MDASolver, self).check_config()

        if not isinstance(self.workflow, CyclicWorkflow):
            msg = "The MDASolver requires a CyclicWorkflow workflow."
            self.raise_exception(msg, RuntimeError)

    def execute(self):
        """ Pick our solver method. """

        if self.newton:
            self.execute_Newton()
        else:
            self.execute_Gauss_Seidel()

    def execute_Gauss_Seidel(self):
        """ Solver execution loop: fixed point iteration. """

        # Find dimension of our problem.
        self.workflow.initialize_residual()

        # Initial Run
        self.run_iteration()

        # Initial residuals
        norm = numpy.linalg.norm(self.workflow.calculate_residuals())
        print "Residual vector norm:\n", norm

        # Loop until the residuals converge
        iter_num = 0
        while (norm > self.tolerance) and (iter_num < self.max_iteration):

            # Pull values across severed edges
            for edge in self.workflow._severed_edges:
                src, target = edge
                self.parent.set(target, self.parent.get(src), force=True)

            # Run all components
            self.run_iteration()

            # New residuals
            norm = numpy.linalg.norm(self.workflow.calculate_residuals())
            print "Residual vector norm:\n", norm

            iter_num += 1
            self.record_case()

    def execute_Newton(self):
        """ Solver execution loop: Newton-Krylov. """

        # Find dimension of our problem.
        nEdge = self.workflow.initialize_residual()

        A = LinearOperator((nEdge, nEdge),
                           matvec=self.workflow.matvecFWD,
                           dtype=float)

        # Initial Run
        self.run_iteration()

        # Initial residuals
        norm = numpy.linalg.norm(self.workflow.calculate_residuals())
        print "Residual vector norm:\n", norm

        # Loop until convergence of residuals
        iter_num = 0
        while (norm > self.tolerance) and (iter_num < self.max_iteration):

            # Each comp calculates its own derivatives at the current
            # point. (i.e., linearizes)
            self.workflow.calc_derivatives(first=True)

            # Call GMRES to solve the linear system
            dv, info = gmres(A,
                             -self.workflow.res,
                             tol=self.tolerance,
                             maxiter=100)

            # Increment the model input edges by dv
            self.workflow.set_new_state(dv)

            # Run all components
            self.run_iteration()

            # New residuals
            norm = numpy.linalg.norm(self.workflow.calculate_residuals())
            print "Residual vector norm:\n", norm

            iter_num += 1
            self.record_case()
    def __init__(self):

        super(NewtonSolver, self).__init__()
        self.workflow = CyclicWorkflow()
class NewtonSolver(Driver):
    ''' Wrapper for some Newton style solvers. Currently supports
    fsolve from scipy.optimize.
    '''

    implements(IHasParameters, IHasEqConstraints, ISolver)

    # pylint: disable-msg=E1101
    tolerance = Float(1.0e-8, iotype='in', desc='Global convergence tolerance')

    max_iteration = Int(50, iotype='in', desc='Maximum number of iterations')

    method = Enum('fsolve', ['fsolve'], iotype='in',
                  desc='Solution method (currently only fsolve from scipy optimize)')

    def __init__(self):

        super(NewtonSolver, self).__init__()
        self.workflow = CyclicWorkflow()

    def check_config(self):
        """ This solver requires a CyclicWorkflow. """

        super(NewtonSolver, self).check_config()

        if not isinstance(self.workflow, CyclicWorkflow):
            msg = "The NewtonSolver requires a CyclicWorkflow workflow."
            self.raise_exception(msg, RuntimeError)

    def execute(self):
        """ Pick our solver method. """

        # perform an initial run
        self.pre_iteration()
        self.run_iteration()
        self.post_iteration()

        # One choice
        self.execute_fsolve()

    def execute_fsolve(self):
        """ Solver execution loop: Newton-Krylov. """

        x0 = self.workflow.get_independents()
        fsolve(self._solve_callback, x0, fprime=self._jacobian_callback,
               maxfev=self.max_iteration, xtol=self.tolerance)

    def _solve_callback(self, vals):
        """Function hook for evaluating our equations."""

        self.workflow.set_independents(vals)

        # run the model
        self.pre_iteration()
        self.run_iteration()
        self.post_iteration()
        self.record_case()

        return self.workflow.get_dependents()

    def _jacobian_callback(self, vals):
        """This function is passed to the internal solver to return the
        jacobian of the dependents with respect to the independents."""
        return self.workflow.calc_gradient()
Exemple #10
0
    def __init__(self):
        super(FixedPointIterator, self).__init__()

        self.current_iteration = 0

        self.workflow = CyclicWorkflow()
Exemple #11
0
class FixedPointIterator(Driver):
    """ A simple fixed point iteration driver, which runs a workflow and passes
    the value from the output to the input for the next iteration. Relative
    change and number of iterations are used as termination criterea. This type
    of iteration is also known as Gauss-Seidel."""

    implements(IHasParameters, IHasEqConstraints, ISolver)

    # pylint: disable-msg=E1101
    max_iteration = Int(25,
                        iotype='in',
                        desc='Maximum number of '
                        'iterations before termination.')

    tolerance = Float(1.0e-3,
                      iotype='in',
                      desc='Absolute convergence '
                      'tolerance between iterations.')

    norm_order = Enum('Infinity', ['Infinity', 'Euclidean'],
                      desc='For multivariable iteration, type of norm '
                      'to use to test convergence.')

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

        self.current_iteration = 0

        self.workflow = CyclicWorkflow()

    def execute(self):
        """Perform the iteration."""

        # perform an initial run
        self.pre_iteration()
        self.run_iteration()
        self.post_iteration()
        self.current_iteration = 0

        # Find dimension of our problem.
        self.workflow.initialize_residual()

        # Get and save the intial value of the input parameters
        val0 = self.workflow.get_independents()

        nvar = len(val0)
        delta = zeros(nvar)

        res = self.workflow.get_dependents(fixed_point=True)

        if self.norm_order == 'Infinity':
            order = float('inf')
        else:
            order = self.norm_order

        unconverged = True
        while unconverged:

            if self._stop:
                self.raise_exception('Stop requested', RunStopped)

            # check max iteration
            if self.current_iteration >= self.max_iteration - 1:

                self._logger.warning('Max iterations exceeded without '
                                     'convergence.')
                self.record_case()
                return

            # Pass output to input
            val0 += res
            self.workflow.set_independents(val0)

            # run the workflow
            self.pre_iteration()
            self.run_iteration()
            self.post_iteration()

            self.record_case()

            self.current_iteration += 1

            # check convergence
            delta[:] = self.workflow.get_dependents(fixed_point=True)
            res = delta

            if norm(delta, order) < self.tolerance:
                break
            # relative tolerance -- problematic around 0
            #if abs( (val1-val0)/val0 ) < self.tolerance:
            #    break

    def check_config(self):
        """Make sure the problem is set up right."""

        # We need to figure our severed edges before querying.
        eqcons = self.get_constraints().values()
        n_dep = len(eqcons)
        n_indep = len(self.get_parameters())

        if n_dep != n_indep:
            msg = "The number of input parameters must equal the number of" \
                  " output constraint equations in FixedPointIterator."
            self.raise_exception(msg, RuntimeError)

        # Check to make sure we don't have a null problem.
        if n_dep == 0:
            self.workflow._get_topsort()
            if len(self.workflow._severed_edges) == 0:
                msg = "FixedPointIterator requires a cyclic workflow, or a " + \
                "parameter/constraint pair."
                self.raise_exception(msg, RuntimeError)

        # Check the eq constraints to make sure they look ok.
        for eqcon in eqcons:

            if eqcon.rhs.text == '0' or eqcon.lhs.text == '0':
                msg = "Please specify constraints in the form 'A=B'"
                msg += ': %s = %s' % (eqcon.lhs.text, eqcon.rhs.text)
                self.raise_exception(msg, RuntimeError)

            if len(eqcon.get_referenced_varpaths()) > 2:
                msg = "Please specify constraints in the form 'A=B'"
                msg += ': %s = %s' % (eqcon.lhs.text, eqcon.rhs.text)
                self.raise_exception(msg, RuntimeError)
Exemple #12
0
class MDASolver(Driver):
    
    tolerance = Float(1.0e-8, iotype='in', desc='Global convergence tolerance')
    
    max_iteration = Int(30, iotype='in', desc='Maximum number of iterations')
    
    newton = Bool(False, iotype='in', desc='Set to True to use a ' + \
                    'Newton-Krylov method. Defaults to False for ' + \
                    'Gauss-Siedel.')
    
    def __init__(self):
        
        super(MDASolver, self).__init__()
        self.workflow = CyclicWorkflow()
        
    def check_config(self):
        """ This solver requires a CyclicWorkflow. """
        
        super(MDASolver, self).check_config()
        
        if not isinstance(self.workflow, CyclicWorkflow):
            msg = "The MDASolver requires a CyclicWorkflow workflow."
            self.raise_exception(msg, RuntimeError)
        
    def execute(self):
        """ Pick our solver method. """
        
        if self.newton:
            self.execute_Newton()
        else:
            self.execute_Gauss_Seidel()
            
    def execute_Gauss_Seidel(self):
        """ Solver execution loop: fixed point iteration. """
        
        # Find dimension of our problem.
        self.workflow.initialize_residual()
        
        # Initial Run
        self.run_iteration()
        
        # Initial residuals
        norm = numpy.linalg.norm(self.workflow.calculate_residuals())
        print "Residual vector norm:\n", norm
        
        # Loop until the residuals converge
        iter_num = 0
        while (norm > self.tolerance) and (iter_num < self.max_iteration):
            
            # Pull values across severed edges
            for edge in self.workflow._severed_edges:
                src, target = edge
                self.parent.set(target, self.parent.get(src), force=True)
            
            # Run all components
            self.run_iteration()
            
            # New residuals
            norm = numpy.linalg.norm(self.workflow.calculate_residuals())
            print "Residual vector norm:\n", norm
            
            iter_num += 1
            self.record_case()
            
    def execute_Newton(self):
        """ Solver execution loop: Newton-Krylov. """
        
        # Find dimension of our problem.
        nEdge = self.workflow.initialize_residual()
        
        A = LinearOperator((nEdge, nEdge),
                           matvec=self.workflow.matvecFWD,
                           dtype=float)
            
        # Initial Run
        self.run_iteration()
        
        # Initial residuals
        norm = numpy.linalg.norm(self.workflow.calculate_residuals())
        print "Residual vector norm:\n", norm
        
        # Loop until convergence of residuals
        iter_num = 0
        while (norm > self.tolerance) and (iter_num < self.max_iteration):
            
            # Each comp calculates its own derivatives at the current
            # point. (i.e., linearizes)
            self.workflow.calc_derivatives(first=True)
            
            # Call GMRES to solve the linear system
            dv, info = gmres(A, -self.workflow.res,
                             tol=self.tolerance,
                             maxiter=100)
            
            # Increment the model input edges by dv
            self.workflow.set_new_state(dv)
            
            # Run all components
            self.run_iteration()
            
            # New residuals
            norm = numpy.linalg.norm(self.workflow.calculate_residuals())
            print "Residual vector norm:\n", norm
            
            iter_num += 1
            self.record_case()
            
            
            
class FixedPointIterator(Driver):
    """ A simple fixed point iteration driver, which runs a workflow and passes
    the value from the output to the input for the next iteration. Relative
    change and number of iterations are used as termination criterea. This type
    of iteration is also known as Gauss-Seidel."""

    implements(IHasParameters, IHasEqConstraints, ISolver)

    # pylint: disable-msg=E1101
    max_iteration = Int(25, iotype='in', desc='Maximum number of '
                                         'iterations before termination.')

    tolerance = Float(1.0e-3, iotype='in', desc='Absolute convergence '
                                            'tolerance between iterations.')

    norm_order = Enum('Infinity', ['Infinity', 'Euclidean'],
                       desc='For multivariable iteration, type of norm '
                                   'to use to test convergence.')

    def __init__(self):
        super(FixedPointIterator, self).__init__()
        self.current_iteration = 0
        self.workflow = CyclicWorkflow()

    def execute(self):
        """Perform the iteration."""

        # perform an initial run
        self.pre_iteration()
        self.run_iteration()
        self.post_iteration()
        self.current_iteration = 0

        # Find dimension of our problem.
        self.workflow.initialize_residual()

        # Get and save the intial value of the input parameters
        val0 = self.workflow.get_independents()

        nvar = len(val0)
        delta = zeros(nvar)

        res = self.workflow.get_dependents(fixed_point=True)

        if self.norm_order == 'Infinity':
            order = float('inf')
        else:
            order = self.norm_order

        unconverged = True
        while unconverged:

            if self._stop:
                self.raise_exception('Stop requested', RunStopped)

            # check max iteration
            if self.current_iteration >= self.max_iteration-1:
                self._logger.warning('Max iterations exceeded without '
                                     'convergence.')
                return

            # Pass output to input
            val0 += res
            self.workflow.set_independents(val0)

            # run the workflow
            self.pre_iteration()
            self.run_iteration()
            self.post_iteration()

            self.current_iteration += 1

            # check convergence
            delta[:] = self.workflow.get_dependents(fixed_point=True)
            res = delta

            if norm(delta, order) < self.tolerance or self.should_stop():
                break
            # relative tolerance -- problematic around 0
            #if abs( (val1-val0)/val0 ) < self.tolerance:
            #    break

    def check_config(self, strict=False):
        """Make sure the problem is set up right."""

        super(FixedPointIterator, self).check_config(strict=strict)

        # We need to figure our severed edges before querying.
        eqcons = self.get_constraints().values()
        n_dep = len(eqcons)
        n_indep = len(self.get_parameters())

        if n_dep != n_indep:
            msg = "The number of input parameters must equal the number of" \
                  " output constraint equations in FixedPointIterator."
            self.raise_exception(msg, RuntimeError)

        # Check to make sure we don't have a null problem.
        if n_dep == 0:
            self.workflow._get_topsort()
            if len(self.workflow._severed_edges) == 0:
                msg = "FixedPointIterator requires a cyclic workflow, or a " \
                      "parameter/constraint pair."
                self.raise_exception(msg, RuntimeError)

        # Check the eq constraints to make sure they look ok.
        for eqcon in eqcons:

            if eqcon.rhs.text == '0' or eqcon.lhs.text == '0':
                msg = "Please specify constraints in the form 'A=B'"
                msg += ': %s = %s' % (eqcon.lhs.text, eqcon.rhs.text)
                self.raise_exception(msg, RuntimeError)

            if len(eqcon.get_referenced_varpaths()) > 2:
                msg = "Please specify constraints in the form 'A=B'"
                msg += ': %s = %s' % (eqcon.lhs.text, eqcon.rhs.text)
                self.raise_exception(msg, RuntimeError)
class FixedPointIterator(Driver):
    """ A simple fixed point iteration driver, which runs a workflow and passes
    the value from the output to the input for the next iteration. Relative
    change and number of iterations are used as termination criterea. This type
    of iteration is also known as Gauss-Seidel."""

    implements(IHasParameters, IHasEqConstraints, ISolver)

    # pylint: disable-msg=E1101
    max_iteration = Int(25, iotype='in', desc='Maximum number of '
                                         'iterations before termination.')

    tolerance = Float(1.0e-3, iotype='in', desc='Absolute convergence '
                                            'tolerance between iterations.')

    norm_order = Enum('Infinity', ['Infinity', 'Euclidean'],
                       desc='For multivariable iteration, type of norm '
                                   'to use to test convergence.')


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

        self.history = zeros(0)
        self.current_iteration = 0

        self.workflow = CyclicWorkflow()

    def execute(self):
        """Perform the iteration."""

        # perform an initial run
        self.pre_iteration()
        self.run_iteration()
        self.post_iteration()
        self.current_iteration = 0

        # Find dimension of our problem.
        self.workflow.initialize_residual()

        # Get and save the intial value of the input parameters
        val0 = self.workflow.get_independents()

        nvar = len(val0)
        history = zeros([self.max_iteration, nvar])
        delta = zeros(nvar)

        history[0, :] = self.workflow.get_dependents()

        if self.norm_order == 'Infinity':
            order = float('inf')
        else:
            order = self.norm_order

        unconverged = True
        while unconverged:

            if self._stop:
                self.raise_exception('Stop requested', RunStopped)

            # check max iteration
            if self.current_iteration >= self.max_iteration-1:
                self.history = history[:self.current_iteration+1, :]

                self._logger.warning('Max iterations exceeded without '
                                     'convergence.')
                return

            # Pass output to input
            val0 += history[self.current_iteration, :]
            self.workflow.set_independents(val0)

            # run the workflow
            self.pre_iteration()
            self.run_iteration()
            self.post_iteration()

            self.record_case()

            self.current_iteration += 1

            # check convergence
            delta[:] = self.workflow.get_dependents()
            history[self.current_iteration] = delta

            if norm(delta, order) < self.tolerance:
                break
            # relative tolerance -- problematic around 0
            #if abs( (val1-val0)/val0 ) < self.tolerance:
            #    break
        self.history = history[:self.current_iteration+1, :]

    def check_config(self):
        """Make sure the problem is set up right."""

        # We need to figure our severed edges before querying.
        self.workflow._get_topsort()
        n_dep = len(self.workflow.get_dependents())
        n_indep = len(self.workflow.get_independents())

        if n_dep == 0:
            msg = "FixedPointIterator requires a constraint equation or a cyclic workflow."
            self.raise_exception(msg, RuntimeError)

        if n_indep == 0:
            msg = "FixedPointIterator requires an input parameter or a cyclic workflow."
            self.raise_exception(msg, RuntimeError)

        if n_dep != n_indep:
            msg = "The number of input parameters must equal the number of" \
                  " output constraint equations in FixedPointIterator."
            self.raise_exception(msg, RuntimeError)