Exemple #1
0
    def setUp(self):

        model = Group()
        ivc = IndepVarComp()

        mapdata = SampleMap()

        params = mapdata.param_data
        x, y, z = params
        outs = mapdata.output_data
        z = outs[0]
        ivc.add_output('x', x['default'], units=x['units'])
        ivc.add_output('y', y['default'], units=y['units'])
        ivc.add_output('z', z['default'], units=z['units'])

        model.add_subsystem('des_vars', ivc, promotes=["*"])

        comp = MetaModelStructuredComp(method='slinear', extrapolate=True)

        for param in params:
            comp.add_input(param['name'], param['default'], param['values'])

        for out in outs:
            comp.add_output(out['name'], out['default'], out['values'])

        model.add_subsystem('comp', comp, promotes=["*"])
        self.prob = Problem(model)
        self.prob.setup()
        self.prob['x'] = 1.0
        self.prob['y'] = 0.75
        self.prob['z'] = -1.7
Exemple #2
0
def propeller_map_highpower(vec_size=1):
    # Data from https://frautech.wordpress.com/2011/01/28/design-fridays-thats-a-big-prop/
    J = np.linspace(0.0,4.0,9)
    cp = np.linspace(0.0,2.5,13)

    # data = np.array([[0.28,0.51,0.65,0.66,0.65,0.64,0.63,0.62,0.61],
    #                         [0.27,0.50,0.71,0.82,0.81,0.70,0.68,0.67,0.66],
    #                         [0.26,0.49,0.72,0.83,0.86,0.85,0.75,0.70,0.69],
    #                         [0.25,0.45,0.71,0.82,0.865,0.875,0.84,0.79,0.72],
    #                         [0.24,0.42,0.69,0.815,0.87,0.885,0.878,0.84,0.80],
    #                         [0.23,0.40,0.65,0.81,0.865,0.89,0.903,0.873,0.83],
    #                         [0.22,0.38,0.61,0.78,0.85,0.88,0.91,0.90,0.86],
    #                         [0.21,0.34,0.58,0.73,0.83,0.876,0.904,0.91,0.88],
    #                         [0.20,0.31,0.53,0.71,0.81,0.87,0.895,0.91,0.882]])
    data = np.array([[0.28,0.51,0.65,0.66,0.65,0.64,0.63,0.62,0.61],
                            [0.20,0.50,0.71,0.82,0.81,0.70,0.68,0.67,0.66],
                            [0.19,0.49,0.72,0.83,0.86,0.85,0.75,0.70,0.69],
                            [0.18,0.45,0.71,0.82,0.865,0.875,0.84,0.79,0.72],
                            [0.17,0.42,0.69,0.815,0.87,0.885,0.878,0.84,0.80],
                            [0.155,0.40,0.65,0.81,0.865,0.89,0.903,0.873,0.83],
                            [0.13,0.38,0.61,0.78,0.85,0.88,0.91,0.90,0.86],
                            [0.12,0.34,0.58,0.73,0.83,0.876,0.904,0.91,0.88],
                            [0.10,0.31,0.53,0.71,0.81,0.87,0.895,0.91,0.882],
                            [0.08,0.25,0.44,0.62,0.75,0.84,0.88,0.89,0.87],
                            [0.06,0.18,0.35,0.50,0.68,0.79,0.86,0.86,0.85],
                            [0.05,0.14,0.25,0.40,0.55,0.70,0.79,0.80,0.72],
                            [0.04,0.12,0.19,0.29,0.40,0.50,0.60,0.60,0.50]])

    data[:,0] = np.zeros(13)
    # Create regular grid interpolator instance
    interp = MetaModelStructuredComp(method='cubic',extrapolate=False,vec_size=vec_size)
    interp.add_input('cp', 0.3, cp)
    interp.add_input('J', 1, J)
    interp.add_output('eta_prop', 0.8, data)
    return interp
Exemple #3
0
def propeller_map_quadratic(vec_size=1):
    #enter three points in xyz array format:
    #the center of the efficiency bucket (J, cp, eta)
    #two more points (J, cp, eta)
    #points = np.array([[2.2,0.18,0.93], [0.2,0.03,0.40], [0.2,0.7,0.02]])
    points = np.array([[3.1,1.55,0.91], [0,0,0.3], [1.0,2.0,0.5]])
    #solve a linear system for the constants in AJ^2+BJ+C*cp^2+D*cp+E = eta
    #the first point meets the value and has zero gradient
    #the second and third points meet value
    vals = np.column_stack((points[:,0]**2,points[:,0],points[:,1]**2,points[:,1],np.ones((3,))))
    vals = np.vstack((vals,np.array([2*points[0,0],1,0,0,0]),np.array([0,0,2*points[0,1],1,0])))
    rhs = np.concatenate([points[:,2],np.zeros(2)])
    coeffs = np.linalg.solve(vals,rhs)
    Jvec = np.linspace(0,4.0,20)
    cpvec = np.linspace(0,2.0,10)
    J,cp=np.meshgrid(Jvec,cpvec)
    eta = coeffs[0]*J**2+coeffs[1]*J+coeffs[2]*cp**2+coeffs[3]*cp+coeffs[4]
    debug=False
    if debug:
        import matplotlib.pyplot as plt
        CS = plt.contour(J,cp,eta)
        plt.clabel(CS, inline=1, fontsize=10)
        plt.show()
    interp = MetaModelStructuredComp(method='cubic',extrapolate=False,vec_size=vec_size)
    interp.add_input('cp', 0.3, cpvec)
    interp.add_input('J', 1, Jvec)
    interp.add_output('eta_prop', 0.8, eta)
    return interp
    def setup(self):
        nn = self.options['num_nodes']
        nv = self.options['num_vehicles']
        separation = self.options['separation']
        """Add in the old trajectory as a meta model
            """

        mm = MetaModelStructuredComp(method='slinear',
                                     vec_size=nn,
                                     extrapolate=True)
        mm.add_input('t', val=np.zeros(nn), training_data=old_t)
        mm.add_output('interp_x', val=np.zeros(nn), training_data=old_X)
        mm.add_output('interp_y', val=np.zeros(nn), training_data=old_Y)
        self.add_subsystem('mm', mm, promotes=['*'])

        # now add in trajectories to be solved with dymos
        self.add_subsystem('vehicles',
                           Vehicles(num_nodes=nn, num_v=nv),
                           promotes=['*'])

        # add in distance calcs for solved trajectories
        self.add_subsystem('distances1',
                           GridDistComp(num_nodes=nn, num_v=nv, limit=limit),
                           promotes=['*'])

        # add in distance calcs for solved trajectories to the fixed ones
        self.add_subsystem('distances2',
                           SingleDistance(num_nodes=nn, num_v=nv),
                           promotes=['*'])
        self.connect('interp_x', 'fixed_x')
        self.connect('interp_y', 'fixed_y')
Exemple #5
0
def static_propeller_map_Raymer(vec_size=1):
    #Data from Raymer for static thrust of 3-bladed propeller
    cp = np.linspace(0.0,0.60,25)
    raymer_static_data = np.array([2.5,3.0,2.55,2.0,1.85,1.5,1.25,1.05,0.95,0.86,0.79,0.70,0.62,0.53,0.45,0.38,0.32,0.28,0.24,0.21,0.18,0.16,0.14,0.12,0.10])
    interp = MetaModelStructuredComp(method='cubic',extrapolate=True,vec_size=vec_size)
    interp.add_input('cp',0.15,cp)
    interp.add_output('ct_over_cp',1.5,raymer_static_data)
    return interp
Exemple #6
0
def static_propeller_map_highpower(vec_size=1):
    #Factoring up the thrust of the Raymer static thrust data to match the high power data
    cp = np.linspace(0.0,1.0,41)
    factored_raymer_static_data = np.array([2.5,3.0,2.55,2.0,1.85,1.5,1.25,1.05,0.95,0.86,0.79,0.70,0.62,0.53,0.45,0.38,0.32,0.28,0.24,0.21,0.18,0.16,0.14,0.12,0.10,0.09,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08,0.08])
    factored_raymer_static_data[6:] = factored_raymer_static_data[6:]*1.2
    interp = MetaModelStructuredComp(method='cubic',extrapolate=True,vec_size=vec_size)
    interp.add_input('cp',0.15,cp)
    interp.add_output('ct_over_cp',1.5,factored_raymer_static_data)
    return interp
Exemple #7
0
    def test_shape(self):
        import numpy as np
        from openmdao.api import Group, Problem, IndepVarComp
        from openmdao.components.meta_model_structured_comp import MetaModelStructuredComp

        # create input param training data, of sizes 25, 5, and 10 points resp.
        p1 = np.linspace(0, 100, 25)
        p2 = np.linspace(-10, 10, 5)
        p3 = np.linspace(0, 1, 10)

        # can use meshgrid to create a 3D array of test data
        P1, P2, P3 = np.meshgrid(p1, p2, p3, indexing='ij')
        f = np.sqrt(P1) + P2 * P3

        # verify the shape matches the order and size of the input params
        print(f.shape)

        # Create regular grid interpolator instance
        interp = MetaModelStructuredComp(method='cubic')
        interp.add_input('p1', 0.5, training_data=p1)
        interp.add_input('p2', 0.0, training_data=p2)
        interp.add_input('p3', 3.14, training_data=p3)

        interp.add_output('f', 0.0, training_data=f)

        # Set up the OpenMDAO model
        model = Group()
        model.add_subsystem('comp', interp, promotes=["*"])
        prob = Problem(model)
        prob.setup()

        # set inputs
        prob['p1'] = 55.12
        prob['p2'] = -2.14
        prob['p3'] = 0.323

        prob.run_model()

        computed = prob['f']
        actual = 6.73306472

        assert_almost_equal(computed, actual)

        # we can verify all gradients by checking against finite-difference
        prob.check_partials(compact_print=True)
Exemple #8
0
def propeller_map_scaled(vec_size=1,design_J=2.2,design_cp=0.2):
    # Data from Raymer, Aircraft Design A Conceptual Approach, 4th Ed pg 498 fig 13.12 extrapolated in low cp range
    # For a 3 bladed constant-speed propeller, scaled for higher design Cp
    J = np.linspace(0.2,2.8*design_J/2.2,14)
    cp = np.array([0,0.1,0.2,0.3,0.4,0.5])*design_cp/0.2

    #raymer_data = np.ones((9,14))*0.75
    raymer_data = np.array([[0.45,0.6,0.72,0.75,0.70,0.65,0.6,0.55,0.5,0.45,0.40,0.35,0.3,0.25],
                            [0.35,0.6,0.74,0.83,0.86,0.88,0.9,0.9,0.88,0.85,0.83,0.8,0.75,0.7],
                            [0.2,0.35,0.55,0.7,0.8,0.85,0.87,0.9,0.91,0.92,0.9,0.9,0.88,0.87],
                            [0.12,0.22,0.36,0.51,0.66,0.75,0.8,0.85,0.87,0.88,0.91,0.905,0.902,0.9],
                            [0.07,0.15,0.29,0.36,0.45,0.65,0.73,0.77,0.83,0.85,0.87,0.875,0.88,0.895],
                            [0.05,0.12,0.25,0.32,0.38,0.50,0.61,0.72,0.77,0.79,0.83,0.85,0.86,0.865]])
    # Create regular grid interpolator instance
    interp = MetaModelStructuredComp(method='cubic',extrapolate=True,vec_size=vec_size)
    interp.add_input('cp', 0.3, cp)
    interp.add_input('J', 1, J)
    interp.add_output('eta_prop', 0.8, raymer_data)
    return interp
Exemple #9
0
    def test_meta_model(self):
        from openmdao.components.tests.test_meta_model_structured_comp import SampleMap
        from openmdao.components.meta_model_structured_comp import MetaModelStructuredComp

        filename = 'pyxdsm_meta_model'
        out_format = PYXDSM_OUT
        model = Group()
        ivc = IndepVarComp()

        mapdata = SampleMap()

        params = mapdata.param_data
        x, y, z = params
        outs = mapdata.output_data
        z = outs[0]
        ivc.add_output('x', x['default'], units=x['units'])
        ivc.add_output('y', y['default'], units=y['units'])
        ivc.add_output('z', z['default'], units=z['units'])

        model.add_subsystem('des_vars', ivc, promotes=["*"])

        comp = MetaModelStructuredComp(method='slinear', extrapolate=True)

        for param in params:
            comp.add_input(param['name'], param['default'], param['values'])

        for out in outs:
            comp.add_output(out['name'], out['default'], out['values'])

        model.add_subsystem('comp', comp, promotes=["*"])
        prob = Problem(model)
        prob.setup(check=False)
        prob.final_setup()

        write_xdsm(prob,
                   filename=filename,
                   out_format=out_format,
                   quiet=QUIET,
                   show_browser=SHOW,
                   show_parallel=True)
        # Check if file was created
        self.assertTrue(os.path.isfile('.'.join([filename, out_format])))
Exemple #10
0
    def test_training_gradient(self):
        model = Group()
        ivc = IndepVarComp()

        mapdata = SampleMap()

        params = mapdata.param_data
        outs = mapdata.output_data

        ivc.add_output('x', np.array([-0.3, 0.7, 1.2]))
        ivc.add_output('y', np.array([0.14, 0.313, 1.41]))
        ivc.add_output('z', np.array([-2.11, -1.2, 2.01]))

        ivc.add_output('f_train', outs[0]['values'])
        ivc.add_output('g_train', outs[1]['values'])

        comp = MetaModelStructuredComp(training_data_gradients=True,
                                       method='cubic',
                                       num_nodes=3)
        for param in params:
            comp.add_input(param['name'], param['default'], param['values'])

        for out in outs:
            comp.add_output(out['name'], out['default'], out['values'])

        model.add_subsystem('ivc', ivc, promotes=["*"])
        model.add_subsystem('comp',
                            comp,
                            promotes=["*"])


        prob = Problem(model)
        prob.setup()
        prob.run_model()

        val0 = np.array([ 50.26787317,  49.76106232,  19.66117913])
        val1 = np.array([-32.62094041, -31.67449135, -27.46959668])

        tol = 1e-5
        assert_rel_error(self, prob['f'], val0, tol)
        assert_rel_error(self, prob['g'], val1, tol)
        self.run_and_check_derivs(prob)
Exemple #11
0
    def test_raise_out_of_bounds_error(self):
        model = Group()
        ivc = IndepVarComp()

        mapdata = SampleMap()

        params = mapdata.param_data
        x, y, z = params
        outs = mapdata.output_data
        z = outs[0]
        ivc.add_output('x', x['default'], units=x['units'])
        ivc.add_output('y', y['default'], units=y['units'])
        ivc.add_output('z', z['default'], units=z['units'])

        model.add_subsystem('des_vars', ivc, promotes=["*"])

        # Need to make sure extrapolate is False for bounds to be checked
        comp = MetaModelStructuredComp(method='slinear', extrapolate=False)

        for param in params:
            comp.add_input(param['name'], param['default'], param['values'])

        for out in outs:
            comp.add_output(out['name'], out['default'], out['values'])

        model.add_subsystem('comp', comp, promotes=["*"])
        self.prob = Problem(model)
        self.prob.setup()

        self.prob['x'] = 1.0
        self.prob['y'] = 0.75
        self.prob['z'] = 9.0 # intentionally set to be out of bounds

        # The interpolating output name is given as a regexp because the exception could
        #   happen with f or g first. The order those are evaluated comes from the keys of
        #   dict so no guarantee on the order except for Python 3.6 !
        msg = "Error interpolating output '[f|g]' in 'comp' because input 'comp.z' was " \
              "out of bounds \('.*', '.*'\) with value '9.0'"
        with assertRaisesRegex(self, ValueError, msg):
           self.run_and_check_derivs(self.prob)
Exemple #12
0
def propeller_map_Raymer(vec_size=1):
    # Data from Raymer, Aircraft Design A Conceptual Approach, 4th Ed pg 498 fig 13.12 extrapolated in low cp range
    # For a 3 bladed constant-speed propeller
    J = np.linspace(0.2,2.8,14)
    cp = np.array([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8])

    #raymer_data = np.ones((9,14))*0.75
    raymer_data = np.array([[0.45,0.6,0.72,0.75,0.70,0.65,0.6,0.55,0.5,0.45,0.40,0.35,0.3,0.25],
                            [0.35,0.6,0.74,0.83,0.86,0.88,0.9,0.9,0.88,0.85,0.83,0.8,0.75,0.7],
                            [0.2,0.35,0.55,0.7,0.8,0.85,0.87,0.9,0.91,0.92,0.9,0.9,0.88,0.87],
                            [0.12,0.22,0.36,0.51,0.66,0.75,0.8,0.85,0.87,0.88,0.91,0.905,0.902,0.9],
                            [0.07,0.15,0.29,0.36,0.45,0.65,0.73,0.77,0.83,0.85,0.87,0.875,0.88,0.895],
                            [0.05,0.12,0.25,0.32,0.38,0.50,0.61,0.72,0.77,0.79,0.83,0.85,0.86,0.865],
                            [0.04,0.11,0.19,0.26,0.33,0.40,0.51,0.61,0.71,0.74,0.78,0.815,0.83,0.85],
                            [0.035,0.085,0.16,0.22,0.28,0.35,0.41,0.52,0.605,0.69,0.74,0.775,0.8,0.82],
                            [0.03,0.06,0.13,0.19,0.24,0.31,0.35,0.46,0.52,0.63,0.71,0.75,0.78,0.8]])
    # Create regular grid interpolator instance
    interp = MetaModelStructuredComp(method='cubic',extrapolate=True,vec_size=vec_size)
    interp.add_input('cp', 0.3, cp)
    interp.add_input('J', 1, J)
    interp.add_output('eta_prop', 0.8, raymer_data)
    return interp
Exemple #13
0
    def test_xor(self):
        import numpy as np
        from openmdao.api import Group, Problem, IndepVarComp
        from openmdao.components.meta_model_structured_comp import MetaModelStructuredComp

        # Create regular grid interpolator instance
        xor_interp = MetaModelStructuredComp(method='slinear')

        # set up inputs and outputs
        xor_interp.add_input('x', 0.0, training_data=np.array([0.0, 1.0]), units=None)
        xor_interp.add_input('y', 1.0, training_data=np.array([0.0, 1.0]), units=None)

        xor_interp.add_output('xor', 1.0, training_data=np.array([[0.0, 1.0], [1.0, 0.0]]), units=None)

        # Set up the OpenMDAO model
        model = Group()
        ivc = IndepVarComp()
        ivc.add_output('x', 0.0)
        ivc.add_output('y', 1.0)
        model.add_subsystem('ivc', ivc, promotes=["*"])
        model.add_subsystem('comp', xor_interp, promotes=["*"])
        prob = Problem(model)
        prob.setup()

        # Now test out a 'fuzzy' XOR
        prob['x'] = 0.9
        prob['y'] = 0.001242

        prob.run_model()

        computed = prob['xor']
        actual = 0.8990064

        assert_almost_equal(computed, actual)

        # we can verify all gradients by checking against finite-difference
        prob.check_partials(compact_print=True)
    def __init__(self, model, resolution=50, doc=None):
        """
        Initialize parameters.

        Parameters
        ----------
        model : MetaModelComponent
            Reference to meta model component
        resolution : int
            Value used to calculate the size of contour plot meshgrid
        doc : Document
            The bokeh document to build.
        """
        self.prob = Problem()
        self.resolution = resolution
        logging.getLogger("bokeh").setLevel(logging.ERROR)

        # If the surrogate model coming in is structured
        if isinstance(model, MetaModelUnStructuredComp):
            self.is_structured_meta_model = False

            # Create list of input names, check if it has more than one input, then create list
            # of outputs
            self.input_names = [name[0] for name in model._surrogate_input_names]
            if len(self.input_names) < 2:
                raise ValueError('Must have more than one input value')
            self.output_names = [name[0] for name in model._surrogate_output_names]

            # Create reference for untructured component
            self.meta_model = MetaModelUnStructuredComp(
                default_surrogate=model.options['default_surrogate'])

        # If the surrogate model coming in is unstructured
        elif isinstance(model, MetaModelStructuredComp):
            self.is_structured_meta_model = True

            self.input_names = [name for name in model._var_rel_names['input']]

            if len(self.input_names) < 2:
                raise ValueError('Must have more than one input value')

            self.output_names = [name for name in model._var_rel_names['output']]

            self.meta_model = MetaModelStructuredComp(
                distributed=model.options['distributed'],
                extrapolate=model.options['extrapolate'],
                method=model.options['method'],
                training_data_gradients=model.options['training_data_gradients'],
                vec_size=1)

        # Pair input list names with their respective data
        self.training_inputs = {}

        self._setup_empty_prob_comp(model)

        # Setup dropdown menus for x/y inputs and the output value
        self.x_input_select = Select(title="X Input:", value=[x for x in self.input_names][0],
                                     options=[x for x in self.input_names])
        self.x_input_select.on_change('value', self._x_input_update)

        self.y_input_select = Select(title="Y Input:", value=[x for x in self.input_names][1],
                                     options=[x for x in self.input_names])
        self.y_input_select.on_change('value', self._y_input_update)

        self.output_select = Select(title="Output:", value=[x for x in self.output_names][0],
                                    options=[x for x in self.output_names])
        self.output_select.on_change('value', self._output_value_update)

        # Create sliders for each input
        self.slider_dict = {}
        self.predict_inputs = {}
        for title, values in self.training_inputs.items():
            slider_data = np.linspace(min(values), max(values), self.resolution)
            self.predict_inputs[title] = slider_data
            # Calculates the distance between slider ticks
            slider_step = slider_data[1] - slider_data[0]
            slider_object = Slider(start=min(values), end=max(values), value=min(values),
                                   step=slider_step, title=str(title))
            self.slider_dict[title] = slider_object

        self._slider_attrs()

        # Length of inputs and outputs
        self.num_inputs = len(self.input_names)
        self.num_outputs = len(self.output_names)

        # Precalculate the problem bounds.
        limits = np.array([[min(value), max(value)] for value in self.training_inputs.values()])
        self.limit_range = limits[:, 1] - limits[:, 0]

        # Positional indicies
        self.x_index = 0
        self.y_index = 1
        self.output_variable = self.output_names.index(self.output_select.value)

        # Data sources are filled with initial values
        # Slider Column Data Source
        self.slider_source = ColumnDataSource(data=self.predict_inputs)

        # Contour plot Column Data Source
        self.contour_plot_source = ColumnDataSource(data=dict(
            z=np.random.rand(self.resolution, self.resolution)))
        self.contour_training_data_source = ColumnDataSource(
            data=dict(x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution)))

        # Bottom plot Column Data Source
        self.bottom_plot_source = ColumnDataSource(data=dict(
            x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution)))
        self.bottom_plot_scatter_source = ColumnDataSource(data=dict(
            bot_slice_x=np.repeat(0, self.resolution), bot_slice_y=np.repeat(0, self.resolution)))

        # Right plot Column Data Source
        self.right_plot_source = ColumnDataSource(data=dict(
            x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution)))
        self.right_plot_scatter_source = ColumnDataSource(data=dict(
            right_slice_x=np.repeat(0, self.resolution),
            right_slice_y=np.repeat(0, self.resolution)))

        # Text input to change the distance of reach when searching for nearest data points
        self.scatter_distance = TextInput(value="0.1", title="Scatter Distance")
        self.scatter_distance.on_change('value', self._scatter_input)
        self.dist_range = float(self.scatter_distance.value)

        # Grouping all of the sliders and dropdowns into one column
        sliders = [value for value in self.slider_dict.values()]
        sliders.extend(
            [self.x_input_select, self.y_input_select, self.output_select, self.scatter_distance])
        self.sliders_and_selects = row(
            column(*sliders))

        # Layout creation
        self.doc_layout = row(self._contour_data(), self._right_plot(), self.sliders_and_selects)
        self.doc_layout2 = row(self._bottom_plot())

        if doc is None:
            doc = curdoc()

        doc.add_root(self.doc_layout)
        doc.add_root(self.doc_layout2)
        doc.title = 'Meta Model Visualization'