示例#1
0
    def make_prob(self, transcription, n_segs, order, compressed):

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

        gd = GridData(num_segments=n_segs,
                      segment_ends=np.arange(n_segs + 1),
                      transcription=transcription,
                      transcription_order=order,
                      compressed=compressed)

        state_options = {
            'x': {
                'units': 'm',
                'shape': (1, ),
                'fix_initial': True,
                'fix_final': False,
                'solve_segments': False,
                'connected_initial': False,
                'val': 1.0,
                'lower': None,
                'upper': None
            },
            'v': {
                'units': 'm/s',
                'shape': (3, 2),
                'fix_initial': False,
                'fix_final': True,
                'solve_segments': True,
                'connected_initial': False,
                'val': np.ones((3, 2)),
                'lower': None,
                'upper': None
            }
        }

        indep_comp = om.IndepVarComp()
        p.model.add_subsystem('indep', indep_comp, promotes_outputs=['*'])

        indep_comp.add_output('dt_dstau',
                              val=np.zeros((gd.subset_num_nodes['col'])))

        indep_comp.add_output('f_approx:x',
                              val=np.zeros((gd.subset_num_nodes['col'], 1)),
                              units='m')
        indep_comp.add_output('f_computed:x',
                              val=np.zeros((gd.subset_num_nodes['col'], 1)),
                              units='m')

        indep_comp.add_output('f_approx:v',
                              val=np.zeros((gd.subset_num_nodes['col'], 3, 2)),
                              units='m/s')
        indep_comp.add_output('f_computed:v',
                              val=np.zeros((gd.subset_num_nodes['col'], 3, 2)),
                              units='m/s')

        p.model.add_subsystem('defect_comp',
                              subsys=CollocationComp(
                                  grid_data=gd, state_options=state_options))

        indep = StateIndependentsComp(grid_data=gd,
                                      state_options=state_options)
        p.model.add_subsystem('state_indep', indep, promotes_outputs=['*'])

        p.model.connect('f_approx:x', 'defect_comp.f_approx:x')
        p.model.connect('f_approx:v', 'defect_comp.f_approx:v')
        p.model.connect('f_computed:x', 'defect_comp.f_computed:x')
        p.model.connect('f_computed:v', 'defect_comp.f_computed:v')
        p.model.connect('dt_dstau', 'defect_comp.dt_dstau')
        p.model.connect('defect_comp.defects:v', 'state_indep.defects:v')

        self.state_idx_map = {}
        for state_name, options in state_options.items():
            self._make_state_idx_map(state_name, options, gd,
                                     self.state_idx_map)
        p.model.state_indep.configure_io(self.state_idx_map)

        p.setup(force_alloc_complex=True)

        p['dt_dstau'] = np.random.random(gd.subset_num_nodes['col'])

        p['f_approx:x'] = np.random.random((gd.subset_num_nodes['col'], 1))
        p['f_approx:v'] = np.random.random((gd.subset_num_nodes['col'], 3, 2))

        p['f_computed:x'] = np.random.random((gd.subset_num_nodes['col'], 1))
        p['f_computed:v'] = np.random.random(
            (gd.subset_num_nodes['col'], 3, 2))

        p.run_model()
        p.model.run_apply_nonlinear()

        return p
示例#2
0
    def test_distrib_desvar_get_set(self):

        comm = MPI.COMM_WORLD
        size = 3 if comm.rank == 0 else 2

        class DistribComp(om.ExplicitComponent):

            def setup(self):
                self.options['distributed'] = True

                self.add_input('w', val=1.) # this will connect to a non-distributed IVC
                self.add_input('x', shape=size) # this will connect to a distributed IVC

                self.add_output('y', shape=1) # all-gathered output, duplicated on all procs
                self.add_output('z', shape=size) # distributed output

                self.declare_partials('y', 'x')
                self.declare_partials('y', 'w')
                self.declare_partials('z', 'x')

            def compute(self, inputs, outputs):
                x = inputs['x']
                local_y = np.sum((x-5)**2)
                y_g = np.zeros(self.comm.size)
                self.comm.Allgather(local_y, y_g)

                outputs['y'] = np.sum(y_g) + (inputs['w']-10)**2
                outputs['z'] = x**2

            def compute_partials(self, inputs, J):
                x = inputs['x']
                J['y', 'x'] = 2*(x-5)
                J['y', 'w'] = 2*(inputs['w']-10)
                J['z', 'x'] = np.diag(2*x)

        p = om.Problem()
        model = p.model
        driver = p.driver

        # distributed indep var, 'x'
        d_ivc = model.add_subsystem('d_ivc', om.IndepVarComp(distributed=True),
                                    promotes=['*'])
        d_ivc.add_output('x', 2*np.ones(size))

        # non-distributed indep var, 'w'
        ivc = model.add_subsystem('ivc', om.IndepVarComp(distributed=False),
                                  promotes=['*'])
        ivc.add_output('w', size)

        # distributed component, 'dc'
        model.add_subsystem('dc', DistribComp(), promotes=['*'])

        # distributed design var, 'x'
        model.add_design_var('x', lower=-100, upper=100)
        model.add_objective('y')

        # driver that supports distributed design vars
        driver.supports._read_only = False
        driver.supports['distributed_design_vars'] = True

        # run model
        p.setup()
        p.run_model()

        # get distributed design var
        driver.get_design_var_values(get_remote=None)

        assert_near_equal(driver.get_design_var_values(get_remote=True)['d_ivc.x'],
                          [2, 2, 2, 2, 2])

        assert_near_equal(driver.get_design_var_values(get_remote=False)['d_ivc.x'],
                          2*np.ones(size))

        # set distributed design var, set_remote=True
        driver.set_design_var('d_ivc.x', [3, 3, 3, 3, 3], set_remote=True)

        assert_near_equal(driver.get_design_var_values(get_remote=True)['d_ivc.x'],
                          [3, 3, 3, 3, 3])

        # set distributed design var, set_remote=False
        if comm.rank == 0:
            driver.set_design_var('d_ivc.x', 5.0*np.ones(size), set_remote=False)
        else:
            driver.set_design_var('d_ivc.x', 9.0*np.ones(size), set_remote=False)

        assert_near_equal(driver.get_design_var_values(get_remote=True)['d_ivc.x'],
                          [5, 5, 5, 9, 9])

        # run driver
        p.run_driver()

        assert_near_equal(p.get_val('dc.y', get_remote=True), [81, 96])
        assert_near_equal(p.get_val('dc.z', get_remote=True), [25, 25, 25, 81, 81])
示例#3
0
    def test_list_inputs_outputs(self):
        prob = om.Problem()
        model = prob.model

        indep = model.add_subsystem('indep', om.IndepVarComp())
        indep.add_discrete_output('x', 11)

        model.add_subsystem('expl', ModCompEx(3))
        model.add_subsystem('impl', ModCompIm(3))

        model.connect('indep.x', ['expl.x', 'impl.x'])

        prob.setup()

        #
        # list vars before model has been run (relative names)
        #
        expl_inputs = prob.model.expl.list_inputs(out_stream=None)
        expected = {'a': {'value': [10.]}, 'x': {'value': 10}}
        self.assertEqual(dict(expl_inputs), expected)

        impl_inputs = prob.model.impl.list_inputs(out_stream=None)
        expected = {'x': {'value': 10}}
        self.assertEqual(dict(impl_inputs), expected)

        expl_outputs = prob.model.expl.list_outputs(out_stream=None)
        expected = {'b': {'value': [0.]}, 'y': {'value': 0}}
        self.assertEqual(dict(expl_outputs), expected)

        impl_outputs = prob.model.impl.list_outputs(out_stream=None)
        expected = {'y': {'value': 0}}
        self.assertEqual(dict(impl_outputs), expected)

        #
        # run model
        #
        prob.run_model()

        #
        # list inputs, not hierarchical
        #
        stream = StringIO()
        prob.model.list_inputs(values=True,
                               hierarchical=False,
                               out_stream=stream)
        text = stream.getvalue()

        self.assertEqual(1, text.count("3 Input(s) in 'model'"))

        # make sure they are in the correct order
        self.assertTrue(
            text.find('expl.a') < text.find('expl.x') < text.find('impl.x'))

        #
        # list inputs, hierarchical
        #
        stream = StringIO()
        prob.model.list_inputs(values=True,
                               hierarchical=True,
                               out_stream=stream)
        text = stream.getvalue()

        self.assertEqual(1, text.count("3 Input(s) in 'model'"))
        self.assertEqual(1, text.count('\nexpl'))
        self.assertEqual(1, text.count('\n  a'))
        self.assertEqual(1, text.count('\nimpl'))
        self.assertEqual(2, text.count('\n  x'))  # both implicit & explicit

        #
        # list outputs, not hierarchical
        #
        stream = StringIO()
        prob.model.list_outputs(values=True,
                                residuals=True,
                                hierarchical=False,
                                out_stream=stream)
        text = stream.getvalue()

        self.assertEqual(text.count('3 Explicit Output'), 1)
        self.assertEqual(text.count('1 Implicit Output'), 1)

        # make sure they are in the correct order
        self.assertTrue(
            text.find('indep.x') < text.find('expl.b') < text.find('expl.y') <
            text.find('impl.y'))

        #
        # list outputs, hierarchical
        #
        stream = StringIO()
        prob.model.list_outputs(values=True,
                                residuals=True,
                                hierarchical=True,
                                out_stream=stream)
        text = stream.getvalue()

        self.assertEqual(text.count('\nindep'), 1)
        self.assertEqual(text.count('\n  x'), 1)
        self.assertEqual(text.count('\nexpl'), 1)
        self.assertEqual(text.count('\n  b'), 1)
        self.assertEqual(text.count('\nimpl'), 1)
        self.assertEqual(text.count('\n  y'), 2)  # both implicit & explicit
示例#4
0
    '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,
}

## Part-2: Initialize your problem and add flow conditions ------------
# Create the problem and assign the model group
prob = om.Problem()

ny = surf_dict['mesh'].shape[1]
indep_var_comp = om.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)

## Part-3: Add your design variables, constraints, and objective
# Import the Scipy Optimizer and set the driver of the problem to use
# it, which defaults to an SLSQP optimization method
prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['disp'] = True
示例#5
0
    def test_units_with_scaling(self):
        prob = om.Problem()
        model = prob.model

        ivc = om.IndepVarComp()
        ivc.add_output('x', 35.0, units='degF')

        model.add_subsystem('p', ivc, promotes=['x'])
        model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
                                                 x={'value': 2.0, 'units': 'degF'},
                                                 y1={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y1'])

        model.add_subsystem('comp2', om.ExecComp('y2 = 3.0*x',
                                                 x={'value': 2.0, 'units': 'degF'},
                                                 y2={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y2'])

        model.add_design_var('x', units='degC', lower=0.0, upper=100.0, scaler=3.5, adder=77.0)
        model.add_constraint('y1', units='degC', lower=0.0, upper=100.0, scaler=3.5, adder=77.0)
        model.add_objective('y2', units='degC', scaler=3.5, adder=77.0)

        recorder = om.SqliteRecorder('cases.sql')
        prob.driver.add_recorder(recorder)

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

        prob.setup()

        prob.run_driver()

        dv = prob.driver.get_design_var_values()
        assert_near_equal(dv['p.x'][0], ((3.0 * 5 / 9) + 77.0) * 3.5, 1e-8)

        obj = prob.driver.get_objective_values(driver_scaling=True)
        assert_near_equal(obj['comp2.y2'][0], ((73.0 * 5 / 9) + 77.0) * 3.5, 1e-8)

        con = prob.driver.get_constraint_values(driver_scaling=True)
        assert_near_equal(con['comp1.y1'][0], ((38.0 * 5 / 9) + 77.0) * 3.5, 1e-8)

        meta = model.get_design_vars()
        assert_near_equal(meta['p.x']['lower'], ((0.0) + 77.0) * 3.5, 1e-7)
        assert_near_equal(meta['p.x']['upper'], ((100.0) + 77.0) * 3.5, 1e-7)

        meta = model.get_constraints()
        assert_near_equal(meta['comp1.y1']['lower'], ((0.0) + 77.0) * 3.5, 1e-7)
        assert_near_equal(meta['comp1.y1']['upper'], ((100.0) + 77.0) * 3.5, 1e-7)

        stdout = sys.stdout
        strout = StringIO()
        sys.stdout = strout
        try:
            prob.list_problem_vars(desvar_opts=['units'], objs_opts=['units'], cons_opts=['units'])
        finally:
            sys.stdout = stdout
        output = strout.getvalue().split('\n')

        self.assertTrue('275.33' in output[5])
        self.assertTrue('343.3888' in output[12])
        self.assertTrue('411.444' in output[19])
        self.assertTrue('degC' in output[5])
        self.assertTrue('degC' in output[12])
        self.assertTrue('degC' in output[19])

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

        for key, val in totals.items():
            assert_near_equal(val['rel error'][0], 0.0, 1e-6)

        cr = om.CaseReader("cases.sql")
        cases = cr.list_cases('driver')
        case = cr.get_case(cases[0])

        dv = case.get_design_vars()
        assert_near_equal(dv['p.x'][0], ((3.0 * 5 / 9) + 77.0) * 3.5, 1e-8)

        obj = case.get_objectives()
        assert_near_equal(obj['comp2.y2'][0], ((73.0 * 5 / 9) + 77.0) * 3.5, 1e-8)

        con = case.get_constraints()
        assert_near_equal(con['comp1.y1'][0], ((38.0 * 5 / 9) + 77.0) * 3.5, 1e-8)
示例#6
0
    def setUp(self):

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

        ivp = self.p.model.add_subsystem('ivc',
                                         subsys=om.IndepVarComp(),
                                         promotes_outputs=['*'])

        ndn = 20
        nn = 30

        ivp.add_output('phase0:x', val=np.zeros((ndn, 1)), units='m')
        ivp.add_output('phase0:u', val=np.zeros((nn, 3)), units='deg')
        ivp.add_output('phase0:v', val=np.zeros((nn, 3, 3)), units='N')

        ivp.add_output('phase1:x', val=np.zeros((ndn, 1)), units='m')
        ivp.add_output('phase1:u', val=np.zeros((nn, 3)), units='deg')
        ivp.add_output('phase1:v', val=np.zeros((nn, 3, 3)), units='N')

        linkage_comp = PhaseLinkageComp()

        linkage_comp.add_linkage('L01a',
                                 vars=('x', ),
                                 equals=0.0,
                                 shape=(1, ),
                                 units='m')
        linkage_comp.add_linkage('L01b',
                                 vars=('u', ),
                                 equals=0.0,
                                 shape=(3, ),
                                 units='deg')
        linkage_comp.add_linkage('L01c',
                                 vars=('v', ),
                                 equals=0.0,
                                 shape=(3, 3),
                                 units='N')

        self.p.model.add_subsystem('linkage_comp', subsys=linkage_comp)

        self.p.model.connect('phase0:x',
                             'linkage_comp.L01a_x:lhs',
                             src_indices=[-1],
                             flat_src_indices=True)

        self.p.model.connect('phase1:x',
                             'linkage_comp.L01a_x:rhs',
                             src_indices=[0],
                             flat_src_indices=True)

        self.p.model.connect('phase0:u',
                             'linkage_comp.L01b_u:lhs',
                             src_indices=np.arange(-3, 0, dtype=int),
                             flat_src_indices=True)

        self.p.model.connect('phase1:u',
                             'linkage_comp.L01b_u:rhs',
                             src_indices=np.arange(0, 3, dtype=int),
                             flat_src_indices=True)

        self.p.model.connect('phase0:v',
                             'linkage_comp.L01c_v:lhs',
                             src_indices=np.arange(-9, 0, dtype=int).reshape(
                                 (3, 3)),
                             flat_src_indices=True)

        self.p.model.connect('phase1:v',
                             'linkage_comp.L01c_v:rhs',
                             src_indices=np.arange(0, 9, dtype=int).reshape(
                                 (3, 3)),
                             flat_src_indices=True)

        self.p.setup()

        self.p['phase0:x'] = np.random.rand(*self.p['phase0:x'].shape)
        self.p['phase0:u'] = np.random.rand(*self.p['phase0:u'].shape)
        self.p['phase0:v'] = np.random.rand(*self.p['phase0:v'].shape)

        self.p['phase1:x'] = np.random.rand(*self.p['phase1:x'].shape)
        self.p['phase1:u'] = np.random.rand(*self.p['phase1:u'].shape)
        self.p['phase1:v'] = np.random.rand(*self.p['phase1:v'].shape)

        self.p.run_model()
示例#7
0
    def test_simplified_ode_timeseries_output(self):
        """
        # upgrade_doc: begin simplified_ode_output_timeseries
        phase.add_timeseries_output('tas_comp.TAS', shape=(1,), units='m/s')
        # upgrade_doc: end simplified_ode_output_timeseries
        """
        import openmdao.api as om
        import dymos as dm
        from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE

        p = om.Problem(model=om.Group())
        p.driver = om.ScipyOptimizeDriver()
        p.driver.declare_coloring()

        transcription = dm.GaussLobatto(num_segments=1,
                                        order=13,
                                        compressed=False)
        phase = dm.Phase(ode_class=AircraftODE, transcription=transcription)
        p.model.add_subsystem('phase0', phase)

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', om.IndepVarComp())
        assumptions.add_output('S', val=427.8, units='m**2')
        assumptions.add_output('mass_empty', val=1.0, units='kg')
        assumptions.add_output('mass_payload', val=1.0, units='kg')

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(3600, 3600),
                               duration_ref=3600)

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(3600, 3600),
                               duration_ref=3600)

        phase.add_state('range',
                        units='km',
                        fix_initial=True,
                        fix_final=False,
                        scaler=0.01,
                        rate_source='range_rate_comp.dXdt:range',
                        defect_scaler=0.01)
        phase.add_state('mass_fuel',
                        units='kg',
                        fix_final=True,
                        upper=20000.0,
                        lower=0.0,
                        rate_source='propulsion.dXdt:mass_fuel',
                        scaler=1.0E-4,
                        defect_scaler=1.0E-2)
        phase.add_state('alt',
                        rate_source='climb_rate',
                        units='km',
                        fix_initial=True)

        phase.add_control('mach',
                          targets=['tas_comp.mach', 'aero.mach'],
                          units=None,
                          opt=False)

        phase.add_control('climb_rate',
                          targets=['gam_comp.climb_rate'],
                          units='m/s',
                          opt=False)

        phase.add_parameter(
            'S',
            targets=['aero.S', 'flight_equilibrium.S', 'propulsion.S'],
            units='m**2')

        phase.add_parameter('mass_empty',
                            targets=['mass_comp.mass_empty'],
                            units='kg')
        phase.add_parameter('mass_payload',
                            targets=['mass_comp.mass_payload'],
                            units='kg')

        phase.add_path_constraint('propulsion.tau',
                                  lower=0.01,
                                  upper=1.0,
                                  shape=(1, ))

        # upgrade_doc: begin simplified_ode_output_timeseries
        phase.add_timeseries_output('tas_comp.TAS')
        # upgrade_doc: end simplified_ode_output_timeseries

        p.model.connect('assumptions.S', 'phase0.parameters:S')
        p.model.connect('assumptions.mass_empty',
                        'phase0.parameters:mass_empty')
        p.model.connect('assumptions.mass_payload',
                        'phase0.parameters:mass_payload')

        phase.add_objective('time', loc='final', ref=3600)

        p.model.linear_solver = om.DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 1.515132 * 3600.0
        p['phase0.states:range'] = phase.interpolate(ys=(0, 1296.4),
                                                     nodes='state_input')
        p['phase0.states:mass_fuel'] = phase.interpolate(ys=(12236.594555, 0),
                                                         nodes='state_input')
        p['phase0.states:alt'] = 5.0
        p['phase0.controls:mach'] = 0.8
        p['phase0.controls:climb_rate'] = 0.0

        p['assumptions.S'] = 427.8
        p['assumptions.mass_empty'] = 0.15E6
        p['assumptions.mass_payload'] = 84.02869 * 400

        dm.run_problem(p)

        time = p.get_val('phase0.timeseries.time')
        tas = p.get_val('phase0.timeseries.TAS', units='km/s')
        range = p.get_val('phase0.timeseries.states:range')

        assert_near_equal(range, tas * time, tolerance=1.0E-4)

        exp_out = phase.simulate()

        time = exp_out.get_val('phase0.timeseries.time')
        tas = exp_out.get_val('phase0.timeseries.TAS', units='km/s')
        range = exp_out.get_val('phase0.timeseries.states:range')

        assert_near_equal(range, tas * time, tolerance=1.0E-4)
    def test_array_list_vars_options(self):
        class ArrayAdder(om.ExplicitComponent):
            """
            Just a simple component that has array inputs and outputs
            """
            def __init__(self, size):
                super(ArrayAdder, self).__init__()
                self.size = size

            def setup(self):
                self.add_input('x', val=np.zeros(self.size), units='inch')
                self.add_output('y', val=np.zeros(self.size), units='ft')

            def compute(self, inputs, outputs):
                outputs['y'] = inputs['x'] + 10.0

        size = 100  # how many items in the array

        prob = om.Problem()

        prob.model.add_subsystem('des_vars',
                                 om.IndepVarComp('x',
                                                 np.ones(size),
                                                 units='inch'),
                                 promotes=['x'])
        prob.model.add_subsystem('mult', ArrayAdder(size), promotes=['x', 'y'])

        prob.setup()

        prob['x'] = np.ones(size)

        prob.run_driver()

        # logging inputs
        # out_stream - not hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_inputs(values=True,
                               units=True,
                               hierarchical=False,
                               print_arrays=False,
                               out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(1, text.count("1 Input(s) in 'model'"))
        self.assertEqual(1, text.count('mult.x'))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(5, num_non_empty_lines)

        # out_stream - hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_inputs(values=True,
                               units=True,
                               hierarchical=True,
                               print_arrays=False,
                               out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(1, text.count("1 Input(s) in 'model'"))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(7, num_non_empty_lines)
        self.assertEqual(1, text.count('top'))
        self.assertEqual(1, text.count('  mult'))
        self.assertEqual(1, text.count('    x'))

        # logging outputs
        # out_stream - not hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_outputs(values=True,
                                units=True,
                                shape=True,
                                bounds=True,
                                residuals=True,
                                scaling=True,
                                hierarchical=False,
                                print_arrays=False,
                                out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(text.count('2 Explicit Output'), 1)
        # make sure they are in the correct order
        self.assertTrue(text.find("des_vars.x") < text.find('mult.y'))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(8, num_non_empty_lines)

        # Promoted names - no print arrays
        stream = cStringIO()
        prob.model.list_outputs(values=True,
                                prom_name=True,
                                print_arrays=False,
                                out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(text.count('    x       |10.0|   x'), 1)
        self.assertEqual(text.count('    y       |110.0|  y'), 1)
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(num_non_empty_lines, 11)

        # Hierarchical - no print arrays
        stream = cStringIO()
        prob.model.list_outputs(values=True,
                                units=True,
                                shape=True,
                                bounds=True,
                                residuals=True,
                                scaling=True,
                                hierarchical=True,
                                print_arrays=False,
                                out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(text.count('top'), 1)
        self.assertEqual(text.count('  des_vars'), 1)
        self.assertEqual(text.count('    x'), 1)
        self.assertEqual(text.count('  mult'), 1)
        self.assertEqual(text.count('    y'), 1)
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(num_non_empty_lines, 11)

        # Need to explicitly set this to make sure all ways of running this test
        #   result in the same format of the output. When running this test from the
        #   top level via testflo, the format comes out different than if the test is
        #   run individually
        opts = {
            'edgeitems': 3,
            'infstr': 'inf',
            'linewidth': 75,
            'nanstr': 'nan',
            'precision': 8,
            'suppress': False,
            'threshold': 1000,
        }

        from distutils.version import LooseVersion
        if LooseVersion(np.__version__) >= LooseVersion("1.14"):
            opts['legacy'] = '1.13'

        with printoptions(**opts):
            # logging outputs
            # out_stream - not hierarchical - extras - print_arrays
            stream = cStringIO()
            prob.model.list_outputs(values=True,
                                    units=True,
                                    shape=True,
                                    bounds=True,
                                    residuals=True,
                                    scaling=True,
                                    hierarchical=False,
                                    print_arrays=True,
                                    out_stream=stream)
            text = stream.getvalue()
            self.assertEqual(text.count('2 Explicit Output'), 1)
            self.assertEqual(text.count('value:'), 2)
            self.assertEqual(text.count('resids:'), 2)
            self.assertEqual(text.count('['), 4)
            # make sure they are in the correct order
            self.assertTrue(text.find("des_vars.x") < text.find('mult.y'))
            num_non_empty_lines = sum(
                [1 for s in text.splitlines() if s.strip()])
            self.assertEqual(46, num_non_empty_lines)

            # Hierarchical
            stream = cStringIO()
            prob.model.list_outputs(values=True,
                                    units=True,
                                    shape=True,
                                    bounds=True,
                                    residuals=True,
                                    scaling=True,
                                    hierarchical=True,
                                    print_arrays=True,
                                    out_stream=stream)
            text = stream.getvalue()
            self.assertEqual(text.count('2 Explicit Output'), 1)
            self.assertEqual(text.count('value:'), 2)
            self.assertEqual(text.count('resids:'), 2)
            self.assertEqual(text.count('['), 4)
            self.assertEqual(text.count('top'), 1)
            self.assertEqual(text.count('  des_vars'), 1)
            self.assertEqual(text.count('    x'), 1)
            self.assertEqual(text.count('  mult'), 1)
            self.assertEqual(text.count('    y'), 1)
            num_non_empty_lines = sum(
                [1 for s in text.splitlines() if s.strip()])
            self.assertEqual(num_non_empty_lines, 49)
    def test_for_docs_array_list_vars_options(self):

        import numpy as np

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

        class ArrayAdder(om.ExplicitComponent):
            """
            Just a simple component that has array inputs and outputs
            """
            def __init__(self, size):
                super(ArrayAdder, self).__init__()
                self.size = size

            def setup(self):
                self.add_input('x', val=np.zeros(self.size), units='inch')
                self.add_output('y', val=np.zeros(self.size), units='ft')

            def compute(self, inputs, outputs):
                outputs['y'] = inputs['x'] + 10.0

        size = 30

        prob = om.Problem()
        prob.model.add_subsystem('des_vars',
                                 om.IndepVarComp('x',
                                                 np.ones(size),
                                                 units='inch'),
                                 promotes=['x'])
        prob.model.add_subsystem('mult', ArrayAdder(size), promotes=['x', 'y'])

        prob.setup()
        prob['x'] = np.arange(size)
        prob.run_driver()

        prob.model.list_inputs(values=True,
                               units=True,
                               hierarchical=True,
                               print_arrays=True)

        with printoptions(edgeitems=3,
                          infstr='inf',
                          linewidth=75,
                          nanstr='nan',
                          precision=8,
                          suppress=False,
                          threshold=1000,
                          formatter=None):

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

            prob.model.list_outputs(values=True,
                                    implicit=False,
                                    units=True,
                                    shape=True,
                                    bounds=True,
                                    residuals=True,
                                    scaling=True,
                                    hierarchical=True,
                                    print_arrays=True)
示例#10
0
    def test_for_feature_docs_list_vars_options(self):

        import openmdao.api as om

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

        model.add_subsystem(
            'p1',
            om.IndepVarComp(
                'x',
                12.0,
                lower=1.0,
                upper=100.0,
                ref=1.1,
                ref0=2.1,
                units='inch',
            ))
        model.add_subsystem(
            'p2',
            om.IndepVarComp(
                'y',
                1.0,
                lower=2.0,
                upper=200.0,
                ref=1.2,
                res_ref=2.2,
                units='ft',
            ))
        model.add_subsystem(
            'comp',
            om.ExecComp('z=x+y',
                        x={
                            'value': 0.0,
                            'units': 'inch'
                        },
                        y={
                            'value': 0.0,
                            'units': 'inch'
                        },
                        z={
                            'value': 0.0,
                            'units': 'inch'
                        }))
        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()
        prob.set_solver_print(level=0)
        prob.run_model()

        inputs = prob.model.list_inputs(units=True)
        print(inputs)

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

        self.assertEqual(sorted(outputs), [
            ('comp.z', {
                'value': [24.],
                'resids': [0.],
                'units': 'inch',
                'shape': (1, ),
                'lower': None,
                'upper': None,
                'ref': 1.0,
                'ref0': 0.0,
                'res_ref': 1.0
            }),
            ('p1.x', {
                'value': [12.],
                'resids': [0.],
                'units': 'inch',
                'shape': (1, ),
                'lower': [1.],
                'upper': [100.],
                'ref': 1.1,
                'ref0': 2.1,
                'res_ref': 1.1
            }),
            ('p2.y', {
                'value': [1.],
                'resids': [0.],
                'units': 'ft',
                'shape': (1, ),
                'lower': [2.],
                'upper': [200.],
                'ref': 1.2,
                'ref0': 0.0,
                'res_ref': 2.2
            }),
        ])

        outputs = prob.model.list_outputs(implicit=False,
                                          values=True,
                                          units=True,
                                          shape=True,
                                          bounds=True,
                                          residuals=True,
                                          scaling=True,
                                          hierarchical=True,
                                          print_arrays=False)
示例#11
0
    def test_hierarchy_list_vars_options(self):

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

        model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])))

        sub1 = model.add_subsystem('sub1', om.Group())
        sub2 = sub1.add_subsystem('sub2', om.Group())
        g1 = sub2.add_subsystem('g1', SubSellar())
        g2 = model.add_subsystem('g2', SubSellar())

        model.connect('pz.z', 'sub1.sub2.g1.z')
        model.connect('sub1.sub2.g1.y2', 'g2.x')
        model.connect('g2.y2', 'sub1.sub2.g1.x')

        model.nonlinear_solver = om.NewtonSolver()
        model.linear_solver = om.ScipyKrylov()
        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 0

        g1.nonlinear_solver = om.NewtonSolver()
        g1.linear_solver = om.LinearBlockGS()

        g2.nonlinear_solver = om.NewtonSolver()
        g2.linear_solver = om.ScipyKrylov()
        g2.linear_solver.precon = om.LinearBlockGS()
        g2.linear_solver.precon.options['maxiter'] = 2

        prob.setup()
        prob.run_driver()

        # logging inputs
        # out_stream - not hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_inputs(values=True,
                               units=True,
                               hierarchical=False,
                               print_arrays=False,
                               out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(1, text.count("10 Input(s) in 'model'"))
        # make sure they are in the correct order
        self.assertTrue(
            text.find("sub1.sub2.g1.d1.z") < text.find('sub1.sub2.g1.d1.x') <
            text.find('sub1.sub2.g1.d1.y2') < text.find('sub1.sub2.g1.d2.z') <
            text.find('sub1.sub2.g1.d2.y1') < text.find('g2.d1.z') < text.find(
                'g2.d1.x') < text.find('g2.d1.y2') < text.find(
                    'g2.d2.z') < text.find('g2.d2.y1'))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(14, num_non_empty_lines)

        # out_stream - hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_inputs(values=True,
                               units=True,
                               hierarchical=True,
                               print_arrays=False,
                               out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(1, text.count("10 Input(s) in 'model'"))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(23, num_non_empty_lines)
        self.assertEqual(1, text.count('top'))
        self.assertEqual(1, text.count('  sub1'))
        self.assertEqual(1, text.count('    sub2'))
        self.assertEqual(1, text.count('      g1'))
        self.assertEqual(1, text.count('        d1'))
        self.assertEqual(2, text.count('          z'))

        # logging outputs
        # out_stream - not hierarchical - extras - no print_arrays
        stream = cStringIO()
        prob.model.list_outputs(values=True,
                                units=True,
                                shape=True,
                                bounds=True,
                                residuals=True,
                                scaling=True,
                                hierarchical=False,
                                print_arrays=False,
                                out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(text.count('5 Explicit Output'), 1)
        # make sure they are in the correct order
        self.assertTrue(
            text.find("pz.z") < text.find('sub1.sub2.g1.d1.y1') < text.find(
                'sub1.sub2.g1.d2.y2') < text.find('g2.d1.y1') < text.find(
                    'g2.d2.y2'))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(11, num_non_empty_lines)

        # Hierarchical
        stream = cStringIO()
        prob.model.list_outputs(values=True,
                                units=True,
                                shape=True,
                                bounds=True,
                                residuals=True,
                                scaling=True,
                                hierarchical=True,
                                print_arrays=False,
                                out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(text.count('top'), 1)
        self.assertEqual(text.count('          y1'), 1)
        self.assertEqual(text.count('  g2'), 1)
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(num_non_empty_lines, 21)
示例#12
0
    def test_simple_list_vars_options(self):

        import openmdao.api as om

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

        model.add_subsystem(
            'p1',
            om.IndepVarComp('x',
                            12.0,
                            lower=1.0,
                            upper=100.0,
                            ref=1.1,
                            ref0=2.1,
                            units='inch'))
        model.add_subsystem(
            'p2',
            om.IndepVarComp('y',
                            1.0,
                            lower=2.0,
                            upper=200.0,
                            ref=1.2,
                            res_ref=2.2,
                            units='ft'))
        model.add_subsystem(
            'comp',
            om.ExecComp('z=x+y',
                        x={
                            'value': 0.0,
                            'units': 'inch'
                        },
                        y={
                            'value': 0.0,
                            'units': 'inch'
                        },
                        z={
                            'value': 0.0,
                            'units': 'inch'
                        }))
        model.connect('p1.x', 'comp.x')
        model.connect('p2.y', 'comp.y')

        prob.setup()

        # list outputs before model has been run will raise an exception
        msg = "Group (<model>): Unable to list outputs on a Group until model has been run."
        try:
            prob.model.list_outputs()
        except Exception as err:
            self.assertEqual(str(err), msg)
        else:
            self.fail("Exception expected")

        # list_inputs on a component before run is okay, using relative names
        expl_inputs = prob.model.comp.list_inputs(out_stream=None)
        expected = {'x': {'value': 0.}, 'y': {'value': 0.}}
        self.assertEqual(dict(expl_inputs), expected)

        expl_inputs = prob.model.comp.list_inputs(includes='x',
                                                  out_stream=None)
        self.assertEqual(dict(expl_inputs), {'x': {'value': 0.}})

        expl_inputs = prob.model.comp.list_inputs(excludes='x',
                                                  out_stream=None)
        self.assertEqual(dict(expl_inputs), {'y': {'value': 0.}})

        # specifying prom_name should not cause an error
        expl_inputs = prob.model.comp.list_inputs(prom_name=True,
                                                  out_stream=None)
        self.assertEqual(
            dict(expl_inputs), {
                'x': {
                    'value': 0.,
                    'prom_name': 'x'
                },
                'y': {
                    'value': 0.,
                    'prom_name': 'y'
                },
            })

        # list_outputs on a component before run is okay, using relative names
        expl_outputs = prob.model.p1.list_outputs(out_stream=None)
        expected = {'x': {'value': 12.}}
        self.assertEqual(dict(expl_outputs), expected)

        expl_outputs = prob.model.p1.list_outputs(includes='x',
                                                  out_stream=None)
        self.assertEqual(dict(expl_outputs), expected)

        expl_outputs = prob.model.p1.list_outputs(excludes='x',
                                                  out_stream=None)
        self.assertEqual(dict(expl_outputs), {})

        # specifying residuals_tol should not cause an error
        expl_outputs = prob.model.p1.list_outputs(residuals_tol=.01,
                                                  out_stream=None)
        self.assertEqual(dict(expl_outputs), expected)

        # specifying prom_name should not cause an error
        expl_outputs = prob.model.p1.list_outputs(prom_name=True,
                                                  out_stream=None)
        self.assertEqual(dict(expl_outputs),
                         {'x': {
                             'value': 12.,
                             'prom_name': 'x'
                         }})

        # run model
        prob.set_solver_print(level=0)
        prob.run_model()

        # list_inputs tests
        # Can't do exact equality here because units cause comp.y to be slightly different than 12.0
        stream = cStringIO()
        inputs = prob.model.list_inputs(units=True,
                                        shape=True,
                                        out_stream=stream)
        tol = 1e-7
        for actual, expected in zip(sorted(inputs), [('comp.x', {
                'value': [12.],
                'shape': (1, ),
                'units': 'inch'
        }), ('comp.y', {
                'value': [12.],
                'shape': (1, ),
                'units': 'inch'
        })]):
            self.assertEqual(expected[0], actual[0])
            self.assertEqual(expected[1]['units'], actual[1]['units'])
            self.assertEqual(expected[1]['shape'], actual[1]['shape'])
            assert_rel_error(self, expected[1]['value'], actual[1]['value'],
                             tol)

        text = stream.getvalue()

        self.assertEqual(1, text.count("Input(s) in 'model'"))
        self.assertEqual(1, text.count('varname'))
        self.assertEqual(1, text.count('value'))
        self.assertEqual(1, text.count('shape'))
        self.assertEqual(1, text.count('top'))
        self.assertEqual(1, text.count('  comp'))
        self.assertEqual(1, text.count('    x'))
        self.assertEqual(1, text.count('    y'))

        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(8, num_non_empty_lines)

        # list_outputs tests

        # list outputs for implicit comps - should get none
        outputs = prob.model.list_outputs(implicit=True,
                                          explicit=False,
                                          out_stream=None)
        self.assertEqual(outputs, [])

        # list outputs with out_stream - just check to see if it was logged to
        stream = cStringIO()
        outputs = prob.model.list_outputs(out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(1, text.count('Explicit Output'))
        self.assertEqual(1, text.count('Implicit Output'))

        # list outputs with out_stream and all the optional display values True
        stream = cStringIO()
        outputs = prob.model.list_outputs(values=True,
                                          units=True,
                                          shape=True,
                                          bounds=True,
                                          residuals=True,
                                          scaling=True,
                                          hierarchical=False,
                                          print_arrays=False,
                                          out_stream=stream)

        self.assertEqual([
            ('comp.z', {
                'value': [24.],
                'resids': [0.],
                'units': 'inch',
                'shape': (1, ),
                'lower': None,
                'upper': None,
                'ref': 1.0,
                'ref0': 0.0,
                'res_ref': 1.0
            }),
            ('p1.x', {
                'value': [12.],
                'resids': [0.],
                'units': 'inch',
                'shape': (1, ),
                'lower': [1.],
                'upper': [100.],
                'ref': 1.1,
                'ref0': 2.1,
                'res_ref': 1.1
            }),
            ('p2.y', {
                'value': [1.],
                'resids': [0.],
                'units': 'ft',
                'shape': (1, ),
                'lower': [2.],
                'upper': [200.],
                'ref': 1.2,
                'ref0': 0.0,
                'res_ref': 2.2
            }),
        ], sorted(outputs))

        text = stream.getvalue()
        self.assertEqual(1, text.count('varname'))
        self.assertEqual(1, text.count('value'))
        self.assertEqual(1, text.count('resids'))
        self.assertEqual(1, text.count('units'))
        self.assertEqual(1, text.count('shape'))
        self.assertEqual(1, text.count('lower'))
        self.assertEqual(1, text.count('upper'))
        self.assertEqual(3, text.count('ref'))
        self.assertEqual(1, text.count('ref0'))
        self.assertEqual(1, text.count('res_ref'))
        self.assertEqual(1, text.count('p1.x'))
        self.assertEqual(1, text.count('p2.y'))
        self.assertEqual(1, text.count('comp.z'))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(9, num_non_empty_lines)
    def test_steady_aircraft_for_docs(self):
        import matplotlib.pyplot as plt

        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal

        import dymos as dm

        from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE
        from dymos.examples.plotting import plot_results
        from dymos.utils.lgl import lgl

        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.declare_coloring()

        num_seg = 15
        seg_ends, _ = lgl(num_seg + 1)

        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase('phase0',
                               dm.Phase(ode_class=AircraftODE,
                                        transcription=dm.Radau(num_segments=num_seg,
                                                               segment_ends=seg_ends,
                                                               order=3, compressed=False)))

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', om.IndepVarComp())
        assumptions.add_output('S', val=427.8, units='m**2')
        assumptions.add_output('mass_empty', val=1.0, units='kg')
        assumptions.add_output('mass_payload', val=1.0, units='kg')

        phase.set_time_options(fix_initial=True,
                               duration_bounds=(300, 10000),
                               duration_ref=5600)

        phase.add_state('range', units='NM',
                        rate_source='range_rate_comp.dXdt:range',
                        fix_initial=True, fix_final=False, ref=1e-3,
                        defect_ref=1e-3, lower=0, upper=2000)

        phase.add_state('mass_fuel', units='lbm',
                        rate_source='propulsion.dXdt:mass_fuel',
                        fix_initial=True, fix_final=True,
                        upper=1.5E5, lower=0.0, ref=1e2, defect_ref=1e2)

        phase.add_state('alt', units='kft',
                        rate_source='climb_rate',
                        fix_initial=True, fix_final=True,
                        lower=0.0, upper=60, ref=1e-3, defect_ref=1e-3)

        phase.add_control('climb_rate', units='ft/min', opt=True, lower=-3000, upper=3000,
                          targets=['gam_comp.climb_rate'],
                          rate_continuity=True, rate2_continuity=False)

        phase.add_control('mach', targets=['tas_comp.mach', 'aero.mach'], units=None, opt=False)

        phase.add_parameter('S',
                            targets=['aero.S', 'flight_equilibrium.S', 'propulsion.S'],
                            units='m**2')

        phase.add_parameter('mass_empty', targets=['mass_comp.mass_empty'], units='kg')
        phase.add_parameter('mass_payload', targets=['mass_comp.mass_payload'], units='kg')

        phase.add_path_constraint('propulsion.tau', lower=0.01, upper=2.0, shape=(1,))

        p.model.connect('assumptions.S', 'traj.phase0.parameters:S')
        p.model.connect('assumptions.mass_empty', 'traj.phase0.parameters:mass_empty')
        p.model.connect('assumptions.mass_payload', 'traj.phase0.parameters:mass_payload')

        phase.add_objective('range', loc='final', ref=-1.0e-4)

        phase.add_timeseries_output('aero.CL')
        phase.add_timeseries_output('aero.CD')

        p.setup()

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 3600.0
        p['traj.phase0.states:range'][:] = phase.interpolate(ys=(0, 724.0), nodes='state_input')
        p['traj.phase0.states:mass_fuel'][:] = phase.interpolate(ys=(30000, 1e-3), nodes='state_input')
        p['traj.phase0.states:alt'][:] = 10.0

        p['traj.phase0.controls:mach'][:] = 0.8

        p['assumptions.S'] = 427.8
        p['assumptions.mass_empty'] = 0.15E6
        p['assumptions.mass_payload'] = 84.02869 * 400

        dm.run_problem(p)

        assert_near_equal(p.get_val('traj.phase0.timeseries.states:range', units='NM')[-1],
                          726.85, tolerance=1.0E-2)

        exp_out = traj.simulate()

        assert_near_equal(p.get_val('traj.phase0.timeseries.CL')[0],
                          exp_out.get_val('traj.phase0.timeseries.CL')[0],
                          tolerance=1.0E-9)

        assert_near_equal(p.get_val('traj.phase0.timeseries.CD')[0],
                          exp_out.get_val('traj.phase0.timeseries.CD')[0],
                          tolerance=1.0E-9)

        plot_results([('traj.phase0.timeseries.states:range', 'traj.phase0.timeseries.states:alt',
                       'range (NM)', 'altitude (kft)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.states:mass_fuel',
                       'time (s)', 'fuel mass (lbm)'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.CL',
                       'time (s)', 'lift coefficient'),
                      ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.CD',
                       'time (s)', 'drag coefficient')],
                     title='Commercial Aircraft Optimization',
                     p_sol=p, p_sim=exp_out)

        plt.show()
    def test_nonlinear_circuit_analysis(self):
        import numpy as np

        import openmdao.api as om

        class Resistor(om.ExplicitComponent):
            """Computes current across a resistor using Ohm's law."""

            def initialize(self):
                self.options.declare('R', default=1., desc='Resistance in Ohms')

            def setup(self):
                self.add_input('V_in', units='V')
                self.add_input('V_out', units='V')
                self.add_output('I', units='A')

                # partial derivs are constant, so we can assign their values in setup
                R = self.options['R']
                self.declare_partials('I', 'V_in', val=1 / R)
                self.declare_partials('I', 'V_out', val=-1 / R)

            def compute(self, inputs, outputs):
                deltaV = inputs['V_in'] - inputs['V_out']
                outputs['I'] = deltaV / self.options['R']

        class Diode(om.ExplicitComponent):
            """Computes current across a diode using the Shockley diode equation."""

            def initialize(self):
                self.options.declare('Is', default=1e-15, desc='Saturation current in Amps')
                self.options.declare('Vt', default=.025875, desc='Thermal voltage in Volts')

            def setup(self):
                self.add_input('V_in', units='V')
                self.add_input('V_out', units='V')
                self.add_output('I', units='A')

                # non-linear component, so we'll declare the partials here but compute them in compute_partials
                self.declare_partials('I', 'V_in')
                self.declare_partials('I', 'V_out')

            def compute(self, inputs, outputs):
                deltaV = inputs['V_in'] - inputs['V_out']
                Is = self.options['Is']
                Vt = self.options['Vt']
                outputs['I'] = Is * (np.exp(deltaV / Vt) - 1)

            def compute_partials(self, inputs, J):
                deltaV = inputs['V_in'] - inputs['V_out']
                Is = self.options['Is']
                Vt = self.options['Vt']
                I = Is * np.exp(deltaV / Vt)

                J['I', 'V_in'] = I/Vt
                J['I', 'V_out'] = -I/Vt

        class Node(om.ImplicitComponent):
            """Computes voltage residual across a node based on incoming and outgoing current."""

            def initialize(self):
                self.options.declare('n_in', default=1, types=int, desc='number of connections with + assumed in')
                self.options.declare('n_out', default=1, types=int, desc='number of current connections + assumed out')

            def setup(self):
                self.add_output('V', val=5., units='V')

                for i in range(self.options['n_in']):
                    i_name = 'I_in:{}'.format(i)
                    self.add_input(i_name, units='A')
                    self.declare_partials('V', i_name, val=1)

                for i in range(self.options['n_out']):
                    i_name = 'I_out:{}'.format(i)
                    self.add_input(i_name, units='A')
                    self.declare_partials('V', i_name, val=-1)

                    # note: we don't declare any partials wrt `V` here,
                    #      because the residual doesn't directly depend on it

            def apply_nonlinear(self, inputs, outputs, residuals):
                residuals['V'] = 0.
                for i_conn in range(self.options['n_in']):
                    residuals['V'] += inputs['I_in:{}'.format(i_conn)]
                for i_conn in range(self.options['n_out']):
                    residuals['V'] -= inputs['I_out:{}'.format(i_conn)]

        class Circuit(om.Group):

            def setup(self):
                self.add_subsystem('n1', Node(n_in=1, n_out=2), promotes_inputs=[('I_in:0', 'I_in')])
                self.add_subsystem('n2', Node())  # leaving defaults

                self.add_subsystem('R1', Resistor(R=100.), promotes_inputs=[('V_out', 'Vg')])
                self.add_subsystem('R2', Resistor(R=10000.))
                self.add_subsystem('D1', Diode(), promotes_inputs=[('V_out', 'Vg')])

                self.connect('n1.V', ['R1.V_in', 'R2.V_in'])
                self.connect('R1.I', 'n1.I_out:0')
                self.connect('R2.I', 'n1.I_out:1')

                self.connect('n2.V', ['R2.V_out', 'D1.V_in'])
                self.connect('R2.I', 'n2.I_in:0')
                self.connect('D1.I', 'n2.I_out:0')

                self.nonlinear_solver = om.NewtonSolver()
                self.linear_solver = om.DirectSolver()

                self.nonlinear_solver.options['iprint'] = 2
                self.nonlinear_solver.options['maxiter'] = 10
                self.nonlinear_solver.options['solve_subsystems'] = True
                self.nonlinear_solver.linesearch = om.ArmijoGoldsteinLS()
                self.nonlinear_solver.linesearch.options['maxiter'] = 10
                self.nonlinear_solver.linesearch.options['iprint'] = 2


        p = om.Problem()
        model = p.model

        model.add_subsystem('ground', om.IndepVarComp('V', 0., units='V'))
        model.add_subsystem('source', om.IndepVarComp('I', 0.1, units='A'))
        model.add_subsystem('circuit', Circuit())

        model.connect('source.I', 'circuit.I_in')
        model.connect('ground.V', 'circuit.Vg')

        p.setup()

        # set some initial guesses
        p['circuit.n1.V'] = 10.
        p['circuit.n2.V'] = 1e-3

        p.run_model()

        assert_near_equal(p['circuit.n1.V'], 9.90804735, 1e-5)
        assert_near_equal(p['circuit.n2.V'], 0.71278185, 1e-5)
        assert_near_equal(p['circuit.R1.I'], 0.09908047, 1e-5)
        assert_near_equal(p['circuit.R2.I'], 0.00091953, 1e-5)
        assert_near_equal(p['circuit.D1.I'], 0.00091953, 1e-5)

        # sanity check: should sum to .1 Amps
        assert_near_equal(p['circuit.R1.I'] + p['circuit.D1.I'], .1, 1e-6)
示例#15
0
    def test_partial_deriv_plot(self):
        class ArrayComp2D(om.ExplicitComponent):
            """
            A fairly simple array component with an intentional error in compute_partials.
            """
            def setup(self):
                self.JJ = np.array([[1.0, 0.0, 0.0, 7.0], [0.0, 2.5, 0.0, 0.0],
                                    [-1.0, 0.0, 8.0, 0.0],
                                    [0.0, 4.0, 0.0, 6.0]])
                # Params
                self.add_input('x1', np.zeros([4]))
                # Unknowns
                self.add_output('y1', np.zeros([4]))
                self.declare_partials(of='*', wrt='*')

            def compute(self, inputs, outputs):
                """
                Execution.
                """
                outputs['y1'] = self.JJ.dot(inputs['x1'])

            def compute_partials(self, inputs, partials):
                """
                Analytical derivatives.
                """
                # create some error to force the diff plot to show something
                error = np.zeros((4, 4))
                err = 1e-7
                error[0][3] = err
                error[1][2] = -2.0 * err
                partials[('y1', 'x1')] = self.JJ + error

        prob = om.Problem()
        model = prob.model
        model.add_subsystem('x_param1',
                            om.IndepVarComp('x1', np.ones((4))),
                            promotes=['x1'])
        model.add_subsystem('mycomp', ArrayComp2D(), promotes=['x1', 'y1'])
        prob.setup(check=False, mode='fwd')
        check_partials_data = prob.check_partials(out_stream=None)

        # plot with defaults
        fig, ax = om.partial_deriv_plot('y1',
                                        'x1',
                                        check_partials_data,
                                        title="Defaults")
        # Instead of seeing if the images created by matplotlib match what we expect, which
        # is a fragile thing to do in testing, check a data structure inside matplotlib's
        # objects. We will assume matplotlib draws the correct thing.
        expected_array = np.array([[1., 0., 0., 1.], [0., 1., 0., 0.],
                                   [1., 0., 1., 0.], [0., 1., 0., 1.]])
        actual_array = ax[0].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[1., 0., 0., 1.], [0., 1., 1., 0.],
                                   [1., 0., 1., 0.], [0., 1., 0., 1.]])
        actual_array = ax[1].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[9.31322575e-10, 0.0, 0.0, 1.0e-07],
                                   [0.0, 0.0, -2.0e-07, 0.0],
                                   [0.0, 0.0, 9.31322575e-10, 0.0],
                                   [0.0, 0.0, 0.0, 1.86264515e-09]])
        actual_array = ax[2].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)

        # plot with specified jac_method
        fig, ax = om.partial_deriv_plot('y1',
                                        'x1',
                                        check_partials_data,
                                        jac_method="J_fwd",
                                        title="specified jac_method")
        expected_array = np.array([[1., 0., 0., 1.], [0., 1., 0., 0.],
                                   [1., 0., 1., 0.], [0., 1., 0., 1.]])
        actual_array = ax[0].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[1., 0., 0., 1.], [0., 1., 1., 0.],
                                   [1., 0., 1., 0.], [0., 1., 0., 1.]])
        actual_array = ax[1].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[9.31322575e-10, 0.0, 0.0, 1.0e-07],
                                   [0.0, 0.0, -2.0e-07, 0.0],
                                   [0.0, 0.0, 9.31322575e-10, 0.0],
                                   [0.0, 0.0, 0.0, 1.86264515e-09]])
        actual_array = ax[2].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)

        # plot in non-binary mode
        fig, ax = om.partial_deriv_plot('y1',
                                        'x1',
                                        check_partials_data,
                                        binary=False,
                                        title="non-binary")
        expected_array = np.array([[1., 0., 0., 7.], [0., 2.5, 0., 0.],
                                   [-1., 0., 8., 0.], [0., 4., 0., 6.]])
        actual_array = ax[0].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[1.0e+00, 0.0, 0.0, 7.00000010e+00],
                                   [0.0, 2.5e+00, -2.0e-07, 0.0],
                                   [-1.0e+00, 0.0, 8.0e+00, 0.0],
                                   [0.0, 4.0e+00, 0.0, 6.0e+00]])
        actual_array = ax[1].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)
        expected_array = np.array([[9.31322575e-10, 0.0, 0.0, 1.0e-07],
                                   [0.0, 0.0, -2.0e-07, 0.0],
                                   [0.0, 0.0, 9.31322575e-10, 0.0],
                                   [0.0, 0.0, 0.0, 1.86264515e-09]])
        actual_array = ax[2].images[0]._A.data
        assert_near_equal(expected_array, actual_array, 1e-8)

        # plot with different tol values
        # Not obvious how to test this other than image matching
        om.partial_deriv_plot('y1',
                              'x1',
                              check_partials_data,
                              tol=1e-5,
                              title="tol greater than err")
        om.partial_deriv_plot('y1',
                              'x1',
                              check_partials_data,
                              tol=1e-10,
                              title="tol less than err")
示例#16
0
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 26 17:03:44 2019

@author: Morimoto Lab
"""
import openmdao.api as om
import numpy as np
from model import Paraboloid

# We'll use the component that was defined in the last tutorial

N = 20
# build the model
prob = om.Problem()
indeps = prob.model.add_subsystem('indeps', om.IndepVarComp())
"""indeps.add_output('x', 3.0)
indeps.add_output('y', -4.0)"""
indeps.add_output('length1', np.ones(N) * 20)
indeps.add_output('length2', np.ones(N) * 2)
"""indeps.add_output('length3', np.ones(10))"""
indeps.add_output('length4', np.ones(N) * 10)
"""indeps.add_output('kappa1', 1)"""
indeps.add_output('kappa2', 1)
"""indeps.add_output('kappa3', 1)"""
indeps.add_output('kb1', 1)
indeps.add_output('kb2', 1)
indeps.add_output('kb3', 1)
indeps.add_output('l22', np.ones(N) * 10)
indeps.add_output('psi2', np.ones(N))
示例#17
0
    def setup(self):

        ivc = om.IndepVarComp()

        # opts = self.options
        gd = self.options['grid_data']
        control_options = self.options['control_options']
        time_units = self.options['time_units']

        if len(control_options) < 1:
            return

        opt_controls = [
            name for (name, opts) in iteritems(control_options) if opts['opt']
        ]

        if len(opt_controls) > 0:
            ivc = self.add_subsystem('indep_controls',
                                     subsys=om.IndepVarComp(),
                                     promotes_outputs=['*'])

        self.add_subsystem('control_interp_comp',
                           subsys=ControlInterpComp(
                               time_units=time_units,
                               grid_data=gd,
                               control_options=control_options),
                           promotes_inputs=['*'],
                           promotes_outputs=['*'])

        for name, options in iteritems(control_options):
            if options['opt']:
                num_input_nodes = gd.subset_num_nodes['control_input']

                desvar_indices = list(
                    range(gd.subset_num_nodes['control_input']))
                if options['fix_initial']:
                    desvar_indices.pop(0)
                if options['fix_final']:
                    desvar_indices.pop()

                if len(desvar_indices) > 0:
                    coerce_desvar = CoerceDesvar(
                        gd.subset_num_nodes['control_disc'], desvar_indices,
                        options)

                    lb = -INF_BOUND if coerce_desvar(
                        'lower') is None else coerce_desvar('lower')
                    ub = INF_BOUND if coerce_desvar(
                        'upper') is None else coerce_desvar('upper')

                    self.add_design_var(name='controls:{0}'.format(name),
                                        lower=lb,
                                        upper=ub,
                                        scaler=coerce_desvar('scaler'),
                                        adder=coerce_desvar('adder'),
                                        ref0=coerce_desvar('ref0'),
                                        ref=coerce_desvar('ref'),
                                        indices=desvar_indices)

                ivc.add_output(name='controls:{0}'.format(name),
                               val=options['val'],
                               shape=(num_input_nodes,
                                      np.prod(options['shape'])),
                               units=options['units'])
    def setup(self):
        E = self.options['E']
        L = self.options['L']
        b = self.options['b']
        volume = self.options['volume']
        max_bending = self.options['max_bending']
        num_elements = self.options['num_elements']
        num_nodes = num_elements + 1
        num_cp = self.options['num_cp']
        num_load_cases = self.options['num_load_cases']
        parallel_derivs = self.options['parallel_derivs']

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

        x_interp = sine_distribution(num_elements)
        comp = om.SplineComp(method='bsplines',
                             num_cp=num_cp,
                             x_interp_val=x_interp)
        comp.add_spline(y_cp_name='h_cp', y_interp_name='h')
        self.add_subsystem('interp', comp)

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

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

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

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

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

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

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

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

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

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

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

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

            for k in range(num_rhs):
                sub.connect('states_comp.d_%d' % k,
                            'stress_comp.displacements_%d' % k,
                            src_indices=np.arange(2 * num_nodes))

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

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

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

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

                if not self.options['ks_add_constraint']:
                    sub.add_constraint('KS_%d.KS' % k,
                                       upper=0.0,
                                       parallel_deriv_color=color)

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

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

        self.add_design_var('inputs_comp.h_cp', lower=1e-2, upper=10.)
        self.add_objective('volume_comp.volume')
示例#19
0
    def test_prob_getval_dist_disc(self):
        size = 14

        p = om.Problem()

        top = p.model

        ivc = om.IndepVarComp()
        ivc.add_output('invec', np.ones(size))
        ivc.add_discrete_output('disc_in', 'C1foo')
        top.add_subsystem('P', ivc)
        top.connect('P.invec', 'C1.invec')
        top.connect('P.disc_in', 'C1.disc_in')

        C1 = top.add_subsystem(
            "C1", DistribInputDistribOutputDiscreteComp(arr_size=size))
        p.setup()

        # Conclude setup but don't run model.
        p.final_setup()

        rank = p.comm.rank

        p['P.invec'] = np.array([[4, 3, 2, 1, 8, 6, 4, 2, 9, 6, 3, 12, 8,
                                  4.0]])
        p['P.disc_in'] = 'boo'

        p.run_model()

        if rank == 0:
            ans = p.get_val('C1.invec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([4, 3, 2, 1],
                                                     dtype=float))
            ans = p.get_val('C1.outvec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([8, 6, 4, 2],
                                                     dtype=float))
        elif rank == 1:
            ans = p.get_val('C1.invec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([8, 6, 4, 2],
                                                     dtype=float))
            ans = p.get_val('C1.outvec', get_remote=False)
            np.testing.assert_allclose(ans,
                                       np.array([16, 12, 8, 4], dtype=float))
        elif rank == 2:
            ans = p.get_val('C1.invec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([9, 6, 3], dtype=float))
            ans = p.get_val('C1.outvec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([18, 12, 6], dtype=float))
        elif rank == 3:
            ans = p.get_val('C1.invec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([12, 8, 4], dtype=float))
            ans = p.get_val('C1.outvec', get_remote=False)
            np.testing.assert_allclose(ans, np.array([24, 16, 8], dtype=float))

        ans = p.get_val('C1.invec', get_remote=True)
        np.testing.assert_allclose(
            ans,
            np.array([4, 3, 2, 1, 8, 6, 4, 2, 9, 6, 3, 12, 8, 4], dtype=float))
        ans = p.get_val('C1.outvec', get_remote=True)
        np.testing.assert_allclose(
            ans,
            np.array([8, 6, 4, 2, 16, 12, 8, 4, 18, 12, 6, 24, 16, 8],
                     dtype=float))

        ans = p.get_val('C1.disc_in', get_remote=False)
        self.assertEqual(ans, 'boo')
        ans = p.get_val('C1.disc_in', get_remote=True)
        self.assertEqual(ans, 'boo')
        ans = p.get_val('C1.disc_out', get_remote=False)
        self.assertEqual(ans, 'boobar')
        ans = p.get_val('C1.disc_out', get_remote=True)
        self.assertEqual(ans, 'boobar')
示例#20
0
    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,

            # 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 = om.Problem()

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

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

        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], 124229.646011,
                         1e-4)
    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,
            'distributed_fuel_weight':
            False,
            # Constraints
            'exact_failure_constraint':
            False,  # if false, use KS function
            'Wf_reserve':
            15000.,  # [kg] reserve fuel mass
            'span':
            58.  # [m]
        }

        surfaces = [surf_dict]

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

        # Add problem information as an independent variables component
        indep_var_comp = om.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')

                # 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')

        prob.driver = om.ScipyOptimizeDriver()
        prob.driver.options['tol'] = 1e-9

        # prob.driver = om.pyOptSparseDriver()
        # prob.driver.options['optimizer'] = "SNOPT"
        # prob.driver.opt_settings['Major optimality tolerance'] = 1e-6
        # prob.driver.opt_settings['Major feasibility tolerance'] = 1e-8
        # prob.driver.opt_settings['Major iterations limit'] = 200

        # prob.driver.add_recorder(om.SqliteRecorder("wingbox.db"))
        # prob.driver.recording_options['record_derivatives'] = True
        # prob.driver.recording_options['includes'] = ['*']

        prob.model.add_objective('AS_point_0.fuelburn', scaler=1e-5)

        # prob.model.add_design_var('alpha', lower=-15., upper=15.)
        prob.model.add_design_var('wing.twist_cp',
                                  lower=-15.,
                                  upper=15.,
                                  scaler=0.1)
        prob.model.add_design_var('wing.spar_thickness_cp',
                                  lower=0.003,
                                  upper=0.1,
                                  scaler=1e2)
        prob.model.add_design_var('wing.skin_thickness_cp',
                                  lower=0.003,
                                  upper=0.1,
                                  scaler=1e2)
        prob.model.add_design_var('wing.geometry.t_over_c_cp',
                                  lower=0.07,
                                  upper=0.2,
                                  scaler=10.)
        prob.model.add_design_var('wing.geometry.span',
                                  lower=55.,
                                  upper=60.,
                                  scaler=2e-2)

        prob.model.add_constraint('AS_point_0.CL', equals=0.5)
        # prob.model.add_constraint('AS_point_0.L_equals_W', equals=0.)
        prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)
        # prob.model.add_constraint('coupled.wing_loads.fuel_vol_delta', lower=0.)

        # Set up the problem
        prob.setup()

        # om.view_model(prob)

        prob.run_driver()

        # prob.check_partials(form='central', compact_print=True)

        # print(prob['AS_point_0.fuelburn'][0])
        # print(prob['wing.structural_mass'][0]/1.25)
        # print(prob['wing.geometry.span'])
        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 84387.962001,
                         1e-5)
        assert_rel_error(self, prob['wing.structural_mass'][0] / 1.25,
                         13974.684240, 1e-5)
        assert_rel_error(self, prob['wing.geometry.span'][0], 60., 1e-5)
示例#22
0
pde_problem.add_scalar_output('avg_density', avg_density_form, 'density')

# Add output-compliance to the PDE problem:
compliance_form = df.dot(f, displacements_function) * dss(6)
pde_problem.add_scalar_output('compliance', compliance_form, 'displacements')

# Add boundary conditions to the PDE problem:
pde_problem.add_bc(df.DirichletBC(displacements_function_space,
                    df.Constant((0.0, 0.0, 0.0)), '(abs(x[1]-30.) < DOLFIN_EPS)'))

# Define the OpenMDAO problem and model
prob = om.Problem()
num_dof_density = pde_problem.inputs_dict['density']['function'].function_space().dim()

# Add design variables---density on each element:
comp = om.IndepVarComp()
comp.add_output(
    'density_unfiltered',
    shape=num_dof_density,
    val=np.random.random(num_dof_density) * 0.86,
)
prob.model.add_subsystem('indep_var_comp', comp, promotes=['*'])

# add the filter and specifying the filter radius--num_element_filtered=2
comp = GeneralFilterComp(density_function_space=density_function_space, num_element_filtered=2)
prob.model.add_subsystem('general_filter_comp', comp, promotes=['*'])

group = AtomicsGroup(pde_problem=pde_problem)
prob.model.add_subsystem('atomics_group', group, promotes=['*'])

prob.model.add_design_var('density_unfiltered',upper=1, lower=1e-4)
示例#23
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,

            # 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 = om.Problem()

        # Add problem information as an independent variables component
        indep_var_comp = om.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('S_ref_total', val=150.0, units='m**2')

        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,
                                       user_specified_Sref=True)

            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('S_ref_total', point_name + '.S_ref_total')

            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')

        # Set up the problem
        prob.setup()

        # om.view_model(prob)

        prob.run_model()

        assert_rel_error(self, prob['AS_point_0.CL'][0], 1.5775046966345903,
                         1e-6)
        assert_rel_error(self, prob['AS_point_0.CM'][1], -1.61358383281, 1e-5)
    def test_sellar(self):
        # Basic sellar test.

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

        model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])
        model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])

        model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
                                                   z=np.array([0.0, 0.0]), x=0.0),
                            promotes=['obj', 'x', 'z', 'y1', 'y2'])

        model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])
        model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])

        nlbgs = model.nonlinear_solver = om.NonlinearBlockGS()

        prob.setup()

        prob.set_val('x', 1.)
        prob.set_val('z', np.array([5.0, 2.0]))

        prob.set_solver_print(level=0)
        prob.run_model()

        assert_near_equal(prob.get_val('y1'), 25.58830273, .00001)
        assert_near_equal(prob.get_val('y2'), 12.05848819, .00001)

        # Make sure we aren't iterating like crazy
        self.assertEqual(model.nonlinear_solver._iter_count, 8)

        # Only one extra execution
        self.assertEqual(model.d1.execution_count, 8)

        # With run_apply_linear, we execute the components more times.

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

        model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x'])
        model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z'])

        model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2'])
        model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2'])

        model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
                                                   z=np.array([0.0, 0.0]), x=0.0),
                                promotes=['obj', 'x', 'z', 'y1', 'y2'])

        model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])
        model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])

        nlbgs = model.nonlinear_solver = om.NonlinearBlockGS()
        nlbgs.options['use_apply_nonlinear'] = True

        prob.setup()
        prob.set_solver_print(level=0)
        prob.run_model()

        assert_near_equal(prob.get_val('y1'), 25.58830273, .00001)
        assert_near_equal(prob.get_val('y2'), 12.05848819, .00001)

        # Make sure we aren't iterating like crazy
        self.assertEqual(model.nonlinear_solver._iter_count, 7)

        # Nearly double the executions.
        self.assertEqual(model.d1.execution_count, 15)
示例#25
0
    def test_units_error_messages(self):
        prob = om.Problem()
        model = prob.model

        ivc = om.IndepVarComp()
        ivc.add_output('x', 35.0, units='degF')

        model.add_subsystem('p', ivc, promotes=['x'])
        model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
                                                 x={'value': 2.0, 'units': 'degF'},
                                                 y1={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y1'])

        model.add_design_var('x', units='ft', lower=0.0, upper=100.0, scaler=3.5, adder=77.0)
        prob.setup()

        with self.assertRaises(RuntimeError) as context:
            prob.final_setup()

        msg = "<model> <class Group>: Target for design variable x has 'degF' units, but 'ft' units were specified."
        self.assertEqual(str(context.exception), msg)

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

        ivc = om.IndepVarComp()
        ivc.add_output('x', 35.0, units='degF')

        model.add_subsystem('p', ivc, promotes=['x'])
        model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
                                                 x={'value': 2.0, 'units': 'degF'},
                                                 y1={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y1'])

        model.add_constraint('x', units='ft', lower=0.0, upper=100.0)
        prob.setup()

        with self.assertRaises(RuntimeError) as context:
            prob.final_setup()

        msg = "<model> <class Group>: Target for constraint x has 'degF' units, but 'ft' units were specified."
        self.assertEqual(str(context.exception), msg)

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

        ivc = om.IndepVarComp()
        ivc.add_output('x', 35.0, units=None)

        model.add_subsystem('p', ivc, promotes=['x'])
        model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
                                                 x={'value': 2.0},
                                                 y1={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y1'])

        model.add_design_var('x', units='ft', lower=0.0, upper=100.0, scaler=3.5, adder=77.0)
        prob.setup()

        with self.assertRaises(RuntimeError) as context:
            prob.final_setup()

        msg = "<model> <class Group>: Target for design variable x has no units, but 'ft' units were specified."
        self.assertEqual(str(context.exception), msg)

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

        ivc = om.IndepVarComp()
        ivc.add_output('x', 35.0, units=None)

        model.add_subsystem('p', ivc, promotes=['x'])
        model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
                                                 x={'value': 2.0},
                                                 y1={'value': 2.0, 'units': 'degF'}),
                            promotes=['x', 'y1'])

        model.add_constraint('x', units='ft', lower=0.0, upper=100.0)
        prob.setup()

        with self.assertRaises(RuntimeError) as context:
            prob.final_setup()

        msg = "<model> <class Group>: Target for constraint x has no units, but 'ft' units were specified."
        self.assertEqual(str(context.exception), msg)
示例#26
0
    def test_ex_double_integrator_input_times_compressed(self):
        """
        Tests that externally connected t_initial and t_duration function as expected.
        """
        compressed = True
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()

        times_ivc = p.model.add_subsystem('times_ivc',
                                          om.IndepVarComp(),
                                          promotes_outputs=['t0', 'tp'])
        times_ivc.add_output(name='t0', val=0.0, units='s')
        times_ivc.add_output(name='tp', val=1.0, units='s')

        transcription = dm.Radau(num_segments=20,
                                 order=3,
                                 compressed=compressed)
        phase = dm.Phase(ode_class=DoubleIntegratorODE,
                         transcription=transcription)
        p.model.add_subsystem('phase0', phase)

        p.model.connect('t0', 'phase0.t_initial')
        p.model.connect('tp', 'phase0.t_duration')

        phase.set_time_options(input_initial=True,
                               input_duration=True,
                               units='s')

        phase.add_state('v',
                        fix_initial=True,
                        fix_final=True,
                        rate_source='u',
                        units='m/s')
        phase.add_state('x', fix_initial=True, rate_source='v', units='m')

        phase.add_control('u',
                          units='m/s**2',
                          scaler=0.01,
                          continuity=False,
                          rate_continuity=False,
                          rate2_continuity=False,
                          shape=(1, ),
                          lower=-1.0,
                          upper=1.0)

        # Maximize distance travelled in one second.
        phase.add_objective('x', loc='final', scaler=-1)

        p.model.linear_solver = om.DirectSolver()

        p.setup(check=True)

        p['t0'] = 0.0
        p['tp'] = 1.0

        p['phase0.states:x'] = phase.interpolate(ys=[0, 0.25],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 0],
                                                 nodes='state_input')
        p['phase0.controls:u'] = phase.interpolate(ys=[1, -1],
                                                   nodes='control_input')

        p.run_driver()
示例#27
0
            def setup(self):
                self.add_subsystem('dv', om.IndepVarComp('x', 3.0))
                self.add_subsystem('comp', om.ExecComp('y = (x-2)**2'))
                self.connect('dv.x', 'comp.x')

                self.add_design_var('dv.x', lower=-10, upper=10)
示例#28
0
    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
                    '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,

                    # 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_cp' : np.array([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
                    'with_wave' : False,     # if true, compute wave drag
                    'sweep' : 0.,
                    'dihedral' : 0.,
                    }

        surfaces = [surf_dict]

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

        indep_var_comp = om.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')

        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('Mach_number', point_name + '.Mach_number')
            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')

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

        prob.driver = om.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)
示例#29
0
    def setup(self):
        surface = self.options['surface']
        connect_geom_DVs = self.options['connect_geom_DVs']

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

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

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

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

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

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

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

        else:
            from openaerostruct.geometry.geometry_mesh import GeometryMesh

            bsp_inputs = []

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

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

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

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

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

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

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

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

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

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

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

            self.add_subsystem('mesh',
                               GeometryMesh(surface=surface),
                               promotes_inputs=bsp_inputs,
                               promotes_outputs=['mesh'])
示例#30
0
    def setUp(self):
        dm.options['include_check_partials'] = True
        self.p = om.Problem(model=om.Group())

        ivp = self.p.model.add_subsystem('ivc',
                                         subsys=om.IndepVarComp(),
                                         promotes_outputs=['*'])

        ndn = 20
        nn = 30

        ivp.add_output('phase0:x', val=np.zeros((ndn, 1)), units='m')
        ivp.add_output('phase0:u', val=np.zeros((nn, 3)), units='deg')
        ivp.add_output('phase0:v', val=np.zeros((nn, 3, 3)), units='N')

        ivp.add_output('phase1:x', val=np.zeros((ndn, 1)), units='m')
        ivp.add_output('phase1:u', val=np.zeros((nn, 3)), units='deg')
        ivp.add_output('phase1:v', val=np.zeros((nn, 3, 3)), units='N')

        linkage_comp = PhaseLinkageComp()

        x_lnk = LinkageOptionsDictionary()
        x_lnk['phase_a'] = 'phase0'
        x_lnk['phase_b'] = 'phase1'
        x_lnk['var_a'] = 'x'
        x_lnk['var_b'] = 'x'
        x_lnk['loc_a'] = 'final'
        x_lnk['loc_b'] = 'initial'
        x_lnk['units'] = 'm'
        x_lnk['shape'] = (1, )
        x_lnk['equals'] = 0.0

        u_lnk = LinkageOptionsDictionary()
        u_lnk['phase_a'] = 'phase0'
        u_lnk['phase_b'] = 'phase1'
        u_lnk['var_a'] = 'u'
        u_lnk['var_b'] = 'u'
        u_lnk['loc_a'] = 'final'
        u_lnk['loc_b'] = 'initial'
        u_lnk['units'] = 'deg'
        u_lnk['shape'] = (3, )
        u_lnk['equals'] = 0.0

        v_lnk = LinkageOptionsDictionary()
        v_lnk['phase_a'] = 'phase0'
        v_lnk['phase_b'] = 'phase1'
        v_lnk['var_a'] = 'v'
        v_lnk['var_b'] = 'v'
        v_lnk['loc_a'] = 'final'
        v_lnk['loc_b'] = 'initial'
        v_lnk['units'] = 'N'
        v_lnk['shape'] = (3, 3)
        v_lnk['equals'] = 0.0

        linkage_comp.add_linkage_configure(x_lnk)
        linkage_comp.add_linkage_configure(u_lnk)
        linkage_comp.add_linkage_configure(v_lnk)

        self.p.model.add_subsystem('linkage_comp', subsys=linkage_comp)

        self.p.model.connect('phase0:x',
                             'linkage_comp.phase0:x',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.model.connect('phase1:x',
                             'linkage_comp.phase1:x',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.model.connect('phase0:u',
                             'linkage_comp.phase0:u',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.model.connect('phase1:u',
                             'linkage_comp.phase1:u',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.model.connect('phase0:v',
                             'linkage_comp.phase0:v',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.model.connect('phase1:v',
                             'linkage_comp.phase1:v',
                             src_indices=om.slicer[[0, -1], ...])

        self.p.setup()

        self.p['phase0:x'] = np.random.rand(*self.p['phase0:x'].shape)
        self.p['phase0:u'] = np.random.rand(*self.p['phase0:u'].shape)
        self.p['phase0:v'] = np.random.rand(*self.p['phase0:v'].shape)

        self.p['phase1:x'] = np.random.rand(*self.p['phase1:x'].shape)
        self.p['phase1:u'] = np.random.rand(*self.p['phase1:u'].shape)
        self.p['phase1:v'] = np.random.rand(*self.p['phase1:v'].shape)

        self.p.run_model()