def test_mr_temperature_limits_2(self): mc = MR_Temperature_Limits(oxName='MON12', fuelName='M10', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=1000.0) self.assertAlmostEqual(mc.max_MR, 85.131, places=3)
def test_mr_temperature_limits_3(self): mc = MR_Temperature_Limits(oxName=['F2', 'O2'], fuelName=["N2H4", "NH3"], oxPcentL=[65, 35], fuelPcentL=[90, 10], TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=1000.0) self.assertAlmostEqual(mc.max_MR, 79.5403, places=3)
def test_mr_temperature_limits_1(self): mc = MR_Temperature_Limits(oxName='N2O4', fuelName='NH3', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=1000.0) self.assertAlmostEqual(mc.max_MR, 35.3561, places=3)
def test_mr_temperature_limits_1b(self): mc = MR_Temperature_Limits(oxName='N2O4', fuelName='NH3', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=10.0) self.assertAlmostEqual(mc.max_MR, 10, places=3) s = str(mc) self.assertEqual( s, '<N2O4/NH3, Stoich_MR=2.02602, Min MR=0.332277, Max MR=10, Tc Left=1000 R, Tc Right=2506.12 R>' )
def __init__(self, figsize=(10, 8), dpi=70, Pc=500., eps=20., nsteps_sg=100, nsteps_isp=100, legend_loc='best', show_mr_on_plot=False, show_frozen_isp_on_plot=False, bipropL=None, monopropL=None, spec_gravD=None): if bipropL is None: bipropL = [('LOX', 'LH2'), ('N2O4', 'MMH'), ('LOX', 'RP1'), ('FLOX80', 'CH4'), ('IRFNA', 'MHF3'), ('LOX', 'CH4'), ('F2', 'H2'), ('F2', 'N2H4'), ('CLF5', 'N2H4'), ('N2F4', 'N2H4')] self.figsize = figsize self.dpi = dpi self.Pc = Pc self.eps = eps self.headline = 'Pc=%g psia, Area Ratio=%g:1' % (self.Pc, self.eps) self.nsteps_sg = nsteps_sg # controls grid on plot for interplating stage properties self.nsteps_isp = nsteps_isp # 'best', 'upper right', 'right', 'center', 'lower center', 'center right', etc. self.legend_loc = legend_loc self.show_mr_on_plot = show_mr_on_plot self.show_frozen_isp_on_plot = show_frozen_isp_on_plot self.bipropL = bipropL if monopropL is None: monopropL = [] self.monopropL = monopropL self.monoprop_sgIspD = {} #index:name, value:(sg, Isp) self.fig = plt.figure(figsize=figsize, dpi=dpi) # figsize=(NxM) inches self.added_props_to_plot = False if spec_gravD is not None: for key, val in spec_gravD.items(): add_prop_sg(name, val) self.mr_objL = [] self.isp_min = 9999.0 # initialize extents of plot self.isp_max = 0.0 self.sg_min = 9999.0 self.sg_max = 0.0 for (oxName, fuelName) in bipropL: if not got_sg(oxName): raise Exception('%s Specific Gravity Missing...\n'%oxName +\ ' add to spec_gravD["%s"]'%oxName) if not got_sg(fuelName): raise Exception('%s Specific Gravity Missing...\n'%fuelName +\ ' add to spec_gravD["%s"]'%fuelName) tobj = MR_Temperature_Limits(oxName=oxName, fuelName=fuelName, TC_LIMIT=1500.0, PcNominal=Pc, epsNominal=eps, MR_MIN=0.0, MR_MAX=200.0) self.mr_objL.append(MR_Peak_At_EpsPc(tobj, pc=Pc, eps=eps)) add_sg_isp_to_mr_obj(self.mr_objL[-1]) if show_frozen_isp_on_plot: add_frozen_isp_to_mr_obj(self.mr_objL[-1], Pc=Pc, eps=eps) self.isp_min = min(self.isp_min, self.mr_objL[-1].isp_min) self.isp_max = max(self.isp_max, self.mr_objL[-1].isp_max) self.sg_min = min(self.sg_min, self.mr_objL[-1].sg_min) self.sg_max = max(self.sg_max, self.mr_objL[-1].sg_max) for propName in self.monopropL: sg = get_sg(propName) if sg is not None: self.sg_min = min(self.sg_min, sg) self.sg_max = max(self.sg_max, sg) ispObj = CEA_Obj(propName=propName) Isp = ispObj.get_Isp(Pc=Pc, eps=eps) self.isp_min = min(self.isp_min, Isp) self.isp_max = max(self.isp_max, Isp) self.monoprop_sgIspD[propName] = (sg, Isp) self.rhobRange = self.sg_max - self.sg_min self.ispRange = self.isp_max - self.isp_min
def calc_ODE_ODK_FROZ_isp(oxName='N2O4', fuelName='MMH', Pc=1000.0, eps=10.0, pcentBell=80.0, Fvac=1000.0, NumRuns=20, do_show=True): # ============ use RocketCEA to find MR range =================== mc = MR_Temperature_Limits(oxName=oxName, fuelName=fuelName, PcNominal=Pc, epsNominal=eps) mr_peak = MR_Peak_At_EpsPc( mc, pc=Pc, eps=eps, ispType='CEAODE', # ispType can be CEAODE, CEAFROZEN NterpSize=100) print('Peak IspODE=%g sec at MR =' % mr_peak.ispPeak, mr_peak.mrPeak) print() print('MR at 97% Isp (on low side) =', mr_peak.calc_mrLow_minus_NPcentIsp()) print('MR at 97% Isp (on high side) =', mr_peak.calc_mrHigh_minus_NPcentIsp()) mr_lo = round( mr_peak.mrLeftOfPeak - (mr_peak.mrRightOfPeak - mr_peak.mrLeftOfPeak) / 10.0, 2) mr_hi = round(mr_peak.mrRightOfPeak, 2) delMR = (mr_hi - mr_lo) / (NumRuns - 1) # =============================== geomObj = Geometry(Rthrt=5.868 / 2, CR=2.5, eps=eps, pcentBell=pcentBell, RupThroat=1.5, RdwnThroat=1.0, RchmConv=1.0, cham_conv_deg=30, LchmOvrDt=3.10, LchmMin=2.0, LchamberInp=16) core = CoreStream(geomObj, oxName=oxName, fuelName=fuelName, MRcore=1.6, Pc=Pc) R = RocketThruster(name='sample', coreObj=core, injObj=None) ispodeL = [] ispodkL = [] ispodfL = [] mrL = [] MR = mr_lo for _ in range(NumRuns): mrL.append(MR) core.reset_attr('MRcore', MR, re_evaluate=True) R.scale_Rt_to_Thrust(Fvac, Pamb=0.0, use_scipy=False) ispodeL.append(R.coreObj.IspODE) ispodkL.append(R.coreObj.IspODK) ispodfL.append(R.coreObj.IspODF) MR += delMR # ======= find peaks ====== mr_ode_terp = InterpProp(mrL, ispodeL) mr_ode_Peak, isp_ode_peak = gold_search_max(mr_ode_terp, mrL[0], mrL[-1], tol=1.0e-5) mr_odk_terp = InterpProp(mrL, ispodkL) mr_odk_Peak, isp_odk_peak = gold_search_max(mr_odk_terp, mrL[0], mrL[-1], tol=1.0e-5) mr_odf_terp = InterpProp(mrL, ispodfL) mr_odf_Peak, isp_odf_peak = gold_search_max(mr_odf_terp, mrL[0], mrL[-1], tol=1.0e-5) fig, ax = plt.subplots(figsize=(8, 6)) plt.plot(mrL, ispodeL, label='IspODE', color=COLORL[0]) plt.plot(mrL, ispodkL, label='IspODK', color=COLORL[1]) plt.plot(mrL, ispodfL, label='IspODF', color=COLORL[2]) # show ========= optimum MR difference ======== def span_mrpeak(isL): minpt = min(isL) maxpt = max(isL) span = maxpt - minpt return [maxpt - 0.8 * span, maxpt] plt.plot([mr_ode_Peak, mr_ode_Peak], span_mrpeak(ispodeL), '--', label='MRode=%.2f' % mr_ode_Peak, linewidth=2, color=COLORL[0]) plt.plot([mr_odk_Peak, mr_odk_Peak], span_mrpeak(ispodkL), '--', label='MRodk=%.2f' % mr_odk_Peak, linewidth=2, color=COLORL[1]) plt.plot([mr_odf_Peak, mr_odf_Peak], span_mrpeak(ispodfL), '--', label='MRodf=%.2f' % mr_odf_Peak, linewidth=2, color=COLORL[2]) isp_odk_peak = abs(isp_odk_peak) plt.text(mr_odk_Peak, isp_odk_peak, '%i' % int(isp_odk_peak), ha='left', va='bottom', transform=ax.transData, color=COLORL[1]) plt.legend() plt.ylabel('Isp (sec)') plt.xlabel('Mixture Ratio') plt.title( "%s/%s RocketIsp ODE ODK ODF\nFvac=%.0f lbf, Pc=%.0f psia, AR=%.0f:1, %%Bell=%.0f%%"%\ (oxName, fuelName, Fvac, Pc, eps, pcentBell)) png_name = 'odekf_%s_%s_Fvac%g_Pc%g_eps%g.png' % (oxName, fuelName, Fvac, Pc, eps) plt.savefig(png_name, dpi=120) if do_show: plt.show()
from rocketisp.geometry import Geometry from rocketisp.efficiencies import Efficiencies from rocketisp.stream_tubes import CoreStream from rocketisp.rocket_isp import RocketThruster oxName = 'N2O4' fuelName = 'MMH' Fvac = 100 # lbf Pc = 100 # psia eps = 100 pcentBell = 80 mc = MR_Temperature_Limits(oxName=oxName, fuelName=fuelName, PcNominal=Pc, epsNominal=eps, TC_LIMIT=1000.0, MR_MIN=0.0, MR_MAX=1000.0) mr_peak = MR_Peak_At_EpsPc( mc, pc=Pc, eps=eps, ispType='CEAODE', # ispType can be CEAODE, CEAFROZEN NterpSize=100) print('Peak IspODE=%g sec at MR =' % mr_peak.ispPeak, mr_peak.mrPeak) print() print('MR at 97% Isp (on low side) =', mr_peak.calc_mrLow_minus_NPcentIsp()) print('MR at 97% Isp (on high side) =', mr_peak.calc_mrHigh_minus_NPcentIsp())
return self._mrRightOfPeak def get_peak_mr_vs_isp_lists(self, Npts=20): mrL = list(np.linspace(self.mrLeftOfPeak, self.mrRightOfPeak, Npts)) ispL = [self.isp_at_mr(mr=mr) for mr in mrL] return mrL, ispL if __name__ == "__main__": from pylab import * mc = MR_Temperature_Limits(oxName='F2', fuelName='H2', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1400.0, PcNominal=200.0, epsNominal=3.0, MR_MIN=0.0, MR_MAX=1000.0) print('Stoich MR =', mc.Stoich_MR, 'for %s/%s' % (mc.cea_oxName, mc.cea_fuelName)) print() print('Min MR = %g' % mc.min_MR, ' Tc at Min MR =', mc.Tc_at_min_MR) print('Max MR = %g' % mc.max_MR, ' Tc at Max MR =', mc.Tc_at_max_MR) mrcurve = MR_Peak_At_EpsPc(mc, pc=1000., eps=10., ispType='CEAFROZEN') #'CEAFROZEN' ) print('Peak IspODE=%g sec at MR =' % mrcurve.ispPeak, mrcurve.mrPeak) print() print('MR at 97% Isp (on low side) =', mrcurve.mrLeftOfPeak)
from rocketcea.biprop_utils.mr_t_limits import MR_Temperature_Limits mc = MR_Temperature_Limits(oxName='N2O4', fuelName='NH3', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=10.0) print('Stoich MR =', mc.Stoich_MR, 'for %s/%s' % (mc.cea_oxName, mc.cea_fuelName)) print('Min MR = %g' % mc.min_MR, ' Tc at Min MR =', mc.Tc_at_min_MR) print('Max MR = %g' % mc.max_MR, ' Tc at Max MR =', mc.Tc_at_max_MR) print(str(mc)) print('') mc = MR_Temperature_Limits(oxName='MON12', fuelName='M10', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=1000.0) print('Stoich MR =', mc.Stoich_MR, 'for %s/%s' % (mc.cea_oxName, mc.cea_fuelName))