コード例 #1
0
    def test_vectorized_all_derivs(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([[5.0, 12.0, 14.0, 16.0, 21.0, 29.0],
                        [7.0, 13.0, 9.0, 6.0, 12.0, 14.0]])
        n = 12
        x = np.linspace(1.0, 12.0, n)

        for method in SPLINE_METHODS:

            prob = om.Problem()

            # These methods have their own test.
            if method in ['akima', 'bsplines']:
                continue

            opts = {}

            comp = om.SplineComp(method=method, vec_size=2, x_cp_val=xcp, x_interp_val=x,
                                 interp_options=opts)

            comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)
            prob.model.add_subsystem('interp1', comp)

            prob.setup(force_alloc_complex=True)
            prob.run_model()

            if method.startswith('scipy'):
                derivs = prob.check_partials(out_stream=None)
                assert_check_partials(derivs, atol=1e-7, rtol=1e-7)

            else:
                derivs = prob.check_partials(out_stream=None, method='cs')
                assert_check_partials(derivs, atol=1e-12, rtol=1e-12)
コード例 #2
0
    def test_vectorized_akima(self):

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([[5.0, 12.0, 14.0, 16.0, 21.0, 29.0],
                        [7.0, 13.0, 9.0, 6.0, 12.0, 14.0]])
        n = 12
        x = np.linspace(1.0, 12.0, n)

        comp = om.SplineComp(method='akima',
                             vec_size=2,
                             x_cp_val=xcp,
                             x_interp_val=x,
                             interp_options={'delta_x': 0.1})

        comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)
        self.prob.model.add_subsystem('akima1', comp)

        self.prob.setup(force_alloc_complex=True)
        self.prob.run_model()

        y = np.array([[
            5., 12., 13.01239669, 14., 14.99888393, 16., 17.06891741,
            18.26264881, 19.5750558, 21., 24.026042, 29.
        ],
                      [
                          7., 13., 11.02673797, 9., 7.09090909, 6., 6.73660714,
                          8.46428571, 10.45982143, 12., 13.08035714, 14.
                      ]])

        assert_near_equal(y.flatten(),
                          self.prob['akima1.y_val'].flatten(),
                          tolerance=1e-8)

        derivs = self.prob.check_partials(out_stream=None, method='cs')
        assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
コード例 #3
0
    def test(self):
        surface = get_default_surfaces()[0]
        surface['with_wave'] = True
        surface['t_over_c_cp'] = np.array([0.15, 0.21, 0.03, 0.05])

        nx = surface['mesh'].shape[0]
        ny = surface['mesh'].shape[1]
        n_cp = len(surface['t_over_c_cp'])

        group = om.Group()

        indep_var_comp = om.IndepVarComp()
        indep_var_comp.add_output('t_over_c_cp', val=surface['t_over_c_cp'])
        indep_var_comp.add_output('Mach_number', val=.95)
        indep_var_comp.add_output('CL', val=0.7)
        indep_var_comp.add_output('widths', val = np.array([12.14757848, 11.91832712, 11.43730892]),units='m')
        indep_var_comp.add_output('cos_sweep', val = np.array([10.01555924,  9.80832351,  9.79003729]),units='m')
        indep_var_comp.add_output('chords', val = np.array([ 2.72835132,  5.12528179,  7.88916016, 13.6189974]),units='m')
        group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*'])
        
        x_interp = np.linspace(0., 1., int(ny-1))
        comp = group.add_subsystem('t_over_c_bsp', om.SplineComp(
            method='bsplines', x_interp_val=x_interp,
            num_cp=n_cp,
            interp_options={'order' : min(n_cp, 4)}),
            promotes_inputs=['t_over_c_cp'], promotes_outputs=['t_over_c'])
        comp.add_spline(y_cp_name='t_over_c_cp', y_interp_name='t_over_c')

        comp = WaveDrag(surface=surface)
        group.add_subsystem('wavedrag', comp, promotes=['*'])

        run_test(self, group, complex_flag=True)
コード例 #4
0
    def test(self):
        surface = get_default_surfaces()[0]
        surface['t_over_c_cp'] = np.array([0.1, 0.15, 0.2])

        nx = surface['mesh'].shape[0]
        ny = surface['mesh'].shape[1]
        n_cp = len(surface['t_over_c_cp'])

        group = om.Group()

        indep_var_comp = om.IndepVarComp()
        indep_var_comp.add_output('t_over_c_cp', val=surface['t_over_c_cp'])
        group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*'])

        x_interp = np.linspace(0., 1., int(ny - 1))
        comp = group.add_subsystem('t_over_c_bsp',
                                   om.SplineComp(
                                       method='bsplines',
                                       x_interp_val=x_interp,
                                       num_cp=n_cp,
                                       interp_options={'order': min(n_cp, 4)}),
                                   promotes_inputs=['t_over_c_cp'],
                                   promotes_outputs=['t_over_c'])
        comp.add_spline(y_cp_name='t_over_c_cp',
                        y_interp_name='t_over_c',
                        y_cp_val=np.zeros(n_cp))

        comp = ViscousDrag(surface=surface, with_viscous=True)
        group.add_subsystem('viscousdrag', comp, promotes=['*'])

        run_test(self, group, complex_flag=True)
コード例 #5
0
    def test_2to3doc_fixed_grid(self):
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        ncp = len(ycp)
        n = 11

        prob = om.Problem()

        akima_option = {'delta_x': 0.1}
        comp = om.SplineComp(method='akima',
                             num_cp=ncp,
                             x_interp_val=np.linspace(0.0, 1.0, n),
                             interp_options=akima_option)

        prob.model.add_subsystem('comp1', comp)

        comp.add_spline(y_cp_name='chord_cp',
                        y_interp_name='chord',
                        y_cp_val=ycp)

        prob.setup()
        prob.run_model()

        y = np.array([[
            5., 9.4362525, 12., 13.0012475, 14., 14.99875415, 16., 17.93874585,
            21., 24.625, 29.
        ]])

        assert_near_equal(prob['comp1.chord'], y, 1e-6)
コード例 #6
0
    def test_y_units(self):
        x_cp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])

        n = 50
        x = np.linspace(1.0, 12.0, n)

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

        # Set options specific to akima
        akima_option = {'delta_x': 0.1, 'eps': 1e-30}

        comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x,
                             interp_options=akima_option)

        prob.model.add_subsystem('atmosphere', comp)

        comp.add_spline(y_cp_name='alt_cp', y_interp_name='alt', y_cp_val=y_cp, y_units='kft')

        prob.setup(force_alloc_complex=True)
        prob.run_model()

        output = prob.model.list_inputs(units=True)
        self.assertEqual(output[0][1]['units'], 'kft')
コード例 #7
0
    def test_akima_options(self):
        import numpy as np

        import openmdao.api as om

        x_cp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])

        n = 50
        x = np.linspace(1.0, 12.0, n)

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

        # Set options specific to akima
        akima_option = {'delta_x': 0.1, 'eps': 1e-30}

        comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x,
                             interp_options=akima_option)

        prob.model.add_subsystem('atmosphere', comp)

        comp.add_spline(y_cp_name='alt_cp', y_interp_name='alt', y_cp_val=y_cp, y_units='kft')

        prob.setup(force_alloc_complex=True)
        prob.run_model()
コード例 #8
0
    def test_bspline_options(self):
        import numpy as np

        import openmdao.api as om

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

        n_cp = 80
        n_point = 160

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

        model.add_subsystem('px', om.IndepVarComp('x', val=x))

        # Set options specific to bsplines
        bspline_options = {'order': 3}

        comp = om.SplineComp(method='bsplines', x_interp_val=tt, num_cp=n_cp,
                            interp_options=bspline_options)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units=None)

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

        prob.setup(force_alloc_complex=True)
        prob.run_model()
コード例 #9
0
    def test_spline_distribution_example(self):

        import numpy as np

        import openmdao.api as om
        from openmdao.utils.spline_distributions import sine_distribution

        x_cp = np.linspace(0., 1., 6)
        y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 20
        x = om.sine_distribution(20, start=0, end=1, phase=np.pi)

        prob = om.Problem()

        comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x)
        prob.model.add_subsystem('akima1', comp)

        comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=y_cp)

        prob.setup(force_alloc_complex=True)
        prob.run_model()

        akima_y = np.array([[5.         , 5.32381994,  6.28062691 , 7.79410646 , 9.64169506, 11.35166363,
                             12.26525921, 12.99152288, 13.77257256, 14.58710327, 15.41289673, 16.28341046,
                             17.96032258, 20.14140712, 22.31181718, 24.40891577, 26.27368825, 27.74068235,
                             28.67782484, 29.        ]])

        assert_rel_error(self, akima_y.flatten(), prob['akima1.y_val'].flatten(), tolerance=1e-8)
コード例 #10
0
    def test_bsplines_vectorized(self):
        prob = om.Problem()
        model = prob.model

        n_cp = 5
        n_point = 10

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

        t_sin = (0.5 * (1.0 + np.sin(-0.5 * np.pi + 2.0 * tt))) * np.pi * 0.5

        model.add_subsystem('px', om.IndepVarComp('x', val=x))
        bspline_options = {'order': 4}
        comp = om.SplineComp(method='bsplines',
                             x_interp_val=t_sin,
                             num_cp=n_cp,
                             vec_size=2,
                             interp_options=bspline_options)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

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

        prob.setup(force_alloc_complex=True)
        prob.run_model()

        xx = prob['interp.h']

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

            assert_near_equal(
                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_near_equal(
                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)

        derivs = prob.check_partials(out_stream=None, method='cs')
        assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
コード例 #11
0
    def test_basic_example(self):
        import numpy as np

        import openmdao.api as om

        xcp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        ycp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 50
        x = np.linspace(1.0, 12.0, n)

        prob = om.Problem()

        akima_option = {'delta_x': 0.1}
        comp = om.SplineComp(method='akima', x_cp_val=xcp, x_interp_val=x,
                             interp_options=akima_option)

        prob.model.add_subsystem('akima1', comp)

        comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=ycp)

        prob.setup(force_alloc_complex=True)
        prob.run_model()

        akima_y = np.array([[ 5.       ,  7.20902005,  9.21276849, 10.81097162, 11.80335574,
                            12.1278001 , 12.35869145, 12.58588536, 12.81022332, 13.03254681,
                            13.25369732, 13.47451633, 13.69584534, 13.91852582, 14.14281484,
                            14.36710105, 14.59128625, 14.81544619, 15.03965664, 15.26399335,
                            15.48853209, 15.7133486 , 15.93851866, 16.16573502, 16.39927111,
                            16.63928669, 16.8857123 , 17.1384785 , 17.39751585, 17.66275489,
                            17.93412619, 18.21156029, 18.49498776, 18.78433915, 19.07954501,
                            19.38053589, 19.68724235, 19.99959495, 20.31752423, 20.64096076,
                            20.96983509, 21.37579297, 21.94811407, 22.66809748, 23.51629844,
                            24.47327219, 25.51957398, 26.63575905, 27.80238264, 29.        ]])

        assert_rel_error(self, akima_y.flatten(), prob['akima1.y_val'].flatten(), tolerance=1e-8)
コード例 #12
0
    def test_multi_splines(self):

        import numpy as np

        import openmdao.api as om

        x_cp = np.array([1.0, 2.0, 4.0, 6.0, 10.0, 12.0])
        y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        y_cp2 = np.array([1.0, 5.0, 7.0, 8.0, 13.0, 16.0])
        n = 50
        x = np.linspace(1.0, 12.0, n)

        prob = om.Problem()

        comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x)
        prob.model.add_subsystem('akima1', comp)

        comp.add_spline(y_cp_name='ycp1',
                        y_interp_name='y_val1',
                        y_cp_val=y_cp)
        comp.add_spline(y_cp_name='ycp2',
                        y_interp_name='y_val2',
                        y_cp_val=y_cp2)

        prob.setup(force_alloc_complex=True)
        prob.run_model()
コード例 #13
0
    def test_akima_backward_compatibility(self):

        comp = om.SplineComp(method='akima',
                             x_cp_val=self.x_cp,
                             x_interp_val=self.x,
                             interp_options={'delta_x': 0.1})
        comp.add_spline(y_cp_name='ycp',
                        y_interp_name='y_val',
                        y_cp_val=self.y_cp)

        self.prob.model.add_subsystem('akima1', comp)

        self.prob.setup(force_alloc_complex=True)
        self.prob.run_model()

        # Verification array from openmdao 2.x using AkimaSplineComp
        akima_y = np.array([[
            5., 7.20902005, 9.21276849, 10.81097162, 11.80335574, 12.1278001,
            12.35869145, 12.58588536, 12.81022332, 13.03254681, 13.25369732,
            13.47451633, 13.69584534, 13.91852582, 14.14281484, 14.36710105,
            14.59128625, 14.81544619, 15.03965664, 15.26399335, 15.48853209,
            15.7133486, 15.93851866, 16.16573502, 16.39927111, 16.63928669,
            16.8857123, 17.1384785, 17.39751585, 17.66275489, 17.93412619,
            18.21156029, 18.49498776, 18.78433915, 19.07954501, 19.38053589,
            19.68724235, 19.99959495, 20.31752423, 20.64096076, 20.96983509,
            21.37579297, 21.94811407, 22.66809748, 23.51629844, 24.47327219,
            25.51957398, 26.63575905, 27.80238264, 29.
        ]])

        assert_near_equal(akima_y.flatten(),
                          self.prob['akima1.y_val'].flatten(),
                          tolerance=1e-8)

        derivs = self.prob.check_partials(out_stream=None, method='cs')
        assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
コード例 #14
0
    def test_spline_distribution_example(self):

        x_cp = np.linspace(0., 1., 6)
        y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0])
        n = 20
        x = sine_distribution(n, start=0.0, end=1.0, phase=np.pi)

        prob = om.Problem()

        comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x)
        prob.model.add_subsystem('akima1', comp)

        comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=y_cp)

        prob.setup(force_alloc_complex=True)
        prob.run_model()

        assert_array_almost_equal(
            prob['akima1.y_val'],
            np.array([[
                5., 5.32381994, 6.28062691, 7.79410646, 9.64169506,
                11.35166363, 12.26525921, 12.99152288, 13.77257256,
                14.58710327, 15.41289673, 16.28341046, 17.96032258,
                20.14140712, 22.31181718, 24.40891577, 26.27368825,
                27.74068235, 28.67782484, 29.
            ]]))
コード例 #15
0
    def test_no_ycp_val(self):

        comp = om.SplineComp(method='akima', x_cp_val=self.x_cp, x_interp_val=self.x)

        comp.add_spline(y_cp_name='ycp', y_interp_name='y_val')
        self.prob.model.add_subsystem('akima1', comp)

        self.prob.setup(force_alloc_complex=True)
        self.prob.run_model()
コード例 #16
0
ファイル: test_spline_comp.py プロジェクト: wright/OpenMDAO
    def test_bsplines_2to3doc(self):
        from openmdao.utils.spline_distributions import sine_distribution

        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)

        # In 2.x, the BsplinesComp had a built-in sinusoidal distribution.
        t_sin = sine_distribution(n_point) * np.pi * 0.5

        bspline_options = {'order': 4}
        comp = om.SplineComp(method='bsplines',
                             x_interp_val=t_sin,
                             num_cp=n_cp,
                             vec_size=2,
                             interp_options=bspline_options)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

        prob.setup()
        prob.run_model()

        xx = prob['interp.h']

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

            assert_near_equal(
                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_near_equal(
                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)
コード例 #17
0
    def test_multiple_splines(self):

        comp = om.SplineComp(method='akima', x_cp_val=self.x_cp, x_interp_val=self.x)
        self.prob.model.add_subsystem('akima1', comp)

        comp.add_spline(y_cp_name='ycp1', y_interp_name='y_val1', y_cp_val=self.y_cp)
        comp.add_spline(y_cp_name='ycp2', y_interp_name='y_val2', y_cp_val=self.y_cp2)

        self.prob.setup(force_alloc_complex=True)
        self.prob.run_model()
コード例 #18
0
    def test_akima_interp_options(self):

        akima_option = {'delta_x': 0.1, 'eps': 1e-30}
        comp = om.SplineComp(method='akima', x_cp_val=self.x_cp, x_interp_val=self.x,
                             interp_options=akima_option)

        self.prob.model.add_subsystem('atmosphere', comp)

        comp.add_spline(y_cp_name='alt_cp', y_interp_name='alt', y_cp_val=self.y_cp, y_units='kft')

        self.prob.setup(force_alloc_complex=True)
        self.prob.run_model()
コード例 #19
0
ファイル: test_spline_comp.py プロジェクト: wright/OpenMDAO
    def test_bspline_interp_basic(self):
        prob = om.Problem()
        model = prob.model

        n_cp = 80
        n_point = 160

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

        model.add_subsystem('px', om.IndepVarComp('x', val=x))

        bspline_options = {'order': 4}
        comp = om.SplineComp(method='bsplines',
                             x_interp_val=tt,
                             num_cp=n_cp,
                             interp_options=bspline_options)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

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

        prob.setup(force_alloc_complex=True)
        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)

        derivs = prob.check_partials(out_stream=None, method='cs')
        assert_check_partials(derivs, atol=1e-14, rtol=1e-14)
コード例 #20
0
ファイル: test_spline_comp.py プロジェクト: wright/OpenMDAO
    def test_bspline_bug(self):
        # Tests a bug fix where the interp_options weren't passed into
        # the bspline interp comp
        bspline_options = {'order': 3}
        comp = om.SplineComp(method='bsplines',
                             num_cp=6,
                             x_interp_val=self.x,
                             interp_options=bspline_options)

        self.prob.model.add_subsystem('atmosphere', comp)

        comp.add_spline(y_cp_name='alt_cp',
                        y_interp_name='alt',
                        y_cp_val=self.y_cp,
                        y_units='kft')

        self.prob.setup(force_alloc_complex=True)

        # If we set the bspline order to 3, then k should internally be 4
        self.assertEqual(comp.interps['alt'].table.k, 4)
コード例 #21
0
ファイル: test_spline_comp.py プロジェクト: wright/OpenMDAO
    def test_small_akima_spline_bug(self):
        # Fixes a bug that only occure for a 4 point spline.
        prob = om.Problem()

        num_cp = 4
        num_radial = 11
        comp = om.IndepVarComp()
        comp.add_output("chord_cp",
                        units="m",
                        val=np.array([0.1, 0.2, 0.3, 0.15]))
        comp.add_output("theta_cp",
                        units="rad",
                        val=np.array([1.0, 0.8, 0.6, 0.4]))
        prob.model.add_subsystem("inputs_comp", comp, promotes=["*"])

        x_cp = np.linspace(0.0, 1.0, num_cp)
        x_interp = cell_centered(num_radial, start=0.0, end=1.0)
        akima_options = {'delta_x': 0.1}
        comp = om.SplineComp(method='akima',
                             interp_options=akima_options,
                             x_cp_val=x_cp,
                             x_interp_val=x_interp)
        comp.add_spline(y_cp_name='chord_cp',
                        y_interp_name='chord_interp',
                        y_units='m')
        comp.add_spline(y_cp_name='theta_cp',
                        y_interp_name='theta_interp',
                        y_units='rad')
        prob.model.add_subsystem(
            'akima_comp',
            comp,
            promotes_inputs=['chord_cp', 'theta_cp'],
            promotes_outputs=['chord_interp', 'theta_interp'])
        prob.setup()

        # Make sure we don't get an exception
        prob.run_model()
コード例 #22
0
    def setup(self):
        nx = int(self.options["num_x"])
        ny = int(self.options["num_y"])
        n_twist = int(self.options["num_twist"])

        # =================================================================
        #                            Set up mesh
        # =================================================================
        self.add_subsystem(
            "mesh",
            PlanformMesh(num_x=nx, num_y=ny),
            promotes_inputs=[
                ("S", "ac|geom|wing|S_ref"),
                ("AR", "ac|geom|wing|AR"),
                ("taper", "ac|geom|wing|taper"),
                ("sweep", "ac|geom|wing|c4sweep"),
            ],
        )

        # Add bspline component for twist
        x_interp = np.linspace(0.0, 1.0, ny)
        comp = self.add_subsystem(
            "twist_bsp",
            om.SplineComp(method="bsplines",
                          x_interp_val=x_interp,
                          num_cp=n_twist,
                          interp_options={"order": min(n_twist, 4)}),
            promotes_inputs=[("twist_cp", "ac|geom|wing|twist")],
        )
        comp.add_spline(y_cp_name="twist_cp",
                        y_interp_name="twist",
                        y_units="deg")

        # Apply twist spline to mesh
        self.add_subsystem(
            "twist_mesh",
            Rotate(val=np.zeros(ny), mesh_shape=(nx, ny, 3), symmetry=True))
        self.connect("twist_bsp.twist", "twist_mesh.twist")
        self.connect("mesh.mesh", "twist_mesh.in_mesh")

        # =================================================================
        #              Compute atmospheric and fluid properties
        # =================================================================
        self.add_subsystem(
            "temp",
            TemperatureComp(num_nodes=1),
            promotes_inputs=["fltcond|h", "fltcond|TempIncrement"])
        self.add_subsystem("pressure",
                           PressureComp(num_nodes=1),
                           promotes_inputs=["fltcond|h"])
        self.add_subsystem("density", DensityComp(num_nodes=1))
        self.connect("temp.fltcond|T", "density.fltcond|T")
        self.connect("pressure.fltcond|p", "density.fltcond|p")
        self.add_subsystem("sound_speed", SpeedOfSoundComp(num_nodes=1))
        self.connect("temp.fltcond|T", "sound_speed.fltcond|T")
        self.add_subsystem(
            "airspeed",
            om.ExecComp("Utrue = Mach * a",
                        Utrue={
                            "units": "m/s",
                            "val": 200.0
                        },
                        a={
                            "units": "m/s",
                            "val": 300.0
                        }),
            promotes_inputs=[("Mach", "fltcond|M")],
        )
        self.connect("sound_speed.fltcond|a", "airspeed.a")

        # Compute dimensionalized Reynolds number (use linear interpolation from standard atmosphere up
        # to 35k ft to estimate dynamic viscosity)
        self.add_subsystem(
            "Re_calc",
            om.ExecComp(
                "re = rho * u / (-3.329134*10**(-10) * h + 1.792398*10**(-5))",
                re={
                    "units": "1/m",
                    "val": 1e6
                },
                rho={
                    "units": "kg/m**3",
                    "val": 1.0
                },
                u={
                    "units": "m/s",
                    "val": 100.0
                },
                h={
                    "units": "m",
                    "val": 1.0
                },
            ),
            promotes_inputs=[("h", "fltcond|h")],
        )
        self.connect("density.fltcond|rho", "Re_calc.rho")
        self.connect("airspeed.Utrue", "Re_calc.u")

        # =================================================================
        #                       Call OpenAeroStruct
        # =================================================================
        surf_dict = {
            "name": "wing",
            "mesh": np.zeros((nx, ny, 3)),  # this must be defined
            # because the VLMGeometry component uses the shape of the mesh in this
            # dictionary to determine the size of the mesh; the values don't matter
            "symmetry": True,  # if true, model one half of wing
            # reflected across the plane y = 0
            "S_ref_type": "projected",  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            "CL0": 0.0,  # CL of the surface at alpha=0
            "CD0": 0.0,  # CD of the surface at alpha=0
            # Airfoil properties for viscous drag calculation
            "k_lam": 0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            "t_over_c":
            np.array([0.12]),  # thickness over chord ratio (NACA SC2-0612)
            "c_max_t": 0.37,  # chordwise location of maximum (NACA SC2-0612)
            # thickness
            "with_viscous": True,  # if true, compute viscous drag
            "with_wave": True,  # if true, compute wave drag
        }

        # Overwrite any options in the surface dict with those provided in the options
        if self.options["surf_options"] is not None:
            for key in self.options["surf_options"]:
                surf_dict[key] = self.options["surf_options"][key]

        self.add_subsystem(
            "aero_point",
            AeroPoint(surfaces=[surf_dict]),
            promotes_inputs=[("Mach_number", "fltcond|M"),
                             ("alpha", "fltcond|alpha")],
            promotes_outputs=[
                (f"{surf_dict['name']}_perf.CD", "fltcond|CD"),
                (f"{surf_dict['name']}_perf.CL", "fltcond|CL"),
            ],
        )
        self.connect(
            "twist_mesh.mesh",
            [
                f"aero_point.{surf_dict['name']}.def_mesh",
                f"aero_point.aero_states.{surf_dict['name']}_def_mesh"
            ],
        )
        self.connect("airspeed.Utrue", "aero_point.v")
        self.connect("density.fltcond|rho", "aero_point.rho")
        self.connect("Re_calc.re", "aero_point.re")

        # Set input defaults for inputs that go to multiple locations
        self.set_input_defaults("fltcond|M", 0.1)
        self.set_input_defaults("fltcond|alpha", 0.0)

        # Set the thickness to chord ratio for wave and viscous drag calculation.
        # It must have a thickness to chord ratio for each panel, so there must be
        # ny-1 elements. Allow either one value (and duplicate it ny-1 times) or
        # an array of length ny-1, but nothing else.
        # NOTE: for aerostructural cases, this should be a design variable with control points over a spline
        if isinstance(surf_dict["t_over_c"],
                      (int, float)) or surf_dict["t_over_c"].size == 1:
            self.set_input_defaults(
                f"aero_point.{surf_dict['name']}_perf.t_over_c",
                val=surf_dict["t_over_c"] * np.ones(ny - 1))
        elif surf_dict["t_over_c"].size == ny - 1:
            self.set_input_defaults(
                f"aero_point.{surf_dict['name']}_perf.t_over_c",
                val=surf_dict["t_over_c"])
        else:
            raise ValueError(
                f"t_over_c in the surface dict must be either a number or an ndarray "
                f"with either one or ny-1 elements, not {surf_dict['t_over_c']}"
            )
コード例 #23
0
    def test3(self):
        """
        This is an extreme nonphysical case (large twist angles) for checking the computation.
        """

        surface = get_default_surfaces()[0]
        surface['t_over_c_cp'] = np.array([0.1, 0.15, 0.2])
        surface['spar_thickness_cp'] = np.array([0.004, 0.008, 0.02])
        surface['skin_thickness_cp'] = np.array([0.01, 0.015, 0.021])
        surface['fem_chords_cp'] = np.array([2., 3., 4.])
        surface['streamwise_chords_cp'] = np.array([3., 4., 5.])
        surface['fem_twists_cp'] = np.array([5., 3., 2.])

        surface['data_x_upper'] = np.array([
            0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2,
            0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6
        ],
                                           dtype='complex128')
        surface['data_x_lower'] = np.array([
            0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2,
            0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6
        ],
                                           dtype='complex128')
        surface['data_y_upper'] = np.array([
            0.0447, 0.046, 0.0472, 0.0484, 0.0495, 0.0505, 0.0514, 0.0523,
            0.0531, 0.0538, 0.0545, 0.0551, 0.0557, 0.0563, 0.0568, 0.0573,
            0.0577, 0.0581, 0.0585, 0.0588, 0.0591, 0.0593, 0.0595, 0.0597,
            0.0599, 0.06, 0.0601, 0.0602, 0.0602, 0.0602, 0.0602, 0.0602,
            0.0601, 0.06, 0.0599, 0.0598, 0.0596, 0.0594, 0.0592, 0.0589,
            0.0586, 0.0583, 0.058, 0.0576, 0.0572, 0.0568, 0.0563, 0.0558,
            0.0553, 0.0547, 0.0541
        ],
                                           dtype='complex128')
        surface['data_y_lower'] = np.array([
            -0.0447, -0.046, -0.0473, -0.0485, -0.0496, -0.0506, -0.0515,
            -0.0524, -0.0532, -0.054, -0.0547, -0.0554, -0.056, -0.0565,
            -0.057, -0.0575, -0.0579, -0.0583, -0.0586, -0.0589, -0.0592,
            -0.0594, -0.0595, -0.0596, -0.0597, -0.0598, -0.0598, -0.0598,
            -0.0598, -0.0597, -0.0596, -0.0594, -0.0592, -0.0589, -0.0586,
            -0.0582, -0.0578, -0.0573, -0.0567, -0.0561, -0.0554, -0.0546,
            -0.0538, -0.0529, -0.0519, -0.0509, -0.0497, -0.0485, -0.0472,
            -0.0458, -0.0444
        ],
                                           dtype='complex128')
        surface['original_wingbox_airfoil_t_over_c'] = 0.1

        mesh = surface['mesh']
        ny = mesh.shape[1]
        nx = mesh.shape[0]
        n_cp = len(surface['t_over_c_cp'])

        prob = om.Problem()

        indep_var_comp = om.IndepVarComp()
        indep_var_comp.add_output('t_over_c_cp', val=surface['t_over_c_cp'])
        indep_var_comp.add_output('spar_thickness_cp',
                                  val=surface['spar_thickness_cp'])
        indep_var_comp.add_output('skin_thickness_cp',
                                  val=surface['skin_thickness_cp'])
        indep_var_comp.add_output('fem_chords_cp',
                                  val=surface['fem_chords_cp'])
        indep_var_comp.add_output('streamwise_chords_cp',
                                  val=surface['streamwise_chords_cp'])
        indep_var_comp.add_output('fem_twists_cp',
                                  val=surface['fem_twists_cp'])
        prob.model.add_subsystem('indep_var_comp',
                                 indep_var_comp,
                                 promotes=['*'])

        x_interp = np.linspace(0., 1., int(ny - 1))
        comp = prob.model.add_subsystem(
            'bsplines_comp',
            om.SplineComp(method='bsplines',
                          x_interp_val=x_interp,
                          num_cp=n_cp,
                          interp_options={'order': min(n_cp, 4)}),
            promotes_inputs=['*'],
            promotes_outputs=['*'])
        comp.add_spline(y_cp_name='t_over_c_cp', y_interp_name='t_over_c')
        comp.add_spline(y_cp_name='skin_thickness_cp',
                        y_interp_name='skin_thickness',
                        y_units='m')
        comp.add_spline(y_cp_name='spar_thickness_cp',
                        y_interp_name='spar_thickness',
                        y_units='m')
        comp.add_spline(y_cp_name='fem_chords_cp',
                        y_interp_name='fem_chords',
                        y_units='m')
        comp.add_spline(y_cp_name='streamwise_chords_cp',
                        y_interp_name='streamwise_chords',
                        y_units='m')
        comp.add_spline(y_cp_name='fem_twists_cp',
                        y_interp_name='fem_twists',
                        y_units='deg')

        comp = SectionPropertiesWingbox(surface=surface)
        prob.model.add_subsystem('sec_prop_wb', comp, promotes=['*'])

        prob.setup()
        # om.view_model(prob)

        prob.run_model()

        # print( prob['A'] )
        # print( prob['A_enc'] )
        # print( prob['A_int'] )
        # print( prob['Iy'] )
        # print( prob['Qz'] )
        # print( prob['Iz'] )
        # print( prob['J'] )
        # print( prob['htop'] )
        # print( prob['hbottom'] )
        # print( prob['hfront'] )
        # print( prob['hrear'] )

        assert_rel_error(self, prob['A'],
                         np.array([0.0058738, -0.05739528, -0.05042289]), 1e-6)
        assert_rel_error(self, prob['A_enc'],
                         np.array([0.3243776, 0.978003, 2.17591]), 1e-6)
        assert_rel_error(self, prob['A_int'],
                         np.array([0.3132502, 0.949491, 2.11512]), 1e-6)
        assert_rel_error(
            self, prob['Iy'],
            np.array([3.59803239e-05, -1.52910019e-02, -4.01035510e-03]), 1e-6)
        assert_rel_error(self, prob['Qz'],
                         np.array([0.00129261, 0.00870662, 0.02500053]), 1e-6)
        assert_rel_error(self, prob['Iz'],
                         np.array([0.00056586, -0.00582207, -0.02877714]),
                         1e-6)
        assert_rel_error(self, prob['J'],
                         np.array([0.00124939, 0.01241967, 0.06649673]), 1e-6)
        assert_rel_error(self, prob['htop'],
                         np.array([0.53933652, -0.23509863, 0.71255343]), 1e-6)
        assert_rel_error(self, prob['hbottom'],
                         np.array([0.50366564, -0.19185349, 0.73525459]), 1e-6)
        assert_rel_error(self, prob['hfront'],
                         np.array([0.13442747, -0.78514756, -0.3919784]), 1e-6)
        assert_rel_error(self, prob['hrear'],
                         np.array([0.12219305, -0.71214916, -0.35484131]),
                         1e-6)
コード例 #24
0
    def setup(self):
        surface = self.options['surface']
        ny = surface['mesh'].shape[1]

        if 'spar_thickness_cp' in surface.keys(
        ) or 'skin_thickness_cp' in surface.keys():
            # Add independent variables that do not belong to a specific component
            indep_var_comp = om.IndepVarComp()

            # Add structural components to the surface-specific group
            self.add_subsystem('indep_vars', indep_var_comp, promotes=['*'])

        if 'spar_thickness_cp' in surface.keys():
            n_cp = len(surface['spar_thickness_cp'])
            # Add bspline components for active bspline geometric variables.
            x_interp = np.linspace(0., 1., int(ny - 1))
            comp = self.add_subsystem(
                'spar_thickness_bsp',
                om.SplineComp(method='bsplines',
                              x_interp_val=x_interp,
                              num_cp=n_cp,
                              interp_options={'order': min(n_cp, 4)}),
                promotes_inputs=['spar_thickness_cp'],
                promotes_outputs=['spar_thickness'])
            comp.add_spline(y_cp_name='spar_thickness_cp',
                            y_interp_name='spar_thickness')
            indep_var_comp.add_output('spar_thickness_cp',
                                      val=surface['spar_thickness_cp'],
                                      units='m')

        if 'skin_thickness_cp' in surface.keys():
            n_cp = len(surface['skin_thickness_cp'])
            # Add bspline components for active bspline geometric variables.
            x_interp = np.linspace(0., 1., int(ny - 1))
            comp = self.add_subsystem(
                'skin_thickness_bsp',
                om.SplineComp(method='bsplines',
                              x_interp_val=x_interp,
                              num_cp=n_cp,
                              interp_options={'order': min(n_cp, 4)}),
                promotes_inputs=['skin_thickness_cp'],
                promotes_outputs=['skin_thickness'])
            comp.add_spline(y_cp_name='skin_thickness_cp',
                            y_interp_name='skin_thickness')
            indep_var_comp.add_output('skin_thickness_cp',
                                      val=surface['skin_thickness_cp'],
                                      units='m')

        self.add_subsystem(
            'wingbox_geometry',
            WingboxGeometry(surface=surface),
            promotes_inputs=['mesh'],
            promotes_outputs=['fem_chords', 'fem_twists', 'streamwise_chords'])

        self.add_subsystem('wingbox',
                           SectionPropertiesWingbox(surface=surface),
                           promotes_inputs=[
                               'spar_thickness', 'skin_thickness', 't_over_c',
                               'fem_chords', 'fem_twists', 'streamwise_chords'
                           ],
                           promotes_outputs=[
                               'A', 'Iy', 'Qz', 'Iz', 'J', 'A_enc', 'A_int',
                               'htop', 'hbottom', 'hfront', 'hrear'
                           ])
コード例 #25
0
ファイル: test_spline_comp.py プロジェクト: wright/OpenMDAO
    def test_error_messages(self):
        n_cp = 80
        n_point = 160

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

        prob = om.Problem()

        comp = om.SplineComp(method='bsplines', x_interp_val=tt, x_cp_val=t)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

        with self.assertRaises(ValueError) as cm:
            prob.setup()

        msg = "'interp' <class SplineComp>: 'x_cp_val' is not a valid option when using method 'bsplines'. "
        msg += "Set 'num_cp' instead."
        self.assertEqual(str(cm.exception), msg)

        prob = om.Problem()

        comp = om.SplineComp(method='akima',
                             x_interp_val=tt,
                             num_cp=n_cp,
                             x_cp_val=t)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

        with self.assertRaises(ValueError) as cm:
            prob.setup()

        msg = "'interp' <class SplineComp>: It is not valid to set both options 'x_cp_val' and 'num_cp'."
        self.assertEqual(str(cm.exception), msg)

        prob = om.Problem()

        comp = om.SplineComp(method='akima', x_interp_val=tt)

        prob.model.add_subsystem('interp', comp)

        comp.add_spline(y_cp_name='h_cp',
                        y_interp_name='h',
                        y_cp_val=x,
                        y_units='km')

        with self.assertRaises(ValueError) as cm:
            prob.setup()

        msg = "'interp' <class SplineComp>: Either option 'x_cp_val' or 'num_cp' must be set."
        self.assertEqual(str(cm.exception), msg)
コード例 #26
0
    def setup(self):
        surface = self.options['surface']
        connect_geom_DVs = self.options['connect_geom_DVs']

        # Get the surface name and create a group to contain components
        # only for this surface
        ny = surface['mesh'].shape[1]

        # Check if any control points were added to the surface dict
        dv_keys = set([
            'twist_cp', 'chord_cp', 'xshear_cp', 'yshear_cp', 'zshear_cp',
            'sweep', 'span', 'taper', 'dihedral', 't_over_c_cp'
        ])
        active_dv_keys = dv_keys.intersection(set(surface.keys()))
        # Make sure that at least one of them is an independent variable
        make_ivc = False
        for key in active_dv_keys:
            if surface.get(key + '_dv', True):
                make_ivc = True
                break

        if make_ivc or self.options['DVGeo']:
            # Add independent variables that do not belong to a specific component
            indep_var_comp = om.IndepVarComp()

            # If connect_geom_DVs is true, then we promote all of the geometric
            # design variables to their appropriate manipulation functions.
            # If it's false, then we do not connect them, and the user can
            # choose to provide different values to those manipulation functions.
            # This is useful when you want to have morphing DVs, such as twist
            # or span, that are different at each point in a multipoint scheme.
            if connect_geom_DVs:
                self.add_subsystem('indep_vars',
                                   indep_var_comp,
                                   promotes=['*'])
            else:
                self.add_subsystem('indep_vars', indep_var_comp, promotes=[])

        if self.options['DVGeo']:
            from openaerostruct.geometry.ffd_component import GeometryMesh
            indep_var_comp.add_output('shape',
                                      val=np.zeros(
                                          (surface['mx'], surface['my'])),
                                      units='m')

            if 't_over_c_cp' in surface.keys():
                n_cp = len(surface['t_over_c_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny - 1))
                comp = self.add_subsystem(
                    't_over_c_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['t_over_c_cp'],
                    promotes_outputs=['t_over_c'])
                comp.add_spline(y_cp_name='t_over_c_cp',
                                y_interp_name='t_over_c')
                if surface.get('t_over_c_cp_dv', True):
                    indep_var_comp.add_output('t_over_c_cp',
                                              val=surface['t_over_c_cp'])

            self.add_subsystem('mesh',
                               GeometryMesh(surface=surface,
                                            DVGeo=self.options['DVGeo']),
                               promotes_inputs=['shape'],
                               promotes_outputs=['mesh'])

        else:
            from openaerostruct.geometry.geometry_mesh import GeometryMesh

            bsp_inputs = []

            if 'twist_cp' in surface.keys():
                n_cp = len(surface['twist_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny))
                comp = self.add_subsystem(
                    'twist_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['twist_cp'],
                    promotes_outputs=['twist'])
                comp.add_spline(y_cp_name='twist_cp', y_interp_name='twist')
                bsp_inputs.append('twist')

                # Since default assumption is that we want tail rotation as a design variable, add this to allow for trimmed drag polar where the tail rotation should not be a design variable
                if surface.get('twist_cp_dv', True):
                    indep_var_comp.add_output('twist_cp',
                                              val=surface['twist_cp'],
                                              units='deg')

            if 'chord_cp' in surface.keys():
                n_cp = len(surface['chord_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny))
                comp = self.add_subsystem(
                    'chord_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['chord_cp'],
                    promotes_outputs=['chord'])
                comp.add_spline(y_cp_name='chord_cp', y_interp_name='chord')
                bsp_inputs.append('chord')
                if surface.get('chord_cp_dv', True):
                    indep_var_comp.add_output('chord_cp',
                                              val=surface['chord_cp'],
                                              units='m')

            if 't_over_c_cp' in surface.keys():
                n_cp = len(surface['t_over_c_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny - 1))
                comp = self.add_subsystem(
                    't_over_c_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['t_over_c_cp'],
                    promotes_outputs=['t_over_c'])
                comp.add_spline(y_cp_name='t_over_c_cp',
                                y_interp_name='t_over_c')
                if surface.get('t_over_c_cp_dv', True):
                    indep_var_comp.add_output('t_over_c_cp',
                                              val=surface['t_over_c_cp'])

            if 'xshear_cp' in surface.keys():
                n_cp = len(surface['xshear_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny))
                comp = self.add_subsystem(
                    'xshear_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['xshear_cp'],
                    promotes_outputs=['xshear'])
                comp.add_spline(y_cp_name='xshear_cp', y_interp_name='xshear')
                bsp_inputs.append('xshear')
                if surface.get('xshear_cp_dv', True):
                    indep_var_comp.add_output('xshear_cp',
                                              val=surface['xshear_cp'],
                                              units='m')

            if 'yshear_cp' in surface.keys():
                n_cp = len(surface['yshear_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny))
                comp = self.add_subsystem(
                    'yshear_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['yshear_cp'],
                    promotes_outputs=['yshear'])
                comp.add_spline(y_cp_name='yshear_cp', y_interp_name='yshear')
                bsp_inputs.append('yshear')
                if surface.get('yshear_cp_dv', True):
                    indep_var_comp.add_output('yshear_cp',
                                              val=surface['yshear_cp'],
                                              units='m')

            if 'zshear_cp' in surface.keys():
                n_cp = len(surface['zshear_cp'])
                # Add bspline components for active bspline geometric variables.
                x_interp = np.linspace(0., 1., int(ny))
                comp = self.add_subsystem(
                    'zshear_bsp',
                    om.SplineComp(method='bsplines',
                                  x_interp_val=x_interp,
                                  num_cp=n_cp,
                                  interp_options={'order': min(n_cp, 4)}),
                    promotes_inputs=['zshear_cp'],
                    promotes_outputs=['zshear'])
                comp.add_spline(y_cp_name='zshear_cp', y_interp_name='zshear')
                bsp_inputs.append('zshear')
                if surface.get('zshear_cp_dv', True):
                    indep_var_comp.add_output('zshear_cp',
                                              val=surface['zshear_cp'],
                                              units='m')

            if 'sweep' in surface.keys():
                bsp_inputs.append('sweep')
                if surface.get('sweep_dv', True):
                    indep_var_comp.add_output('sweep',
                                              val=surface['sweep'],
                                              units='deg')

            if 'span' in surface.keys():
                bsp_inputs.append('span')
                if surface.get('span_dv', True):
                    indep_var_comp.add_output('span',
                                              val=surface['span'],
                                              units='m')

            if 'dihedral' in surface.keys():
                bsp_inputs.append('dihedral')
                if surface.get('dihedral_dv', True):
                    indep_var_comp.add_output('dihedral',
                                              val=surface['dihedral'],
                                              units='deg')

            if 'taper' in surface.keys():
                bsp_inputs.append('taper')
                if surface.get('taper_dv', True):
                    indep_var_comp.add_output('taper', val=surface['taper'])

            self.add_subsystem('mesh',
                               GeometryMesh(surface=surface),
                               promotes_inputs=bsp_inputs,
                               promotes_outputs=['mesh'])
コード例 #27
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']

        x_interp = sine_distribution(num_elements)
        comp = om.SplineComp(method='bsplines', num_cp=num_cp, x_interp_val=x_interp)
        comp.add_spline(y_cp_name='h_cp', y_interp_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 = 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,
                            'stress_comp.displacements_%d' % k,
                            src_indices=np.arange(2 *num_nodes))

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

                comp = om.KSComp(width=num_elements, upper=max_bending,
                                 add_constraint=self.options['ks_add_constraint'],
                                 parallel_deriv_color=color)

                sub.add_subsystem('KS_%d' % k, comp)

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

                if not self.options['ks_add_constraint']:
                    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('interp.h', 'I_comp.h')
        self.connect('interp.h', 'volume_comp.h')
        self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')

        self.add_design_var('interp.h_cp', lower=1e-2, upper=10.)
        self.add_objective('volume_comp.volume')
コード例 #28
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)

        x_interp = sine_distribution(num_elements)
        comp = om.SplineComp(method='bsplines',
                             num_cp=num_cp,
                             x_interp_val=x_interp)
        comp.add_spline(y_cp_name='h_cp', y_interp_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 = 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,
                            'compliance_comp.displacements_%d' % k,
                            src_indices=np.arange(2 * num_nodes))

                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')
コード例 #29
0
    def test2(self):
        """
        This is for checking the computation.
        """

        surface = get_default_surfaces()[0]
        surface['t_over_c_cp'] = np.array([0.1, 0.15, 0.2])
        surface['spar_thickness_cp'] = np.array([0.004, 0.008, 0.02])
        surface['skin_thickness_cp'] = np.array([0.01, 0.015, 0.021])
        surface['fem_chords_cp'] = np.array([2., 3., 4.])
        surface['streamwise_chords_cp'] = np.array([3., 4., 5.])
        surface['fem_twists_cp'] = np.array([5., 3., 2.]) / 180. * np.pi

        surface['data_x_upper'] = np.array([
            0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2,
            0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6
        ],
                                           dtype='complex128')
        surface['data_x_lower'] = np.array([
            0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2,
            0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31,
            0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42,
            0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53,
            0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6
        ],
                                           dtype='complex128')
        surface['data_y_upper'] = np.array([
            0.0447, 0.046, 0.0472, 0.0484, 0.0495, 0.0505, 0.0514, 0.0523,
            0.0531, 0.0538, 0.0545, 0.0551, 0.0557, 0.0563, 0.0568, 0.0573,
            0.0577, 0.0581, 0.0585, 0.0588, 0.0591, 0.0593, 0.0595, 0.0597,
            0.0599, 0.06, 0.0601, 0.0602, 0.0602, 0.0602, 0.0602, 0.0602,
            0.0601, 0.06, 0.0599, 0.0598, 0.0596, 0.0594, 0.0592, 0.0589,
            0.0586, 0.0583, 0.058, 0.0576, 0.0572, 0.0568, 0.0563, 0.0558,
            0.0553, 0.0547, 0.0541
        ],
                                           dtype='complex128')
        surface['data_y_lower'] = np.array([
            -0.0447, -0.046, -0.0473, -0.0485, -0.0496, -0.0506, -0.0515,
            -0.0524, -0.0532, -0.054, -0.0547, -0.0554, -0.056, -0.0565,
            -0.057, -0.0575, -0.0579, -0.0583, -0.0586, -0.0589, -0.0592,
            -0.0594, -0.0595, -0.0596, -0.0597, -0.0598, -0.0598, -0.0598,
            -0.0598, -0.0597, -0.0596, -0.0594, -0.0592, -0.0589, -0.0586,
            -0.0582, -0.0578, -0.0573, -0.0567, -0.0561, -0.0554, -0.0546,
            -0.0538, -0.0529, -0.0519, -0.0509, -0.0497, -0.0485, -0.0472,
            -0.0458, -0.0444
        ],
                                           dtype='complex128')
        surface['original_wingbox_airfoil_t_over_c'] = 0.1

        mesh = surface['mesh']
        ny = mesh.shape[1]
        nx = mesh.shape[0]
        n_cp = len(surface['t_over_c_cp'])

        prob = om.Problem()

        indep_var_comp = om.IndepVarComp()
        indep_var_comp.add_output('t_over_c_cp', val=surface['t_over_c_cp'])
        indep_var_comp.add_output('spar_thickness_cp',
                                  val=surface['spar_thickness_cp'])
        indep_var_comp.add_output('skin_thickness_cp',
                                  val=surface['skin_thickness_cp'])
        indep_var_comp.add_output('fem_chords_cp',
                                  val=surface['fem_chords_cp'])
        indep_var_comp.add_output('streamwise_chords_cp',
                                  val=surface['streamwise_chords_cp'])
        indep_var_comp.add_output('fem_twists_cp',
                                  val=surface['fem_twists_cp'])
        prob.model.add_subsystem('indep_var_comp',
                                 indep_var_comp,
                                 promotes=['*'])

        x_interp = np.linspace(0., 1., int(ny - 1))
        comp = prob.model.add_subsystem(
            'bsplines_comp',
            om.SplineComp(method='bsplines',
                          x_interp_val=x_interp,
                          num_cp=n_cp,
                          interp_options={'order': min(n_cp, 4)}),
            promotes_inputs=['*'],
            promotes_outputs=['*'])
        comp.add_spline(y_cp_name='t_over_c_cp', y_interp_name='t_over_c')
        comp.add_spline(y_cp_name='skin_thickness_cp',
                        y_interp_name='skin_thickness',
                        y_units='m')
        comp.add_spline(y_cp_name='spar_thickness_cp',
                        y_interp_name='spar_thickness',
                        y_units='m')
        comp.add_spline(y_cp_name='fem_chords_cp',
                        y_interp_name='fem_chords',
                        y_units='m')
        comp.add_spline(y_cp_name='streamwise_chords_cp',
                        y_interp_name='streamwise_chords',
                        y_units='m')
        comp.add_spline(y_cp_name='fem_twists_cp',
                        y_interp_name='fem_twists',
                        y_units='deg')

        comp = SectionPropertiesWingbox(surface=surface)
        prob.model.add_subsystem('sec_prop_wb', comp, promotes=['*'])

        prob.setup()
        # om.view_model(prob)

        prob.run_model()

        # print( prob['A'] )
        # print( prob['A_enc'] )
        # print( prob['A_int'] )
        # print( prob['Iy'] )
        # print( prob['Qz'] )
        # print( prob['Iz'] )
        # print( prob['J'] )
        # print( prob['htop'] )
        # print( prob['hbottom'] )
        # print( prob['hfront'] )
        # print( prob['hrear'] )

        assert_rel_error(self, prob['A'],
                         np.array([0.02203548, 0.0563726, 0.11989703]), 1e-6)
        assert_rel_error(self, prob['A_enc'],
                         np.array([0.3243776, 0.978003, 2.17591]), 1e-6)
        assert_rel_error(self, prob['A_int'],
                         np.array([0.3132502, 0.949491, 2.11512]), 1e-6)
        assert_rel_error(self, prob['Iy'],
                         np.array([0.00218612, 0.01455083, 0.06342765]), 1e-6)
        assert_rel_error(self, prob['Qz'],
                         np.array([0.00169233, 0.00820558, 0.02707493]), 1e-6)
        assert_rel_error(self, prob['Iz'],
                         np.array([0.00055292, 0.00520911, 0.02785168]), 1e-6)
        assert_rel_error(self, prob['J'],
                         np.array([0.00124939, 0.01241967, 0.06649673]), 1e-6)
        assert_rel_error(self, prob['htop'],
                         np.array([0.19106873, 0.36005945, 0.5907887]), 1e-6)
        assert_rel_error(self, prob['hbottom'],
                         np.array([0.19906584, 0.37668887, 0.61850335]), 1e-6)
        assert_rel_error(self, prob['hfront'],
                         np.array([0.52341176, 0.78649186, 1.04902676]), 1e-6)
        assert_rel_error(self, prob['hrear'],
                         np.array([0.47524073, 0.71429312, 0.95303545]), 1e-6)
コード例 #30
0
    def setup(self):
        surface = self.options['surface']
        connect_geom_DVs = self.options['connect_geom_DVs']
        mesh = surface['mesh']
        ny = mesh.shape[1]

        if connect_geom_DVs:
            # Add independent variables that do not belong to a specific component
            indep_var_comp = om.IndepVarComp()

            # Add structural components to the surface-specific group
            self.add_subsystem('indep_vars', indep_var_comp, promotes=['*'])

        if 'thickness_cp' in surface.keys():
            n_cp = len(surface['thickness_cp'])
            # Add bspline components for active bspline geometric variables.
            x_interp = np.linspace(0., 1., int(ny - 1))
            comp = self.add_subsystem(
                'thickness_bsp',
                om.SplineComp(method='bsplines',
                              x_interp_val=x_interp,
                              num_cp=n_cp,
                              interp_options={'order': min(n_cp, 4)}),
                promotes_inputs=['thickness_cp'],
                promotes_outputs=['thickness'])
            comp.add_spline(y_cp_name='thickness_cp',
                            y_interp_name='thickness',
                            y_units='m')
            if connect_geom_DVs:
                indep_var_comp.add_output('thickness_cp',
                                          val=surface['thickness_cp'],
                                          units='m')

        if 'radius_cp' in surface.keys():
            n_cp = len(surface['radius_cp'])
            # Add bspline components for active bspline geometric variables.
            x_interp = np.linspace(0., 1., int(ny - 1))
            comp = self.add_subsystem(
                'radius_bsp',
                om.SplineComp(method='bsplines',
                              x_interp_val=x_interp,
                              num_cp=n_cp,
                              interp_options={'order': min(n_cp, 4)}),
                promotes_inputs=['radius_cp'],
                promotes_outputs=['radius'])
            comp.add_spline(y_cp_name='radius_cp',
                            y_interp_name='radius',
                            y_units='m')
            if connect_geom_DVs:
                indep_var_comp.add_output('radius_cp',
                                          val=surface['radius_cp'],
                                          units='m')
        else:
            self.add_subsystem('radius_comp',
                               RadiusComp(surface=surface),
                               promotes_inputs=['mesh', 't_over_c'],
                               promotes_outputs=['radius'])

        self.add_subsystem('tube',
                           SectionPropertiesTube(surface=surface),
                           promotes_inputs=['thickness', 'radius'],
                           promotes_outputs=['A', 'Iy', 'Iz', 'J'])