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()
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'])
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')
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')
def __init__(self): super(MySolver, self).__init__() self.workflow = CyclicWorkflow()
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()
def __init__(self): super(FixedPointIterator, self).__init__() self.current_iteration = 0 self.workflow = CyclicWorkflow()
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)
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)