def test_list_driver(get_tf): xyz = [[[1, 2], [3, 4], [5, 6]], [[4, 3], [6, 5], [2, 1]]] lst = [[('x', [1, 2]), ('y', [3, 4]), ('z', [5, 6])], [('x', [4, 3]), ('y', [6, 5]), ('z', [2, 1])]] tf = get_tf(driver=lst) # pure list npt.assert_array_equal(tf.get_DOE_array(), xyz) tf = get_tf(driver=ListGenerator(lst)) # list generator npt.assert_array_equal(tf.get_DOE_array(), xyz) tf = get_tf(driver=DOEDriver(ListGenerator(lst))) # DOEDriver npt.assert_array_equal(tf.get_DOE_array(), xyz)
def __init__(self, generator=None, **kwargs): """ Construct A DOEDriver. """ # if given a list, create a ListGenerator if isinstance(generator, list): generator = ListGenerator(generator) elif generator and not isinstance(generator, DOEGenerator): if inspect.isclass(generator): raise TypeError( "DOEDriver requires an instance of DOEGenerator, " "but a class object was found: %s" % generator.__name__) else: raise TypeError( "DOEDriver requires an instance of DOEGenerator, " "but an instance of %s was found." % type(generator).__name__) super().__init__(**kwargs) # What we support self.supports['integer_design_vars'] = True # What we don't support self.supports['distributed_design_vars'] = False self.supports._read_only = True if generator is not None: self.options['generator'] = generator self._name = '' self._problem_comm = None self._color = None
def __init__(self, generator=None, **kwargs): """ Constructor. Parameters ---------- generator : DOEGenerator, list or None The case generator or a list of DOE cases. **kwargs : dict of keyword arguments Keyword arguments that will be mapped into the Driver options. """ # if given a list, create a ListGenerator if isinstance(generator, list): generator = ListGenerator(generator) elif generator and not isinstance(generator, DOEGenerator): if inspect.isclass(generator): raise TypeError("DOEDriver requires an instance of DOEGenerator, " "but a class object was found: %s" % generator.__name__) else: raise TypeError("DOEDriver requires an instance of DOEGenerator, " "but an instance of %s was found." % type(generator).__name__) super(DOEDriver, self).__init__(**kwargs) if generator is not None: self.options['generator'] = generator self._name = '' self._recorders = [] self._comm = None self._color = None
def test_turbine_Type_multistart_XYZ_optimization(): plot_comp = DummyCostPlotComp(optimal, delay=.5) plot_comp = NoPlot() xyz = [(0, 0, 0), (1, 1, 1)] p1 = DummyCost(optimal_state=optimal, inputs=['x', 'y', 'z', 'type']) p2 = TurbineXYZOptimizationProblem( cost_comp=p1, turbineXYZ=xyz, min_spacing=2, boundary_comp=get_boundary_comp(), plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(disp=True, optimizer='COBYLA', maxiter=10)) p3 = InitialXYZOptimizationProblem( cost_comp=p2, turbineXYZ=xyz, min_spacing=2, boundary_comp=get_boundary_comp(), driver=DOEDriver(ListGenerator([[('x', [0, 4]), ('y', [2, 2]), ('z', [4, 1])]]))) tf = TurbineTypeOptimizationProblem( cost_comp=p3, turbineTypes=[0, 0], lower=0, upper=1, driver=DOEDriver(FullFactorialGenerator(1))) case_gen = tf.driver.options['generator'] cost, state, recorder = tf.optimize() print(cost) # print (state) print(recorder.get('type')) print(recorder.get('cost')) best_index = np.argmin(recorder.get('cost')) initial_xyz_recorder = recorder['recorder'][best_index] xyz_recorder = initial_xyz_recorder.get('recorder')[0] npt.assert_almost_equal(xyz_recorder['cost'][-1], cost)
def test_3level_type_multistart_XYZ_optimization(): design_vars = {k: v for k, v in zip('xy', optimal.T)} design_vars['z'] = (optimal[:, 2], 0, 4) xyz_problem = TopFarmProblem(design_vars, cost_comp=DummyCost(optimal, ['x', 'y', 'z', 'type']), constraints=[ SpacingConstraint(2), XYBoundaryConstraint([(0, 0), (4, 4)], 'square') ], driver=EasyScipyOptimizeDriver(disp=False)) initial_xyz_problem = TopFarmProblem( design_vars={k: v for k, v in zip('xyz', optimal.T)}, cost_comp=xyz_problem, driver=DOEDriver( ListGenerator([[('x', [0, 4]), ('y', [2, 2]), ('z', [4, 1])]]))) tf = TopFarmProblem({'type': ([0, 0], 0, 1)}, cost_comp=initial_xyz_problem, driver=DOEDriver(FullFactorialGenerator(2))) cost, _, recorder = tf.optimize() best_index = np.argmin(recorder.get('cost')) initial_xyz_recorder = recorder['recorder'][best_index] xyz_recorder = initial_xyz_recorder.get('recorder')[0] npt.assert_almost_equal(xyz_recorder['cost'][-1], cost)
def test_ListRecorder(): from openmdao.api import Problem, IndepVarComp from openmdao.test_suite.components.paraboloid import Paraboloid prob = Problem() model = prob.model model.add_subsystem('p1', IndepVarComp('x', 0.), promotes=['*']) model.add_subsystem('p2', IndepVarComp('y', 0.), promotes=['*']) model.add_subsystem('comp', Paraboloid(), promotes=['*']) model.add_design_var('x', lower=-10, upper=10) model.add_design_var('y', lower=-10, upper=10) model.add_objective('f_xy') xyf = [[0.98, 4.30, 74.1844], [2.06, 0.90, 23.7476], [-1.53, 2.92, 60.9397], [-1.25, 7.84, 145.4481]] prob.driver = DOEDriver(ListGenerator([[('x', xy[0]), ('y', xy[1])] for xy in xyf])) recorder = TopFarmListRecorder() recorder._initialize_database() recorder._cleanup_abs2meta() recorder.record_iteration_problem(None, None, None) recorder.record_iteration_system(None, None, None) recorder.record_iteration_solver(None, None, None) recorder.record_viewer_data(None) recorder.record_metadata_solver(None) recorder.record_derivatives_driver(None, None, None) recorder.shutdown() prob.driver.add_recorder(recorder) prob.driver.recording_options['record_desvars'] = True prob.driver.recording_options['includes'] = ['*'] prob.driver.recording_options['record_inputs'] = True prob.setup() prob.run_driver() prob.cleanup() assert recorder.num_cases == 4 npt.assert_array_equal(recorder.get('counter'), range(1, 5)) npt.assert_array_equal(recorder['counter'], range(1, 5)) npt.assert_array_almost_equal(recorder.get(['x', 'y', 'f_xy']), xyf, 4) for xyf, k in zip(xyf[0], ['x', 'y', 'f_xy']): npt.assert_allclose(recorder[k][0], xyf) with pytest.raises(KeyError, match="missing"): recorder.get('missing')
def __init__(self, generator, n_iter=1000, step_size=0.1, offset=0.5, verbose=False): DOEGenerator.__init__(self) self.n_iter = n_iter self.step_size = step_size self.offset = offset if isinstance(generator, list): generator = ListGenerator(generator) self.generator = generator self.verbose = verbose
def __init__(self, generator=None, **kwargs): """ Construct A DOEDriver. Parameters ---------- generator : DOEGenerator, list or None The case generator or a list of DOE cases. **kwargs : dict of keyword arguments Keyword arguments that will be mapped into the Driver options. """ # if given a list, create a ListGenerator if isinstance(generator, list): generator = ListGenerator(generator) elif generator and not isinstance(generator, DOEGenerator): if inspect.isclass(generator): raise TypeError( "DOEDriver requires an instance of DOEGenerator, " "but a class object was found: %s" % generator.__name__) else: raise TypeError( "DOEDriver requires an instance of DOEGenerator, " "but an instance of %s was found." % type(generator).__name__) super().__init__(**kwargs) # What we support self.supports['integer_design_vars'] = True # What we don't support self.supports['distributed_design_vars'] = False self.supports._read_only = True if generator is not None: self.options['generator'] = generator self._name = '' self._recorders = [] self._problem_comm = None self._color = None
def test_NestedTopFarmListRecorder(tf_generator): optimal = [(0, 2, 4, 1), (4, 2, 1, 0)] type_lst = [[0, 0], [1, 0], [0, 1]] p1 = DummyCost(optimal_state=optimal, inputs=['x', 'y', 'z', 'type']) p2 = tf_generator(cost_comp=p1, driver=EasyScipyOptimizeDriver(disp=False)) tf = TopFarmProblem({'type': ([0, 0], 0, 1)}, cost_comp=p2, driver=DOEDriver( ListGenerator([[('type', t)] for t in type_lst]))) cost, _, recorder = tf.optimize() npt.assert_almost_equal(cost, 0) npt.assert_array_almost_equal(recorder.get('type'), type_lst) npt.assert_array_almost_equal(recorder.get('cost'), [1, 0, 2]) for sub_rec in recorder.get('recorder'): npt.assert_array_almost_equal( np.array([sub_rec[k][-1] for k in ['x', 'y', 'z']]).T, np.array(optimal)[:, :3])
def test_ListRecorder(): from openmdao.api import Problem, IndepVarComp from openmdao.test_suite.components.paraboloid import Paraboloid prob = Problem() model = prob.model model.add_subsystem('p1', IndepVarComp('x', 0.), promotes=['*']) model.add_subsystem('p2', IndepVarComp('y', 0.), promotes=['*']) model.add_subsystem('comp', Paraboloid(), promotes=['*']) model.add_design_var('x', lower=-10, upper=10) model.add_design_var('y', lower=-10, upper=10) model.add_objective('f_xy') xyf = [[0.98, 4.30, 74.1844], [2.06, 0.90, 23.7476], [-1.53, 2.92, 60.9397], [-1.25, 7.84, 145.4481]] prob.driver = DOEDriver( ListGenerator([[('x', xy[0]), ('y', xy[1])] for xy in xyf])) recorder = ListRecorder() prob.driver.add_recorder(recorder) prob.setup() prob.run_driver() prob.cleanup() cases = recorder.driver_cases assert cases.num_cases == 4 npt.assert_array_equal(recorder.get('counter'), range(1, 5)) npt.assert_array_equal(recorder['counter'], range(1, 5)) npt.assert_array_almost_equal(recorder.get(['x', 'y', 'f_xy']), xyf, 4) for xyf, k in zip(xyf[0], ['x', 'y', 'f_xy']): npt.assert_allclose(cases.get_case(0).outputs[k][0], xyf) with pytest.raises(KeyError, match="missing"): recorder.get('missing')
def __init__(self, generator): DOEGenerator.__init__(self) if isinstance(generator, list): generator = ListGenerator(generator) self.generator = generator
def __init__(self, design_vars, cost_comp, driver=EasyScipyOptimizeDriver(), constraints=[], plot_comp=NoPlot(), record_id=None, expected_cost=1, ext_vars={}): """Initialize TopFarmProblem Parameters ---------- design_vars : dict or list of key-initial_value-tuples Design variables for the problem.\n Ex: {'x': [1,2,3], 'y':([3,2,1],0,1), 'z':([4,5,6],[4,5,4], [6,7,6])}\n Ex: [('x', [1,2,3]), ('y',([3,2,1],0,1)), ('z',([4,5,6],[4,5,4], [6,7,6]))]\n Ex: zip('xy', pos.T)\n The keys (x, y, z) are the names of the design variable.\n The values are either\n - the initial value or\n - a tuple of (initial value, lower bound, upper bound) cost_comp : ExplicitComponent or TopFarmProblem A cost component in the style of an OpenMDAO v2 ExplicitComponent. Pure python cost functions can be wrapped using ``CostModelComponent`` class in ``topfarm.cost_models.cost_model_wrappers``.\n For nested problems, the cost comp_comp is typically a TopFarmProblem driver : openmdao Driver, optinal Driver used to solve the optimization driver. For an example, see the ``EasyScipyOptimizeDriver`` class in ``topfarm.easy_drivers``. constraints : list of Constraint-objects E.g. XYBoundaryConstraint, SpacingConstraint plot_comp : ExplicitComponent, optional OpenMDAO ExplicitComponent used to plot the state (during optimization). For no plotting, pass in the ``topfarm.plotting.NoPlot`` class. record_id : string "<record_id>:<case>", optional Identifier for the optimization. Allows a user to restart an optimization where it left off.\n record_id can be name (saves as recordings/<name>.pkl), abs or relative path Case can be:\n - "", "latest", "-1": Continue from latest\n - "best": Continue from best case (minimum cost)\n - "0": Start from scratch (initial position)\n - "4": Start from case number 4\n expected_cost : int or float Used to scale the cost. This has influence on some drivers, e.g. SLSQP where it affects the step size ext_vars : dict or list of key-initial_value tuple Used for nested problems to propagate variables from parent problem\n Ex. {'type': [1,2,3]}\n Ex. [('type', [1,2,3])]\n Examples -------- See main() in the bottom of this file """ if mpi.MPI: comm = None else: from openmdao.utils.mpi import FakeComm comm = FakeComm() Problem.__init__(self, comm=comm) if isinstance(cost_comp, TopFarmProblem): cost_comp = cost_comp.as_component() cost_comp.parent = self self.cost_comp = cost_comp if isinstance(driver, list): driver = DOEDriver(ListGenerator(driver)) elif isinstance(driver, DOEGenerator): driver = DOEDriver(generator=driver) self.driver = driver self.plot_comp = plot_comp self.record_id = record_id self.load_recorder() if not isinstance(design_vars, dict): design_vars = dict(design_vars) self.design_vars = design_vars self.indeps = self.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) for k in [topfarm.x_key, topfarm.y_key, topfarm.type_key]: if k in design_vars: if isinstance(design_vars[k], tuple): self.n_wt = len(design_vars[k][0]) else: self.n_wt = len(design_vars[k]) break else: self.n_wt = 0 for constr in constraints: if self.driver.supports['inequality_constraints']: if isinstance(self.driver, SimpleGADriver): constr.setup_as_penalty(self) else: constr.setup_as_constraint(self) else: constr.setup_as_penalty(self) self.model.constraint_components = [ constr.constraintComponent for constr in constraints ] do = self.driver.options for k, v in design_vars.items(): if isinstance(v, tuple): assert len( v ) == 3, "Design_vars values must be either value or (value, lower, upper)" self.indeps.add_output(k, v[0]) if ('optimizer' in do and do['optimizer'] == 'COBYLA'): ref0 = np.min(v[1]) ref1 = np.max(v[2]) l, u = [lu * (ref1 - ref0) + ref0 for lu in [v[1], v[2]]] kwargs = { 'ref0': ref0, 'ref': ref1, 'lower': l, 'upper': u } else: kwargs = {'lower': v[1], 'upper': v[2]} else: self.indeps.add_output(k, v) kwargs = {} if 'optimizer' in do and do['optimizer'] == 'SLSQP': # Upper and lower disturbs SLSQP when running with constraints. Add limits as constraints self.model.add_constraint(k, kwargs.get('lower', None), kwargs.get('upper', None)) kwargs = { 'lower': np.nan, 'upper': np.nan } # Default +/- sys.float_info.max does not work for SLSQP self.model.add_design_var(k, **kwargs) for k, v in ext_vars.items(): self.indeps.add_output(k, v) self.ext_vars = ext_vars self.model.add_subsystem('cost_comp', cost_comp, promotes=['*']) self.model.add_objective('cost', scaler=1 / abs(expected_cost)) if plot_comp: self.model.add_subsystem('plot_comp', plot_comp, promotes=['*']) plot_comp.problem = self plot_comp.n_wt = self.n_wt self.setup()