def setup(self): thermo_data = self.options['thermo_data'] elements = self.options['elements'] use_WAR = self.options['use_WAR'] if use_WAR == True: if 'H' not in elements or 'O' not in elements: raise ValueError( 'The provided elements to FlightConditions do not contain H or O. In order to specify a nonzero WAR the elements must contain both H and O.' ) # inputs if use_WAR == True: mix = ThermoAdd(inflow_thermo_data=thermo_data, mix_thermo_data=thermo_data, inflow_elements=elements, mix_elements='Water') self.add_subsystem('WAR', mix, promotes_inputs=(('Fl_I:stat:W', 'W'), ('mix:ratio', 'WAR')), promotes_outputs=(('composition_out', 'composition'), )) set_TP = Thermo(mode='total_TP', fl_name='Fl_O:tot', method='CEA', thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) in_vars = ('T', 'P', 'composition') self.add_subsystem('totals', set_TP, promotes_inputs=in_vars, promotes_outputs=('Fl_O:tot:*', )) set_stat_MN = Thermo(mode='static_MN', fl_name='Fl_O:stat', method='CEA', thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('exit_static', set_stat_MN, promotes_inputs=('MN', 'W', 'composition'), promotes_outputs=('Fl_O:stat:*', )) self.connect('totals.h', 'exit_static.ht') self.connect('totals.S', 'exit_static.S') self.connect('Fl_O:tot:P', 'exit_static.guess:Pt') self.connect('totals.gamma', 'exit_static.guess:gamt')
def test_mix_2fuel(self): thermo_spec = species_data.janaf air_thermo = species_data.Properties(thermo_spec, init_elements=CEA_AIR_COMPOSITION) p = om.Problem() fuel = 'JP-7' p.model = ThermoAdd(spec=thermo_spec, inflow_composition=CEA_AIR_COMPOSITION, mix_mode='reactant', mix_composition=[fuel, fuel], mix_names=['fuel1', 'fuel2']) p.setup(force_alloc_complex=True) # p['Fl_I:stat:P'] = 158.428 p['Fl_I:stat:W'] = 38.8 p['Fl_I:tot:h'] = 181.381769 p['Fl_I:tot:composition'] = air_thermo.b0 # half the ratio from the 1 fuel test ratio = 0.02673 / 2. p['fuel1:ratio'] = ratio p['fuel2:ratio'] = ratio p.run_model() tol = 5e-7 assert_near_equal(p['mass_avg_h'], 176.65965638, tolerance=tol) assert_near_equal(p['Wout'], 39.837124, tolerance=tol) assert_near_equal(p['fuel1:W'], p['Fl_I:stat:W'] * ratio, tolerance=tol) assert_near_equal(p['fuel2:W'], p['Fl_I:stat:W'] * ratio, tolerance=tol) assert_near_equal(p['composition_out'], np.array([ 0.0003149, 0.00186566, 0.00371394, 0.05251212, 0.01410888 ]), tolerance=tol) data = p.check_partials(out_stream=None, method='fd') # data = p.check_partials(method='cs') assert_check_partials( data, atol=2.e-4, rtol=2.e-4) # can't get very accurate checks with FD
def test_mix_1fuel(self): thermo_spec = species_data.janaf air_thermo = species_data.Properties(thermo_spec, init_elements=AIR_ELEMENTS) p = om.Problem() fuel = 'JP-7' p.model = ThermoAdd(inflow_thermo_data=thermo_spec, mix_thermo_data=thermo_spec, inflow_elements=AIR_ELEMENTS, mix_mode='reactant', mix_elements=fuel, mix_names='fuel') p.setup(force_alloc_complex=True) # p['Fl_I:stat:P'] = 158.428 p['Fl_I:stat:W'] = 38.8 p['Fl_I:tot:h'] = 181.381769 p['Fl_I:tot:composition'] = air_thermo.b0 p['fuel:ratio'] = 0.02673 p.run_model() tol = 5e-7 assert_near_equal(p['mass_avg_h'], 176.65965638, tolerance=tol) assert_near_equal(p['Wout'], 39.837124, tolerance=tol) assert_near_equal(p['fuel:W'], p['Fl_I:stat:W'] * p['fuel:ratio'], tolerance=tol) assert_near_equal(p['composition_out'], np.array([ 0.0003149, 0.00186566, 0.00371394, 0.05251212, 0.01410888 ]), tolerance=tol) # data = p.check_partials(out_stream=None, method='cs') data = p.check_partials(method='cs') assert_check_partials(data, atol=1.e-6, rtol=1.e-6)
def test_mix_2flow(self): thermo_spec = species_data.janaf p = om.Problem() p.model = ThermoAdd( spec=thermo_spec, inflow_composition=CEA_AIR_FUEL_COMPOSITION, mix_mode='flow', mix_composition=[CEA_AIR_COMPOSITION, CEA_AIR_COMPOSITION], mix_names=['mix1', 'mix2']) p.setup(force_alloc_complex=True) p['Fl_I:stat:W'] = 62.15 # p['Fl_I:tot:h'] = 181.381769 p['Fl_I:tot:composition'] = [ 0.000313780313538, 0.0021127831122, 0.004208814234964, 0.052325087161902, 0.014058631311261 ] p['mix1:W'] = 4.44635 / 2 p['mix1:composition'] = [ 3.23319258e-04, 1.10132241e-05, 5.39157736e-02, 1.44860147e-02 ] p['mix2:W'] = 4.44635 / 2 p['mix2:composition'] = [ 3.23319258e-04, 1.10132241e-05, 5.39157736e-02, 1.44860147e-02 ] p.run_model() tol = 5e-7 assert_near_equal(p['Wout'], 62.15 + 4.44635, tolerance=tol) # assert_near_equal(p['composition_out'], np.array([0.0003149, 0.00186566, 0.00371394, 0.05251212, 0.01410888]), tolerance=tol) assert_near_equal(p['composition_out'], np.array([ 0.00031442, 0.00197246, 0.00392781, 0.05243129, 0.01408717 ]), tolerance=tol)
def test_mix_1flow(self): thermo_spec = species_data.janaf p = om.Problem() p.model = ThermoAdd(spec=thermo_spec, inflow_composition=CEA_AIR_FUEL_COMPOSITION, mix_mode='flow', mix_composition=CEA_AIR_COMPOSITION, mix_names='mix') p.setup(force_alloc_complex=True) p['Fl_I:stat:W'] = 62.15 p['Fl_I:tot:composition'] = [ 0.000313780313538, 0.0021127831122, 0.004208814234964, 0.052325087161902, 0.014058631311261 ] p['Fl_I:tot:h'] = 10. p['mix:W'] = 4.44635 p['mix:composition'] = [ 3.23319258e-04, 1.10132241e-05, 5.39157736e-02, 1.44860147e-02 ] p['mix:h'] = 5 p.run_model() tol = 5e-7 assert_near_equal(p['Wout'], 62.15 + 4.44635, tolerance=tol) assert_near_equal(p['composition_out'], np.array([ 0.00031442, 0.00197246, 0.00392781, 0.05243129, 0.01408717 ]), tolerance=tol) assert_near_equal(p['mass_avg_h'], (62.15 * 10 + 4.44635 * 5) / (62.15 + 4.44635), tol)
def test_mix_1flow(self): thermo_spec = species_data.janaf p = om.Problem() p.model = ThermoAdd(inflow_thermo_data=thermo_spec, mix_thermo_data=thermo_spec, inflow_elements=AIR_FUEL_ELEMENTS, mix_mode='flow', mix_elements=AIR_ELEMENTS, mix_names='mix') p.setup(force_alloc_complex=True) p['Fl_I:stat:W'] = 62.15 p['Fl_I:tot:composition'] = [ 0.000313780313538, 0.0021127831122, 0.004208814234964, 0.052325087161902, 0.014058631311261 ] p['mix:W'] = 4.44635 p['mix:composition'] = [ 3.23319258e-04, 1.10132241e-05, 5.39157736e-02, 1.44860147e-02 ] p.run_model() tol = 5e-7 assert_near_equal(p['Wout'], 62.15 + 4.44635, tolerance=tol) # assert_near_equal(p['composition_out'], np.array([0.0003149, 0.00186566, 0.00371394, 0.05251212, 0.01410888]), tolerance=tol) assert_near_equal(p['composition_out'], np.array([ 0.00031442, 0.00197246, 0.00392781, 0.05243129, 0.01408717 ]), tolerance=tol)
def test_war_vals(self): """ verifies that the ThermoAdd component gives the right answers when adding water to dry air """ prob = om.Problem() thermo_spec = species_data.wet_air air_thermo = species_data.Properties(thermo_spec, init_elements=CEA_AIR_COMPOSITION) prob.model.add_subsystem('war', ThermoAdd( spec=thermo_spec, inflow_composition=CEA_AIR_COMPOSITION, mix_composition='Water'), promotes=['*']) prob.setup(force_alloc_complex=True) # p['Fl_I:stat:P'] = 158.428 prob['Fl_I:stat:W'] = 38.8 prob['mix:ratio'] = .0001 # WAR prob['Fl_I:tot:h'] = 181.381769 prob['Fl_I:tot:composition'] = air_thermo.b0 prob.run_model() tol = 1e-5 assert_near_equal(prob['composition_out'][0], 3.23286926e-04, tol) assert_near_equal(prob['composition_out'][1], 1.10121227e-05, tol) assert_near_equal(prob['composition_out'][2], 1.11005769e-05, tol) assert_near_equal(prob['composition_out'][3], 5.39103820e-02, tol) assert_near_equal(prob['composition_out'][4], 1.44901169e-02, tol)
def setup(self): design = self.options['design'] thermo_data = self.options['thermo_data'] flow1_elements = self.options['Fl_I1_elements'] in_flow = FlowIn(fl_name='Fl_I1') self.add_subsystem('in_flow1', in_flow, promotes=['Fl_I1:*']) flow2_elements = self.options['Fl_I2_elements'] in_flow = FlowIn(fl_name='Fl_I2') self.add_subsystem('in_flow2', in_flow, promotes=['Fl_I2:*']) if design: # internal flow station to compute the area that is needed to match the static pressures if self.options['designed_stream'] == 1: Fl1_stat = Thermo(mode='static_Ps', fl_name="Fl_I1_calc:stat", method='CEA', thermo_kwargs={'elements':flow1_elements, 'spec':thermo_data}) self.add_subsystem('Fl_I1_stat_calc', Fl1_stat, promotes_inputs=[('composition', 'Fl_I1:tot:composition'), ('S', 'Fl_I1:tot:S'), ('ht', 'Fl_I1:tot:h'), ('W', 'Fl_I1:stat:W'), ('Ps', 'Fl_I2:stat:P')], promotes_outputs=['Fl_I1_calc:stat*']) self.add_subsystem('area_calc', AreaSum(), promotes_inputs=['Fl_I2:stat:area'], promotes_outputs=[('area_sum', 'area')]) self.connect('Fl_I1_calc:stat:area', 'area_calc.Fl_I1:stat:area') else: Fl2_stat = Thermo(mode='static_Ps', fl_name="Fl_I2_calc:stat", method='CEA', thermo_kwargs={'elements':flow2_elements, 'spec':thermo_data}) self.add_subsystem('Fl_I2_stat_calc', Fl2_stat, promotes_inputs=[('composition', 'Fl_I2:tot:composition'), ('S', 'Fl_I2:tot:S'), ('ht', 'Fl_I2:tot:h'), ('W', 'Fl_I2:stat:W'), ('Ps', 'Fl_I1:stat:P')], promotes_outputs=['Fl_I2_calc:stat:*']) self.add_subsystem('area_calc', AreaSum(), promotes_inputs=['Fl_I1:stat:area'], promotes_outputs=[('area_sum', 'area')]) self.connect('Fl_I2_calc:stat:area', 'area_calc.Fl_I2:stat:area') else: if self.options['designed_stream'] == 1: Fl1_stat = Thermo(mode='static_A', fl_name="Fl_I1_calc:stat", method='CEA', thermo_kwargs={'elements':flow1_elements, 'spec':thermo_data}) self.add_subsystem('Fl_I1_stat_calc', Fl1_stat, promotes_inputs=[('composition', 'Fl_I1:tot:composition'), ('S', 'Fl_I1:tot:S'), ('ht', 'Fl_I1:tot:h'), ('W', 'Fl_I1:stat:W'), ('guess:Pt', 'Fl_I1:tot:P'), ('guess:gamt', 'Fl_I1:tot:gamma')], promotes_outputs=['Fl_I1_calc:stat*']) else: Fl2_stat = Thermo(mode='static_A', fl_name="Fl_I2_calc:stat", method='CEA', thermo_kwargs={'elements':flow2_elements, 'spec':thermo_data}) self.add_subsystem('Fl_I2_stat_calc', Fl2_stat, promotes_inputs=[('composition', 'Fl_I2:tot:composition'), ('S', 'Fl_I2:tot:S'), ('ht', 'Fl_I2:tot:h'), ('W', 'Fl_I2:stat:W'), ('guess:Pt', 'Fl_I2:tot:P'), ('guess:gamt', 'Fl_I2:tot:gamma')], promotes_outputs=['Fl_I2_calc:stat*']) self.add_subsystem('extraction_ratio', om.ExecComp('ER=Pt1/Pt2', Pt1={'units':'Pa'}, Pt2={'units':'Pa'}), promotes_inputs=[('Pt1', 'Fl_I1:tot:P'), ('Pt2', 'Fl_I2:tot:P')], promotes_outputs=['ER']) self.add_subsystem('mix_flow', ThermoAdd(mix_thermo_data=thermo_data, mix_mode='flow', mix_names='mix', inflow_elements=flow1_elements, mix_elements=flow2_elements), promotes_inputs=[('Fl_I:stat:W', 'Fl_I1:stat:W'), ('Fl_I:tot:composition', 'Fl_I1:tot:composition'), ('Fl_I:tot:h', 'Fl_I1:tot:h'), ('mix:W', 'Fl_I2:stat:W'), ('mix:composition', 'Fl_I2:tot:composition'), ('mix:h', 'Fl_I2:tot:h')]) if self.options['designed_stream'] == 1: self.add_subsystem('impulse_mix', MixImpulse(), promotes_inputs=[('Fl_I1:stat:W','Fl_I1_calc:stat:W'), ('Fl_I1:stat:P','Fl_I1_calc:stat:P'), ('Fl_I1:stat:V','Fl_I1_calc:stat:V'), ('Fl_I1:stat:area','Fl_I1_calc:stat:area'), 'Fl_I2:stat:W', 'Fl_I2:stat:P', 'Fl_I2:stat:V', 'Fl_I2:stat:area']) else: self.add_subsystem('impulse_mix', MixImpulse(), promotes_inputs=['Fl_I1:stat:W', 'Fl_I1:stat:P', 'Fl_I1:stat:V', 'Fl_I1:stat:area', ('Fl_I2:stat:W','Fl_I2_calc:stat:W'), ('Fl_I2:stat:P','Fl_I2_calc:stat:P'), ('Fl_I2:stat:V','Fl_I2_calc:stat:V'), ('Fl_I2:stat:area','Fl_I2_calc:stat:area')]) # group to converge for the impulse balance conv = self.add_subsystem('impulse_converge', om.Group(), promotes=['*']) if self.options['internal_solver']: newton = conv.nonlinear_solver = om.NewtonSolver() newton.options['maxiter'] = 30 newton.options['atol'] = 1e-2 newton.options['solve_subsystems'] = True newton.options['max_sub_solves'] = 20 newton.options['reraise_child_analysiserror'] = False newton.linesearch = om.BoundsEnforceLS() newton.linesearch.options['bound_enforcement'] = 'scalar' newton.linesearch.options['iprint'] = -1 conv.linear_solver = om.DirectSolver(assemble_jac=True) out_tot = Thermo(mode='total_hP', fl_name='Fl_O:tot', method='CEA', thermo_kwargs={'elements':self.options['Fl_I1_elements'], 'spec':thermo_data}) conv.add_subsystem('out_tot', out_tot, promotes_outputs=['Fl_O:tot:*']) self.connect('mix_flow.composition_out', 'out_tot.composition') self.connect('mix_flow.mass_avg_h', 'out_tot.h') # note: gets Pt from the balance comp out_stat = Thermo(mode='static_A', fl_name='Fl_O:stat', method='CEA', thermo_kwargs={'elements':self.options['Fl_I1_elements'], 'spec':thermo_data}) conv.add_subsystem('out_stat', out_stat, promotes_outputs=['Fl_O:stat:*'], promotes_inputs=['area', ]) self.connect('mix_flow.composition_out', 'out_stat.composition') self.connect('mix_flow.Wout','out_stat.W') conv.connect('Fl_O:tot:S', 'out_stat.S') self.connect('mix_flow.mass_avg_h', 'out_stat.ht') conv.connect('Fl_O:tot:P', 'out_stat.guess:Pt') conv.connect('Fl_O:tot:gamma', 'out_stat.guess:gamt') conv.add_subsystem('imp_out', Impulse()) conv.connect('Fl_O:stat:P', 'imp_out.P') conv.connect('Fl_O:stat:area', 'imp_out.area') conv.connect('Fl_O:stat:V', 'imp_out.V') conv.connect('Fl_O:stat:W', 'imp_out.W') balance = conv.add_subsystem('balance', om.BalanceComp()) balance.add_balance('P_tot', val=100, units='psi', eq_units='N', lower=1e-3, upper=10000) conv.connect('balance.P_tot', 'out_tot.P') conv.connect('imp_out.impulse', 'balance.lhs:P_tot') self.connect('impulse_mix.impulse_mix', 'balance.rhs:P_tot') #note that this connection comes from outside the convergence group
def setup(self): thermo_method = self.options['thermo_method'] thermo_data = self.options['thermo_data'] elements = self.options['elements'] bleed_elements = self.options['bleed_elements'] map_data = self.options['map_data'] designFlag = self.options['design'] bleeds = self.options['bleed_names'] statics = self.options['statics'] interp_method = self.options['map_interp_method'] map_extrap = self.options['map_extrap'] num_element = len(elements) num_bld_element = len(bleed_elements) # Create inlet flow station in_flow = FlowIn(fl_name='Fl_I') self.add_subsystem('in_flow', in_flow, promotes_inputs=['Fl_I:*']) self.add_subsystem('corrinputs', CorrectedInputsCalc(), promotes_inputs=[ 'Nmech', ('W_in', 'Fl_I:stat:W'), ('Pt', 'Fl_I:tot:P'), ('Tt', 'Fl_I:tot:T') ], promotes_outputs=['Np', 'Wp']) turb_map = TurbineMap(map_data=map_data, design=designFlag, interp_method=interp_method, extrap=map_extrap) if designFlag: self.add_subsystem( 'map', turb_map, promotes_inputs=['Np', 'Wp', 'PR', 'eff'], promotes_outputs=['s_PR', 's_Wp', 's_eff', 's_Np']) else: self.add_subsystem( 'map', turb_map, promotes_inputs=['Np', 'Wp', 's_PR', 's_Wp', 's_eff', 's_Np'], promotes_outputs=['PR', 'eff']) # Calculate pressure drop across turbine self.add_subsystem('press_drop', PressureDrop(), promotes_inputs=['PR', ('Pt_in', 'Fl_I:tot:P')]) # Calculate ideal flow station properties ideal_flow = Thermo(mode='total_SP', method=thermo_method, thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('ideal_flow', ideal_flow, promotes_inputs=[('S', 'Fl_I:tot:S'), ('composition', 'Fl_I:tot:composition')]) self.connect("press_drop.Pt_out", "ideal_flow.P") # # Calculate enthalpy drop across turbine # self.add_subsystem("enth_drop", EnthalpyDrop(), promotes=['eff']) # self.connect("Fl_I:tot:h", "enth_drop.ht_in") # self.connect("ideal_flow.h", "enth_drop.ht_out_ideal") for BN in bleeds: bld_flow = FlowIn(fl_name=BN) self.add_subsystem(BN, bld_flow, promotes_inputs=[f'{BN}:*']) # # Calculate bleed parameters blds = BleedPressure(bleed_names=bleeds) self.add_subsystem('blds', blds, promotes_inputs=[ ('Pt_in', 'Fl_I:tot:P'), ] + [f'{BN}:frac_P' for BN in bleeds]) self.connect('press_drop.Pt_out', 'blds.Pt_out') bleed_element_list = [bleed_elements for name in bleeds] bld_mix = ThermoAdd(mix_thermo_data=thermo_data, inflow_elements=elements, mix_elements=bleed_element_list, mix_names=bleeds, mix_mode='flow') self.add_subsystem( 'bld_mix', bld_mix, promotes_inputs=['Fl_I:stat:W', 'Fl_I:tot:composition'] + [(f'{BN}:W', f'{BN}:stat:W') for BN in bleeds] + [(f'{BN}:composition', f'{BN}:tot:composition') for BN in bleeds], promotes_outputs=[('Wout', 'W_out')]) bleed_names2 = [] for BN in bleeds: # Determine bleed inflow properties bleed_names2.append(BN + '_inflow') inflow = Thermo(mode='total_hP', method=thermo_method, thermo_kwargs={ 'elements': bleed_elements, 'spec': thermo_data }) self.add_subsystem(BN + '_inflow', inflow, promotes_inputs=[('composition', BN + ":tot:composition"), ('h', BN + ':tot:h')]) self.connect(f'blds.{BN}:Pt', f'{BN}_inflow.P') # Ideally expand bleeds to exit pressure bleed_names2.append(f'{BN}_ideal') ideal = Thermo(mode='total_SP', method=thermo_method, thermo_kwargs={ 'elements': bleed_elements, 'spec': thermo_data }) self.add_subsystem(f'{BN}_ideal', ideal, promotes_inputs=[('composition', BN + ":tot:composition")]) self.connect(f"{BN}_inflow.flow:S", f"{BN}_ideal.S") self.connect("press_drop.Pt_out", f"{BN}_ideal.P") # Calculate shaft power and exit enthalpy with cooling flows production self.add_subsystem('pwr_turb', EnthalpyAndPower(bleed_names=bleeds), promotes_inputs=[ 'Nmech', 'eff', 'W_out', ('W_in', 'Fl_I:stat:W'), ('ht_in', 'Fl_I:tot:h') ] + [(BN + ':W', BN + ':stat:W') for BN in bleeds] + [(BN + ':ht', BN + ':tot:h') for BN in bleeds] + [(BN + ':ht_ideal', BN + '_ideal.h') for BN in bleeds], promotes_outputs=['power', 'trq', 'ht_out_b4bld']) self.connect('ideal_flow.h', 'pwr_turb.ht_out_ideal') # Calculate real flow station properties before bleed air is added real_flow_b4bld = Thermo(mode='total_hP', fl_name="Fl_O_b4bld:tot", method=thermo_method, thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('real_flow_b4bld', real_flow_b4bld, promotes_inputs=[('composition', 'Fl_I:tot:composition')]) self.connect('ht_out_b4bld', 'real_flow_b4bld.h') self.connect('press_drop.Pt_out', 'real_flow_b4bld.P') # Calculate Polytropic efficiency self.add_subsystem('eff_poly_calc', eff_poly_calc(), promotes_inputs=[ 'PR', ('S_in', 'Fl_I:tot:S'), ('Rt', 'Fl_I:tot:R') ], promotes_outputs=['eff_poly']) self.connect('real_flow_b4bld.Fl_O_b4bld:tot:S', 'eff_poly_calc.S_out') # Calculate real flow station properties real_flow = Thermo(mode='total_hP', fl_name="Fl_O:tot", method=thermo_method, thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('real_flow', real_flow, promotes_outputs=['Fl_O:tot:*']) self.connect("pwr_turb.ht_out", "real_flow.h") self.connect("press_drop.Pt_out", "real_flow.P") self.connect("bld_mix.composition_out", "real_flow.composition") # Calculate static properties if statics: if designFlag: # SetStaticMN out_stat = Thermo(mode='static_MN', fl_name="Fl_O:stat", method=thermo_method, thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('out_stat', out_stat, promotes_inputs=['MN'], promotes_outputs=['Fl_O:stat:*']) self.connect('bld_mix.composition_out', 'out_stat.composition') self.connect('Fl_O:tot:S', 'out_stat.S') self.connect('Fl_O:tot:h', 'out_stat.ht') self.connect('W_out', 'out_stat.W') self.connect('Fl_O:tot:P', 'out_stat.guess:Pt') self.connect('Fl_O:tot:gamma', 'out_stat.guess:gamt') else: # SetStaticArea out_stat = Thermo(mode='static_A', fl_name="Fl_O:stat", method=thermo_method, thermo_kwargs={ 'elements': elements, 'spec': thermo_data }) self.add_subsystem('out_stat', out_stat, promotes_inputs=['area'], promotes_outputs=['Fl_O:stat:*']) self.connect('bld_mix.composition_out', 'out_stat.composition') self.connect('Fl_O:tot:S', 'out_stat.S') self.connect('Fl_O:tot:h', 'out_stat.ht') self.connect('W_out', 'out_stat.W') self.connect('Fl_O:tot:P', 'out_stat.guess:Pt') self.connect('Fl_O:tot:gamma', 'out_stat.guess:gamt') self.set_order( ['in_flow', 'corrinputs', 'map', 'press_drop', 'ideal_flow'] + bleeds + ['bld_mix', 'blds'] + bleed_names2 + [ 'pwr_turb', 'real_flow_b4bld', 'eff_poly_calc', 'real_flow', 'out_stat' ]) else: self.add_subsystem('W_passthru', PassThrough('W_out', 'Fl_O:stat:W', 1.0, units="lbm/s"), promotes=['*']) self.set_order( ['in_flow', 'corrinputs', 'map', 'press_drop', 'ideal_flow'] + bleeds + ['bld_mix', 'blds'] + bleed_names2 + [ 'pwr_turb', 'real_flow_b4bld', 'eff_poly_calc', 'real_flow', 'W_passthru' ]) self.set_input_defaults('eff', val=0.99, units=None)
def setup(self): thermo_method = self.options['thermo_method'] thermo_data = self.options['thermo_data'] if self.options['inflow_thermo_data'] is not None: # Set the inflow thermodynamic data package if it is different from the outflow one inflow_thermo_data = self.options['inflow_thermo_data'] else: # Set the inflow thermodynamic data package if it is the same as the outflow one inflow_thermo_data = thermo_data inflow_elements = self.options['inflow_elements'] air_fuel_elements = self.options['air_fuel_elements'] design = self.options['design'] statics = self.options['statics'] fuel_type = self.options['fuel_type'] num_air_element = len(inflow_elements) # Create combustor flow station in_flow = FlowIn(fl_name='Fl_I') self.add_subsystem('in_flow', in_flow, promotes=['Fl_I:tot:*', 'Fl_I:stat:*']) # Perform combustor engineering calculations self.add_subsystem('mix_fuel', ThermoAdd(inflow_thermo_data=inflow_thermo_data, mix_thermo_data=thermo_data, inflow_elements=inflow_elements, mix_elements=fuel_type), promotes=[ 'Fl_I:stat:W', ('mix:ratio', 'Fl_I:FAR'), 'Fl_I:tot:composition', 'Fl_I:tot:h', ('mix:W', 'Wfuel'), 'Wout' ]) # Pressure loss prom_in = [('Pt_in', 'Fl_I:tot:P'), 'dPqP'] self.add_subsystem('p_loss', PressureLoss(), promotes_inputs=prom_in) # Calculate vitiated flow station properties vit_flow = Thermo(mode='total_hP', fl_name='Fl_O:tot', method=thermo_method, thermo_kwargs={ 'elements': air_fuel_elements, 'spec': thermo_data }) self.add_subsystem('vitiated_flow', vit_flow, promotes_outputs=['Fl_O:*']) self.connect("mix_fuel.mass_avg_h", "vitiated_flow.h") self.connect("mix_fuel.composition_out", "vitiated_flow.composition") self.connect("p_loss.Pt_out", "vitiated_flow.P") if statics: if design: # Calculate static properties. out_stat = Thermo(mode='static_MN', fl_name='Fl_O:stat', method=thermo_method, thermo_kwargs={ 'elements': air_fuel_elements, 'spec': thermo_data }) prom_in = ['MN'] prom_out = ['Fl_O:stat:*'] self.add_subsystem('out_stat', out_stat, promotes_inputs=prom_in, promotes_outputs=prom_out) self.connect("mix_fuel.composition_out", "out_stat.composition") self.connect('Fl_O:tot:S', 'out_stat.S') self.connect('Fl_O:tot:h', 'out_stat.ht') self.connect('Fl_O:tot:P', 'out_stat.guess:Pt') self.connect('Fl_O:tot:gamma', 'out_stat.guess:gamt') self.connect('Wout', 'out_stat.W') else: # Calculate static properties. out_stat = Thermo(mode='static_A', fl_name='Fl_O:stat', method=thermo_method, thermo_kwargs={ 'elements': air_fuel_elements, 'spec': thermo_data }) prom_in = ['area'] prom_out = ['Fl_O:stat:*'] self.add_subsystem('out_stat', out_stat, promotes_inputs=prom_in, promotes_outputs=prom_out) self.connect("mix_fuel.composition_out", "out_stat.composition") self.connect('Fl_O:tot:S', 'out_stat.S') self.connect('Fl_O:tot:h', 'out_stat.ht') self.connect('Fl_O:tot:P', 'out_stat.guess:Pt') self.connect('Fl_O:tot:gamma', 'out_stat.guess:gamt') self.connect('Wout', 'out_stat.W') else: self.add_subsystem('W_passthru', PassThrough('Wout', 'Fl_O:stat:W', 1.0, units="lbm/s"), promotes=['*'])
def setup(self): self.add_subsystem('cooling_calcs', CoolingCalcs(n_stages=self.options['n_stages'], i_row=self.options['i_row'], T_safety=self.options['T_safety'], T_metal=self.options['T_metal']), promotes_inputs=[ 'Pt_in', 'Pt_out', 'W_primary', 'Tt_primary', 'Tt_cool', 'ht_primary', 'ht_cool', 'x_factor', 'turb_pwr' ], promotes_outputs=['W_cool']) consts = self.add_subsystem( 'consts', om.IndepVarComp()) # values that should not be changed ever consts.add_output('bld_frac_P', val=1) # self.add_subsystem('mix_n', Bleeds(thermo_data=self.options['thermo_data'], # main_flow_elements=AIR_FUEL_ELEMENTS, # bld_flow_elements=AIR_ELEMENTS, # bleed_names=['cool'] # ), # promotes_inputs=['Pt_in', 'Pt_out', ('W_in','W_primary'), ('n_in', 'n_primary'), ('cool:n', 'n_cool')], # promotes_outputs=['W_out']) self.add_subsystem( 'mix_n', ThermoAdd(mix_thermo_data=self.options['thermo_data'], inflow_elements=AIR_FUEL_ELEMENTS, mix_mode='flow', mix_elements=AIR_ELEMENTS, mix_names='cool'), promotes_inputs=[('Fl_I:stat:W', 'W_primary'), ('Fl_I:tot:composition', 'composition_primary'), 'cool:composition'], promotes_outputs=[ ('Wout', 'W_out'), ]) mixed_flow = Thermo(mode='total_hP', fl_name='Fl_O:tot', method='CEA', thermo_kwargs={ 'elements': AIR_FUEL_ELEMENTS, 'spec': self.options['thermo_data'] }) self.add_subsystem('mixed_flow', mixed_flow, promotes_outputs=['Fl_O:tot:*']) # promoted # self.connect('', 'mix_n.Pt_in') # self.connect('', 'mix_n.Pt_out') # self.connect('', 'mix_n.W_primary') # self.connect('', 'mix_n.n_in') # self.connect('', 'mix_n.cool:n') self.connect('W_cool', 'mix_n.cool:W') # self.connect('consts.bld_frac_P', 'mix_n.cool:frac_P') self.connect('mix_n.composition_out', 'mixed_flow.composition') self.connect('cooling_calcs.ht_out', 'mixed_flow.h') self.connect('cooling_calcs.Pt_stage', 'mixed_flow.P')