Пример #1
0
    def test(self):
        """
        This is an opt problem that tests the wingbox model with wave drag and the fuel vol constraint
        """

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 7,
            'num_x': 2,
            '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
            'type':
            'aerostruct',
            '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,
            'num_x':
            mesh.shape[0],
            'num_y':
            mesh.shape[1],
            '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':
            True,  # 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,
            # Constraints
            'exact_failure_constraint':
            False,  # if false, use KS function
            'fuel_density':
            803.,
            'Wf_reserve':
            15000.,
        }

        surfaces = [surf_dict]

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

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=.85 * 295.07, units='m/s')
        indep_var_comp.add_output('alpha', val=0., units='deg')
        indep_var_comp.add_output('M', 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=(143000 - 2.5 * 11600 + 34000) + 15000,
                                  units='kg')
        indep_var_comp.add_output('a', 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 = Aerostruct(surface=surface)

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

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

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

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

            prob.model.add_subsystem(point_name, AS_point)

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

            for surface in surfaces:

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

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

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

                # 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_weight', point_name + '.' +
                    'total_perf.' + name + '_structural_weight')

                # Connect wingbox properties to von Mises stress calcs
                prob.model.connect(name + '.Qz', com_name + 'Qz')
                prob.model.connect(name + '.Iz', com_name + 'Iz')
                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 + '.skin_thickness',
                                   com_name + 'skin_thickness')
                prob.model.connect(name + '.t_over_c', com_name + 't_over_c')

            #=======================================================================================
            # Here we add the fuel volume constraint componenet to the model
            #=======================================================================================
            prob.model.add_subsystem('fuel_vol_delta',
                                     WingboxFuelVolDelta(surface=surface))
            prob.model.connect('AS_point_0.fuelburn',
                               'fuel_vol_delta.fuelburn')
            prob.model.connect('wing.nodes', 'fuel_vol_delta.nodes')
            prob.model.connect('wing.A_int', 'fuel_vol_delta.A_int')
            #=======================================================================================
            #=======================================================================================

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

        # from openmdao.api import pyOptSparseDriver
        # prob.driver = pyOptSparseDriver()
        # prob.driver.add_recorder(SqliteRecorder("cases.sql"))
        # 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.model.add_objective('AS_point_0.fuelburn', scaler=1e-5)

        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_constraint('AS_point_0.total_perf.CL', equals=0.5)
        prob.model.add_constraint('AS_point_0.wing_perf.failure', upper=0.)

        #=======================================================================================
        # Here we add the fuel volume constraint
        #=======================================================================================
        prob.model.add_constraint('fuel_vol_delta.fuel_vol_delta', lower=0.)
        #=======================================================================================
        #=======================================================================================

        # Set up the problem
        prob.setup()

        # from openmdao.api import view_model
        # 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_weight'][0]/1.25)

        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 85033.119351,
                         1e-5)
        assert_rel_error(self, prob['wing.structural_weight'][0] / 1.25,
                         185666.261281, 1e-5)
Пример #2
0
        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.model.connect('alpha', 'AS_point_0' + '.alpha')
prob.model.connect('alpha_maneuver', 'AS_point_1' + '.alpha')

# Here we add the fuel volume constraint componenet to the model
prob.model.add_subsystem('fuel_vol_delta',
                         WingboxFuelVolDelta(surface=surface))
prob.model.connect('wing.struct_setup.fuel_vols', 'fuel_vol_delta.fuel_vols')
prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn')

if surf_dict['distributed_fuel_weight']:
    prob.model.connect('wing.struct_setup.fuel_vols',
                       'AS_point_0.coupled.wing.struct_states.fuel_vols')
    prob.model.connect('fuel_mass',
                       'AS_point_0.coupled.wing.struct_states.fuel_mass')

    prob.model.connect('wing.struct_setup.fuel_vols',
                       'AS_point_1.coupled.wing.struct_states.fuel_vols')
    prob.model.connect('fuel_mass',
                       'AS_point_1.coupled.wing.struct_states.fuel_mass')

comp = ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn', units='kg')
Пример #3
0
        prob.model.connect(name + '.t_over_c', com_name + 't_over_c')

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


#docs checkpoint 17

prob.model.connect('alpha', 'AS_point_0' + '.alpha')
prob.model.connect('alpha_maneuver', 'AS_point_1' + '.alpha')

#docs checkpoint 18

# Here we add the fuel volume constraint componenet to the model
prob.model.add_subsystem('fuel_vol_delta', WingboxFuelVolDelta(surface=surface))
prob.model.connect('wing.struct_setup.fuel_vols', 'fuel_vol_delta.fuel_vols')
prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn')

if surf_dict['distributed_fuel_weight']:
    prob.model.connect('wing.struct_setup.fuel_vols', 'AS_point_0.coupled.wing.struct_states.fuel_vols')
    prob.model.connect('fuel_mass', 'AS_point_0.coupled.wing.struct_states.fuel_mass')

    prob.model.connect('wing.struct_setup.fuel_vols', 'AS_point_1.coupled.wing.struct_states.fuel_vols')
    prob.model.connect('fuel_mass', 'AS_point_1.coupled.wing.struct_states.fuel_mass')

#docs checkpoint 19

comp = om.ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn', units='kg')
prob.model.add_subsystem('fuel_diff', comp,
    promotes_inputs=['fuel_mass'],
    def test(self):

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

        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
            'S_ref_type':
            'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'mesh':
            mesh,
            'twist_cp':
            np.array([4., 5., 8., 8., 8., 9.]),
            'fem_model_type':
            'wingbox',
            'data_x_upper':
            upper_x,
            'data_x_lower':
            lower_x,
            'data_y_upper':
            upper_y,
            'data_y_lower':
            lower_y,
            '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]),
            'original_wingbox_airfoil_t_over_c':
            0.12,

            # Aerodynamic deltas.
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            # They can be used to account for things that are not included, such as contributions from the fuselage, nacelles, tail surfaces, etc.
            'CL0':
            0.0,
            'CD0':
            0.0078,
            'with_viscous':
            True,  # if true, compute viscous drag
            'with_wave':
            True,  # if true, compute wave drag

            # Airfoil properties for viscous drag calculation
            'k_lam':
            0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            'c_max_t':
            .38,  # chordwise location of maximum thickness
            't_over_c_cp':
            np.array([0.08, 0.08, 0.08, 0.10, 0.10, 0.08]),

            # 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
            'wing_weight_ratio':
            1.25,
            'exact_failure_constraint':
            False,  # if false, use KS function
            'struct_weight_relief':
            True,
            'distributed_fuel_weight':
            True,
            'fuel_density':
            803.,  # [kg/m^3] fuel density (only needed if the fuel-in-wing volume constraint is used)
            'Wf_reserve':
            15000.,  # [kg] reserve fuel mass
        }

        surfaces = [surf_dict]

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

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v',
                                  val=np.array([.85 * 295.07, .64 * 340.294]),
                                  units='m/s')
        indep_var_comp.add_output('alpha', val=0., units='deg')
        indep_var_comp.add_output('alpha_maneuver', val=0., units='deg')
        indep_var_comp.add_output('Mach_number', val=np.array([0.85, 0.64]))
        indep_var_comp.add_output('re',val=np.array([0.348*295.07*.85*1./(1.43*1e-5), \
                                  1.225*340.294*.64*1./(1.81206*1e-5)]),  units='1/m')
        indep_var_comp.add_output('rho',
                                  val=np.array([0.348, 1.225]),
                                  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=np.array([295.07, 340.294]),
                                  units='m/s')
        indep_var_comp.add_output('load_factor', val=np.array([1., 2.5]))
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')
        indep_var_comp.add_output('fuel_mass', val=10000., units='kg')

        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 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 aerostruct points
        for i in range(2):

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

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

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v', src_indices=[i])
            prob.model.connect('Mach_number',
                               point_name + '.Mach_number',
                               src_indices=[i])
            prob.model.connect('re', point_name + '.re', src_indices=[i])
            prob.model.connect('rho', point_name + '.rho', src_indices=[i])
            prob.model.connect('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',
                               src_indices=[i])
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor',
                               point_name + '.load_factor',
                               src_indices=[i])
            prob.model.connect('fuel_mass',
                               point_name + '.total_perf.L_equals_W.fuelburn')
            prob.model.connect('fuel_mass',
                               point_name + '.total_perf.CG.fuelburn')

            for surface in surfaces:

                name = surface['name']

                if surf_dict['distributed_fuel_weight']:
                    prob.model.connect('load_factor',
                                       point_name + '.coupled.load_factor',
                                       src_indices=[i])

                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')
                if surf_dict['struct_weight_relief']:
                    prob.model.connect(
                        name + '.element_mass',
                        point_name + '.coupled.' + name + '.element_mass')

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

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

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

        prob.model.connect('alpha', 'AS_point_0' + '.alpha')
        prob.model.connect('alpha_maneuver', 'AS_point_1' + '.alpha')

        # Here we add the fuel volume constraint componenet to the model
        prob.model.add_subsystem('fuel_vol_delta',
                                 WingboxFuelVolDelta(surface=surface))
        prob.model.connect('wing.struct_setup.fuel_vols',
                           'fuel_vol_delta.fuel_vols')
        prob.model.connect('AS_point_0.fuelburn', 'fuel_vol_delta.fuelburn')

        if surf_dict['distributed_fuel_weight']:
            prob.model.connect(
                'wing.struct_setup.fuel_vols',
                'AS_point_0.coupled.wing.struct_states.fuel_vols')
            prob.model.connect(
                'fuel_mass', 'AS_point_0.coupled.wing.struct_states.fuel_mass')

            prob.model.connect(
                'wing.struct_setup.fuel_vols',
                'AS_point_1.coupled.wing.struct_states.fuel_vols')
            prob.model.connect(
                'fuel_mass', 'AS_point_1.coupled.wing.struct_states.fuel_mass')

        comp = ExecComp('fuel_diff = (fuel_mass - fuelburn) / fuelburn')
        prob.model.add_subsystem('fuel_diff',
                                 comp,
                                 promotes_inputs=['fuel_mass'],
                                 promotes_outputs=['fuel_diff'])
        prob.model.connect('AS_point_0.fuelburn', 'fuel_diff.fuelburn')

        ## Use these settings if you do not have pyOptSparse or SNOPT
        prob.driver = ScipyOptimizeDriver()
        prob.driver.options['optimizer'] = 'SLSQP'
        prob.driver.options['tol'] = 1e-8

        recorder = SqliteRecorder("unit_test.db")
        prob.driver.add_recorder(recorder)

        # We could also just use prob.driver.recording_options['includes']=['*'] here, but for large meshes the database file becomes extremely large. So we just select the variables we need.
        prob.driver.recording_options['includes'] = [
            'alpha',
            'rho',
            'v',
            'cg',
            'AS_point_1.cg',
            'AS_point_0.cg',
            'AS_point_0.coupled.wing_loads.loads',
            'AS_point_1.coupled.wing_loads.loads',
            'AS_point_0.coupled.wing.normals',
            'AS_point_1.coupled.wing.normals',
            'AS_point_0.coupled.wing.widths',
            'AS_point_1.coupled.wing.widths',
            'AS_point_0.coupled.aero_states.wing_sec_forces',
            'AS_point_1.coupled.aero_states.wing_sec_forces',
            'AS_point_0.wing_perf.CL1',
            'AS_point_1.wing_perf.CL1',
            'AS_point_0.coupled.wing.S_ref',
            'AS_point_1.coupled.wing.S_ref',
            'wing.geometry.twist',
            'wing.mesh',
            'wing.skin_thickness',
            'wing.spar_thickness',
            'wing.t_over_c',
            'wing.structural_mass',
            'AS_point_0.wing_perf.vonmises',
            'AS_point_1.wing_perf.vonmises',
            'AS_point_0.coupled.wing.def_mesh',
            'AS_point_1.coupled.wing.def_mesh',
        ]

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

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

        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('fuel_mass',
                                  lower=0.,
                                  upper=2e5,
                                  scaler=1e-5)
        prob.model.add_design_var('alpha_maneuver', lower=-15., upper=15)

        prob.model.add_constraint('AS_point_0.CL', equals=0.5)
        prob.model.add_constraint('AS_point_1.L_equals_W', equals=0.)
        prob.model.add_constraint('AS_point_1.wing_perf.failure', upper=0.)

        prob.model.add_constraint('fuel_vol_delta.fuel_vol_delta', lower=0.)
        prob.model.add_constraint('fuel_diff', equals=0.)

        # Set up the problem
        prob.setup()

        prob.run_driver()

        # print(prob['AS_point_0.fuelburn'][0])
        # print(prob['wing.structural_mass'][0]/surf_dict['wing_weight_ratio'])
        # print(prob['wing.geometry.t_over_c_cp'])

        assert_rel_error(self, prob['AS_point_0.fuelburn'][0], 101937.827384,
                         1e-5)
        assert_rel_error(
            self,
            prob['wing.structural_mass'][0] / surf_dict['wing_weight_ratio'],
            36539.6437566, 1e-5)
        assert_rel_error(
            self, prob['wing.geometry.t_over_c_cp'],
            np.array([
                0.10247881, 0.08207636, 0.11114547, 0.13114547, 0.10207636,
                0.09365598
            ]), 1e-5)