Ejemplo n.º 1
0
    def test_speed(self):
        from openmdao.api import Problem, Group, IndepVarComp, ExecComp
        from openmdao.core.tests.test_units import SpeedComp

        comp = IndepVarComp()
        comp.add_output('distance', val=1., units='m')
        comp.add_output('time', val=1., units='s')

        prob = Problem(model=Group())
        prob.model.add_subsystem('c1', comp)
        prob.model.add_subsystem('c2', SpeedComp())
        prob.model.add_subsystem('c3', ExecComp('f=speed',speed={'units': 'm/s'}))
        prob.model.connect('c1.distance', 'c2.distance')
        prob.model.connect('c1.time', 'c2.time')
        prob.model.connect('c2.speed', 'c3.speed')

        prob.setup()
        prob.run_model()

        assert_rel_error(self, prob['c1.distance'], 1.)  # units: m
        assert_rel_error(self, prob['c2.distance'], 1.e-3)  # units: km

        assert_rel_error(self, prob['c1.time'], 1.)  # units: s
        assert_rel_error(self, prob['c2.time'], 1./3600.)  # units: h

        assert_rel_error(self, prob['c2.speed'], 3.6)  # units: km/h
        assert_rel_error(self, prob['c3.f'], 1.0)  # units: km/h
Ejemplo n.º 2
0
    def setUp(self):
        self.nn = 100

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 4))
        ivc.add_output(name='b', shape=(self.nn, 4))

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        self.p.model.add_subsystem(name='dot_prod_comp',
                                   subsys=DotProductComp(vec_size=self.nn, length=4))

        self.p.model.connect('a', 'dot_prod_comp.a')
        self.p.model.connect('b', 'dot_prod_comp.b')

        self.p.setup()

        self.p['a'] = np.random.rand(self.nn, 4)
        self.p['b'] = np.random.rand(self.nn, 4)

        self.p.run_model()
Ejemplo n.º 3
0
    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 3))
        ivc.add_output(name='b', shape=(self.nn, 3))

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        adder=self.p.model.add_subsystem(name='add_subtract_comp',
                                   subsys=AddSubtractComp())
        adder.add_equation('adder_output',['input_a','input_b'],vec_size=self.nn,length=3)

        self.p.model.connect('a', 'add_subtract_comp.input_a')
        self.p.model.connect('b', 'add_subtract_comp.input_b')

        self.p.setup()

        self.p['a'] = np.random.rand(self.nn, 3)
        self.p['b'] = np.random.rand(self.nn, 3)

        self.p.run_model()
Ejemplo n.º 4
0
    def setUp(self):
        self.nn = 10

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn,))
        ivc.add_output(name='b', shape=(self.nn,))

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        demux_comp = self.p.model.add_subsystem(name='demux_comp',
                                                subsys=DemuxComp(vec_size=self.nn))

        demux_comp.add_var('a', shape=(self.nn,))
        demux_comp.add_var('b', shape=(self.nn,))

        self.p.model.connect('a', 'demux_comp.a')
        self.p.model.connect('b', 'demux_comp.b')

        self.p.setup(force_alloc_complex=True)

        self.p['a'] = np.random.rand(self.nn)
        self.p['b'] = np.random.rand(self.nn)

        self.p.run_model()
Ejemplo n.º 5
0
    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 3, 1))
        ivc.add_output(name='b', shape=(self.nn, 3, 1))

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        self.p.model.add_subsystem(name='cross_prod_comp',
                                   subsys=CrossProductComp(vec_size=self.nn))

        self.p.model.connect('a', 'cross_prod_comp.a')
        self.p.model.connect('b', 'cross_prod_comp.b')

        self.p.setup(force_alloc_complex=True)

        self.p['a'] = np.random.rand(self.nn, 3, 1)
        self.p['b'] = np.random.rand(self.nn, 3, 1)

        self.p['a'][:, 0, 0] = 2.0
        self.p['a'][:, 1, 0] = 3.0
        self.p['a'][:, 2, 0] = 4.0

        self.p['b'][:, 0, 0] = 5.0
        self.p['b'][:, 1, 0] = 6.0
        self.p['b'][:, 2, 0] = 7.0

        self.p.run_model()
Ejemplo n.º 6
0
    def test_iimplicit(self):
        # Testing that our scale/unscale contexts leave the output vector in the correct state when
        # linearize is called on implicit components.
        prob = Problem()
        model = prob.model

        inputs_comp = IndepVarComp()
        inputs_comp.add_output('x1_u', val=1.0)

        model.add_subsystem('p', inputs_comp)
        mycomp = model.add_subsystem('comp', MyImplicitComp())

        model.connect('p.x1_u', 'comp.x2_u')

        model.linear_solver = DirectSolver()
        model.nonlinear_solver = NewtonSolver()
        model.nonlinear_solver.options['atol'] = 1e-12
        model.nonlinear_solver.options['rtol'] = 1e-12

        model.add_design_var('p.x1_u', lower=-11, upper=11)
        model.add_constraint('p.x1_u', upper=3.3)
        model.add_objective('comp.x3_u')
        model.add_objective('comp.x3_s')

        prob.setup()
        prob.run_model()

        totals = prob.check_totals(compact_print=True, out_stream=None)

        for (of, wrt) in totals:
            assert_rel_error(self, totals[of, wrt]['abs error'][0], 0.0, 1e-7)
Ejemplo n.º 7
0
    def setUp(self):
        self.nn = 5

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='a', shape=(self.nn, 3), units='lbf')
        ivc.add_output(name='b', shape=(self.nn, 3), units='ft/s')

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['a', 'b'])

        self.p.model.add_subsystem(name='dot_prod_comp',
                                   subsys=DotProductComp(vec_size=self.nn,
                                                         a_units='N', b_units='m/s',
                                                         c_units='W'))

        self.p.model.connect('a', 'dot_prod_comp.a')
        self.p.model.connect('b', 'dot_prod_comp.b')

        self.p.setup()

        self.p['a'] = np.random.rand(self.nn, 3)
        self.p['b'] = np.random.rand(self.nn, 3)

        self.p.run_model()
    def test_structural_weight_loads(self):
        surface = get_default_surfaces()[0]

        comp = StructureWeightLoads(surface=surface)

        group = Group()

        indep_var_comp = IndepVarComp()

        ny = surface['mesh'].shape[1]

        #carefully chosen "random" values that give non-uniform derivatives outputs that are good for testing
        nodesval = np.array([[1., 2., 4.],
                            [20., 22., 7.],
                            [8., 17., 14.],
                            [13., 14., 16.]],dtype=complex)
        element_weights_val = np.arange(ny-1)+1

        indep_var_comp.add_output('nodes', val=nodesval,units='m')
        indep_var_comp.add_output('element_weights', val=element_weights_val,units='N')

        group.add_subsystem('indep_var_comp', indep_var_comp, promotes=['*'])
        group.add_subsystem('load', comp, promotes=['*'])

        p = run_test(self, group, complex_flag=True, compact_print=True)
Ejemplo n.º 9
0
    def test_raise_no_error_on_singular(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS',
                               rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0)

        teg.add_subsystem(name='thrust_bal', subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

        teg.linear_solver = DirectSolver(assemble_jac=False)

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4

        prob.setup(check=False)
        prob.set_solver_print(level=0)

        teg.linear_solver.options['err_on_singular'] = False
        prob.run_model()
Ejemplo n.º 10
0
    def setup(self):
        surface = self.options['surface']
        mesh = surface['mesh']
        nx = mesh.shape[0]
        ny = mesh.shape[1]

        # Add independent variables that do not belong to a specific component
        indep_var_comp = IndepVarComp()

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

        if 'struct' in surface['type']:
            self.add_subsystem('radius_comp',
                RadiusComp(surface=surface),
                promotes_inputs=['mesh', 't_over_c'],
                promotes_outputs=['radius'])

        if 'thickness_cp' in surface.keys():
            n_cp = len(surface['thickness_cp'])
            # Add bspline components for active bspline geometric variables.
            self.add_subsystem('thickness_bsp', BsplinesComp(
                in_name='thickness_cp', out_name='thickness', units='m',
                num_control_points=n_cp, num_points=int(ny-1),
                bspline_order=min(n_cp, 4), distribution='uniform'),
                promotes_inputs=['thickness_cp'], promotes_outputs=['thickness'])
            indep_var_comp.add_output('thickness_cp', val=surface['thickness_cp'], units='m')

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

        self.p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='A', shape=(self.nn, 6, 4))
        ivc.add_output(name='x', shape=(self.nn, 4))

        self.p.model.add_subsystem(name='ivc',
                                   subsys=ivc,
                                   promotes_outputs=['A', 'x'])

        self.p.model.add_subsystem(name='mat_vec_product_comp',
                                   subsys=MatrixVectorProductComp(vec_size=self.nn,
                                                                  A_shape=(6, 4)))

        self.p.model.connect('A', 'mat_vec_product_comp.A')
        self.p.model.connect('x', 'mat_vec_product_comp.x')

        self.p.setup(force_alloc_complex=True)

        self.p['A'] = np.random.rand(self.nn, 6, 4)
        self.p['x'] = np.random.rand(self.nn, 4)

        self.p.run_model()
Ejemplo n.º 12
0
    def test_const_jacobian(self):
        import numpy as np

        from openmdao.api import Problem, Group, IndepVarComp, DirectSolver, DenseJacobian
        from openmdao.jacobians.tests.test_jacobian_features import SimpleCompConst

        model = Group()
        comp = IndepVarComp()
        for name, val in (('x', 1.), ('y1', np.ones(2)), ('y2', np.ones(2)),
                          ('y3', np.ones(2)), ('z', np.ones((2, 2)))):
            comp.add_output(name, val)
        model.add_subsystem('input_comp', comp, promotes=['x', 'y1', 'y2', 'y3', 'z'])

        problem = Problem(model=model)
        model.suppress_solver_output = True
        model.linear_solver = DirectSolver()
        model.jacobian = DenseJacobian()
        model.add_subsystem('simple', SimpleCompConst(),
                            promotes=['x', 'y1', 'y2', 'y3', 'z', 'f', 'g'])
        problem.setup(check=False)
        problem.run_model()
        totals = problem.compute_totals(['f', 'g'],
                                              ['x', 'y1', 'y2', 'y3', 'z'])

        assert_rel_error(self, totals['f', 'x'], [[1.]])
        assert_rel_error(self, totals['f', 'z'], np.ones((1, 4)))
        assert_rel_error(self, totals['f', 'y1'], np.zeros((1, 2)))
        assert_rel_error(self, totals['f', 'y2'], np.zeros((1, 2)))
        assert_rel_error(self, totals['f', 'y3'], np.zeros((1, 2)))
        assert_rel_error(self, totals['g', 'x'], [[1], [0], [0], [1]])
        assert_rel_error(self, totals['g', 'z'], np.zeros((4, 4)))
        assert_rel_error(self, totals['g', 'y1'], [[1, 0], [1, 0], [0, 1], [0, 1]])
        assert_rel_error(self, totals['g', 'y2'], [[1, 0], [0, 1], [1, 0], [0, 1]])
        assert_rel_error(self, totals['g', 'y3'], [[1, 0], [1, 0], [0, 1], [0, 1]])
Ejemplo n.º 13
0
    def test_const_jacobian(self):
        model = Group()
        comp = IndepVarComp()
        for name, val in (('x', 1.), ('y1', np.ones(2)), ('y2', np.ones(2)),
                          ('y3', np.ones(2)), ('z', np.ones((2, 2)))):
            comp.add_output(name, val)
        model.add_subsystem('input_comp', comp, promotes=['x', 'y1', 'y2', 'y3', 'z'])

        problem = Problem(model=model)
        problem.set_solver_print(level=0)
        model.linear_solver = ScipyKrylov()
        model.jacobian = COOJacobian()
        model.add_subsystem('simple', SimpleCompConst(),
                            promotes=['x', 'y1', 'y2', 'y3', 'z', 'f', 'g'])
        problem.setup(check=False)
        problem.run_model()
        totals = problem.compute_totals(['f', 'g'],
                                              ['x', 'y1', 'y2', 'y3', 'z'])

        jacobian = {}
        jacobian['f', 'x'] = [[1.]]
        jacobian['f', 'z'] = np.ones((1, 4))
        jacobian['f', 'y1'] = np.zeros((1, 2))
        jacobian['f', 'y2'] = np.zeros((1, 2))
        jacobian['f', 'y3'] = np.zeros((1, 2))

        jacobian['g', 'y1'] = [[1, 0], [1, 0], [0, 1], [0, 1]]
        jacobian['g', 'y2'] = [[1, 0], [0, 1], [1, 0], [0, 1]]
        jacobian['g', 'y3'] = [[1, 0], [1, 0], [0, 1], [0, 1]]

        jacobian['g', 'x'] = [[1], [0], [0], [1]]
        jacobian['g', 'z'] = np.zeros((4, 4))

        assert_rel_error(self, totals, jacobian)
Ejemplo n.º 14
0
    def test_sparse_jacobian(self):
        import numpy as np

        from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent

        class SparsePartialComp(ExplicitComponent):
            def setup(self):
                self.add_input('x', shape=(4,))
                self.add_output('f', shape=(2,))

                self.declare_partials(of='f', wrt='x', rows=[0, 1, 1, 1], cols=[0, 1, 2, 3])

            def compute_partials(self, inputs, partials):
                # Corresponds to the [(0,0), (1,1), (1,2), (1,3)] entries.
                partials['f', 'x'] = [1., 2., 3., 4.]

        model = Group()
        comp = IndepVarComp()
        comp.add_output('x', np.ones(4))

        model.add_subsystem('input', comp)
        model.add_subsystem('example', SparsePartialComp())

        model.connect('input.x', 'example.x')

        problem = Problem(model=model)
        problem.setup(check=False)
        problem.run_model()
        totals = problem.compute_totals(['example.f'], ['input.x'])

        assert_rel_error(self, totals['example.f', 'input.x'], [[1., 0., 0., 0.], [0., 2., 3., 4.]])
Ejemplo n.º 15
0
    def setup(self, compname, inputs, state0):
        # create instance of component type
        try:
            comp = eval('%s(NTIME)' % compname)
        except TypeError:
            try:
                comp = eval('%s()' % compname)
            except TypeError:
                comp = eval('%s(NTIME, 300)' % compname)

        # collect metadata for component inputs
        prob = Problem(comp)
        prob.setup()
        prob.final_setup()

        self.inputs_dict = {}
        for name, meta in prob.model.list_inputs(units=True, out_stream=None):
            self.inputs_dict[name.split('.')[-1]] = meta

        # create independent vars for each input, initialized with random values
        indep = IndepVarComp()
        for item in inputs + state0:
            shape = self.inputs_dict[item]['value'].shape
            units = self.inputs_dict[item]['units']
            indep.add_output(item, np.random.random(shape), units=units)

        # setup problem for test
        self.prob = Problem()
        self.prob.model.add_subsystem('indep', indep, promotes=['*'])
        self.prob.model.add_subsystem('comp', comp, promotes=['*'])

        self.prob.setup()
    def test(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 7,
                     'wing_type' : 'CRM',
                     'symmetry' : True,
                     'num_twist_cp' : 5}

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
                    # Wing definition
                    'name' : 'wing',        # name of the surface
                    'symmetry' : True,     # if true, model one half of wing
                                            # reflected across the plane y = 0
                    'fem_model_type' : 'tube',

                    'mesh' : mesh,
                    'radius_cp' : np.ones((5)) * 0.5,

                    # Structural values are based on aluminum 7075
                    'E' : 70.e9,            # [Pa] Young's modulus of the spar
                    'G' : 30.e9,            # [Pa] shear modulus of the spar
                    'yield' : 500.e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case
                    'mrho' : 3.e3,          # [kg/m^3] material density
                    'fem_origin' : 0.35,    # normalized chordwise location of the spar
                    't_over_c_cp' : np.array([0.15]),      # maximum airfoil thickness
                    'thickness_cp' : np.ones((3)) * .1,
                    'wing_weight_ratio' : 2.,
                    'struct_weight_relief' : False,    # True to add the weight of the structure to the loads on the structure
                    'distributed_fuel_weight' : False,
                    'exact_failure_constraint' : False,
                    }

        # Create the problem and assign the model group
        prob = Problem()

        ny = surf_dict['mesh'].shape[1]

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('loads', val=np.ones((ny, 6)) * 2e5, units='N')
        indep_var_comp.add_output('load_factor', val=1.)

        struct_group = SpatialBeamAlone(surface=surf_dict)

        # Add indep_vars to the structural group
        struct_group.add_subsystem('indep_vars',
             indep_var_comp,
             promotes=['*'])

        prob.model.add_subsystem(surf_dict['name'], struct_group)

        # Set up the problem
        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['wing.structural_mass'][0], 117819.798089, 1e-4)
Ejemplo n.º 17
0
    def setup(self):
        E = self.metadata['E']
        L = self.metadata['L']
        b = self.metadata['b']
        volume = self.metadata['volume']
        num_elements = self.metadata['num_elements']
        num_nodes = num_elements + 1

        force_vector = np.zeros(2 * num_nodes)
        force_vector[-2] = -1.

        inputs_comp = IndepVarComp()
        inputs_comp.add_output('h', shape=num_elements)
        self.add_subsystem('inputs_comp', inputs_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)

        comp = GlobalStiffnessMatrixComp(num_elements=num_elements)
        self.add_subsystem('global_stiffness_matrix_comp', comp)

        comp = StatesComp(num_elements=num_elements, force_vector=force_vector)
        self.add_subsystem('states_comp', comp)

        comp = DisplacementsComp(num_elements=num_elements)
        self.add_subsystem('displacements_comp', comp)

        comp = ComplianceComp(num_elements=num_elements, force_vector=force_vector)
        self.add_subsystem('compliance_comp', comp)

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

        self.connect('inputs_comp.h', 'I_comp.h')
        self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')
        self.connect(
            'local_stiffness_matrix_comp.K_local',
            'global_stiffness_matrix_comp.K_local')
        self.connect(
            'global_stiffness_matrix_comp.K',
            'states_comp.K')
        self.connect(
            'states_comp.d',
            'displacements_comp.d')
        self.connect(
            'displacements_comp.displacements',
            'compliance_comp.displacements')
        self.connect(
            'inputs_comp.h',
            'volume_comp.h')

        self.add_design_var('inputs_comp.h', lower=1e-2, upper=10.)
        self.add_objective('compliance_comp.compliance')
        self.add_constraint('volume_comp.volume', equals=volume)
Ejemplo n.º 18
0
    def test_add_output(self):
        """Define two independent variables using the add_output method."""
        from openmdao.api import Problem, IndepVarComp

        comp = IndepVarComp()
        comp.add_output('indep_var_1', val=1.0, lower=0, upper=10)
        comp.add_output('indep_var_2', val=2.0, lower=1, upper=20)

        prob = Problem(comp).setup(check=False)

        assert_rel_error(self, prob['indep_var_1'], 1.0)
        assert_rel_error(self, prob['indep_var_2'], 2.0)
Ejemplo n.º 19
0
    def test_scalar_with_guess_func_additional_input(self):

        model = Group(assembled_jac_type='dense')

        bal = BalanceComp()
        bal.add_balance('x')
        bal.add_input('guess_x', val=0.0)

        ivc = IndepVarComp()
        ivc.add_output(name='y_tgt', val=4)
        ivc.add_output(name='guess_x', val=2.5)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x'])
        model.add_subsystem(name='exec', subsys=exec_comp)
        model.add_subsystem(name='balance', subsys=bal)

        model.connect('guess_x', 'balance.guess_x')
        model.connect('y_tgt', 'balance.rhs:x')
        model.connect('balance.x', 'exec.x')
        model.connect('exec.y', 'balance.lhs:x')

        model.linear_solver = DirectSolver(assemble_jac=True)
        model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0)

        prob = Problem(model)
        prob.setup()

        # run problem without a guess function
        prob['balance.x'] = .5
        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        iters_no_guess = model.nonlinear_solver._iter_count

        # run problem with same initial value and a guess function
        def guess_function(inputs, outputs, resids):
            outputs['x'] = inputs['guess_x']

        bal.options['guess_func'] = guess_function

        prob['balance.x'] = .5
        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        iters_with_guess = model.nonlinear_solver._iter_count

        # verify it converges faster with the guess function
        self.assertTrue(iters_with_guess < iters_no_guess)
Ejemplo n.º 20
0
    def test_keys(self):
        p = Problem()
        comp = IndepVarComp()
        comp.add_output('v1', val=1.0)
        comp.add_output('v2', val=2.0)
        p.model.add_subsystem('des_vars', comp, promotes=['*'])
        p.setup()
        p.final_setup()

        keys = sorted(p.model._outputs.keys())
        expected = ['des_vars.v1', 'des_vars.v2']

        self.assertListEqual(keys, expected, msg='keys() is not returning the expected names')
Ejemplo n.º 21
0
    def test_iter(self):
        p = Problem()
        comp = IndepVarComp()
        comp.add_output('v1', val=1.0)
        comp.add_output('v2', val=2.0)
        p.model.add_subsystem('des_vars', comp, promotes=['*'])
        p.setup()
        p.final_setup()

        outputs = [n for n in p.model._outputs]
        expected = ['des_vars.v1', 'des_vars.v2']

        self.assertListEqual(outputs, expected, msg='Iter is not returning the expected names')
Ejemplo n.º 22
0
    def test_dot(self):
        p = Problem()
        comp = IndepVarComp()
        comp.add_output('v1', val=1.0)
        comp.add_output('v2', val=2.0)
        p.model.add_subsystem('des_vars', comp, promotes=['*'])
        p.setup()
        p.final_setup()

        new_vec = p.model._outputs._clone()
        new_vec.set_const(3.)

        self.assertEqual(new_vec.dot(p.model._outputs), 9.)
Ejemplo n.º 23
0
    def test_scalar_with_guess_func_additional_input(self):

        n = 1

        prob = Problem(model=Group())

        bal = BalanceComp()

        bal.add_balance('x', guess_func=lambda inputs, resids: inputs['guess_x'])
        bal.add_input('guess_x', val=0.0)

        ivc = IndepVarComp()
        ivc.add_output(name='y_tgt', val=4)
        ivc.add_output(name='guess_x', val=2.5)

        exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1})

        prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x'])

        prob.model.add_subsystem(name='exec', subsys=exec_comp)

        prob.model.add_subsystem(name='balance', subsys=bal)

        prob.model.connect('guess_x', 'balance.guess_x')
        prob.model.connect('y_tgt', 'balance.rhs:x')
        prob.model.connect('balance.x', 'exec.x')
        prob.model.connect('exec.y', 'balance.lhs:x')

        prob.model.linear_solver = DirectSolver()

        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.model.jacobian = DenseJacobian()

        prob.setup()

        prob['balance.x'] = np.random.rand(n)

        prob.run_model()

        assert_almost_equal(prob['balance.x'], 2.0, decimal=7)

        np.set_printoptions(linewidth=1024)

        cpd = prob.check_partials()

        for (of, wrt) in cpd['balance']:
            assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
Ejemplo n.º 24
0
    def test(self):
        surface = get_default_surfaces()[0]
        ny = surface['mesh'].shape[1]

        group = Group()

        ivc = IndepVarComp()
        ivc.add_output('nodes', val=np.random.random_sample((ny, 3)))

        comp = Weight(surface=surface)

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

        run_test(self, group, compact_print=False, complex_flag=True)
Ejemplo n.º 25
0
    def test_add_output_type_bug(self):
        prob = Problem()
        model = prob.model

        ivc = IndepVarComp()
        ivc.add_output('x1', val=[1, 2, 3], lower=0, upper=10)

        model.add_subsystem('p', ivc)

        prob.setup()

        prob['p.x1'][0] = 0.5
        prob.run_model()

        assert_rel_error(self, prob['p.x1'][0], 0.5)
Ejemplo n.º 26
0
    def test(self):
        """
        An example demonstrating a trivial use case of DemuxComp
        """
        import numpy as np
        from openmdao.api import Problem, Group, IndepVarComp, DemuxComp, ExecComp
        from openmdao.utils.assert_utils import assert_rel_error

        # The number of elements to be demuxed
        n = 3

        # The size of each element to be demuxed
        m = 100

        p = Problem(model=Group())

        ivc = IndepVarComp()
        ivc.add_output(name='pos_ecef', shape=(m, 3), units='km')

        p.model.add_subsystem(name='ivc',
                              subsys=ivc,
                              promotes_outputs=['pos_ecef'])

        mux_comp = p.model.add_subsystem(name='demux',
                                         subsys=DemuxComp(vec_size=n))

        mux_comp.add_var('pos', shape=(m, n), axis=1, units='km')

        p.model.add_subsystem(name='longitude_comp',
                              subsys=ExecComp('long = atan(y/x)',
                                              x={'value': np.ones(m), 'units': 'km'},
                                              y={'value': np.ones(m), 'units': 'km'},
                                              long={'value': np.ones(m), 'units': 'rad'}))

        p.model.connect('demux.pos_0', 'longitude_comp.x')
        p.model.connect('demux.pos_1', 'longitude_comp.y')
        p.model.connect('pos_ecef', 'demux.pos')

        p.setup()

        p['pos_ecef'][:, 0] = 6378 * np.cos(np.linspace(0, 2*np.pi, m))
        p['pos_ecef'][:, 1] = 6378 * np.sin(np.linspace(0, 2*np.pi, m))
        p['pos_ecef'][:, 2] = 0.0

        p.run_model()

        expected = np.arctan(p['pos_ecef'][:, 1] / p['pos_ecef'][:, 0])
        assert_rel_error(self, p.get_val('longitude_comp.long'), expected)
Ejemplo n.º 27
0
    def test_dot_petsc(self):
        if not PETScVector:
            raise unittest.SkipTest("PETSc is not installed")

        p = Problem()
        comp = IndepVarComp()
        comp.add_output('v1', val=1.0)
        comp.add_output('v2', val=2.0)
        p.model.add_subsystem('des_vars', comp, promotes=['*'])
        p.setup()
        p.final_setup()

        new_vec = p.model._outputs._clone()
        new_vec.set_const(3.)

        self.assertEqual(new_vec.dot(p.model._outputs), 9.)
Ejemplo n.º 28
0
    def test_debug_after_raised_error(self):
        prob = Problem()
        model = prob.model

        comp = IndepVarComp()
        comp.add_output('dXdt:TAS', val=1.0)
        comp.add_output('accel_target', val=2.0)
        model.add_subsystem('des_vars', comp, promotes=['*'])

        teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group())
        teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*'])

        thrust_bal = BalanceComp()
        thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS',
                               rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0)

        teg.add_subsystem(name='thrust_bal', subsys=thrust_bal,
                          promotes_inputs=['dXdt:TAS', 'accel_target'],
                          promotes_outputs=['thrust'])

        teg.linear_solver = DirectSolver()

        teg.nonlinear_solver = NewtonSolver()
        teg.nonlinear_solver.options['solve_subsystems'] = True
        teg.nonlinear_solver.options['max_sub_solves'] = 1
        teg.nonlinear_solver.options['atol'] = 1e-4
        teg.nonlinear_solver.options['debug_print'] = True

        prob.setup(check=False)
        prob.set_solver_print(level=0)

        stdout = sys.stdout
        strout = StringIO()
        sys.stdout = strout

        with self.assertRaises(RuntimeError) as cm:
            prob.run_model()

        sys.stdout = stdout

        output = strout.getvalue()
        target = "'thrust_equilibrium_group.thrust_bal.thrust'"
        self.assertTrue(target in output, msg=target + "NOT FOUND IN" + output)

        # Make sure exception is unchanged.
        expected_msg = "Singular entry found in 'thrust_equilibrium_group' for row associated with state/residual 'thrust'."
        self.assertEqual(expected_msg, str(cm.exception))
    def test2(self):
        surfaces = get_default_surfaces()

        group = Group()

        comp = MomentCoefficient(surfaces=surfaces)

        indep_var_comp = IndepVarComp()

        indep_var_comp.add_output('S_ref_total', val=1e4, units='m**2')

        group.add_subsystem('moment_calc', comp)
        group.add_subsystem('indep_var_comp', indep_var_comp)

        group.connect('indep_var_comp.S_ref_total', 'moment_calc.S_ref_total')

        run_test(self, group)
Ejemplo n.º 30
0
    def test(self):
        surfaces = get_default_surfaces()

        group = Group()

        comp = VLMGeometry(surface=surfaces[0])

        indep_var_comp = IndepVarComp()

        indep_var_comp.add_output('def_mesh', val=surfaces[0]['mesh'], units='m')

        group.add_subsystem('geom', comp)
        group.add_subsystem('indep_var_comp', indep_var_comp)

        group.connect('indep_var_comp.def_mesh', 'geom.def_mesh')

        run_test(self, group)
    def test(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 3,
            'wing_type': 'rect',
            'symmetry': False,
            'span': 10.,
            'chord': 1,
            'span_cos_spacing': 1.
        }

        mesh = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'type': 'aero',
            'symmetry': False,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'twist_cp': np.zeros(5),
            'mesh': mesh,
            'num_x': mesh.shape[0],
            'num_y': mesh.shape[1],

            # 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': 0.12,  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,  # if true, compute viscous drag
            'sweep': 0.,
            'dihedral': 0.,
        }

        surfaces = [surf_dict]

        # Create the problem and the model group
        prob = Problem()

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5.)
        indep_var_comp.add_output('M', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            geom_group = Geometry(surface=surface)

            # Add tmp_group to the problem as the name of the surface.
            # Note that is a group and performance group for each
            # individual surface.
            prob.model.add_subsystem(surface['name'], geom_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            # Create the aero point group and add it to the model
            aero_group = AeroPoint(surfaces=surfaces)
            point_name = 'aero_point_{}'.format(i)
            prob.model.add_subsystem(point_name, aero_group)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('M', point_name + '.M')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('cg', point_name + '.cg')

            # Connect the parameters within the model for each aero point
            for surface in surfaces:

                name = surface['name']

                # Connect the mesh from the geometry component to the analysis point
                prob.model.connect(name + '.mesh',
                                   point_name + '.' + name + '.def_mesh')

                # Perform the connections with the modified names within the
                # 'aero_states' group.
                prob.model.connect(
                    name + '.mesh',
                    point_name + '.aero_states.' + name + '_def_mesh')

        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-5

        # # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('wing.twist_cp', lower=-10., upper=15.)
        prob.model.add_design_var('wing.sweep', lower=10., upper=30.)
        prob.model.add_design_var('wing.dihedral', lower=-10., upper=20.)
        prob.model.add_constraint(point_name + '.wing_perf.CL', equals=0.5)
        prob.model.add_objective(point_name + '.wing_perf.CD', scaler=1e4)

        # Set up the problem
        prob.setup()

        prob.run_driver()

        assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5, 1e-5)
        assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0],
                         0.019234984422361764, 1e-3)
        TestPoint_x = trajectory_x[59]
        TestPoint_y = trajectory_y[59]

        outputs['life_dist'] = np.linalg.norm(
            [x - TestPoint_x, y - TestPoint_y])


if __name__ == '__main__':

    from openmdao.api import Problem, Group, IndepVarComp

    group = Group()

    comp = IndepVarComp()
    comp.add_output('l1')
    comp.add_output('l2')
    group.add_subsystem('i_comp', comp, promotes=['*'])

    comp = FkComp()
    group.add_subsystem('fk_comp', comp, promotes=['*'])

    comp = LiftPointCon()
    group.add_subsystem('lift_con', comp, promotes=['*'])

    prob = Problem()
    prob.model = group

    prob.setup()
    prob.run_model()
    prob.model.list_outputs()
Ejemplo n.º 33
0
    def setup(self):
        RefBlade = self.options['RefBlade']
        npts_coarse_power_curve = self.options['npts_coarse_power_curve']
        npts_spline_power_curve = self.options['npts_spline_power_curve']
        regulation_reg_II5 = self.options['regulation_reg_II5']
        regulation_reg_III = self.options['regulation_reg_III']
        flag_Cp_Ct_Cq_Tables = self.options['flag_Cp_Ct_Cq_Tables']
        Analysis_Level = self.options['Analysis_Level']
        FASTpref = self.options['FASTpref']
        topLevelFlag = self.options['topLevelFlag']
        rc_verbosity = self.options['rc_verbosity']
        rc_tex_table = self.options['rc_tex_table']
        rc_generate_plots = self.options['rc_generate_plots']
        rc_show_plots = self.options['rc_show_plots']
        rc_show_warnings = self.options['rc_show_warnings']
        rc_discrete = self.options['rc_discrete']
        NPTS = len(RefBlade['pf']['s'])

        rotorIndeps = IndepVarComp()
        rotorIndeps.add_discrete_output('tiploss', True)
        rotorIndeps.add_discrete_output('hubloss', True)
        rotorIndeps.add_discrete_output('wakerotation', True)
        rotorIndeps.add_discrete_output('usecd', True)
        rotorIndeps.add_discrete_output(
            'nSector',
            val=4,
            desc=
            'number of sectors to divide rotor face into in computing thrust and power'
        )
        self.add_subsystem('rotorIndeps', rotorIndeps, promotes=['*'])

        if topLevelFlag:
            sharedIndeps = IndepVarComp()
            sharedIndeps.add_output(
                'lifetime',
                val=20.0,
                units='year',
                desc='project lifetime for fatigue analysis')
            sharedIndeps.add_output('hub_height', val=0.0, units='m')
            sharedIndeps.add_output('rho', val=1.225, units='kg/m**3')
            sharedIndeps.add_output('mu', val=1.81e-5, units='kg/(m*s)')
            sharedIndeps.add_output('shearExp', val=0.2)
            self.add_subsystem('sharedIndeps', sharedIndeps, promotes=['*'])

        # --- Rotor Aero & Power ---
        self.add_subsystem('rg',
                           RotorGeometry(RefBlade=RefBlade,
                                         topLevelFlag=True,
                                         verbosity=rc_verbosity,
                                         tex_table=rc_tex_table,
                                         generate_plots=rc_generate_plots,
                                         show_plots=rc_show_plots,
                                         show_warnings=rc_show_warnings,
                                         discrete=rc_discrete),
                           promotes=['*'])
        self.add_subsystem('ra',
                           RotorAeroPower(
                               RefBlade=RefBlade,
                               npts_coarse_power_curve=npts_coarse_power_curve,
                               npts_spline_power_curve=npts_spline_power_curve,
                               regulation_reg_II5=regulation_reg_II5,
                               regulation_reg_III=regulation_reg_III,
                               flag_Cp_Ct_Cq_Tables=flag_Cp_Ct_Cq_Tables,
                               topLevelFlag=False),
                           promotes=['*'])
        self.add_subsystem(
            'rs',
            RotorStructure(RefBlade=RefBlade,
                           topLevelFlag=False,
                           Analysis_Level=Analysis_Level),
            promotes=[
                'fst_vt_in',
                'VfactorPC',
                'turbulence_class',
                'gust_stddev',
                'pitch_extreme',
                'azimuth_extreme',
                'rstar_damage',
                'Mxb_damage',
                'Myb_damage',
                'strain_ult_spar',
                'strain_ult_te',
                'm_damage',
                'gamma_fatigue',
                'gamma_freq',
                'gamma_f',
                'gamma_m',
                'dynamic_amplification',
                'azimuth_load180',
                'azimuth_load0',
                'azimuth_load120',
                'azimuth_load240',
                'nSector',
                'rho',
                'mu',
                'shearExp',
                'tiploss',
                'hubloss',
                'wakerotation',
                'usecd',
                'bladeLength',
                'R',
                'V_mean',
                'chord',
                'theta',
                'precurve',
                'presweep',
                'Rhub',
                'Rtip',
                'r',
                'r_in',
                'airfoils_cl',
                'airfoils_cd',
                'airfoils_cm',
                'airfoils_aoa',
                'airfoils_Re',
                'z',
                'EA',
                'EIxx',
                'EIyy',
                'EIxy',
                'GJ',
                'rhoA',
                'rhoJ',
                'x_ec',
                'y_ec',
                'Tw_iner',
                'flap_iner',
                'edge_iner',
                'eps_crit_spar',
                'eps_crit_te',
                'xu_strain_spar',
                'xl_strain_spar',
                'yu_strain_spar',
                'yl_strain_spar',
                'xu_strain_te',
                'xl_strain_te',
                'yu_strain_te',
                'yl_strain_te',
                'precurveTip',
                'presweepTip',
                'precone',
                'tilt',
                'yaw',
                'nBlades',
                'downwind',
                'control_tsr',
                'control_pitch',
                'lifetime',
                'hub_height',
                'mass_one_blade',
                'mass_all_blades',
                'I_all_blades',
                'freq_pbeam',
                'freq_curvefem',
                'modes_coef_curvefem',
                'tip_deflection',
                'tip_position',
                'ground_clearance',
                'strainU_spar',
                'strainL_spar',
                'strainU_te',
                'strainL_te',  #'eps_crit_spar','eps_crit_te',
                'root_bending_moment',
                'Mxyz',
                'damageU_spar',
                'damageL_spar',
                'damageU_te',
                'damageL_te',
                'delta_bladeLength_out',
                'delta_precurve_sub_out',
                'Fxyz_1',
                'Fxyz_2',
                'Fxyz_3',
                'Fxyz_4',
                'Fxyz_5',
                'Fxyz_6',
                'Mxyz_1',
                'Mxyz_2',
                'Mxyz_3',
                'Mxyz_4',
                'Mxyz_5',
                'Mxyz_6',
                'Fxyz_total',
                'Mxyz_total',
                'TotalCone',
                'Pitch'
            ])

        # self.add_subsystem('rc', RotorCost(RefBlade=RefBlade, verbosity=rc_verbosity),
        #                    promotes=['bladeLength','total_blade_cost','Rtip','Rhub','r','chord','le_location','materials','upperCS','lowerCS','websCS','profile'])

        self.add_subsystem('obj_cmp',
                           ExecComp('obj = -AEP',
                                    AEP={
                                        'units': 'kW*h',
                                        'value': 1000000.0
                                    },
                                    obj={'units': 'kW*h'}),
                           promotes=['*'])

        # Connections between rotor_aero and rotor_structure
        self.connect('V_mean', 'wind.Uref')
        self.connect('wind_zvec', 'wind.z')
        self.connect('rated_V', ['rs.V_hub', 'rs.setuppc.Vrated'])
        self.connect('rated_Omega', [
            'rs.Omega', 'rs.aero_rated.Omega_load',
            'rs.aero_rated_0.Omega_load', 'rs.aero_rated_120.Omega_load',
            'rs.aero_rated_240.Omega_load'
        ])
        self.connect('rated_pitch', 'rs.aero_rated.pitch_load')
        self.connect('V_extreme50', 'rs.aero_extrm.V_load')
        self.connect('V_extreme_full', 'rs.aero_extrm_forces.Uhub')
        self.connect('theta', 'rs.tip.theta', src_indices=[NPTS - 1])

        # Connections to AeroelasticSE
        if Analysis_Level >= 1:
            self.add_subsystem(
                'aeroelastic',
                FASTLoadCases(RefBlade=RefBlade,
                              npts_coarse_power_curve=npts_coarse_power_curve,
                              npts_spline_power_curve=npts_spline_power_curve,
                              FASTpref=FASTpref),
                promotes=[
                    'fst_vt_in', 'fst_vt_out', 'FASTpref_updated', 'r',
                    'le_location', 'chord', 'theta', 'precurve', 'shearExp',
                    'presweep', 'Rhub', 'Rtip', 'turbulence_class',
                    'turbine_class', 'V_R25', 'rho', 'mu', 'control_maxTS',
                    'control_maxOmega', 'hub_height', 'airfoils_cl',
                    'airfoils_cd', 'airfoils_cm', 'airfoils_aoa',
                    'airfoils_Re', 'airfoils_coord_x', 'airfoils_coord_y',
                    'rthick'
                ])

            self.connect('rhoA', 'aeroelastic.beam:rhoA')
            self.connect('EIxx', 'aeroelastic.beam:EIxx')
            self.connect('EIyy', 'aeroelastic.beam:EIyy')
            self.connect('Tw_iner', 'aeroelastic.beam:Tw_iner')
            self.connect('modes_coef_curvefem',
                         'aeroelastic.modes_coef_curvefem')
            self.connect('rs.z_az', 'aeroelastic.z_az')
            self.connect('V', 'aeroelastic.U_init')
            self.connect('Omega', 'aeroelastic.Omega_init')
            self.connect('pitch', 'aeroelastic.pitch_init')
            self.connect('rated_V', 'aeroelastic.Vrated')
            self.connect('rs.gust.V_gust', 'aeroelastic.Vgust')
            self.connect('V_mean', 'aeroelastic.V_mean_iec')
            self.connect('machine_rating', 'aeroelastic.control_ratedPower')
            if Analysis_Level > 1:
                self.connect('aeroelastic.dx_defl', 'rs.tip.dx')
                self.connect('aeroelastic.dy_defl', 'rs.tip.dy')
                self.connect('aeroelastic.dz_defl', 'rs.tip.dz')
                self.connect('aeroelastic.loads_Px',
                             'rs.loads_strain.aeroloads_Px')
                self.connect('aeroelastic.loads_Py',
                             'rs.loads_strain.aeroloads_Py')
                self.connect('aeroelastic.loads_Pz',
                             'rs.loads_strain.aeroloads_Pz')
                self.connect('aeroelastic.loads_Omega',
                             'rs.loads_strain.aeroloads_Omega')
                self.connect('aeroelastic.loads_azimuth',
                             'rs.loads_strain.aeroloads_azimuth')
                self.connect('aeroelastic.loads_pitch',
                             'rs.loads_strain.aeroloads_pitch')
                self.connect('aeroelastic.root_bending_moment',
                             'rs.root_bending_moment_in')
                self.connect('aeroelastic.Mxyz', 'rs.Mxyz_in')
Ejemplo n.º 34
0
    def setup(self):
        debug = self.options['debug']
        '''
           HubSE class
              The HubSE class is used to represent the hub system of a wind turbine. 
              HubSE integrates the hub, pitch system and spinner / nose cone components for the hub system.
        '''
        self.add_subsystem('hub', Hub_OM(debug=debug), promotes=['*'])
        self.add_subsystem('pitchSystem',
                           PitchSystem_OM(debug=debug),
                           promotes=['*'])
        self.add_subsystem('spinner', Spinner_OM(debug=debug), promotes=['*'])
        if self.options['mass_only']:
            self.add_subsystem('adder',
                               Hub_Mass_Adder_OM(debug=debug),
                               promotes=['*'])
        else:
            self.add_subsystem('adder',
                               Hub_System_Adder_OM(debug=debug),
                               promotes=['*'])

        if self.options['topLevelFlag']:
            sharedIndeps = IndepVarComp()
            sharedIndeps.add_output('rotor_diameter', 0.0, units='m')
            sharedIndeps.add_discrete_output('number_of_blades', 0)
            sharedIndeps.add_output('blade_root_diameter', 0.0, units='m')
            sharedIndeps.add_output('blade_mass', 0.0, units='kg')
            sharedIndeps.add_output('machine_rating', 0.0, units='kW')
            sharedIndeps.add_output('shaft_angle', 0.0, units='rad')
            sharedIndeps.add_output('rotor_rpm', 0.0, units='rpm')
            self.add_subsystem('sharedIndeps', sharedIndeps, promotes=['*'])
Ejemplo n.º 35
0
    def setup(self):
        shape = self.options['shape']
        module = self.options['options_dictionary']

        comp = IndepVarComp()
        comp.add_output('mass_scalar')
        comp.add_output('normalized_power', shape=shape)
        self.add_subsystem('inputs_comp', comp, promotes=['*'])

        comp = ScalarExpansionComp(
            shape=shape,
            out_name='mass',
            in_name='mass_scalar',
        )
        self.add_subsystem('mass_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='weight',
            coeff=constants.g,
            powers_dict=dict(
                mass=1.,
            ),
        )
        self.add_subsystem('weight_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='usable_energy',
            coeff=module['specific_energy'] * (1 - module['reserve']),
            powers_dict=dict(
                mass=1.,
            ),
        )
        self.add_subsystem('usable_energy_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='maximum_power',
            coeff=module['specific_power'],
            powers_dict=dict(
                mass=1.,
            ),
        )
        self.add_subsystem('maximum_power_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='power',
            powers_dict=dict(
                normalized_power=1.,
                maximum_power=1.,
            ),
        )
        self.add_subsystem('power_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='energy',
            powers_dict=dict(
                power=1.,
                time=1.,
            ),
        )
        self.add_subsystem('energy_comp', comp, promotes=['*'])

        comp = LinearCombinationComp(
            shape=shape,
            out_name='energy_constraint',
            coeffs_dict=dict(
                energy=1.,
                usable_energy=-1.,
            ),
        )
        self.add_subsystem('energy_constraint_comp', comp, promotes=['*'])
Ejemplo n.º 36
0
def add_prob_vars(case_settings, surfaces):
    # Create the problem and assign the model group
    prob = Problem()

    # Add problem information as an independent variables component
    indep_var_comp = IndepVarComp()
    indep_var_comp.add_output('v', val=np.array([102.9, .75 * 102.9]), units='m/s')
    indep_var_comp.add_output('alpha', val=0., units='deg')
    indep_var_comp.add_output('alpha_maneuver', val=0., units='deg')
    indep_var_comp.add_output('Mach_number', val=np.array([0.305, 0.75 * 0.305]))
    indep_var_comp.add_output('re',val=np.array([6.03e6, 0.75 * 6.03e6]),  units='1/m')
    indep_var_comp.add_output('rho', val=np.array([1.05549, 1.225]), units='kg/m**3')
    indep_var_comp.add_output('CT', val=0.45/3600, units='1/s')
    indep_var_comp.add_output('R', val=0.74e6, units='m')
    indep_var_comp.add_output('speed_of_sound', val= np.array([334.4, 342.]), units='m/s')
    indep_var_comp.add_output('load_factor', val=np.array([1., 2.5]))
    indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')
    indep_var_comp.add_output('fuel_mass', val=800., units='kg')

    if case_settings['engine_mass'] or case_settings['engine_thrust']:
        point_mass_locations = np.array([[-0.85, -3., 0.15],
                                         [-0.55, -6., 0.15]])
        indep_var_comp.add_output('point_mass_locations', val=point_mass_locations, units='m')

    if case_settings['engine_thrust']:
        engine_thrusts = np.array([[250., 250.]])
        indep_var_comp.add_output('engine_thrusts', val=engine_thrusts, units='N')

    # TODO : need to fix this one too
    if case_settings['engine_mass']:
        indep_var_comp.add_output('W0_without_point_masses', val=6000. + surfaces[0]['Wf_reserve'] - 350.,  units='kg')

        prob.model.add_subsystem('W0_comp',
            ExecComp('W0 = W0_without_point_masses + sum(point_masses)', units='kg', point_masses=np.zeros((2))),
            promotes=['*'])

        point_masses = np.array([[175., 175.]])
        indep_var_comp.add_output('point_masses', val=point_masses, units='kg')

    else:
        indep_var_comp.add_output('W0', val=6000 + surfaces[0]['Wf_reserve'],  units='kg')

    prob.model.add_subsystem('prob_vars',
         indep_var_comp,
         promotes=['*'])

    return prob
    def setup(self):
        E = self.metadata['E']
        L = self.metadata['L']
        b = self.metadata['b']
        volume = self.metadata['volume']
        num_elements = self.metadata['num_elements']
        num_nodes = num_elements + 1
        num_cp = self.metadata['num_cp']
        num_load_cases = self.metadata['num_load_cases']

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

        comp = 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)

        comp = GlobalStiffnessMatrixComp(num_elements=num_elements)
        self.add_subsystem('global_stiffness_matrix_comp', comp)

        # Parallel Subsystem for load cases.
        par = self.add_subsystem('parallel', 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, 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('global_stiffness_matrix_comp.K',
                         'parallel.%s.states_comp.K' % 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 = 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('local_stiffness_matrix_comp.K_local',
                     'global_stiffness_matrix_comp.K_local')
        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')
Ejemplo n.º 38
0
    def test(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 7,
                     'num_x' : 2,
                     'wing_type' : 'rect',
                     'symmetry' : True}

        mesh = generate_mesh(mesh_dict)

        surf_dict = {
                    # Wing definition
                    'name' : 'wing',        # name of the surface
                    'type' : 'aero',
                    'symmetry' : True,     # if true, model one half of wing
                                            # reflected across the plane y = 0
                    'S_ref_type' : 'wetted', # how we compute the wing area,
                                             # can be 'wetted' or 'projected'
                    'fem_model_type' : 'tube',

                    'mesh' : mesh,
                    'num_x' : mesh.shape[0],
                    'num_y' : mesh.shape[1],

                    # 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.015,            # 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' : 0.15,      # thickness over chord ratio (NACA0015)
                    'c_max_t' : .303,       # chordwise location of maximum (NACA0015)
                                            # thickness
                    'with_viscous' : True,  # if true, compute viscous drag
                    }

        # Create a dictionary to store options about the surface
        mesh_dict = {'num_y' : 5,
                     'num_x' : 3,
                     'wing_type' : 'rect',
                     'symmetry' : True,
                     'offset' : np.array([50, 0., 0.])}

        mesh = generate_mesh(mesh_dict)

        surf_dict2 = {
                    # Wing definition
                    'name' : 'tail',        # name of the surface
                    'type' : 'aero',
                    'symmetry' : True,     # if true, model one half of wing
                                            # reflected across the plane y = 0
                    'S_ref_type' : 'wetted', # how we compute the wing area,
                                             # can be 'wetted' or 'projected'

                    'mesh' : mesh,
                    'num_x' : mesh.shape[0],
                    'num_y' : mesh.shape[1],

                    # 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

                    'fem_origin' : 0.35,

                    # Airfoil properties for viscous drag calculation
                    'k_lam' : 0.05,         # percentage of chord with laminar
                                            # flow, used for viscous drag
                    't_over_c' : 0.15,      # thickness over chord ratio (NACA0015)
                    'c_max_t' : .303,       # chordwise location of maximum (NACA0015)
                                            # thickness
                    'with_viscous' : True,  # if true, compute viscous drag
                    }

        surfaces = [surf_dict, surf_dict2]

        # Create the problem and the model group
        prob = Problem()

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5.)
        indep_var_comp.add_output('M', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars',
            indep_var_comp,
            promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            geom_group = Geometry(surface=surface)

            # Add tmp_group to the problem as the name of the surface.
            # Note that is a group and performance group for each
            # individual surface.
            prob.model.add_subsystem(surface['name'], geom_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            # Create the aero point group and add it to the model
            aero_group = AeroPoint(surfaces=surfaces)
            point_name = 'aero_point_{}'.format(i)
            prob.model.add_subsystem(point_name, aero_group)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('M', point_name + '.M')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('cg', point_name + '.cg')

            # Connect the parameters within the model for each aero point
            for surface in surfaces:

                name = surface['name']

                # Connect the mesh from the geometry component to the analysis point
                prob.model.connect(name + '.mesh', point_name + '.' + name + '.def_mesh')

                # Perform the connections with the modified names within the
                # 'aero_states' group.
                prob.model.connect(name + '.mesh', point_name + '.aero_states.' + name + '_def_mesh')

        # Set up the problem
        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0], 0.035076501750605345, 1e-6)
        assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.4523608754613204, 1e-6)
        assert_rel_error(self, prob['aero_point_0.CM'][1], -10.59426779178033, 1e-6)
Ejemplo n.º 39
0
    def test(self):
        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 2,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 5
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'thickness_cp': np.array([.1, .2, .3]),
            'twist_cp': twist_cp,
            'mesh': mesh,
            'n_point_masses': 1,

            # 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.015,  # 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_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,
            'with_wave': False,  # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.35,  # normalized chordwise location of the spar
            'wing_weight_ratio': 2.,
            'struct_weight_relief':
            False,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight': False,
            # Constraints
            'exact_failure_constraint': False,  # if false, use KS function
        }

        surfaces = [surf_dict]

        # Create the problem and assign the model group
        prob = Problem()

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('CT',
                                  val=grav_constant * 17.e-6,
                                  units='1/s')
        indep_var_comp.add_output('R', val=11.165e6, units='m')
        indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg')
        indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

        point_masses = np.array([[8000.]])
        engine_thrusts = np.array([[80.e3]])

        point_mass_locations = np.array([[25, -10., -1.]])

        indep_var_comp.add_output('point_masses', val=point_masses, units='kg')
        indep_var_comp.add_output('engine_thrusts',
                                  val=engine_thrusts,
                                  units='N')
        indep_var_comp.add_output('point_mass_locations',
                                  val=point_mass_locations,
                                  units='m')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            aerostruct_group = AerostructGeometry(surface=surface)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces)

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('speed_of_sound',
                               point_name + '.speed_of_sound')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor')
            prob.model.connect('load_factor',
                               point_name + '.coupled.load_factor')

            for surface in surfaces:

                com_name = point_name + '.' + name + '_perf'
                prob.model.connect(
                    name + '.local_stiff_transformed', point_name +
                    '.coupled.' + name + '.local_stiff_transformed')
                prob.model.connect(name + '.nodes',
                                   point_name + '.coupled.' + name + '.nodes')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh',
                                   point_name + '.coupled.' + name + '.mesh')

                # Connect performance calculation variables
                prob.model.connect(name + '.radius', com_name + '.radius')
                prob.model.connect(name + '.thickness',
                                   com_name + '.thickness')
                prob.model.connect(name + '.nodes', com_name + '.nodes')
                prob.model.connect(
                    name + '.cg_location',
                    point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(
                    name + '.structural_mass', point_name + '.' +
                    'total_perf.' + name + '_structural_mass')
                prob.model.connect(name + '.t_over_c', com_name + '.t_over_c')

            coupled_name = point_name + '.coupled.' + name
            prob.model.connect('point_masses', coupled_name + '.point_masses')
            prob.model.connect('engine_thrusts',
                               coupled_name + '.engine_thrusts')
            prob.model.connect('point_mass_locations',
                               coupled_name + '.point_mass_locations')

        # Set up the problem
        prob.setup()

        prob.run_model()

        print(prob['AS_point_0.fuelburn'][0])
        print(prob['AS_point_0.CM'][1])

        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 277112.600118,
                         1e-4)
        assert_rel_error(self, prob['AS_point_0.CM'][1], -0.565647440276, 1e-5)
    def test(self):
        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 7,
            'num_x': 2,
            'wing_type': 'CRM',
            'symmetry': False,
            'num_twist_cp': 2,
            'span_cos_spacing': 1.
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'type': 'aerostruct',
            'symmetry': False,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'thickness_cp': np.ones(2) * 0.06836728,
            'twist_cp': twist_cp,
            'mesh': mesh,
            'num_x': mesh.shape[0],
            'num_y': mesh.shape[1],

            # 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.015,  # 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_cp':
            np.array([0.12]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,
            'with_wave': False,  # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.35,  # normalized chordwise location of the spar
            'wing_weight_ratio': 1.,

            # Constraints
            'exact_failure_constraint': False,  # if false, use KS function
        }

        surfaces = [surf_dict]

        # Create the problem and assign the model group
        prob = Problem()

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('M', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('CT', val=9.80665 * 17.e-6, units='1/s')
        indep_var_comp.add_output('R', val=11.165e6, units='m')
        indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg')
        indep_var_comp.add_output('a', val=295.4, units='m/s')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            aerostruct_group = Aerostruct(surface=surface)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces)

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('M', point_name + '.M')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('a', point_name + '.a')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor')

            for surface in surfaces:

                prob.model.connect('load_factor', name + '.load_factor')

                com_name = point_name + '.' + name + '_perf'
                prob.model.connect(name + '.K',
                                   point_name + '.coupled.' + name + '.K')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh',
                                   point_name + '.coupled.' + name + '.mesh')
                prob.model.connect(
                    name + '.element_weights',
                    point_name + '.coupled.' + name + '.element_weights')

                # Connect performance calculation variables
                prob.model.connect(name + '.radius', com_name + '.radius')
                prob.model.connect(name + '.thickness',
                                   com_name + '.thickness')
                prob.model.connect(name + '.nodes', com_name + '.nodes')
                prob.model.connect(
                    name + '.cg_location',
                    point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(
                    name + '.structural_weight', point_name + '.' +
                    'total_perf.' + name + '_structural_weight')
                prob.model.connect(name + '.t_over_c', com_name + '.t_over_c')

        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9

        # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('wing.twist_cp', lower=-15., upper=15.)
        prob.model.add_design_var('wing.thickness_cp',
                                  lower=0.01,
                                  upper=0.5,
                                  scaler=1e2)
        prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)
        prob.model.add_constraint('AS_point_0.wing_perf.thickness_intersects',
                                  upper=0.)

        # Add design variables, constraisnt, and objective on the problem
        prob.model.add_design_var('alpha', lower=-10., upper=10.)
        prob.model.add_constraint('AS_point_0.L_equals_W', equals=0.)
        prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5)

        # Set up the problem
        prob.setup()

        # from openmdao.api import view_model
        # view_model(prob)

        prob.run_driver()

        assert_rel_error(self, prob['AS_point_0.wing_perf.CL'][0],
                         0.469152412337, 1e-6)
        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 95396.2868311,
                         1e-6)
        assert_rel_error(self, prob['AS_point_0.wing_perf.failure'][0], 0.,
                         1e-6)
        assert_rel_error(self, prob['AS_point_0.CM'][1], -0.13357819566, 1e-4)
Ejemplo n.º 41
0
        result = self.options['deriv'](
            *[inputs[in_name].flatten() for in_name in in_names])

        for ind, in_name in enumerate(in_names):
            partials[out_name, in_name] = result[ind]


if __name__ == '__main__':
    from openmdao.api import Problem, IndepVarComp

    shape = (2, 3, 4)

    prob = Problem()

    comp = IndepVarComp()
    comp.add_output('x', np.random.rand(*shape))
    comp.add_output('y', np.random.rand(*shape))
    comp.add_output('z', np.random.rand(*shape))
    prob.model.add_subsystem('inputs_comp', comp, promotes=['*'])

    def func(x, y, z):
        return x * y * z

    def deriv(x, y, z):
        return (
            y * z,
            x * z,
            x * y,
        )

    comp = GeneralOperationComp(
Ejemplo n.º 42
0
    def setup(self):
        lsm_solver = self.options['lsm_solver']
        num_bpts = self.options['num_bpts']
        upperbound = self.options['ub']
        lowerbound = self.options['lb']

        Sf = self.options['Sf']
        Sg = self.options['Sg']
        constraintDistance = self.options['constraintDistance']

        num_dvs = 2 # number of lambdas
        
        # inputs (IndepVarComp: component)
        comp = IndepVarComp()
        comp.add_output('lambdas', val = 0.0, shape = num_dvs)
        comp.add_output('Sf', val=Sf)
        comp.add_output('Sg', val=Sg)
        comp.add_output('constraintDistance', val=constraintDistance)

        self.add_subsystem('inputs_comp', comp)        
        self.add_design_var('inputs_comp.lambdas', 
            lower = np.array([lowerbound[0], lowerbound[1]]), 
            upper = np.array([upperbound[0], upperbound[1]]))

        # scalings setup # verified (10/24)
        comp = ScalingComp(nBpts= num_bpts, lsm_solver=lsm_solver)
        self.add_subsystem('scaling_f_comp',comp)
        self.connect('inputs_comp.Sf', 'scaling_f_comp.x') 
        
        comp = ScalingComp(nBpts= num_bpts, lsm_solver=lsm_solver)
        self.add_subsystem('scaling_g_comp',comp)
        self.connect('inputs_comp.Sg', 'scaling_g_comp.x')

        # displacements setup
        comp = DisplacementComp(lsm_solver = lsm_solver, nBpts = num_bpts, ndvs = num_dvs)
        self.add_subsystem('displacement_comp', comp)
        
        self.connect('inputs_comp.lambdas', 'displacement_comp.lambdas')
        self.connect('inputs_comp.Sf', 'displacement_comp.Sf')
        self.connect('inputs_comp.Sg', 'displacement_comp.Sg')

        self.connect('scaling_f_comp.y', 'displacement_comp.Scale_f')
        self.connect('scaling_g_comp.y', 'displacement_comp.Scale_g')

        # integration setup
        comp = IntegralComp(lsm_solver=lsm_solver, nBpts=num_bpts)
        self.add_subsystem('integral_f_comp', comp)
        self.connect('inputs_comp.Sf', 'integral_f_comp.x')

        comp = IntegralComp(lsm_solver=lsm_solver, nBpts=num_bpts)
        self.add_subsystem('integral_g_comp', comp)
        self.connect('inputs_comp.Sg', 'integral_g_comp.x')
        
        # objective setup
        comp = ObjectiveComp(lsm_solver = lsm_solver, nBpts = num_bpts)
        comp.add_objective('delF')
        self.add_subsystem('objective_comp', comp)
        
        self.connect('displacement_comp.displacements', 'objective_comp.displacements')
        self.connect('integral_f_comp.y', 'objective_comp.Cf')
        self.connect('scaling_f_comp.y', 'objective_comp.scale_f')


        # constraint setup
        comp = ConstraintComp(lsm_solver = lsm_solver, nBpts = num_bpts)
        comp.add_constraint('delG', upper = 0.0 )
        self.add_subsystem('constraint_comp', comp)

        self.connect('displacement_comp.displacements', 'constraint_comp.displacements')
        self.connect('integral_g_comp.y', 'constraint_comp.Cg')
        self.connect('scaling_g_comp.y', 'constraint_comp.scale_g')
        self.connect('inputs_comp.constraintDistance', 'constraint_comp.constraintDistance')
Ejemplo n.º 43
0
            'blade_drag_coeff',
            'glauert_factor',
        ]
        self.options['get_res_func'] = get_res_func
        self.options['get_derivs_func'] = get_derivs_func


if __name__ == '__main__':
    import numpy as np

    from openmdao.api import Problem, IndepVarComp

    blade_solidity = 0.2

    shape = (2, 3)

    prob = Problem()

    comp = IndepVarComp()
    comp.add_output('eta2', np.random.random(shape))
    comp.add_output('eta3', np.random.random(shape))
    comp.add_output('power_coeff', np.random.random(shape))
    comp.add_output('advance_ratio', np.random.random(shape))
    prob.model.add_subsystem('input_comp', comp, promotes=['*'])

    comp = Eta1Comp(shape=shape, blade_solidity=blade_solidity)
    prob.model.add_subsystem('comp', comp, promotes=['*'])

    prob.setup(check=True)
    prob.run_model()
    prob.check_partials(compact_print=True)
Ejemplo n.º 44
0
    def test(self):
        from openaerostruct.geometry.utils import generate_mesh, write_FFD_file

        from openaerostruct.integration.aerostruct_groups import AerostructGeometry, AerostructPoint

        from openmdao.api import IndepVarComp, Problem, Group, SqliteRecorder
        from pygeo import DVGeometry

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 2,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 5
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'thickness_cp': np.array([.1, .2, .3]),
            'mesh': mesh,
            'geom_manipulator': 'FFD',
            'mx': 2,
            'my': 3,

            # 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.015,  # 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_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,
            'with_wave': False,  # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.35,  # normalized chordwise location of the spar
            'wing_weight_ratio': 2.,
            'struct_weight_relief':
            False,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight': False,
            # Constraints
            'exact_failure_constraint': False,  # if false, use KS function
        }

        surfaces = [surf_dict]

        # Create the problem and assign the model group
        prob = Problem()

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('CT', val=9.80665 * 17.e-6, units='1/s')
        indep_var_comp.add_output('R', val=11.165e6, units='m')
        indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg')
        indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            filename = write_FFD_file(surface, surface['mx'], surface['my'])
            DVGeo = DVGeometry(filename)
            aerostruct_group = AerostructGeometry(surface=surface, DVGeo=DVGeo)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces)

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('speed_of_sound',
                               point_name + '.speed_of_sound')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor')

            for surface in surfaces:

                prob.model.connect('load_factor', name + '.load_factor')

                com_name = point_name + '.' + name + '_perf'
                prob.model.connect(name + '.K',
                                   point_name + '.coupled.' + name + '.K')
                prob.model.connect(name + '.nodes',
                                   point_name + '.coupled.' + name + '.nodes')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh',
                                   point_name + '.coupled.' + name + '.mesh')

                # Connect performance calculation variables
                prob.model.connect(name + '.radius', com_name + '.radius')
                prob.model.connect(name + '.thickness',
                                   com_name + '.thickness')
                prob.model.connect(name + '.nodes', com_name + '.nodes')
                prob.model.connect(
                    name + '.cg_location',
                    point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(
                    name + '.structural_weight', point_name + '.' +
                    'total_perf.' + name + '_structural_weight')
                prob.model.connect(name + '.t_over_c', com_name + '.t_over_c')

        # Import the Scipy Optimizer and set the driver of the problem to use
        # it, which defaults to an SLSQP optimization method
        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()

        recorder = SqliteRecorder("aerostruct_ffd.db")
        prob.driver.add_recorder(recorder)
        prob.driver.recording_options['record_derivatives'] = True
        prob.driver.recording_options['includes'] = ['*']

        # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('wing.shape', lower=-3, upper=2)
        prob.model.add_design_var('wing.thickness_cp',
                                  lower=0.01,
                                  upper=0.5,
                                  scaler=1e2)
        prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)
        prob.model.add_constraint('AS_point_0.wing_perf.thickness_intersects',
                                  upper=0.)

        # Add design variables, constraisnt, and objective on the problem
        prob.model.add_design_var('alpha', lower=-10., upper=10.)
        prob.model.add_constraint('AS_point_0.L_equals_W', equals=0.)
        prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5)

        # iprofile.setup()
        # iprofile.start()

        # Set up the problem
        prob.setup()

        # from openmdao.api import view_model
        # view_model(prob, outfile='aerostruct_ffd', show_browser=False)

        # prob.run_model()
        prob.run_driver()

        # prob.check_partials(compact_print=True)

        # print("\nWing CL:", prob['aero_point_0.wing_perf.CL'])
        # print("Wing CD:", prob['aero_point_0.wing_perf.CD'])

        # from helper import plot_3d_points
        #
        # mesh = prob['aero_point_0.wing.def_mesh']
        # plot_3d_points(mesh)
        #
        # filename = mesh_dict['wing_type'] + '_' + str(mesh_dict['num_x']) + '_' + str(mesh_dict['num_y'])
        # filename += '_' + str(surf_dict['mx']) + '_' + str(surf_dict['my']) + '.mesh'
        # np.save(filename, mesh)

        assert_rel_error(self, prob['AS_point_0.fuelburn'][0],
                         104675.0989232741, 1e-3)
Ejemplo n.º 45
0
    def compute_partials(self, inputs, partials):
        in_name = self.options['in_name']
        out_name = self.options['out_name']
        partials[out_name, in_name] = 1.0 - (
            (1.0 / np.tanh(inputs[in_name]))**2).flatten()


if __name__ == "__main__":
    from openmdao.api import Problem, IndepVarComp, Group
    n = 100
    val = np.random.rand(n)
    indeps = IndepVarComp()
    indeps.add_output(
        'x',
        val=val,
        shape=(n, ),
    )
    prob = Problem()
    prob.model = Group()
    prob.model.add_subsystem(
        'indeps',
        indeps,
        promotes=['*'],
    )
    prob.model.add_subsystem(
        'coth',
        CotanhComp(in_name='x', out_name='y', shape=(n, )),
        promotes=['*'],
    )
    prob.setup()
Ejemplo n.º 46
0
            tmps[ind] = array

        partials[out_name, in2_name] = (tmps[0] + tmps[1] + tmps[2]).flatten()


if __name__ == '__main__':
    from openmdao.api import Problem, IndepVarComp

    shape = (2, 4, 3, 5)
    axis = 2

    prob = Problem()

    comp = IndepVarComp()
    comp.add_output('in1', val=np.random.random(shape))
    comp.add_output('in2', val=np.random.random(shape))
    prob.model.add_subsystem('ivc', comp, promotes=['*'])

    comp = CrossProductComp(
        shape=shape,
        axis=axis,
        out_name='out',
        in1_name='in1',
        in2_name='in2',
    )
    prob.model.add_subsystem('comp', comp, promotes=['*'])

    prob.setup(check=True)
    prob.run_model()
    prob.check_partials(compact_print=True)
Ejemplo n.º 47
0
    def setup(self):

        map_data = self.options['map_data']
        design = self.options['design']
        method = self.options['interp_method']
        extrap = self.options['extrap']

        params = map_data.param_data
        outputs = map_data.output_data

        # Define map which will be used
        readmap = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            readmap.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            readmap.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])

        # Create instance of map for evaluating actual operating point
        if design:
            # In design mode, operating point specified by default values for RlineMap, NcMap and alphaMap
            mapDesPt = IndepVarComp()
            mapDesPt.add_output('NcMap',
                                val=map_data.defaults['NcMap'],
                                units='rpm')
            mapDesPt.add_output('RlineMap',
                                val=map_data.defaults['RlineMap'],
                                units=None)
            self.add_subsystem('mapDesPt', subsys=mapDesPt, promotes=['*'])

            # Evaluate map using design point values
            self.add_subsystem(
                'map',
                readmap,
                promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'],
                promotes_outputs=['effMap', 'PRmap', 'WcMap'])

            # Compute map scalars based on input PR, eff, Nc and Wc as well as unscaled map values
            self.add_subsystem(
                'scalars',
                MapScalars(),
                promotes_inputs=[
                    'PR', 'eff', 'Nc', 'Wc', 'NcMap', 'effMap', 'PRmap',
                    'WcMap'
                ],
                promotes_outputs=['s_Nc', 's_PR', 's_eff', 's_Wc'])

        else:
            # In off-design mode, RlineMap, NcMap and alphaMap are input to map
            self.add_subsystem(
                'map',
                readmap,
                promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'],
                promotes_outputs=['effMap', 'PRmap', 'WcMap'])

            # Compute scaled map outputs base on input scalars and unscaled map values
            self.add_subsystem('scaledOutput',
                               ScaledMapValues(),
                               promotes_inputs=[
                                   's_PR', 's_eff', 's_Wc', 's_Nc', 'NcMap',
                                   'effMap', 'PRmap', 'WcMap'
                               ],
                               promotes_outputs=['PR', 'eff'])

            # Use balance component to vary NcMap and RlineMap to match incoming corrected flow and speed
            map_bal = BalanceComp()
            map_bal.add_balance('NcMap',
                                val=map_data.defaults['NcMap'],
                                units='rpm',
                                eq_units='rpm')
            map_bal.add_balance('RlineMap',
                                val=map_data.defaults['RlineMap'],
                                units=None,
                                eq_units='lbm/s',
                                lower=map_data.RlineStall)
            self.add_subsystem(name='map_bal',
                               subsys=map_bal,
                               promotes_inputs=[('lhs:NcMap', 'Nc'),
                                                ('lhs:RlineMap', 'Wc')],
                               promotes_outputs=['NcMap', 'RlineMap'])
            self.connect('scaledOutput.Nc', 'map_bal.rhs:NcMap')
            self.connect('scaledOutput.Wc', 'map_bal.rhs:RlineMap')

        # Define the Rline corresponding to stall
        RlineStall = IndepVarComp()
        RlineStall.add_output('RlineStall',
                              val=map_data.RlineStall,
                              units=None)
        self.add_subsystem('stall_R', subsys=RlineStall)

        # Evaluate map for the constant speed stall margin (SMN)
        SMN_map = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            SMN_map.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            SMN_map.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])

        self.add_subsystem('SMN_map',
                           SMN_map,
                           promotes_inputs=['NcMap', 'alphaMap'])
        self.connect('stall_R.RlineStall', 'SMN_map.RlineMap')

        # Evaluate map for the constant speed stall margin (SMN)
        SMW_map = MetaModelStructuredComp(method=method, extrapolate=extrap)
        for p in params:
            SMW_map.add_input(p['name'],
                              val=p['default'],
                              units=p['units'],
                              training_data=p['values'])
        for o in outputs:
            SMW_map.add_output(o['name'],
                               val=o['default'],
                               units=o['units'],
                               training_data=o['values'])
        self.add_subsystem('SMW_map', SMW_map, promotes_inputs=['alphaMap'])
        self.connect('stall_R.RlineStall', 'SMW_map.RlineMap')

        # Use balance to vary NcMap on SMW map to hold corrected flow constant
        SMW_bal = BalanceComp()
        SMW_bal.add_balance('NcMap',
                            val=map_data.defaults['NcMap'],
                            units='rpm',
                            eq_units='lbm/s')
        self.add_subsystem(name='SMW_bal', subsys=SMW_bal)
        self.connect('SMW_bal.NcMap', 'SMW_map.NcMap')
        self.connect('WcMap', 'SMW_bal.lhs:NcMap')
        self.connect('SMW_map.WcMap', 'SMW_bal.rhs:NcMap')

        # Compute the stall margins
        self.add_subsystem('stall_margins',
                           StallCalcs(),
                           promotes_inputs=[('PR_actual', 'PRmap'),
                                            ('Wc_actual', 'WcMap')],
                           promotes_outputs=['SMN', 'SMW'])
        self.connect('SMN_map.PRmap', 'stall_margins.PR_SMN')
        self.connect('SMW_map.PRmap', 'stall_margins.PR_SMW')
        self.connect('SMN_map.WcMap', 'stall_margins.Wc_SMN')
Ejemplo n.º 48
0
def fctOptim(mrhoi, skin, spar, span, toverc):

    # Starting time
    starttime = time.time()

    # Materials
    #sandw1=material(66.35,4.25e9,1.63e9,58.7e6/1.5,34.7,"sandw1")
    #sandw2=material(174.5,14.15e9,5.44e9,195.6e6/1.5,43.4,"sandw2")
    #sandw3=material(483,42.5e9,16.3e9,586e6/1.5,46.8,"sandw3")
    sandw4 = material(504.5, 42.5e9, 16.3e9, 586e6 / 1.5, 44.9, "sandw4")
    #sandw5=material(574.5,42.5e9,16.3e9,586e6/1.5,39.3,"sandw5")
    sandw5 = material(560.5, 42.5e9, 16.3e9, 586e6 / 1.5, 40.3, "sandw5")
    sandw6 = material(529, 42.5e9, 16.3e9, 237e6 / 1.5, 42.75, "sandw6")
    al7075 = material(2.80e3, 72.5e9, 27e9, 444.5e6 / 1.5,
                      13.15 * (1 - 0.426) + 2.61 * 0.426,
                      "al7075")  #from EDUPACK
    #al7075oas=material(2.78e3,73.1e9,73.1e9/2/1.33,444.5e6/1.5,13.15*(1-0.426)+2.61*0.426,"al7075") #from OAS example
    qiCFRP = material(1565, 54.9e9, 21e9, 670e6 / 1.5, 48.1, "qiCFRP")
    steel = material(7750, 200e9, 78.5e9, 562e6 / 1.5,
                     4.55 * (1 - 0.374) + 1.15 * 0.374, "steel")
    gfrp = material(1860, 21.4e9, 8.14e9, 255e6, 6.18,
                    "gfrp")  #epoxy-Eglass,woven,QI
    #nomat=material(1370,0.01,0.01,0.01,60,"noMaterial")
    nomat = material(50, 1e8, 1e4, 1e5, 6000, "noMaterial")
    #nomat=material(50,1e8,1e4,1e5,60,"noMaterial")
    fakemat = material((2.80e3 + 7750) / 2, (72.5e9 + 200e9) / 2,
                       (27e9 + 78.5e9) / 2, (444.5e6 / 1.5 + 562e6 / 1.5) / 2,
                       (13.15 * (1 - 0.426) + 2.61 * 0.426 + 4.55 *
                        (1 - 0.374) + 1.15 * 0.374) / 2, "fakemat")
    nomatEnd = material(10000, 5e9, 2e9, 20e6 / 1.5, 60, "nomatEnd")

    materials = [
        al7075, qiCFRP, steel, gfrp, nomat, fakemat, nomatEnd, sandw4, sandw5,
        sandw6
    ]
    #    materials=[al7075, qiCFRP, steel, gfrp, nomat, fakemat, nomatEnd, sandw3, sandw4, sandw5, sandw6]
    #    materials=[al7075, qiCFRP, steel, gfrp, nomat, fakemat, nomatEnd,sandw1,sandw2,sandw3]
    #    materials=[sandw4, sandw5, nomat, nomatEnd]

    # Provide coordinates for a portion of an airfoil for the wingbox cross-section as an nparray with dtype=complex (to work with the complex-step approximation for derivatives).
    # These should be for an airfoil with the chord scaled to 1.
    # We use the 10% to 60% portion of the NACA 63412 airfoil for this case
    # We use the coordinates available from airfoiltools.com. Using such a large number of coordinates is not necessary.
    # The first and last x-coordinates of the upper and lower surfaces must be the same
    upper_x = 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')
    lower_x = 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')
    upper_y = np.array([
        0.0513, 0.0537, 0.0559, 0.0580, 0.0600, 0.0619, 0.0636, 0.0652, 0.0668,
        0.0682, 0.0696, 0.0709, 0.0721, 0.0732, 0.0742, 0.0752, 0.0761, 0.0769,
        0.0776, 0.0782, 0.0788, 0.0793, 0.0797, 0.0801, 0.0804, 0.0806, 0.0808,
        0.0808, 0.0808, 0.0807, 0.0806, 0.0804, 0.0801, 0.0798, 0.0794, 0.0789,
        0.0784, 0.0778, 0.0771, 0.0764, 0.0757, 0.0749, 0.0740, 0.0732, 0.0723,
        0.0713, 0.0703, 0.0692, 0.0681, 0.0669, 0.0657
    ],
                       dtype='complex128')
    lower_y = np.array([
        -0.0296, -0.0307, -0.0317, -0.0326, -0.0335, -0.0343, -0.0350, -0.0357,
        -0.0363, -0.0368, -0.0373, -0.0378, -0.0382, -0.0386, -0.0389, -0.0391,
        -0.0394, -0.0395, -0.0397, -0.0398, -0.0398, -0.0398, -0.0398, -0.0397,
        -0.0396, -0.0394, -0.0392, -0.0389, -0.0386, -0.0382, -0.0378, -0.0374,
        -0.0369, -0.0363, -0.0358, -0.0352, -0.0345, -0.0338, -0.0331, -0.0324,
        -0.0316, -0.0308, -0.0300, -0.0292, -0.0283, -0.0274, -0.0265, -0.0256,
        -0.0246, -0.0237, -0.0227
    ],
                       dtype='complex128')

    Rcurv = RadiusCurvature(upper_x, lower_x, upper_y, lower_y)

    # Create a dictionary to store options about the surface
    mesh_dict = {
        'num_y': 15,
        'num_x': 3,
        'wing_type': 'rect',
        'symmetry': True,
        'chord_cos_spacing': 0,
        'span_cos_spacing': 0,
        'num_twist_cp': 4
    }

    mesh = generate_mesh(mesh_dict)

    # Batteries and solar panels
    densityPV = 0.23  #kg/m^2
    energeticDensityBattery = 435 * 0.995 * 0.95 * 0.875 * 0.97  #Wh/kg 0.995=battery controller efficiency, 0.95=end of life capacity loss of 5%, 0.97=min battery SOC of 3%, 0.875=packaging efficiency
    emissionBat = 0.104 / 0.995 / 0.95 / 0.875 / 0.97  #[kgCO2/Wh]
    night_hours = 13  #h
    productivityPV = 350.0 * 0.97 * 0.95  #[W/m^2] 350 from Zephyr power figure, 0.97=MPPT efficiency, 0.95=battery round trip efficiency
    emissionPV = 0.05 / 0.97 / 0.95  #[kgCO2/W] emissions of the needed PV surface to produce 1W
    emissionsPerW = emissionPV + emissionBat * night_hours  #[kgCO2/W]

    # Dictionary for the lifting surface
    surf_dict = {
        # Wing definition
        'name':
        'wing',  # give the surface some name
        'symmetry':
        True,  # if True, model only one half of the lifting surface
        'S_ref_type':
        'projected',  # how we compute the wing area,
        # can be 'wetted' or 'projected'
        'mesh':
        mesh,
        'fem_model_type':
        'wingbox',  # 'wingbox' or 'tube'
        'data_x_upper':
        upper_x,
        'data_x_lower':
        lower_x,
        'data_y_upper':
        upper_y,
        'data_y_lower':
        lower_y,
        'airfoil_radius_curvature':
        Rcurv,
        'twist_cp':
        np.array([10., 20., 20., 20.]),  # [deg]
        'chord_cp': [1.5],  # [m]
        'span':
        span,  #[m]
        'taper':
        0.3,
        'spar_thickness_cp':
        np.array([spar, spar, spar, spar]),  # [m]
        'skin_thickness_cp':
        np.array([skin / 2, skin, skin * 1.5, 2 * skin]),  # [m]
        't_over_c_cp':
        np.array([0.75 * toverc, toverc, toverc, 1.25 * toverc]),  #TODELETE
        'original_wingbox_airfoil_t_over_c':
        0.12,

        # Aerodynamic deltas.
        # 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.
        # They can be used to account for things that are not included, such as contributions from the fuselage, camber, etc.
        'CL0':
        0.0,  # CL delta
        'CD0':
        0.0078,  # CD delta
        'with_viscous':
        True,  # if true, compute viscous drag
        'with_wave':
        True,  # if true, compute wave drag

        # Airfoil properties for viscous drag calculation
        'k_lam':
        0.80,
        #'k_lam' : 0.05,         # fraction of chord with laminar
        # flow, used for viscous drag
        'c_max_t':
        .349,  # chordwise location of maximum thickness

        # Materials
        'materlist':
        materials,
        'puissanceMM':
        1,  #power used in muli-material function

        # Structural values
        'strength_factor_for_upper_skin':
        1.0,  # the yield stress is multiplied by this factor for the upper skin
        'wing_weight_ratio':
        1.,
        'exact_failure_constraint':
        False,  # if false, use KS function
        'struct_weight_relief':
        True,

        # Engines
        'n_point_masses':
        1,  # number of point masses in the system; in this case, the engine (omit option if no point masses)

        # Power
        'productivityPV':
        productivityPV,  #[W/m^2]
        'densityPV':
        densityPV + productivityPV / energeticDensityBattery *
        night_hours,  #[kg/m^2] the weight of the batteries is counted here
        'payload_power':
        125.5,  #[W] payload=150 + avionics=211
        'motor_propeller_efficiency':
        0.84,  #thrusting power/electrical power used by propulsion
        'co2PV':
        emissionsPerW * productivityPV /
        (densityPV + productivityPV / energeticDensityBattery *
         night_hours),  #[kgCO2/kg] #co2 burden of PV cells and battery
        'prop_density':
        0.0058,  #[kg/W]
        'mppt_density':
        0.00045,  #[kg/W]
    }

    surfaces = [surf_dict]

    # Create the problem and assign the model group
    prob = Problem()

    # Add problem information as an independent variables component data for altitude=23240 m and 0 m
    speed = 15.56  #m/s
    speed_dive = 1.4 * speed  #m/s
    gust_speed = 3.4  #m/s
    rho_air = 0.089  #kg/m**3
    speed_sound = 295.1  #m/s
    #n_gust = 1 + 0.5*rho_air*speed_dive*gust_speed*2*pi/3000

    indep_var_comp = IndepVarComp()
    indep_var_comp.add_output('Mach_number',
                              val=np.array([
                                  speed / speed_sound,
                                  (speed_dive**2 + gust_speed**2)**0.5 /
                                  speed_sound, 0
                              ]))
    indep_var_comp.add_output(
        'v',
        val=np.array([speed, (speed_dive**2 + gust_speed**2)**0.5, 0]),
        units='m/s')
    indep_var_comp.add_output('re',val=np.array([rho_air*speed*1./(1.4*1e-5), \
                              rho_air*speed_dive*1./(1.4*1e-5), 0]),  units='1/m') #L=10m,
    indep_var_comp.add_output('rho',
                              val=np.array([rho_air, rho_air, 1.225]),
                              units='kg/m**3')
    indep_var_comp.add_output('speed_of_sound',
                              val=np.array([speed_sound, speed_sound, 340]),
                              units='m/s')

    indep_var_comp.add_output('W0_without_point_masses', val=8, units='kg')

    indep_var_comp.add_output('load_factor', val=np.array([1., 1.1, 0.]))
    indep_var_comp.add_output('alpha', val=0., units='deg')
    indep_var_comp.add_output('alpha_gust',
                              val=atan(gust_speed / speed_dive) * 180 / pi,
                              units='deg')

    indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

    indep_var_comp.add_output('mrho',
                              val=np.array([mrhoi, mrhoi]),
                              units='kg/m**3')

    indep_var_comp.add_output('engine_location', val=-0.3)  #VMGM

    prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

    # Loop over each surface in the surfaces list
    for surface in surfaces:

        # Get the surface name and create a group to contain components
        # only for this surface
        name = surface['name']

        aerostruct_group = AerostructGeometry(surface=surface)

        # Add groups to the problem with the name of the surface.
        prob.model.add_subsystem(name, aerostruct_group)

    prob.model.add_subsystem('YoungMM',
                             YoungMM(surface=surface),
                             promotes_inputs=['mrho'],
                             promotes_outputs=['young'])  #VMGM
    prob.model.add_subsystem('ShearMM',
                             ShearMM(surface=surface),
                             promotes_inputs=['mrho'],
                             promotes_outputs=['shear'])  #VMGM
    prob.model.add_subsystem('YieldMM',
                             YieldMM(surface=surface),
                             promotes_inputs=['mrho'],
                             promotes_outputs=['yield'])  #VMGM
    prob.model.add_subsystem('CO2MM',
                             CO2MM(surface=surface),
                             promotes_inputs=['mrho'],
                             promotes_outputs=['co2'])  #VMGM
    prob.model.add_subsystem(
        'PointMassLocations',
        PointMassLocations(surface=surface),
        promotes_inputs=['engine_location', 'span', 'nodes'],
        promotes_outputs=['point_mass_locations'])  #VMGM
    prob.model.add_subsystem('PointMasses',
                             PointMasses(surface=surface),
                             promotes_inputs=['PV_surface'],
                             promotes_outputs=['point_masses'])  #VMGM

    prob.model.add_subsystem(
        'W0_comp',
        ExecComp('W0 = W0_without_point_masses + 2*sum(point_masses)',
                 units='kg'),
        promotes=['*'])

    prob.model.connect('mrho',
                       name + '.struct_setup.structural_mass.mrho')  #ED
    prob.model.connect('young', name +
                       '.struct_setup.assembly.local_stiff.young')  #VMGM
    prob.model.connect('shear', name +
                       '.struct_setup.assembly.local_stiff.shear')  #VMGM
    prob.model.connect('wing.span', 'span')  #VMGM
    prob.model.connect('AS_point_0.total_perf.PV_surface', 'PV_surface')  #VMGM
    prob.model.connect(name + '.nodes', 'nodes')  #VMGM

    # Loop through and add a certain number of aerostruct points
    for i in range(3):
        #    for i in range(1):

        point_name = 'AS_point_{}'.format(i)
        # Connect the parameters within the model for each aero point

        # Create the aerostruct point group and add it to the model
        AS_point = AerostructPoint(surfaces=surfaces)

        prob.model.add_subsystem(point_name, AS_point)
        # Connect flow properties to the analysis point
        prob.model.connect('v', point_name + '.v', src_indices=[i])
        prob.model.connect('Mach_number',
                           point_name + '.Mach_number',
                           src_indices=[i])
        prob.model.connect('re', point_name + '.re', src_indices=[i])
        prob.model.connect('rho', point_name + '.rho', src_indices=[i])
        prob.model.connect('W0', point_name + '.W0')
        prob.model.connect('speed_of_sound',
                           point_name + '.speed_of_sound',
                           src_indices=[i])
        prob.model.connect('empty_cg', point_name + '.empty_cg')
        prob.model.connect('load_factor',
                           point_name + '.load_factor',
                           src_indices=[i])

        for surface in surfaces:

            name = surface['name']

            prob.model.connect('load_factor',
                               point_name + '.coupled.load_factor',
                               src_indices=[i])  #for PV distributed weight

            com_name = point_name + '.' + name + '_perf.'
            prob.model.connect(
                name + '.local_stiff_transformed',
                point_name + '.coupled.' + name + '.local_stiff_transformed')
            prob.model.connect(name + '.nodes',
                               point_name + '.coupled.' + name + '.nodes')
            prob.model.connect('young',
                               com_name + 'struct_funcs.vonmises.young')
            prob.model.connect('shear',
                               com_name + 'struct_funcs.vonmises.shear')
            prob.model.connect('yield',
                               com_name + 'struct_funcs.failure.yield')  #VMGM
            prob.model.connect('young',
                               com_name + 'struct_funcs.buckling.young')  #VMGM
            prob.model.connect('shear',
                               com_name + 'struct_funcs.buckling.shear')  #VMGM
            prob.model.connect(name + '.t_over_c', com_name +
                               'struct_funcs.buckling.t_over_c')  #VMGM

            # Connect aerodyamic mesh to coupled group mesh
            prob.model.connect(name + '.mesh',
                               point_name + '.coupled.' + name + '.mesh')
            if surf_dict['struct_weight_relief']:
                prob.model.connect(
                    name + '.element_mass',
                    point_name + '.coupled.' + name + '.element_mass')

            # Connect performance calculation variables
            prob.model.connect(name + '.nodes', com_name + 'nodes')
            prob.model.connect(
                name + '.cg_location',
                point_name + '.' + 'total_perf.' + name + '_cg_location')
            prob.model.connect(
                name + '.structural_mass',
                point_name + '.' + 'total_perf.' + name + '_structural_mass')

            # Connect wingbox properties to von Mises stress calcs
            prob.model.connect(name + '.Qz', com_name + 'Qz')
            prob.model.connect(name + '.J', com_name + 'J')
            prob.model.connect(name + '.A_enc', com_name + 'A_enc')
            prob.model.connect(name + '.htop', com_name + 'htop')
            prob.model.connect(name + '.hbottom', com_name + 'hbottom')
            prob.model.connect(name + '.hfront', com_name + 'hfront')
            prob.model.connect(name + '.hrear', com_name + 'hrear')
            prob.model.connect(name + '.Qx', com_name + 'Qx')

            prob.model.connect(name + '.spar_thickness',
                               com_name + 'spar_thickness')
            prob.model.connect(name + '.skin_thickness',
                               com_name + 'skin_thickness')
            prob.model.connect(name + '.t_over_c', com_name + 't_over_c')

            coupled_name = point_name + '.coupled.' + name
            prob.model.connect('point_masses', coupled_name + '.point_masses')
            prob.model.connect('point_mass_locations',
                               coupled_name + '.point_mass_locations')

    prob.model.connect('alpha', 'AS_point_0' + '.alpha')
    prob.model.connect('alpha_gust', 'AS_point_1' + '.alpha')
    prob.model.connect('alpha', 'AS_point_2' + '.alpha')  #VMGM

    # Here we add the co2 objective componenet to the model
    prob.model.add_subsystem('emittedco2',
                             structureCO2(surfaces=surfaces),
                             promotes_inputs=['co2'],
                             promotes_outputs=['emitted_co2'])  #VMGM
    prob.model.connect('wing.structural_mass', 'emittedco2.mass')
    prob.model.connect('AS_point_0.total_perf.PV_mass', 'emittedco2.PV_mass')
    prob.model.connect('wing.spars_mass', 'emittedco2.spars_mass')  #VMGM

    #Here we add the thickness constraint to the model
    prob.model.add_subsystem('acceptableThickness',
                             checkThickness(surface=surface),
                             promotes_outputs=['acceptableThickness'])
    prob.model.connect('wing.geometry.t_over_c_cp',
                       'acceptableThickness.t_over_c')
    prob.model.connect('wing.chord_cp', 'acceptableThickness.chordroot')
    prob.model.connect('wing.skin_thickness_cp',
                       'acceptableThickness.skinThickness')
    prob.model.connect('wing.taper', 'acceptableThickness.taper')

    prob.model.connect('wing.struct_setup.PV_areas',
                       'AS_point_0.coupled.wing.struct_states.PV_areas')
    prob.model.connect('AS_point_0.total_perf.PV_mass',
                       'AS_point_0.coupled.wing.struct_states.PV_mass')
    prob.model.connect('wing.struct_setup.PV_areas',
                       'AS_point_1.coupled.wing.struct_states.PV_areas')
    prob.model.connect('AS_point_0.total_perf.PV_mass',
                       'AS_point_1.coupled.wing.struct_states.PV_mass')
    prob.model.connect('wing.chord_cp',
                       'AS_point_1.wing_perf.struct_funcs.chord')
    prob.model.connect('wing.taper', 'AS_point_1.wing_perf.struct_funcs.taper')
    prob.model.connect('wing.struct_setup.PV_areas',
                       'AS_point_2.coupled.wing.struct_states.PV_areas')  #VMGM
    prob.model.connect('AS_point_0.total_perf.PV_mass',
                       'AS_point_2.coupled.wing.struct_states.PV_mass')  #VMGM
    prob.model.connect('wing.chord_cp',
                       'AS_point_2.wing_perf.struct_funcs.chord')  #VMGM
    prob.model.connect('wing.taper',
                       'AS_point_2.wing_perf.struct_funcs.taper')  #VMGM

    # Objective function
    prob.model.add_objective('emitted_co2', scaler=1e-4)

    # Design variables
    prob.model.add_design_var('wing.twist_cp',
                              lower=-20.,
                              upper=20.,
                              scaler=0.1)  #VMGM
    prob.model.add_design_var('wing.spar_thickness_cp',
                              lower=0.0001,
                              upper=0.1,
                              scaler=1e4)
    prob.model.add_design_var('wing.skin_thickness_cp',
                              lower=0.0001,
                              upper=0.1,
                              scaler=1e3)
    prob.model.add_design_var('wing.span', lower=1., upper=1000., scaler=0.1)
    prob.model.add_design_var('wing.chord_cp', lower=1.4, upper=500., scaler=1)
    ##prob.model.add_design_var('wing.span', lower=1., upper=50., scaler=0.1)
    ##prob.model.add_design_var('wing.chord_cp', lower=1., upper=500., scaler=1)
    prob.model.add_design_var('wing.taper', lower=0.3, upper=0.99, scaler=10)
    prob.model.add_design_var('wing.geometry.t_over_c_cp',
                              lower=0.01,
                              upper=0.4,
                              scaler=10.)
    prob.model.add_design_var('mrho', lower=504.5, upper=504.5,
                              scaler=0.001)  #ED
    #prob.model.add_design_var('mrho', lower=500, upper=8000, scaler=0.001) #ED
    prob.model.add_design_var('engine_location', lower=-1, upper=0,
                              scaler=10.)  #VMGM

    # Constraints
    prob.model.add_constraint('AS_point_0.L_equals_W', equals=0.)
    prob.model.add_constraint(
        'AS_point_0.enough_power', upper=0.
    )  #Make sure needed power stays below the solar power producible by the wing
    prob.model.add_constraint(
        'acceptableThickness', upper=0.
    )  #Make sure skin thickness fits in the wing (to avoid negative spar mass)
    #prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)  #VMGM
    #prob.model.add_constraint('AS_point_0.wing_perf.buckling', upper=0.)  #VMGM
    prob.model.add_constraint('AS_point_1.wing_perf.failure', upper=0.)
    prob.model.add_constraint('AS_point_1.wing_perf.buckling', upper=0.)
    prob.model.add_constraint('AS_point_2.wing_perf.failure', upper=0.)  #VMGM
    prob.model.add_constraint('AS_point_2.wing_perf.buckling', upper=0.)  #VMGM
    prob.model.add_constraint(
        'AS_point_0.coupled.wing.S_ref',
        upper=200.)  # Surface constarint to avoid snowball effect

    #prob.model.approx_totals(method='fd', step=5e-7, form='forward', step_calc='rel')
    #prob.model.nonlinear_solver = newton = NewtonSolver()

    prob.driver = ScipyOptimizeDriver()
    prob.driver.options['optimizer'] = 'SLSQP'
    prob.driver.options['tol'] = 1e-6
    prob.driver.options['maxiter'] = 250
    #prob.driver.options['debug_print'] = ['desvars','ln_cons','nl_cons','totals']

    recorder = SqliteRecorder("aerostructMrhoi" + str(mrhoi) + "sk" +
                              str(skin) + "sr" + str(spar) + "sn" + str(span) +
                              "tc" + str(toverc) + ".db")
    prob.driver.add_recorder(recorder)

    # We could also just use prob.driver.recording_options['includes']=['*'] here, but for large meshes the database file becomes extremely large. So we just select the variables we need.
    prob.driver.recording_options['includes'] = [
        'alpha',
        'rho',
        'v',
        'cg',
        'alpha_gust',  #
        'AS_point_1.cg',
        'AS_point_0.cg',  #
        'AS_point_0.cg',  #ED
        'AS_point_0.coupled.wing_loads.loads',
        'AS_point_1.coupled.wing_loads.loads',  #
        'AS_point_2.coupled.wing_loads.loads',  #
        'AS_point_0.coupled.wing.normals',
        'AS_point_1.coupled.wing.normals',  #
        'AS_point_0.coupled.wing.widths',
        'AS_point_1.coupled.wing.widths',  #
        'AS_point_0.coupled.aero_states.wing_sec_forces',
        'AS_point_1.coupled.aero_states.wing_sec_forces',  #
        'AS_point_2.coupled.aero_states.wing_sec_forces',  #
        'AS_point_0.wing_perf.CL1',
        'AS_point_1.wing_perf.CL1',  #
        'AS_point_0.coupled.wing.S_ref',
        'AS_point_1.coupled.wing.S_ref',  #
        'wing.geometry.twist',
        'wing.geometry.mesh.taper.taper',
        'wing.geometry.mesh.stretch.span',
        'wing.geometry.mesh.scale_x.chord',
        'wing.mesh',
        'wing.skin_thickness',
        'wing.spar_thickness',
        'wing.t_over_c',
        'wing.structural_mass',
        'AS_point_0.wing_perf.vonmises',
        'AS_point_1.wing_perf.vonmises',  #
        'AS_point_0.coupled.wing.def_mesh',
        'AS_point_1.coupled.wing.def_mesh',  #
        'AS_point_0.total_perf.PV_mass',
        'AS_point_0.total_perf.total_weight',
        'AS_point_0.CL',
        'AS_point_0.CD',
        'yield',
        'point_masses',  #VMGM
        'point_mass_locations',  #VMGM
        'engine_location',  #VMGM
    ]

    prob.driver.recording_options['record_objectives'] = True
    prob.driver.recording_options['record_constraints'] = True
    prob.driver.recording_options['record_desvars'] = True
    prob.driver.recording_options['record_inputs'] = True

    # Set up the problem
    prob.setup()

    ##prob.run_model() #ED2
    ##data = prob.check_partials(out_stream=None, compact_print=True, method='cs') #ED2
    ##print(data)  #ED2

    prob.run_driver()
    ##print (prob.model.list_outputs(values=False, implicit=False))  #VMGM
    print('The wingbox mass (including the wing_weight_ratio) is',
          prob['wing.structural_mass'][0], '[kg]')
    endtime = time.time()
    totaltime = endtime - starttime
    print('computing time is', totaltime)
    print('co2 emissions are', prob['emitted_co2'][0])
    print('The wing surface is', prob['AS_point_0.coupled.wing.S_ref'][0],
          '[m2]')  #VMGM

    return prob['wing.structural_mass'][0], totaltime, prob['mrho'][0], prob[
        'emitted_co2'][0]
    def test_multiple_masses(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 31,
            'wing_type': 'rect',
            'span': 10,
            'symmetry': True
        }

        mesh = generate_mesh(mesh_dict)

        surface = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'fem_model_type': 'tube',
            'mesh': mesh,

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.5,  # normalized chordwise location of the spar
            't_over_c_cp': np.array([0.15]),  # maximum airfoil thickness
            'thickness_cp': np.ones((3)) * .1,
            'wing_weight_ratio': 2.,
            'struct_weight_relief':
            False,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight': False,
            'exact_failure_constraint': False,
        }

        # Create the problem and assign the model group
        prob = Problem()

        ny = surface['mesh'].shape[1]
        surface['n_point_masses'] = 2

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('loads', val=np.zeros((ny, 6)), units='N')
        indep_var_comp.add_output('load_factor', val=1.)

        point_masses = np.array([[10., 20.]])

        point_mass_locations = np.array([[1., -1., 0.], [1., -2., 0.]])

        indep_var_comp.add_output('point_masses', val=point_masses, units='kg')
        indep_var_comp.add_output('point_mass_locations',
                                  val=point_mass_locations,
                                  units='m')

        struct_group = SpatialBeamAlone(surface=surface)

        # Add indep_vars to the structural group
        struct_group.add_subsystem('indep_vars',
                                   indep_var_comp,
                                   promotes=['*'])

        prob.model.add_subsystem(surface['name'], struct_group, promotes=['*'])

        # Set up the problem
        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['vonmises'][-1, 0], 1557126.5793494075,
                         1e-4)
Ejemplo n.º 50
0
            'yield' : 500.e6 / 2.5, # [Pa] yield stress divided by 2.5 for limiting case
            'mrho' : 3.e3,          # [kg/m^3] material density
            'fem_origin' : 0.35,    # normalized chordwise location of the spar
            'wing_weight_ratio' : 2.,
            'struct_weight_relief' : False,    # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight' : False,
            # Constraints
            'exact_failure_constraint' : False, # if false, use KS function
            }

# Create the problem and assign the model group
prob = Problem()

# Add problem information as an independent variables component
indep_var_comp = IndepVarComp()
indep_var_comp.add_output('v', val=248.136, units='m/s')
indep_var_comp.add_output('alpha', val=5., units='deg')
indep_var_comp.add_output('Mach_number', val=0.84)
indep_var_comp.add_output('re', val=1.e6, units='1/m')
indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
indep_var_comp.add_output('CT', val=grav_constant * 17.e-6, units='1/s')
indep_var_comp.add_output('R', val=11.165e6, units='m')
indep_var_comp.add_output('W0', val=0.4 * 3e5,  units='kg')
indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s')
indep_var_comp.add_output('load_factor', val=1.)
indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')
indep_var_comp.add_output('delta_aileron', val=0.)

prob.model.add_subsystem('prob_vars',
     indep_var_comp,
     promotes=['*'])
Ejemplo n.º 51
0

if __name__ == '__main__':
    from openmdao.api import Problem, Group, IndepVarComp
    from numpy import sqrt

    class RSSMerge(AbstractWakeMerging):
        def compute(self, inputs, outputs):
            all_du = inputs['all_du']
            add = 0.0
            for du in all_du:
                add += du**2.0
            root = sqrt(add)

            outputs['u'] = root

    model = Group()
    ivc = IndepVarComp()

    ivc.add_output('deficits', [0.16, 0.14, 0.15, 0.18])

    model.add_subsystem('indep', ivc)
    model.add_subsystem('rms', RSSMerge(4))

    model.connect('indep.deficits', 'rms.all_du')

    prob = Problem(model)
    prob.setup()
    prob.run_model()
    print(prob['rms.u'])
Ejemplo n.º 52
0
        out_name = self.options['out_name']

        partials[out_name, in_names[0]] = np.tile(inputs[in_names[1]],
                                                  in_shapes[0])
        partials[out_name, in_names[1]] = np.repeat(inputs[in_names[0]],
                                                    in_shapes[1])


if __name__ == '__main__':
    from openmdao.api import Problem, IndepVarComp
    import time

    prob = Problem()

    comp = IndepVarComp()
    comp.add_output('x', np.arange(7))
    comp.add_output('y', np.arange(3, 6))

    prob.model.add_subsystem('input_comp', comp, promotes=['*'])

    comp = VectorOuterProductComp(
        in_names=['x', 'y'],
        in_shapes=[7, 3],
        out_name='f',
    )

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

    start = time.time()

    prob.setup(check=True)
Ejemplo n.º 53
0
        J['K_q', 'k'] = [[q_1 + E_k - q_2], [q_2 - q_1 - E_k]]
        J['K_q', 'E_k'] = [[k], [-k]]
        J['K_q', 'q_1'] = [[k], [-k]]
        J['K_q', 'q_2'] = [[-k], [k]]
        J['F', 'tor'] = [[1], [0]]


if __name__ == '__main__':
    from openmdao.api import Problem, IndepVarComp

    num = 20

    prob = Problem()

    comp = IndepVarComp()
    comp.add_output('k', val=14.1543)
    comp.add_output('E_k', val=0)
    comp.add_output('tor', 0.5)
    comp.add_output('q', val=np.random.random((num, 2)))
    comp.add_output('w', val=np.random.random((num, 2)))
    comp.add_output('p_1', 0.311658)
    comp.add_output('p_2', 0.155)
    comp.add_output('p_3', 0.10024)
    comp.add_output('p_4', 9.39299)
    comp.add_output('p_5', 3.278)
    prob.model.add_subsystem('ivc', comp, promotes=['*'])

    comp = elements(num=num)
    prob.model.add_subsystem('elements', comp, promotes=['*'])

    prob.setup()
Ejemplo n.º 54
0
from engine_hours_comp import EngineHoursComp
from tooling_hours_comp import ToolingHoursComp
from mfg_hours_comp import MfgHoursComp
from quality_hours_comp import QualityHoursComp
from devel_support_comp import DevelSupportComp
from flight_test_cost_comp import FlightTestCostComp
from mfg_material_cost_comp import MfgMaterialCostComp
from rdte_fly_cost_comp import RdteFlyCostComp

prob = Problem()

group = Group()

# Adding all of the Explicit components to the main group
comp = IndepVarComp()
comp.add_output('We', val=4.)
comp.add_output('V', val=83.)
comp.add_output('Q', val=500.)
comp.add_output('FTA', val=2.)
comp.add_output('Re', val=86.0 * 1.530)
comp.add_output('Rt', val=88.0 * 1.530)
comp.add_output('Rq', val=81.0 * 1.530)
comp.add_output('Rm', val=73.0 * 1.530)
comp.add_output('Ceng', val=19.99)
comp.add_output('Neng', val=2.0)
comp.add_output('Cav', val=113.08)
group.add_subsystem('ivc', comp, promotes=['*', '*'])

group.add_subsystem('ehc', EngineHoursComp(), promotes=['*', '*'])
group.add_subsystem('thc', ToolingHoursComp(), promotes=['*', '*'])
group.add_subsystem('mhc', MfgHoursComp(), promotes=['*', '*'])
Ejemplo n.º 55
0
    def test(self):
        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 3,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 6,
            'chord_cos_spacing': 0,
            'span_cos_spacing': 0,
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name':
            'wing',  # name of the surface
            'symmetry':
            True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type':
            'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type':
            'wingbox',
            'spar_thickness_cp':
            np.array([0.004, 0.005, 0.005, 0.008, 0.008, 0.01]),  # [m]
            'skin_thickness_cp':
            np.array([0.005, 0.01, 0.015, 0.020, 0.025, 0.026]),
            'twist_cp':
            np.array([4., 5., 8., 8., 8., 9.]),
            'mesh':
            mesh,
            'data_x_upper':
            upper_x,
            'data_x_lower':
            lower_x,
            'data_y_upper':
            upper_y,
            'data_y_lower':
            lower_y,
            'strength_factor_for_upper_skin':
            1.,

            # 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.0078,  # 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_cp':
            np.array([0.08, 0.08, 0.08, 0.10, 0.10, 0.08]),
            'original_wingbox_airfoil_t_over_c':
            0.12,
            'c_max_t':
            .38,  # chordwise location of maximum thickness
            'with_viscous':
            True,
            'with_wave':
            False,  # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E':
            73.1e9,  # [Pa] Young's modulus
            'G': (
                73.1e9 / 2 / 1.33
            ),  # [Pa] shear modulus (calculated using E and the Poisson's ratio here)
            'yield': (420.e6 / 1.5),  # [Pa] allowable yield stress
            'mrho':
            2.78e3,  # [kg/m^3] material density
            'strength_factor_for_upper_skin':
            1.0,  # the yield stress is multiplied by this factor for the upper skin
            # 'fem_origin' : 0.35,    # normalized chordwise location of the spar
            'wing_weight_ratio':
            1.25,
            'struct_weight_relief':
            True,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight':
            False,
            # Constraints
            'exact_failure_constraint':
            False,  # if false, use KS function
            'Wf_reserve':
            15000.,  # [kg] reserve fuel mass
        }

        surfaces = [surf_dict]

        # Create the problem and assign the model group
        prob = Problem()

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s')
        indep_var_comp.add_output('alpha', val=0., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.85)
        indep_var_comp.add_output('re',
                                  val=0.348 * 295.07 * .85 * 1. /
                                  (1.43 * 1e-5),
                                  units='1/m')
        indep_var_comp.add_output('rho', val=0.348, units='kg/m**3')
        indep_var_comp.add_output('CT', val=0.53 / 3600, units='1/s')
        indep_var_comp.add_output('R', val=14.307e6, units='m')
        indep_var_comp.add_output('W0',
                                  val=148000 + surf_dict['Wf_reserve'],
                                  units='kg')
        indep_var_comp.add_output('speed_of_sound', val=295.07, units='m/s')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            aerostruct_group = AerostructGeometry(surface=surface)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces)

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('speed_of_sound',
                               point_name + '.speed_of_sound')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor')

            for surface in surfaces:

                com_name = point_name + '.' + name + '_perf.'
                prob.model.connect(
                    name + '.local_stiff_transformed', point_name +
                    '.coupled.' + name + '.local_stiff_transformed')
                prob.model.connect(name + '.nodes',
                                   point_name + '.coupled.' + name + '.nodes')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh',
                                   point_name + '.coupled.' + name + '.mesh')
                prob.model.connect(
                    name + '.element_mass',
                    point_name + '.coupled.' + name + '.element_mass')
                prob.model.connect(
                    'load_factor',
                    point_name + '.coupled.' + name + '.load_factor')

                # Connect performance calculation variables
                prob.model.connect(name + '.nodes', com_name + 'nodes')
                prob.model.connect(
                    name + '.cg_location',
                    point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(
                    name + '.structural_mass', point_name + '.' +
                    'total_perf.' + name + '_structural_mass')

                # Connect wingbox properties to von Mises stress calcs
                prob.model.connect(name + '.Qz', com_name + 'Qz')
                prob.model.connect(name + '.J', com_name + 'J')
                prob.model.connect(name + '.A_enc', com_name + 'A_enc')
                prob.model.connect(name + '.htop', com_name + 'htop')
                prob.model.connect(name + '.hbottom', com_name + 'hbottom')
                prob.model.connect(name + '.hfront', com_name + 'hfront')
                prob.model.connect(name + '.hrear', com_name + 'hrear')

                prob.model.connect(name + '.spar_thickness',
                                   com_name + 'spar_thickness')
                prob.model.connect(name + '.t_over_c', com_name + 't_over_c')

        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9
        prob.driver.options['disp'] = True

        # Set up the problem
        prob.setup()

        AS_point.nonlinear_solver.options['iprint'] = 2
        #
        # from openmdao.api import view_model
        # view_model(prob)

        prob.run_model()

        # prob.model.list_outputs(values=True,
        #                         implicit=False,
        #                         units=True,
        #                         shape=True,
        #                         bounds=True,
        #                         residuals=True,
        #                         scaling=True,
        #                         hierarchical=False,
        #                         print_arrays=True)

        # print(prob['AS_point_0.fuelburn'][0])
        # print(prob['wing.structural_mass'][0]/1.25)

        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 112469.567077,
                         1e-5)
        assert_rel_error(self, prob['wing.structural_mass'][0] / 1.25,
                         24009.5230566, 1e-5)
    def setup(self):
        shape = self.options['shape']
        part = self.options['part']

        comp = IndepVarComp()
        comp.add_output('sweep_30', val=30. * np.pi / 180., shape=shape)
        self.add_subsystem('sweep_30_comp', comp, promotes=['*'])

        comp = ElementwiseMinComp(
            shape=shape, 
            out_name='sweep_capped_30', 
            in_names=['sweep', 'sweep_30'], 
            rho=10.,
        )
        self.add_subsystem('sweep_capped_30_comp', comp, promotes=['*'])

        comp = LinearPowerCombinationComp(
            shape=shape,
            out_name='oswald_efficiency_unswept',
            constant=1.14,
            terms_list=[
                (-1.78 * 0.045, dict(
                    aspect_ratio=0.68,
                )),
            ],
        )
        self.add_subsystem('oswald_efficiency_unswept_comp', comp, promotes=['*'])

        comp = LinearPowerCombinationComp(
            shape=shape,
            out_name='oswald_efficiency_swept',
            constant=-3.1,
            terms_list=[
                (4.61, dict(
                    cos_sweep=0.15,
                )),
                (-4.61 * 0.045, dict(
                    aspect_ratio=0.68,
                    cos_sweep=0.15,
                )),
            ],
        )
        self.add_subsystem('oswald_efficiency_swept_comp', comp, promotes=['*'])

        comp = LinearPowerCombinationComp(
            shape=shape,
            out_name='oswald_efficiency',
            terms_list=[
                (1. / (30. * np.pi / 180.), dict(
                    oswald_efficiency_unswept=1.,
                )),
                (-1. / (30. * np.pi / 180.), dict(
                    oswald_efficiency_unswept=1.,
                    sweep_capped_30=1.,
                )),
                (1. / (30. * np.pi / 180.), dict(
                    oswald_efficiency_swept=1.,
                    sweep_capped_30=1.,
                )),
            ],
        )
        self.add_subsystem('oswald_efficiency_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='induced_drag_coeff',
            coeff=1. / np.pi,
            powers_dict=dict(
                lift_coeff=2.,
                oswald_efficiency=-1.,
                aspect_ratio=-1.,
            ),
        )
        self.add_subsystem('induced_drag_coeff_comp', comp, promotes=['*'])
Ejemplo n.º 57
0
from drag_models.reynolds_comp import Reynolds
from drag_models.form_factors_comp import FormFactors
from drag_models.c_f_comp import Cf
from drag_models.drag_coefficient_zero_comp import Cd0
from drag_models.drag_coefficient_comp import Cd
from drag_models.k_comp import K
from drag_models.drag_m_comp import DragModelComp
from drag_models.lift_drag_comp import LD

prob = Problem()
group = Group()

comp = IndepVarComp()

comp.add_output('rho', val=1.225)
comp.add_output('V', val=23.)
comp.add_output('mu', val=2.008 * 10**(-5))
comp.add_output('sweep', val=30.)
comp.add_output('tc1', val=0.12)
comp.add_output('xc1', val=0.3)
comp.add_output('C_bar', val=0.30)
comp.add_output('S', val=.57)
comp.add_output('Dq', val=0.0278709)
comp.add_output('Cd0_23', val=0.007380519)
comp.add_output('b', val=2)  # total spa
comp.add_output('Cl', val=.7)  #

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

group.add_subsystem('re', Reynolds(), promotes=['*'])
Ejemplo n.º 58
0
    def setup(self):
        num_times = self.options['num_times']
        num_cp = self.options['num_cp']
        step_size = self.options['step_size']
        cubesat = self.options['cubesat']
        mtx = self.options['mtx']

        shape = (3, num_times)

        thrust_unit_vec = np.outer(
            np.array([1., 0., 0.]),
            np.ones(num_times),
        )

        comp = IndepVarComp()
        comp.add_output('thrust_unit_vec_b_3xn', val=thrust_unit_vec)
        comp.add_output('thrust_scalar_mN_cp', val=1.e-3 * np.ones(num_cp))
        comp.add_output('initial_propellant_mass', 0.17)
        comp.add_design_var('thrust_scalar_mN_cp', lower=0., upper=20000)
        self.add_subsystem('inputs_comp', comp, promotes=['*'])

        comp = MtxVecComp(
            num_times=num_times,
            mtx_name='rot_mtx_i_b_3x3xn',
            vec_name='thrust_unit_vec_b_3xn',
            out_name='thrust_unit_vec_3xn',
        )
        self.add_subsystem('thrust_unit_vec_3xn_comp', comp, promotes=['*'])

        comp = LinearCombinationComp(
            shape=(num_cp, ),
            out_name='thrust_scalar_cp',
            coeffs_dict=dict(thrust_scalar_mN_cp=1.e-3),
        )
        self.add_subsystem('thrust_scalar_cp_comp', comp, promotes=['*'])

        comp = BsplineComp(
            num_pt=num_times,
            num_cp=num_cp,
            jac=mtx,
            in_name='thrust_scalar_cp',
            out_name='thrust_scalar',
        )
        self.add_subsystem('thrust_scalar_comp', comp, promotes=['*'])

        comp = ArrayExpansionComp(
            shape=shape,
            expand_indices=[0],
            in_name='thrust_scalar',
            out_name='thrust_scalar_3xn',
        )
        self.add_subsystem('thrust_scalar_3xn_comp', comp, promotes=['*'])

        comp = PowerCombinationComp(
            shape=shape,
            out_name='thrust_3xn',
            powers_dict=dict(
                thrust_unit_vec_3xn=1.,
                thrust_scalar_3xn=1.,
            ),
        )
        self.add_subsystem('thrust_3xn_comp', comp, promotes=['*'])

        comp = LinearCombinationComp(
            shape=(num_times, ),
            out_name='mass_flow_rate',
            coeffs_dict=dict(thrust_scalar=-1. /
                             (cubesat['acceleration_due_to_gravity'] *
                              cubesat['specific_impulse'])))
        self.add_subsystem('mass_flow_rate_comp', comp, promotes=['*'])

        comp = PropellantMassRK4Comp(
            num_times=num_times,
            step_size=step_size,
        )
        self.add_subsystem('propellant_mass_rk4_comp', comp, promotes=['*'])

        comp = ExecComp(
            'total_propellant_used=propellant_mass[0] - propellant_mass[-1]',
            propellant_mass=np.empty(num_times),
        )
        self.add_subsystem('total_propellant_used_comp', comp, promotes=['*'])
Ejemplo n.º 59
0
 if surface['sweep'] == 0:
     surfname = 'str'
     ailList = ailList_straight
 else:
     surfname = 'swp'
     ailList = ailList_swept
 
 for aileron in ailList:
     surface['control_surfaces'] = [aileron]
     print(surfname+'_'+aileron['name']+'\n')
     # Create the problem and assign the model group
     prob = Problem()
     
     # Add problem information as an independent variables component
     indep_var_comp = IndepVarComp()
     indep_var_comp.add_output('v', val=25., units='m/s')
     indep_var_comp.add_output('alpha', val=alpha, units='deg')
     indep_var_comp.add_output('re', val=5e5, units='1/m')
     indep_var_comp.add_output('rho', val=rho, units='kg/m**3')
     indep_var_comp.add_output('cg', val=cg_loc, units='m')
     indep_var_comp.add_output('delta_aileron', val=12.5,units='deg')
     indep_var_comp.add_output('omega', val=np.array([1.,0.,0.]),units='rad/s')
     
     prob.model.add_subsystem('prob_vars',
          indep_var_comp,
          promotes=['*'])
     
     aerostruct_group = AerostructGeometry(surface=surface)
     
     name = 'wing'
     
Ejemplo n.º 60
0
    def test(self):
        import numpy as np

        from openmdao.api import IndepVarComp, Problem, Group, NewtonSolver, \
            ScipyIterativeSolver, LinearBlockGS, NonlinearBlockGS, \
            DirectSolver, LinearBlockGS, PetscKSP, SqliteRecorder

        from openaerostruct.geometry.utils import generate_mesh
        from openaerostruct.geometry.geometry_group import Geometry
        from openaerostruct.aerodynamics.aero_groups import AeroPoint

        # Create a dictionary to store options about the mesh
        mesh_dict = {
            'num_y': 7,
            'num_x': 2,
            'wing_type': 'CRM',
            'symmetry': False,
            'num_twist_cp': 5
        }

        # Generate the aerodynamic mesh based on the previous dictionary
        mesh, twist_cp = generate_mesh(mesh_dict)

        # Create a dictionary with info and options about the aerodynamic
        # lifting surface
        surface = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': False,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'twist_cp': twist_cp,
            'mesh': mesh,

            # 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.015,  # 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_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,  # if true, compute viscous drag
            'with_wave': False,  # if true, compute wave drag
        }

        # Create the OpenMDAO problem
        prob = Problem()

        # Create an independent variable component that will supply the flow
        # conditions to the problem.
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('cg', val=np.zeros((3)), units='m')

        # Add this IndepVarComp to the problem model
        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Create and add a group that handles the geometry for the
        # aerodynamic lifting surface
        geom_group = Geometry(surface=surface)
        prob.model.add_subsystem(surface['name'], geom_group)

        # Create the aero point group, which contains the actual aerodynamic
        # analyses
        aero_group = AeroPoint(surfaces=[surface])
        point_name = 'aero_point_0'
        prob.model.add_subsystem(
            point_name,
            aero_group,
            promotes_inputs=['v', 'alpha', 'Mach_number', 're', 'rho', 'cg'])

        name = surface['name']

        # Connect the mesh from the geometry component to the analysis point
        prob.model.connect(name + '.mesh',
                           point_name + '.' + name + '.def_mesh')

        # Perform the connections with the modified names within the
        # 'aero_states' group.
        prob.model.connect(name + '.mesh',
                           point_name + '.aero_states.' + name + '_def_mesh')

        prob.model.connect(name + '.t_over_c',
                           point_name + '.' + name + '_perf.' + 't_over_c')

        # Import the Scipy Optimizer and set the driver of the problem to use
        # it, which defaults to an SLSQP optimization method
        from openmdao.api import ScipyOptimizeDriver
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9

        # Setup problem and add design variables, constraint, and objective
        prob.model.add_design_var('wing.twist_cp', lower=-10., upper=15.)
        prob.model.add_constraint(point_name + '.wing_perf.CL', equals=0.5)
        prob.model.add_objective(point_name + '.wing_perf.CD', scaler=1e4)

        # Set up and run the optimization problem
        prob.setup()
        prob.run_model()
        # prob.check_partials()
        # exit()
        prob.run_driver()

        assert_rel_error(self, prob['aero_point_0.wing_perf.CD'][0],
                         0.03339013029042684, 1e-5)
        assert_rel_error(self, prob['aero_point_0.wing_perf.CL'][0], 0.5, 1e-6)
        assert_rel_error(self, prob['aero_point_0.CM'][1], -1.7886135541410009,
                         1e-4)