def setUp(self): """Initialization function called before every test function""" self.fs = FlowStation() self.fs.W = 100 self.fs.setDryAir() self.fs.setTotalTP(518, 15)
def test_copyFS(self): #print "TESTING" self.new_fs = FlowStation() self.new_fs.copy_from(self.fs) assert_rel_error(self, self.new_fs.Tt, 518, .0001) assert_rel_error(self, self.new_fs.Pt, 15, .0001)
def testMN(self): self.fs = FlowStation() self.fs.setReactant(6) self.fs.W = 100 self.fs.setTotalTP(5000, 540) self.fs.Mach = 3. assert_rel_error(self, self.fs.Mach, 3., .0001) assert_rel_error(self, self.fs.Ts, 2052.78, .0001) assert_rel_error(self, self.fs.Ps, 13.032, .0001) assert_rel_error(self, self.fs.Vflow, 24991.2, .0001) assert_rel_error(self, self.fs.rhos, .001192, .0001) assert_rel_error(self, self.fs.gams, 1.370663, .0001)
class HotH2(unittest.TestCase): def testMN( self ): self.fs = FlowStation() self.fs.setReactant(6) self.fs.W = 100 self.fs.setTotalTP( 5000, 540 ); self.fs.Mach = 3. assert_rel_error(self,self.fs.Mach, 3., .0001) assert_rel_error(self,self.fs.Ts, 2052.78, .0001) assert_rel_error(self,self.fs.Ps, 13.032, .0001) assert_rel_error(self,self.fs.Vflow, 24991.2, .0001) assert_rel_error(self,self.fs.rhos, .001192, .0001) assert_rel_error(self,self.fs.gams, 1.370663, .0001)
def test_add(self): self.fs1 = FlowStation() self.fs1.setDryAir() self.fs1.setTotalTP(1100, 15) self.fs1.W = 100. self.fs1.setWAR(.02) self.fs1.setTotalTP(1100, 400) self.fs.add(self.fs1) assert_rel_error(self, self.fs.Tt, 1932.471, .0001) assert_rel_error(self, self.fs.W, 202.5, .0001) assert_rel_error(self, self.fs.FAR, .012623, .001) assert_rel_error(self, self.fs.Pt, 400, .001) assert_rel_error(self, self.fs.ht, 71.83056, .0001) assert_rel_error(self, self.fs.gamt, 1.3200, .0001) assert_rel_error(self, self.fs.WAR, .00990099, .0001)
def execute(self): Fl_I = self.Fl_I Fl_O = self.Fl_O Fl_O.copy_from( Fl_I ) Fl_bld1 = self.Fl_bld1 Fl_bld1.copy_from( Fl_I ) Fl_bld2 = self.Fl_bld2 Fl_bld2.copy_from( Fl_I ) FO_ideal = FlowStation() FO_ideal.copy_from( Fl_I ) PtOut = Fl_I.Pt*self.PR FO_ideal.setTotalSP( Fl_I.s,PtOut ) htOut = Fl_I.ht + ( FO_ideal.ht - Fl_I.ht )/self.eff # set the exit conditions to knowm enthalpy and pressure Fl_O.setTotalTP( 518, 15 ) Fl_O.setTotal_hP( htOut, PtOut ) # set the condtions for bleed 1 Wbleed1 = self.Wfrac1*Fl_I.W htBleed1 = Fl_I.ht+ self.hfrac1*( Fl_O.ht - Fl_I.ht ) PtBleed1 = Fl_I.Pt + self.Pfrac1*( Fl_O.Pt - Fl_I.Pt ) Fl_bld1.setTotal_hP( htBleed1,PtBleed1 ) Fl_bld1.W = Wbleed1 # set the conditions for bleed 2 Wbleed2 = self.Wfrac2*Fl_I.W; htBleed2 = Fl_I.ht+ self.hfrac2*( Fl_O.ht - Fl_I.ht) PtBleed2 = Fl_I.Pt + self.Pfrac2*( Fl_O.Pt - Fl_I.Pt ) Fl_bld2.setTotal_hP( htBleed2,PtBleed2 ) Fl_bld2.W = Wbleed2 # subtract the bleed flow from the exit flow Wout = Fl_I.W - Fl_bld1.W - Fl_bld2.W Fl_O.W = Wout # determine the power self.pwr = Fl_I.W * ( Fl_I.ht - Fl_O.ht ) * 1.4148; self.pwr = self.pwr - Fl_bld1.W*(Fl_bld1.ht-Fl_O.ht)*1.4148 - Fl_bld2.W*(Fl_bld2.ht-Fl_O.ht)*1.4148 self.trq = 550. * self.pwr / self.Nmech;
def test_copyFS(self): #print "TESTING" self.new_fs = FlowStation() self.new_fs.copy_from(self.fs) assert_rel_error(self,self.new_fs.Tt, 518, .0001) assert_rel_error(self,self.new_fs.Pt, 15, .0001)
def configure(self): hx = self.add('hx', HeatExchanger()) driver = self.add('driver',BroydenSolver()) driver.add_parameter('hx.T_hot_out',low=0.,high=1000.) driver.add_parameter('hx.T_cold_out',low=0.,high=1000.) driver.add_constraint('hx.residual_qmax=0') driver.add_constraint('hx.residual_e_balance=0') #hx.Wh = 0.49 #hx.Cp_hot = 1.006 #hx.T_hot_in = 791 fs = FlowStation() fs.setTotalTP(1423.8, 0.302712118187) #R, psi fs.W = 1.0 hx.Fl_I = fs hx.W_cold = .45 hx.T_hot_out = hx.Fl_I.Tt hx.T_cold_out = hx.T_cold_in driver.workflow.add(['hx'])
def execute(self): Fl_I = self.Fl_I Fl_O = self.Fl_O fs_ideal = FlowStation() Fl_O.W = Fl_I.W if self.run_design: #Design Calculations Pt_out = self.Fl_I.Pt * self.PR_des self.PR = self.PR_des fs_ideal.setTotalSP(Fl_I.s, Pt_out) ht_out = (fs_ideal.ht - Fl_I.ht) / self.eff_des + Fl_I.ht Fl_O.setTotal_hP(ht_out, Pt_out) Fl_O.Mach = self.MNexit_des self._exit_area_des = Fl_O.area self._Wc_des = Fl_I.Wc else: #Assumed Op Line Calculation self.PR = self._op_line(Fl_I.Wc) self.eff = self.eff_des #TODO: add in eff variation with W #Operational Conditions Pt_out = Fl_I.Pt * self.PR fs_ideal.setTotalSP(Fl_I.s, Pt_out) ht_out = (fs_ideal.ht - Fl_I.ht) / self.eff + Fl_I.ht Fl_O.setTotal_hP(ht_out, Pt_out) Fl_O.area = self._exit_area_des #causes Mach to be calculated based on fixed area C = GAS_CONSTANT * math.log(self.PR) delta_s = Fl_O.s - Fl_I.s self.eff_poly = C / (C + delta_s) self.pwr = Fl_I.W * (Fl_O.ht - Fl_I.ht) * 1.4148532 #btu/s to hp self.tip_radius = (Fl_O.area / math.pi / (1 - self.hub_to_tip**2))**.5 self.hub_radius = self.hub_to_tip * self.tip_radius
def execute(self): Fl_I = self.Fl_I Fl_O = self.Fl_O fs_ideal = FlowStation() Fl_O.W = Fl_I.W if self.run_design: #Design Calculations Pt_out = self.Fl_I.Pt*self.PR_des self.PR = self.PR_des fs_ideal.setTotalSP(Fl_I.s, Pt_out) ht_out = (fs_ideal.ht-Fl_I.ht)/self.eff_des + Fl_I.ht Fl_O.setTotal_hP(ht_out, Pt_out) Fl_O.Mach = self.MNexit_des self._exit_area_des = Fl_O.area self._Wc_des = Fl_I.Wc else: #Assumed Op Line Calculation self.PR = self._op_line(Fl_I.Wc) self.eff = self.eff_des #TODO: add in eff variation with W #Operational Conditions Pt_out = Fl_I.Pt*self.PR fs_ideal.setTotalSP(Fl_I.s, Pt_out) ht_out = (fs_ideal.ht-Fl_I.ht)/self.eff + Fl_I.ht Fl_O.setTotal_hP(ht_out, Pt_out) Fl_O.area = self._exit_area_des #causes Mach to be calculated based on fixed area C = GAS_CONSTANT*math.log(self.PR) delta_s = Fl_O.s - Fl_I.s self.eff_poly = C/(C+delta_s) self.pwr = Fl_I.W*(Fl_O.ht - Fl_I.ht) * 1.4148532 #btu/s to hp self.tip_radius = (Fl_O.area/math.pi/(1-self.hub_to_tip**2))**.5 self.hub_radius = self.hub_to_tip*self.tip_radius
def test_add( self ): self.fs1 = FlowStation() self.fs1.setDryAir() self.fs1.setTotalTP(1100, 15) self.fs1.W = 100. self.fs1.setWAR( .02 ) self.fs1.setTotalTP(1100, 400) self.fs.add( self.fs1 ) assert_rel_error(self,self.fs.Tt, 1932.471, .0001) assert_rel_error(self,self.fs.W, 202.5, .0001) assert_rel_error(self,self.fs.FAR, .012623, .001) assert_rel_error(self,self.fs.Pt, 400, .001) assert_rel_error(self,self.fs.ht, 71.83056, .0001) assert_rel_error(self,self.fs.gamt, 1.3200, .0001) assert_rel_error(self,self.fs.WAR, .00990099, .0001)
def test_copy_flow(self): a = set_as_top(Assembly()) a.add('comp1', DummyComp()) a.add('comp2', DummyComp()) a.connect('comp1.Fl_O', 'comp2.Fl_I') a.driver.workflow.add(['comp1', 'comp2']) fs = FlowStation() fs.W = 100 fs.setDryAir() fs.setTotalTP(518, 15) a.comp1.Fl_I = fs a.run()
def execute(self): fs_tube = self.fs_tube = FlowStation() tube_rad = cu(self.radius_tube, 'cm', 'ft') #convert to ft inlet_rad = cu(self.radius_inlet, 'cm', 'ft') #A = pi(r^2) self._tube_area = pi * (tube_rad**2) #ft**2 self._inlet_area = pi * (inlet_rad**2) #ft**2 self._bypass_area = self._tube_area - self._inlet_area self._Ts = cu(self.Ts_tube, 'degK', 'degR') #convert to R self._Ps = cu(self.Ps_tube, 'Pa', 'psi') #convert to psi area_ratio_target = self._tube_area / self._bypass_area #iterate over pod speed until the area ratio = A_tube / A_bypass def f(m_guess): fs_tube.setStaticTsPsMN( self._Ts, self._Ps, m_guess ) #set the static conditions iteratively until correct (Ts, Ps are known) gam = fs_tube.gamt g_exp = (gam + 1) / (2 * (gam - 1)) ar = ((gam + 1) / 2)**(-1 * g_exp) * ( (1 + (gam - 1) / 2 * m_guess**2)**g_exp) / m_guess return ar - area_ratio_target #Solve for Mach where AR = AR_target self.limit_Mach = secant( f, .3, x_min=0, x_max=1 ) #value not actually needed, fs_tube contains necessary flow information self.limit_speed = cu(fs_tube.Vflow, 'ft', 'm') #convert to meters/second #excess mass flow calculation fs_tube.setStaticTsPsMN(self._Ts, self._Ps, self.Mach_pod) self.W_tube = cu(fs_tube.rhos * fs_tube.Vflow * self._tube_area, 'lbm', 'kg') #convert to kg/sec fs_tube.Mach = self.Mach_bypass #Kantrowitz flow is at these total conditions, but with Mach 1 self.W_kant = cu(fs_tube.rhos * fs_tube.Vflow * self._bypass_area, 'lbm', 'kg') #convert to kg/sec #print "test", fs_tube.rhos, fs_tube.Vflow, self._bypass_area, self.W_kant self.W_excess = self.W_tube - self.W_kant
class TestStatics(unittest.TestCase): def setUp(self): self.fs = FlowStation() self.fs.W = 100. self.fs.setDryAir() self.fs.setTotalTP(1100, 400) #print (self.fs._flow) #all test cases use the same checks here, so just re-use def _assert(self): assert_rel_error(self,self.fs.area, 32.006, .0001) assert_rel_error(self,self.fs.Mach, .3, .0001) assert_rel_error(self,self.fs.Ps, 376.194, .0001) assert_rel_error(self,self.fs.Ts, 1081.781, .0001) assert_rel_error(self,self.fs.Vflow, 479.519, .0001) assert_rel_error(self,self.fs.rhos, .93826, .0001) assert_rel_error(self,self.fs.gams, 1.37596, .0001) def test_set_Mach(self): self.fs.Mach = .3 self._assert() def test_set_area(self): self.fs.area = 32.006 self.assertLess(self.fs.Mach, 1) self._assert() def test_set_Ps(self): self.fs.Ps = 376.194 self._assert() def test_setStaticTsPsMN(self): self.fs.setStaticTsPsMN(1081.802, 376.219, .3) self._assert() def test_set_sub(self): self.fs.sub_or_super = "sub" self.fs.area = 32 self.assertLess(self.fs.Mach, 1) def test_set_super(self): self.fs.sub_or_super = "super" self.fs.area = 32 self.assertGreater(self.fs.Mach, 1)
class TestStatics(unittest.TestCase): def setUp(self): self.fs = FlowStation() self.fs.W = 100. self.fs.setDryAir() self.fs.setTotalTP(1100, 400) #print (self.fs._flow) #all test cases use the same checks here, so just re-use def _assert(self): assert_rel_error(self, self.fs.area, 32.006, .0001) assert_rel_error(self, self.fs.Mach, .3, .0001) assert_rel_error(self, self.fs.Ps, 376.194, .0001) assert_rel_error(self, self.fs.Ts, 1081.781, .0001) assert_rel_error(self, self.fs.Vflow, 479.519, .0001) assert_rel_error(self, self.fs.rhos, .93826, .0001) assert_rel_error(self, self.fs.gams, 1.37596, .0001) def test_set_Mach(self): self.fs.Mach = .3 self._assert() def test_set_area(self): self.fs.area = 32.006 self.assertLess(self.fs.Mach, 1) self._assert() def test_set_Ps(self): self.fs.Ps = 376.194 self._assert() def test_setStaticTsPsMN(self): self.fs.setStaticTsPsMN(1081.802, 376.219, .3) self._assert() def test_set_sub(self): self.fs.sub_or_super = "sub" self.fs.area = 32 self.assertLess(self.fs.Mach, 1) def test_set_super(self): self.fs.sub_or_super = "super" self.fs.area = 32 self.assertGreater(self.fs.Mach, 1)
def execute(self): Fl_I = self.Fl_I Fl_O = self.Fl_O Fl_ref = self.Fl_ref fs_throat = FlowStation() fs_exitIdeal = FlowStation() fs_throat.W = Fl_I.W Pt_out = (1 - self.dPqP) * Fl_I.Pt fs_throat.setTotalTP(Fl_I.Tt, Pt_out) fs_throat.Mach = 1.0 self.Athroat_dmd = fs_throat.area fs_exitIdeal.W = Fl_I.W fs_exitIdeal.setTotalTP(Fl_I.Tt, Pt_out) fs_exitIdeal.Ps = Fl_ref.Ps Fl_O.W = Fl_I.W Fl_O.setTotalTP(Fl_I.Tt, Pt_out) Fl_O.Mach = fs_exitIdeal.Mach if self.run_design: # Design Calculations at throat self.Athroat_des = fs_throat.area # Design calculations at exit self.Aexit_des = fs_exitIdeal.area self.switchRegime = "PERFECTLY_EXPANDED" else: # Find subsonic solution, curve 4 Fl_O.sub_or_super = "sub" Fl_O.area = self.Aexit_des MachSubsonic = Fl_O.Mach if MachSubsonic > 1: print "invalid nozzle subsonic solution" PsSubsonic = Fl_O.Ps # Find supersonic solution, curve 5 Fl_O.sub_or_super = "super" Fl_O.area = self.Aexit_des MachSupersonic = Fl_O.Mach PsSupersonic = Fl_O.Ps # normal shock at nozzle exit, curve c Fl_O.sub_or_super = "sub" Msuper = MachSupersonic PtExit = self.shockPR(Msuper, fs_throat.gams) * fs_throat.Pt Fl_O.setTotalTP(fs_throat.Tt, PtExit) Fl_O.area = self.Aexit_des PsShock = Fl_O.Ps # find correct operating regime # curves 1 to 4 if Fl_ref.Ps >= PsSubsonic: self.switchRegime = "UNCHOKED" fs_throat.sub_or_super = "sub" Fl_O.sub_or_super = "sub" fs_throat.area = self.Athroat_des Fl_O.setTotalTP(fs_throat.Tt, fs_throat.Pt) Fl_O.area = self.Aexit_des # between curves 4 and c elif Fl_ref.Ps < PsSubsonic and Fl_ref.Ps >= PsShock: self.switchRegime = "NORMAL_SHOCK" Fl_O.sub_or_super = "sub" Fl_O.Ps = Fl_ref.Ps # between curves c and 5 elif Fl_ref.Ps < PsShock and Fl_ref.Ps > PsSupersonic: self.switchRegime = "OVEREXPANDED" Fl_O.sub_or_super = "super" Fl_O.setTotalTP(fs_throat.Tt, fs_throat.Pt) Fl_O.area = self.Aexit_des # between curves 5 and e elif Fl_ref.Ps <= PsSupersonic: self.switchRegime = "UNDEREXPANDED" Fl_O.sub_or_super = "super" Fl_O.setTotalTP(fs_throat.Tt, fs_throat.Pt) Fl_O.area = self.Aexit_des if abs(Fl_ref.Ps - PsSupersonic) / Fl_ref.Ps < .001: self.switchRegime = "PERFECTLY_EXPANDED" self.Fg = Fl_O.W * Fl_O.Vflow / 32.174 + Fl_O.area * (Fl_O.Ps - Fl_ref.Ps) self.PR = fs_throat.Pt / Fl_O.Ps self.AR = Fl_O.area / fs_throat.area self.WqAexit = Fl_I.W / self.Athroat_des self.WqAexit_dmd = Fl_I.W / self.Athroat_dmd if self.switchRegime == "UNCHOKED": self.WqAexit = Fl_I.W / Fl_ref.Ps self.WqAexit_dmd = Fl_I.W / Fl_O.Ps
class FlowStationTestCase(unittest.TestCase): def setUp(self): """Initialization function called before every test function""" self.fs = FlowStation() self.fs.W = 100 self.fs.setDryAir() self.fs.setTotalTP(518, 15) def tearDown(self): """Clean up function called after every test function""" pass #nothing to do for this test def test_copyFS(self): #print "TESTING" self.new_fs = FlowStation() self.new_fs.copy_from(self.fs) assert_rel_error(self, self.new_fs.Tt, 518, .0001) assert_rel_error(self, self.new_fs.Pt, 15, .0001) #all test function have to start with "test_" as the function name def test_setTotalTP(self): self.assertAlmostEqual(self.fs.Pt, 15.0, places=2) self.assertAlmostEqual(self.fs.Tt, 518, places=2) self.assertAlmostEqual( self.fs.ht, -6.32357, places=4) #Tom says the ht values will be different self.assertAlmostEqual(self.fs.W, 100, places=2) self.assertAlmostEqual(self.fs.rhot, .07812, places=4) def test_setTotal_hP(self): ht = self.fs.ht self.fs.setTotalTP(1000, 40) #just to move things around a bit self.fs.setTotal_hP(ht, 15) self.test_setTotalTP( ) #just call this since it has all the checks we need def test_setTotal_SP(self): s = self.fs.s self.fs.setTotalTP(1000, 40) #just to move things around a bit self.fs.setTotalSP(s, 15) self.test_setTotalTP( ) #just call this since it has all the checks we need def test_delh(self): ht = self.fs.ht self.fs.setTotalTP(1000, 40) diffh = self.fs.ht - ht assert_rel_error(self, diffh, 117.4544, .0001) def test_dels(self): s = self.fs.s self.fs.setTotalTP(1000, 40) diffs = self.fs.s - s assert_rel_error(self, diffs, .092609, .0001) def test_set_WAR(self): self.fs.setWAR(0.02) self.fs.setTotalTP(1000, 15) assert_rel_error(self, self.fs.Pt, 15., .0001) assert_rel_error(self, self.fs.Tt, 1000, .0001) assert_rel_error(self, self.fs.WAR, 0.02, .0001) assert_rel_error(self, self.fs.FAR, 0, .0001) assert_rel_error(self, self.fs.ht, -.11513, .0001) def test_setDryAir(self): self.fs.setDryAir() self.fs.setTotalTP(1000, 15) assert_rel_error(self, self.fs.Pt, 15., .0001) assert_rel_error(self, self.fs.Tt, 1000, .0001) assert_rel_error(self, self.fs.WAR, 0.0, .0001) assert_rel_error(self, self.fs.FAR, 0, .0001) assert_rel_error(self, self.fs.ht, 111.129, .0001) assert_rel_error(self, self.fs.WAR, 0, .0001) assert_rel_error(self, self.fs.FAR, 0, .0001)
def setUp(self): self.fs = FlowStation() self.fs.W = 100. self.fs.setDryAir() self.fs.setTotalTP(1100, 400)
class FlowStationTestCase(unittest.TestCase): def setUp(self): """Initialization function called before every test function""" self.fs = FlowStation() self.fs.W = 100 self.fs.setDryAir() self.fs.setTotalTP(518, 15) def tearDown(self): """Clean up function called after every test function""" pass #nothing to do for this test def test_copyFS(self): #print "TESTING" self.new_fs = FlowStation() self.new_fs.copy_from(self.fs) assert_rel_error(self,self.new_fs.Tt, 518, .0001) assert_rel_error(self,self.new_fs.Pt, 15, .0001) #all test function have to start with "test_" as the function name def test_setTotalTP(self): self.assertAlmostEqual(self.fs.Pt, 15.0, places=2) self.assertAlmostEqual(self.fs.Tt, 518, places=2) self.assertAlmostEqual(self.fs.ht, -6.32357, places=4) #Tom says the ht values will be different self.assertAlmostEqual(self.fs.W, 100, places=2) self.assertAlmostEqual(self.fs.rhot, .07812, places=4) def test_setTotal_hP(self): ht = self.fs.ht self.fs.setTotalTP(1000, 40) #just to move things around a bit self.fs.setTotal_hP(ht, 15) self.test_setTotalTP() #just call this since it has all the checks we need def test_setTotal_SP(self): s = self.fs.s self.fs.setTotalTP(1000, 40) #just to move things around a bit self.fs.setTotalSP(s, 15) self.test_setTotalTP() #just call this since it has all the checks we need def test_delh(self): ht = self.fs.ht self.fs.setTotalTP(1000, 40) diffh = self.fs.ht - ht assert_rel_error(self,diffh, 117.4544, .0001) def test_dels(self): s = self.fs.s self.fs.setTotalTP(1000, 40) diffs = self.fs.s - s assert_rel_error(self,diffs, .092609, .0001) def test_set_WAR(self): self.fs.setWAR( 0.02 ) self.fs.setTotalTP(1000, 15); assert_rel_error(self,self.fs.Pt, 15., .0001) assert_rel_error(self,self.fs.Tt, 1000, .0001) assert_rel_error(self,self.fs.WAR, 0.02, .0001) assert_rel_error(self,self.fs.FAR, 0, .0001) assert_rel_error(self,self.fs.ht, -.11513, .0001) def test_setDryAir(self): self.fs.setDryAir() self.fs.setTotalTP(1000, 15); assert_rel_error(self,self.fs.Pt, 15.,.0001) assert_rel_error(self,self.fs.Tt, 1000, .0001) assert_rel_error(self,self.fs.WAR, 0.0, .0001) assert_rel_error(self,self.fs.FAR, 0, .0001) assert_rel_error(self,self.fs.ht, 111.129, .0001) assert_rel_error(self,self.fs.WAR, 0, .0001) assert_rel_error(self,self.fs.FAR, 0, .0001)
def setUp(self): self.fs = FlowStation() self.fs.setDryAir() self.fs.setTotalTP(1100, 400) self.fs.W = 100 self.fs.burn(4, 2.5, -642)
class TestBurn(unittest.TestCase): def setUp(self): self.fs = FlowStation() self.fs.setDryAir() self.fs.setTotalTP(1100, 400) self.fs.W = 100 self.fs.burn(4, 2.5, -642) #all test cases use the same checks here, so just re-use def _assert(self): #print (self.fs._flow) assert_rel_error(self,self.fs.W, 102.5, places=2) assert_rel_error(self, self.fs.FAR, .025, .0001) assert_rel_error(self, self.fs.Pt, 400, .0001) assert_rel_error(self, self.fs.Tt, 2669.69, .0001) assert_rel_error(self, self.fs.ht, 117.171, .0001) assert_rel_error(self, self.fs.rhot, .404265, .0001) assert_rel_error(self, self.fs.W, 102.5, .0001) assert_rel_error(self, self.fs.gamt, 1.293336, .0001) def test_burn(self): self._assert() def test_add(self): self.fs1 = FlowStation() self.fs1.setDryAir() self.fs1.setTotalTP(1100, 15) self.fs1.W = 100. self.fs1.setWAR(.02) self.fs1.setTotalTP(1100, 400) self.fs.add(self.fs1) assert_rel_error(self, self.fs.Tt, 1932.471, .0001) assert_rel_error(self, self.fs.W, 202.5, .0001) assert_rel_error(self, self.fs.FAR, .012623, .001) assert_rel_error(self, self.fs.Pt, 400, .001) assert_rel_error(self, self.fs.ht, 71.83056, .0001) assert_rel_error(self, self.fs.gamt, 1.3200, .0001) assert_rel_error(self, self.fs.WAR, .00990099, .0001)
class TestBurn(unittest.TestCase): def setUp(self): self.fs = FlowStation() self.fs.setDryAir() self.fs.setTotalTP(1100, 400) self.fs.W = 100 self.fs.burn(4,2.5, -642) #all test cases use the same checks here, so just re-use def _assert(self): #print (self.fs._flow) assert_rel_error(self,self.fs.W, 102.5, places=2) assert_rel_error(self,self.fs.FAR, .025, .0001) assert_rel_error(self,self.fs.Pt, 400, .0001) assert_rel_error(self,self.fs.Tt, 2669.69, .0001) assert_rel_error(self,self.fs.ht, 117.171, .0001) assert_rel_error(self,self.fs.rhot, .404265, .0001) assert_rel_error(self,self.fs.W, 102.5, .0001) assert_rel_error(self,self.fs.gamt, 1.293336, .0001) def test_burn(self): self._assert() def test_add( self ): self.fs1 = FlowStation() self.fs1.setDryAir() self.fs1.setTotalTP(1100, 15) self.fs1.W = 100. self.fs1.setWAR( .02 ) self.fs1.setTotalTP(1100, 400) self.fs.add( self.fs1 ) assert_rel_error(self,self.fs.Tt, 1932.471, .0001) assert_rel_error(self,self.fs.W, 202.5, .0001) assert_rel_error(self,self.fs.FAR, .012623, .001) assert_rel_error(self,self.fs.Pt, 400, .001) assert_rel_error(self,self.fs.ht, 71.83056, .0001) assert_rel_error(self,self.fs.gamt, 1.3200, .0001) assert_rel_error(self,self.fs.WAR, .00990099, .0001)
def setUp(self): self.fs = FlowStation() self.fs.setDryAir() self.fs.setTotalTP(1100, 400) self.fs.W = 100 self.fs.burn(4,2.5, -642)
def execute(self): Fl_I = self.Fl_I Fl_O = self.Fl_O Fl_ref = self.Fl_ref fs_throat = FlowStation() fs_exitIdeal = FlowStation() fs_throat.W = Fl_I.W Pt_out = (1-self.dPqP)*Fl_I.Pt fs_throat.setTotalTP( Fl_I.Tt, Pt_out ) fs_throat.Mach = 1.0 self.Athroat_dmd = fs_throat.area fs_exitIdeal.W = Fl_I.W fs_exitIdeal.setTotalTP( Fl_I.Tt, Pt_out ) fs_exitIdeal.Ps = Fl_ref.Ps Fl_O.W = Fl_I.W Fl_O.setTotalTP( Fl_I.Tt, Pt_out ) Fl_O.Mach = fs_exitIdeal.Mach if self.run_design: # Design Calculations at throat self.Athroat_des = fs_throat.area # Design calculations at exit self.Aexit_des = fs_exitIdeal.area self.switchRegime = "PERFECTLY_EXPANDED" else: # Find subsonic solution, curve 4 Fl_O.sub_or_super = "sub" Fl_O.area = self.Aexit_des MachSubsonic = Fl_O.Mach if MachSubsonic > 1: print "invalid nozzle subsonic solution" PsSubsonic = Fl_O.Ps # Find supersonic solution, curve 5 Fl_O.sub_or_super = "super" Fl_O.area = self.Aexit_des MachSupersonic = Fl_O.Mach PsSupersonic = Fl_O.Ps # normal shock at nozzle exit, curve c Fl_O.sub_or_super = "sub" Msuper = MachSupersonic PtExit = self.shockPR( Msuper, fs_throat.gams ) * fs_throat.Pt Fl_O.setTotalTP( fs_throat.Tt, PtExit ) Fl_O.area = self.Aexit_des PsShock = Fl_O.Ps # find correct operating regime # curves 1 to 4 if Fl_ref.Ps >= PsSubsonic: self.switchRegime = "UNCHOKED" fs_throat.sub_or_super = "sub" Fl_O.sub_or_super = "sub" fs_throat.area = self.Athroat_des Fl_O.setTotalTP( fs_throat.Tt, fs_throat.Pt ) Fl_O.area = self.Aexit_des # between curves 4 and c elif Fl_ref.Ps < PsSubsonic and Fl_ref.Ps >= PsShock: self.switchRegime = "NORMAL_SHOCK" Fl_O.sub_or_super = "sub" Fl_O.Ps = Fl_ref.Ps # between curves c and 5 elif Fl_ref.Ps < PsShock and Fl_ref.Ps > PsSupersonic: self.switchRegime = "OVEREXPANDED" Fl_O.sub_or_super = "super" Fl_O.setTotalTP( fs_throat.Tt, fs_throat.Pt ) Fl_O.area = self.Aexit_des # between curves 5 and e elif Fl_ref.Ps <= PsSupersonic: self.switchRegime = "UNDEREXPANDED" Fl_O.sub_or_super = "super" Fl_O.setTotalTP( fs_throat.Tt, fs_throat.Pt ) Fl_O.area = self.Aexit_des if abs(Fl_ref.Ps - PsSupersonic)/Fl_ref.Ps < .001: self.switchRegime = "PERFECTLY_EXPANDED" self.Fg = Fl_O.W*Fl_O.Vflow/32.174 + Fl_O.area*(Fl_O.Ps-Fl_ref.Ps) self.PR = fs_throat.Pt/Fl_O.Ps self.AR = Fl_O.area/fs_throat.area self.WqAexit = Fl_I.W/self.Athroat_des self.WqAexit_dmd = Fl_I.W/self.Athroat_dmd if self.switchRegime == "UNCHOKED": self.WqAexit = Fl_I.W/Fl_ref.Ps self.WqAexit_dmd = Fl_I.W/Fl_O.Ps