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)
示例#2
0
    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
示例#3
0
    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
示例#4
0
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)
示例#5
0
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)
示例#6
0
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
示例#8
0
    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
示例#9
0
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])
示例#10
0
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')
示例#11
0
 def __init__(self, generator):
     DOEGenerator.__init__(self)
     if isinstance(generator, list):
         generator = ListGenerator(generator)
     self.generator = generator
示例#12
0
    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()