def setup(self): nn = self.options['num_nodes'] flight_phase = self.options['flight_phase'] # a propulsion system needs to be defined in order to provide thrust # information for the mission analysis code # propulsion_promotes_outputs = ['fuel_flow', 'thrust'] propulsion_promotes_inputs = ["fltcond|*", "throttle"] self.add_subsystem('propmodel', CFM56(num_nodes=nn, plot=False), promotes_inputs=propulsion_promotes_inputs) doubler = om.ExecComp(['thrust=2*thrust_in', 'fuel_flow=2*fuel_flow_in'], thrust_in={'val': 1.0*np.ones((nn,)), 'units': 'kN'}, thrust={'val': 1.0*np.ones((nn,)), 'units': 'kN'}, fuel_flow={'val': 1.0*np.ones((nn,)), 'units': 'kg/s', 'tags': ['integrate', 'state_name:fuel_used', 'state_units:kg', 'state_val:1.0', 'state_promotes:True']}, fuel_flow_in={'val': 1.0*np.ones((nn,)), 'units': 'kg/s'}) self.add_subsystem('doubler', doubler, promotes_outputs=['*']) self.connect('propmodel.thrust', 'doubler.thrust_in') self.connect('propmodel.fuel_flow', 'doubler.fuel_flow_in') # use a different drag coefficient for takeoff versus cruise if flight_phase not in ['v0v1', 'v1v0', 'v1vr', 'rotate']: cd0_source = 'ac|aero|polar|CD0_cruise' else: cd0_source = 'ac|aero|polar|CD0_TO' self.add_subsystem('drag', PolarDrag(num_nodes=nn), promotes_inputs=['fltcond|CL', 'ac|geom|*', ('CD0', cd0_source), 'fltcond|q', ('e', 'ac|aero|polar|e')], promotes_outputs=['drag']) # generally the weights module will be custom to each airplane passthru = om.ExecComp('OEW=x', x={'val': 1.0, 'units': 'kg'}, OEW={'val': 1.0, 'units': 'kg'}) self.add_subsystem('OEW', passthru, promotes_inputs=[('x', 'ac|weights|OEW')], promotes_outputs=['OEW']) self.add_subsystem('weight', oc.AddSubtractComp(output_name='weight', input_names=['ac|weights|MTOW', 'fuel_used'], units='kg', vec_size=[1, nn], scaling_factors=[1, -1]), promotes_inputs=['*'], promotes_outputs=['weight'])
def test_defaults(self): p = Problem() p.model = CFM56() p.setup(force_alloc_complex=True) p.set_val('throttle', 0.5) p.set_val('fltcond|h', 10e3, units='ft') p.set_val('fltcond|M', 0.5) p.run_model() assert_near_equal(p.get_val('thrust', units='lbf'), 7050.73840869*np.ones(1), tolerance=1e-6) assert_near_equal(p.get_val('fuel_flow', units='kg/s'), 0.50273824*np.ones(1), tolerance=1e-6) assert_near_equal(p.get_val('T4', units='degK'), 1432.06813946*np.ones(1), tolerance=1e-6) partials = p.check_partials(method='cs',compact_print=True) assert_check_partials(partials)
def test_vectorized(self): nn = 5 p = Problem() p.model = CFM56(num_nodes=nn) p.setup(force_alloc_complex=True) p.set_val('throttle', np.linspace(0.0001, 1., nn)) p.set_val('fltcond|h', np.linspace(0, 40e3, nn), units='ft') p.set_val('fltcond|M', np.linspace(0.1, 0.9, nn)) p.run_model() assert_near_equal(p.get_val('thrust', units='lbf'), np.array([1445.41349482, 3961.46624224, 5278.43191982, 5441.44404298, 6479.00525867]), tolerance=5e-3) assert_near_equal(p.get_val('fuel_flow', units='kg/s'), np.array([0.17032429, 0.25496437, 0.35745638, 0.40572545, 0.4924194]), tolerance=5e-3) assert_near_equal(p.get_val('T4', units='degK'), np.array([1005.38911171, 1207.57548728, 1381.94820904, 1508.07901676, 1665.37063872]), tolerance=5e-3) partials = p.check_partials(method='cs',compact_print=True) assert_check_partials(partials)
def setup(self): nn = self.options['num_nodes'] flight_phase = self.options['flight_phase'] # a propulsion system needs to be defined in order to provide thrust # information for the mission analysis code propulsion_promotes_inputs = ["fltcond|*", "throttle"] self.add_subsystem('propmodel', CFM56(num_nodes=nn, plot=False), promotes_inputs=propulsion_promotes_inputs) doubler = om.ExecComp( ['thrust=2*thrust_in', 'fuel_flow=2*fuel_flow_in'], thrust_in={ 'val': 1.0 * np.ones((nn, )), 'units': 'kN' }, thrust={ 'val': 1.0 * np.ones((nn, )), 'units': 'kN' }, fuel_flow={ 'val': 1.0 * np.ones((nn, )), 'units': 'kg/s', 'tags': [ 'integrate', 'state_name:fuel_used', 'state_units:kg', 'state_val:1.0', 'state_promotes:True' ] }, fuel_flow_in={ 'val': 1.0 * np.ones((nn, )), 'units': 'kg/s' }) self.add_subsystem('doubler', doubler, promotes_outputs=['*']) self.connect('propmodel.thrust', 'doubler.thrust_in') self.connect('propmodel.fuel_flow', 'doubler.fuel_flow_in') oas_surf_dict = {} # options for OpenAeroStruct # Grid size and number of spline control points (must be same as B738AnalysisGroup) global NUM_X, NUM_Y, NUM_TWIST, NUM_TOVERC, NUM_SKIN, NUM_SPAR, USE_SURROGATE if USE_SURROGATE: self.add_subsystem( 'drag', OASAerostructDragPolar(num_nodes=nn, num_x=NUM_X, num_y=NUM_Y, num_twist=NUM_TWIST, num_toverc=NUM_TOVERC, num_skin=NUM_SKIN, num_spar=NUM_SPAR, surf_options=oas_surf_dict), promotes_inputs=[ 'fltcond|CL', 'fltcond|M', 'fltcond|h', 'fltcond|q', 'ac|geom|wing|S_ref', 'ac|geom|wing|AR', 'ac|geom|wing|taper', 'ac|geom|wing|c4sweep', 'ac|geom|wing|twist', 'ac|geom|wing|toverc', 'ac|geom|wing|skin_thickness', 'ac|geom|wing|spar_thickness', 'ac|aero|CD_nonwing' ], promotes_outputs=[ 'drag', 'ac|weights|W_wing', ('failure', 'ac|struct|failure') ]) else: self.add_subsystem( 'drag', OASAerostructDragPolarExact(num_nodes=nn, num_x=NUM_X, num_y=NUM_Y, num_twist=NUM_TWIST, num_toverc=NUM_TOVERC, num_skin=NUM_SKIN, num_spar=NUM_SPAR, surf_options=oas_surf_dict), promotes_inputs=[ 'fltcond|CL', 'fltcond|M', 'fltcond|h', 'fltcond|q', 'ac|geom|wing|S_ref', 'ac|geom|wing|AR', 'ac|geom|wing|taper', 'ac|geom|wing|c4sweep', 'ac|geom|wing|twist', 'ac|geom|wing|toverc', 'ac|geom|wing|skin_thickness', 'ac|geom|wing|spar_thickness', 'ac|aero|CD_nonwing' ], promotes_outputs=[ 'drag', 'ac|weights|W_wing', ('failure', 'ac|struct|failure') ]) # generally the weights module will be custom to each airplane passthru = om.ExecComp('OEW=x', x={ 'val': 1.0, 'units': 'kg' }, OEW={ 'val': 1.0, 'units': 'kg' }) self.add_subsystem('OEW', passthru, promotes_inputs=[('x', 'ac|weights|OEW')], promotes_outputs=['OEW']) # Use Raymer as estimate for 737 original wing weight, subtract it # out, then add in OpenAeroStruct wing weight estimate self.add_subsystem('weight', oc.AddSubtractComp(output_name='weight', input_names=[ 'ac|weights|MTOW', 'fuel_used', 'ac|weights|orig_W_wing', 'ac|weights|W_wing' ], units='kg', vec_size=[1, nn, 1, 1], scaling_factors=[1, -1, -1, 1]), promotes_inputs=['*'], promotes_outputs=['weight'])
def setup(self): nn = self.options['num_nodes'] flight_phase = self.options['flight_phase'] # a propulsion system needs to be defined in order to provide thrust # information for the mission analysis code propulsion_promotes_inputs = ["fltcond|*", "throttle"] self.add_subsystem('propmodel', CFM56(num_nodes=nn, plot=False), promotes_inputs=propulsion_promotes_inputs) doubler = om.ExecComp( ['thrust=2*thrust_in', 'fuel_flow=2*fuel_flow_in'], thrust_in={ 'val': 1.0 * np.ones((nn, )), 'units': 'kN' }, thrust={ 'val': 1.0 * np.ones((nn, )), 'units': 'kN' }, fuel_flow={ 'val': 1.0 * np.ones((nn, )), 'units': 'kg/s', 'tags': [ 'integrate', 'state_name:fuel_used', 'state_units:kg', 'state_val:1.0', 'state_promotes:True' ] }, fuel_flow_in={ 'val': 1.0 * np.ones((nn, )), 'units': 'kg/s' }) self.add_subsystem('doubler', doubler, promotes_outputs=['*']) self.connect('propmodel.thrust', 'doubler.thrust_in') self.connect('propmodel.fuel_flow', 'doubler.fuel_flow_in') # use a different drag coefficient for takeoff versus cruise oas_surf_dict = {} # options for OpenAeroStruct oas_surf_dict['t_over_c'] = acdata['ac']['geom']['wing']['toverc'][ 'value'] self.add_subsystem('drag', OASDragPolar(num_nodes=nn, num_x=3, num_y=7, num_twist=3, surf_options=oas_surf_dict), promotes_inputs=[ 'fltcond|CL', 'fltcond|M', 'fltcond|h', 'fltcond|q', 'ac|geom|wing|S_ref', 'ac|geom|wing|AR', 'ac|geom|wing|taper', 'ac|geom|wing|c4sweep', 'ac|geom|wing|twist', 'ac|aero|CD_nonwing' ], promotes_outputs=['drag']) self.set_input_defaults( 'ac|aero|CD_nonwing', 0.0145) # based on matching fuel burn of B738.py example # generally the weights module will be custom to each airplane passthru = om.ExecComp('OEW=x', x={ 'val': 1.0, 'units': 'kg' }, OEW={ 'val': 1.0, 'units': 'kg' }) self.add_subsystem('OEW', passthru, promotes_inputs=[('x', 'ac|weights|OEW')], promotes_outputs=['OEW']) self.add_subsystem('weight', oc.AddSubtractComp( output_name='weight', input_names=['ac|weights|MTOW', 'fuel_used'], units='kg', vec_size=[1, nn], scaling_factors=[1, -1]), promotes_inputs=['*'], promotes_outputs=['weight'])