コード例 #1
0
    def test_basic(self):
        prob = om.Problem()
        model = prob.model

        n_cp = 80
        n_point = 160

        t = np.linspace(0, 3.0 * np.pi, n_cp)
        x = np.sin(t)

        model.add_subsystem('px', om.IndepVarComp('x', val=x))
        model.add_subsystem(
            'interp',
            om.BsplinesComp(num_control_points=n_cp,
                            num_points=n_point,
                            in_name='h_cp',
                            out_name='h',
                            distribution='uniform'))

        model.connect('px.x', 'interp.h_cp')

        prob.setup()
        prob.run_model()

        xx = prob['interp.h'].flatten()
        tt = np.linspace(0, 3.0 * np.pi, n_point)

        x_expected = np.sin(tt)
        delta = xx - x_expected

        # Here we test that we don't have crazy interpolation error.
        self.assertLess(max(delta), .15)
        # And that it gets middle points a little better.
        self.assertLess(max(delta[15:-15]), .06)
コード例 #2
0
    def test_vectorized(self):
        import numpy as np

        import openmdao.api as om
        from openmdao.utils.general_utils import printoptions

        prob = om.Problem()
        model = prob.model

        n_cp = 5
        n_point = 10

        t = np.linspace(0, 0.5 * np.pi, n_cp)
        x = np.empty((2, n_cp))
        x[0, :] = np.sin(t)
        x[1, :] = 2.0 * np.sin(t)

        model.add_subsystem('px', om.IndepVarComp('x', val=x))
        model.add_subsystem(
            'interp',
            om.BsplinesComp(num_control_points=n_cp,
                            num_points=n_point,
                            vec_size=2,
                            in_name='h_cp',
                            out_name='h'))
        model.connect('px.x', 'interp.h_cp')

        prob.setup()
        prob.run_model()

        xx = prob['interp.h']

        with printoptions(precision=3, floatmode='fixed'):
            self.assertEqual('Control Points:', 'Control Points:')
            assert_rel_error(
                self, x[0, :],
                np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5)
            assert_rel_error(
                self, x[1, :],
                2.0 * np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]),
                1e-5)

            self.assertEqual('Output Points:', 'Output Points:')
            assert_rel_error(
                self, xx[0, :],
                np.array([
                    0., 0.06687281, 0.23486869, 0.43286622, 0.6062628,
                    0.74821484, 0.86228902, 0.94134389, 0.98587725, 1.
                ]), 1e-5)
            assert_rel_error(
                self, xx[1, :], 2.0 * np.array([
                    0., 0.06687281, 0.23486869, 0.43286622, 0.6062628,
                    0.74821484, 0.86228902, 0.94134389, 0.98587725, 1.
                ]), 1e-5)
コード例 #3
0
    def test_distribution_sine(self):
        import openmdao.api as om

        prob = om.Problem()
        model = prob.model

        n_cp = 20
        n_point = 100

        tvec = np.linspace(0, 1.0, n_cp)
        t = 3.0 * np.pi * 0.5 * (1.0 + np.sin(-0.5 * np.pi + tvec * np.pi))
        x = np.sin(t)

        model.add_subsystem('px', om.IndepVarComp('x', val=x))
        model.add_subsystem(
            'interp',
            om.BsplinesComp(num_control_points=n_cp,
                            num_points=n_point,
                            in_name='h_cp',
                            out_name='h',
                            distribution='sine'))
        model.connect('px.x', 'interp.h_cp')

        prob.setup()
        prob.run_model()

        xx = prob['interp.h'].flatten()
        ttvec = np.linspace(0, 1.0, n_point)
        tt = 3.0 * np.pi * 0.5 * (1.0 + np.sin(-0.5 * np.pi + ttvec * np.pi))

        import matplotlib.pyplot as plt

        plt.figure(1)
        plt.plot(tt, xx, "b")
        plt.plot(t, x, "ro")
        plt.xlabel("Distance along Beam")
        plt.ylabel('Design Variable')
        plt.title("Sine Distribution of Control Points")
        plt.legend(['Variable', 'Control Points'], loc=4)
        plt.grid(True)
        plt.show()
コード例 #4
0
    def test_units(self):
        n_cp = 5
        n_point = 10

        interp = om.BsplinesComp(num_control_points=n_cp,
                                 num_points=n_point,
                                 in_name='h_cp',
                                 out_name='h',
                                 units='inch')

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

        # verify that both input and output of the bsplines comp have proper units
        inputs = interp.list_inputs(units=True, out_stream=None)
        self.assertEqual(len(inputs), 1)
        for var, meta in inputs:
            self.assertEqual(meta['units'], 'inch')

        outputs = interp.list_outputs(units=True, out_stream=None)
        self.assertEqual(len(outputs), 1)
        for var, meta in outputs:
            self.assertEqual(meta['units'], 'inch')
コード例 #5
0
    def setup(self):
        E = self.options['E']
        L = self.options['L']
        b = self.options['b']
        volume = self.options['volume']
        num_elements = self.options['num_elements']
        num_nodes = num_elements + 1
        num_cp = self.options['num_cp']
        num_load_cases = self.options['num_load_cases']

        inputs_comp = om.IndepVarComp()
        inputs_comp.add_output('h_cp', shape=num_cp)
        self.add_subsystem('inputs_comp', inputs_comp)

        comp = om.BsplinesComp(num_control_points=num_cp,
                               num_points=num_elements,
                               in_name='h_cp',
                               out_name='h')
        self.add_subsystem('interp', comp)

        I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b)
        self.add_subsystem('I_comp', I_comp)

        comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L)
        self.add_subsystem('local_stiffness_matrix_comp', comp)

        # Parallel Subsystem for load cases.
        par = self.add_subsystem('parallel', om.ParallelGroup())

        # Determine how to split cases up over the available procs.
        nprocs = self.comm.size
        divide = divide_cases(num_load_cases, nprocs)

        obj_srcs = []
        for j, this_proc in enumerate(divide):
            num_rhs = len(this_proc)

            name = 'sub_%d' % j
            sub = par.add_subsystem(name, om.Group())

            # Load is a sinusoidal distributed force of varying spatial frequency.
            force_vector = np.zeros((2 * num_nodes, num_rhs))
            for i, k in enumerate(this_proc):

                end = 1.5 * np.pi
                if num_load_cases > 1:
                    end += k * 0.5 * np.pi / (num_load_cases - 1)

                x = np.linspace(0, end, num_nodes)
                f = -np.sin(x)
                force_vector[0:-1:2, i] = f

            comp = MultiStatesComp(num_elements=num_elements,
                                   force_vector=force_vector,
                                   num_rhs=num_rhs)
            sub.add_subsystem('states_comp', comp)

            comp = MultiDisplacementsComp(num_elements=num_elements,
                                          num_rhs=num_rhs)
            sub.add_subsystem('displacements_comp', comp)

            comp = MultiComplianceComp(num_elements=num_elements,
                                       force_vector=force_vector,
                                       num_rhs=num_rhs)
            sub.add_subsystem('compliance_comp', comp)

            self.connect('local_stiffness_matrix_comp.K_local',
                         'parallel.%s.states_comp.K_local' % name)

            for k in range(num_rhs):
                sub.connect('states_comp.d_%d' % k,
                            'displacements_comp.d_%d' % k)
                sub.connect('displacements_comp.displacements_%d' % k,
                            'compliance_comp.displacements_%d' % k)

                obj_srcs.append('parallel.%s.compliance_comp.compliance_%d' %
                                (name, k))

        comp = VolumeComp(num_elements=num_elements, b=b, L=L)
        self.add_subsystem('volume_comp', comp)

        comp = om.ExecComp([
            'obj = ' +
            ' + '.join(['compliance_%d' % i for i in range(num_load_cases)])
        ])
        self.add_subsystem('obj_sum', comp)

        for j, src in enumerate(obj_srcs):
            self.connect(src, 'obj_sum.compliance_%d' % j)

        self.connect('inputs_comp.h_cp', 'interp.h_cp')
        self.connect('interp.h', 'I_comp.h')
        self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')
        self.connect('interp.h', 'volume_comp.h')

        self.add_design_var('inputs_comp.h_cp', lower=1e-2, upper=10.)
        self.add_constraint('volume_comp.volume', equals=volume)
        self.add_objective('obj_sum.obj')
コード例 #6
0
    def setup(self):
        E = self.options['E']
        L = self.options['L']
        b = self.options['b']
        volume = self.options['volume']
        max_bending = self.options['max_bending']
        num_elements = self.options['num_elements']
        num_nodes = num_elements + 1
        num_cp = self.options['num_cp']
        num_load_cases = self.options['num_load_cases']
        parallel_derivs = self.options['parallel_derivs']

        inputs_comp = om.IndepVarComp()
        inputs_comp.add_output('h_cp', shape=num_cp)
        self.add_subsystem('inputs_comp', inputs_comp)

        comp = om.BsplinesComp(num_control_points=num_cp,
                               num_points=num_elements,
                               in_name='h_cp',
                               out_name='h')
        self.add_subsystem('interp', comp)

        I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b)
        self.add_subsystem('I_comp', I_comp)

        comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L)
        self.add_subsystem('local_stiffness_matrix_comp', comp)

        # Parallel Subsystem for load cases.
        par = self.add_subsystem('parallel', om.ParallelGroup())

        # Determine how to split cases up over the available procs.
        nprocs = self.comm.size
        divide = divide_cases(num_load_cases, nprocs)

        for j, this_proc in enumerate(divide):
            num_rhs = len(this_proc)

            name = 'sub_%d' % j
            sub = par.add_subsystem(name, om.Group())

            # Load is a sinusoidal distributed force of varying spatial frequency.
            force_vector = np.zeros((2 * num_nodes, num_rhs))
            for i, k in enumerate(this_proc):

                end = 1.5 * np.pi
                if num_load_cases > 1:
                    end += k * 0.5 * np.pi / (num_load_cases - 1)

                x = np.linspace(0, end, num_nodes)
                f = -np.sin(x)
                force_vector[0:-1:2, i] = f

            comp = MultiStatesComp(num_elements=num_elements,
                                   force_vector=force_vector,
                                   num_rhs=num_rhs)
            sub.add_subsystem('states_comp', comp)

            comp = MultiDisplacementsComp(num_elements=num_elements,
                                          num_rhs=num_rhs)
            sub.add_subsystem('displacements_comp', comp)

            comp = MultiStressComp(num_elements=num_elements,
                                   E=E,
                                   num_rhs=num_rhs)
            sub.add_subsystem('stress_comp', comp)

            self.connect('local_stiffness_matrix_comp.K_local',
                         'parallel.%s.states_comp.K_local' % name)

            for k in range(num_rhs):
                sub.connect('states_comp.d_%d' % k,
                            'displacements_comp.d_%d' % k)
                sub.connect('displacements_comp.displacements_%d' % k,
                            'stress_comp.displacements_%d' % k)

                comp = om.KSComp(width=num_elements)
                comp.options['upper'] = max_bending
                sub.add_subsystem('KS_%d' % k, comp)

                sub.connect('stress_comp.stress_%d' % k, 'KS_%d.g' % k)

                if parallel_derivs:
                    color = 'red_%d' % k
                else:
                    color = None

                sub.add_constraint('KS_%d.KS' % k,
                                   upper=0.0,
                                   parallel_deriv_color=color)

        comp = VolumeComp(num_elements=num_elements, b=b, L=L)
        self.add_subsystem('volume_comp', comp)

        self.connect('inputs_comp.h_cp', 'interp.h_cp')
        self.connect('interp.h', 'I_comp.h')
        self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')
        self.connect('interp.h', 'volume_comp.h')

        self.add_design_var('inputs_comp.h_cp', lower=1e-2, upper=10.)
        self.add_objective('volume_comp.volume')