def test_new_propellants(self): card_str = """ oxid N2O4(L) N 2 O 4 wt%=96.5 h,cal=-4676.0 t(k)=298.15 oxid SIO2 SI 1 O 2 wt%=3,5 h,cal=-216000.0 t(k)=298.15 rho.g/cc=1.48 """ add_new_oxidizer('GelN2O4', card_str) # ========== card_str = """ fuel CH6N2(L) C 1 H 6 N 2 wt%=60.00 h,cal=12900.0 t(k)=298.15 rho=.874 fuel AL 1 wt%=40.00 h,cal=0.0 t(k)=298.15 rho=.1 """ add_new_fuel('MMH_AL', card_str) C = CEA_Obj(oxName="GelN2O4", fuelName="MMH_AL", fac_CR=None) IspODE = C.get_Isp(Pc=1850.0, MR=0.7, eps=40.0) self.assertAlmostEqual(IspODE, 380.83236183365057, places=3) # ========== card_str = """ name H2O2(L) H 2 O 2 wt%=100.00 h,cal=-44880.0 t(k)=298.15 rho.g/cc=1.407 """ add_new_propellant('MyProp', card_str) C = CEA_Obj(propName="MyProp", fac_CR=None) IspODE = C.get_Isp(Pc=1850.0, eps=40.0) self.assertAlmostEqual(IspODE, 189.9709005711723, places=3)
def test_win32_rocketcea_data_dir_spaces(self): """On Windows, use short path names when spaces in ROCKETCEA_DATA_DIR""" if sys.platform == 'win32': save_ROCKETCEA_DATA_DIR = get_rocketcea_data_dir() try: with tempfile.TemporaryDirectory() as tmpdirname: print('created temporary directory', tmpdirname) subdir = os.path.join(tmpdirname, 'cea w spaces') os.mkdir(subdir) print('subdir =', subdir) print('os.path.exists(subdir) =', os.path.exists(subdir)) print() set_rocketcea_data_dir(subdir) C = CEA_Obj(oxName='LOX', fuelName='LH2', make_debug_prints=True) Isp = C.get_Isp(Pc=100.0, MR=1.0, eps=40.0) print(Isp) finally: # restore set_rocketcea_data_dir(save_ROCKETCEA_DATA_DIR)
def test_get_Isp(self): """ test call to get_Isp( Pc=100.0, MR=1.0, eps=40.0) """ C = CEA_Obj(oxName="LOX", fuelName="MMH", fac_CR=None) IspODE = C.get_Isp(Pc=100.0, MR=1.0, eps=40.0) self.assertAlmostEqual(IspODE, 351.7388076713265, places=3) del C
def test_get_Isp(self): """ test call to get_Isp( Pc=100.0, MR=1.0, eps=40.0) """ C = CEA_Obj(oxName="LOX", fuelName="MMH", fac_CR=2.5) IspODE = C.get_Isp(Pc=100.0, MR=1.0, eps=40.0) self.assertAlmostEqual(IspODE, 351.7235908873327, places=3) del C
def test_use_Mpa_as_input_Pc(self): """test use Mpa as input Pc""" C = CEA_Obj( oxName='LOX', fuelName='LH2', fac_CR=None) CwU = CEA_Obj_w_units( oxName='LOX', fuelName='LH2', pressure_units='MPa', fac_CR=None) a = C.get_Isp(Pc=1000.0, MR=6.0, eps=40.0) b = CwU.get_Isp(Pc=1000.0/145.037738, MR=6.0, eps=40.0) self.assertAlmostEqual(a, b, delta=0.01)
def test_froz_get_Isp(self): """ test call to get_Isp( Pc=100.0, MR=1.0, eps=40.0) """ C = CEA_Obj(oxName="LOX", fuelName="MMH", fac_CR=None) IspODE = C.get_Isp(Pc=100.0, MR=1.0, eps=40.0, frozen=1, frozenAtThroat=0) self.assertAlmostEqual(IspODE, 335.7939948810785, places=3) del C
from rocketcea.cea_obj import CEA_Obj C = CEA_Obj(oxName="LOX", fuelName="H2", useFastLookup=0) Pc = 500. MR = 6.0 for eps in [2., 5., 7., 10., 20., 50.]: IspVac = C.get_Isp(Pc=Pc, MR=MR, eps=eps) IspAmb, mode = C.estimate_Ambient_Isp(Pc=Pc, MR=MR, eps=eps, Pamb=14.7) print('Pc=%4i eps=%3i IspAmb/IspVac= %6.2f/%6.2f Mode= %s' % (int(Pc), int(eps), IspAmb, IspVac, mode))
'CH4': 0.444, 'C2H6_167': 0.8343, 'N2H4': 1.0037, 'CLF5': 1.776, 'MMH': 0.8702, 'N2O4': 1.433, 'NH3': 0.405 } for oxName,fuelName in [('OF2','B2H6'),('OF2','C3H8'),('OF2','CH4'),\ ('OF2','C2H6_167'),('OF2','N2H4'),\ ('CLF5','N2H4'),('N2O4','MMH')]: ispObj = CEA_Obj(oxName=oxName, fuelName=fuelName) ispL = [ispObj.get_Isp(Pc=Pc, MR=MR, eps=eps) for MR in mrL] sgOx = sgD[oxName] sgFuel = sgD[fuelName] rhoIspL = [] for MR, Isp in zip(mrL, ispL): sgBulk = (MR + 1.0) / (MR / sgOx + 1. / sgFuel) rhoIspL.append(Isp * sgBulk) rhoIspLL.append([max(rhoIspL), '%s/%s' % (oxName, fuelName), rhoIspL]) rhoIspLL.sort(reverse=True) # sort in-place from high to low for maxIsp, name, rhoIspL in rhoIspLL: plot(mrL, rhoIspL, label=name, linewidth=2)
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
from rocketcea.cea_obj import CEA_Obj, ROCKETCEA_DATA_DIR print('ROCKETCEA_DATA_DIR =', ROCKETCEA_DATA_DIR) C = CEA_Obj(oxName='LOX', fuelName='LH2', makeOutput=1, make_debug_prints=True) Isp = C.get_Isp(Pc=100.0, MR=1.0, eps=40.0) print(Isp)
class CEA_Obj(object): """ RocketCEA wraps the NASA FORTRAN CEA code to calculate Isp, cstar, and Tcomb This object wraps the English unit version of CEA_Obj to enable desired user units. """ def __init__(self, propName='', oxName='', fuelName='', useFastLookup=0, makeOutput=0, isp_units='sec', cstar_units='ft/sec', pressure_units='psia', temperature_units='degR', sonic_velocity_units='ft/sec', enthalpy_units='BTU/lbm', density_units='lbm/cuft', specific_heat_units='BTU/lbm degR', viscosity_units='millipoise', thermal_cond_units='mcal/cm-K-s', fac_CR=None, make_debug_prints=False): """:: #: RocketCEA wraps the NASA FORTRAN CEA code to calculate Isp, cstar, and Tcomb #: This object wraps the English unit version of CEA_Obj to enable desired user units. #: Same as CEA_Obj with standard units except, input and output units can be specified. #: parameter default options #: isp_units = 'sec', # N-s/kg, m/s, km/s #: cstar_units = 'ft/sec', # m/s #: pressure_units = 'psia', # MPa, KPa, Pa, Bar, Atm, Torr #: temperature_units = 'degR', # K, C, F #: sonic_velocity_units = 'ft/sec', # m/s #: enthalpy_units = 'BTU/lbm', # J/g, kJ/kg, J/kg, kcal/kg, cal/g #: density_units = 'lbm/cuft', # g/cc, sg, kg/m^3 #: specific_heat_units = 'BTU/lbm degR' # kJ/kg-K, cal/g-C, J/kg-K (# note: cal/g K == BTU/lbm degR) #: viscosity_units = 'millipoise' # lbf-sec/sqin, lbf-sec/sqft, lbm/ft-sec, poise, centipoise #: thermal_cond_units = 'mcal/cm-K-s' # millical/cm-degK-sec, BTU/hr-ft-degF, BTU/s-in-degF, cal/s-cm-degC, W/cm-degC #: fac_CR, Contraction Ratio of finite area combustor (None=infinite) #: if make_debug_prints is True, print debugging info to terminal. """ self.isp_units = isp_units self.cstar_units = cstar_units self.pressure_units = pressure_units self.temperature_units = temperature_units self.sonic_velocity_units = sonic_velocity_units self.enthalpy_units = enthalpy_units self.density_units = density_units self.specific_heat_units = specific_heat_units self.viscosity_units = viscosity_units self.thermal_cond_units = thermal_cond_units self.fac_CR = fac_CR # Units objects for input/output (e.g. Pc and Pamb) self.Pc_U = get_units_obj('psia', pressure_units) # units of output quantities self.isp_U = get_units_obj('sec', isp_units) self.cstar_U = get_units_obj('ft/sec', cstar_units) self.temperature_U = get_units_obj('degR', temperature_units) self.sonic_velocity_U = get_units_obj('ft/sec', sonic_velocity_units) self.enthalpy_U = get_units_obj('BTU/lbm', enthalpy_units) self.density_U = get_units_obj('lbm/cuft', density_units) self.specific_heat_U = get_units_obj('BTU/lbm degR', specific_heat_units) self.viscosity_U = get_units_obj('millipoise', viscosity_units) self.thermal_cond_U = get_units_obj('mcal/cm-K-s', thermal_cond_units) self.cea_obj = CEA_Obj_default(propName=propName, oxName=oxName, fuelName=fuelName, useFastLookup=useFastLookup, makeOutput=makeOutput, fac_CR=fac_CR, make_debug_prints=make_debug_prints) self.desc = self.cea_obj.desc def get_IvacCstrTc(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspVac, Cstar, Tcomb = self.cea_obj.get_IvacCstrTc(Pc=Pc, MR=MR, eps=eps) IspVac = self.isp_U.dval_to_uval(IspVac) Cstar = self.cstar_U.dval_to_uval(Cstar) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return IspVac, Cstar, Tcomb def getFrozen_IvacCstrTc(self, Pc=100.0, MR=1.0, eps=40.0, frozenAtThroat=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspFrozen, Cstar, Tcomb = self.cea_obj.getFrozen_IvacCstrTc( Pc=Pc, MR=MR, eps=eps, frozenAtThroat=frozenAtThroat) IspFrozen = self.isp_U.dval_to_uval(IspFrozen) Cstar = self.cstar_U.dval_to_uval(Cstar) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return IspFrozen, Cstar, Tcomb def get_IvacCstrTc_exitMwGam(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspVac, Cstar, Tcomb, mw, gam = self.cea_obj.get_IvacCstrTc_exitMwGam( Pc=Pc, MR=MR, eps=eps) IspVac = self.isp_U.dval_to_uval(IspVac) Cstar = self.cstar_U.dval_to_uval(Cstar) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return IspVac, Cstar, Tcomb, mw, gam def get_IvacCstrTc_ChmMwGam(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspVac, Cstar, Tcomb, mw, gam = self.cea_obj.get_IvacCstrTc_ChmMwGam( Pc=Pc, MR=MR, eps=eps) IspVac = self.isp_U.dval_to_uval(IspVac) Cstar = self.cstar_U.dval_to_uval(Cstar) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return IspVac, Cstar, Tcomb, mw, gam def get_IvacCstrTc_ThtMwGam(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspVac, Cstar, Tcomb, mw, gam = self.cea_obj.get_IvacCstrTc_ThtMwGam( Pc=Pc, MR=MR, eps=eps) IspVac = self.isp_U.dval_to_uval(IspVac) Cstar = self.cstar_U.dval_to_uval(Cstar) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return IspVac, Cstar, Tcomb, mw, gam def __call__(self, Pc=100.0, MR=1.0, eps=40.0): return self.get_Isp(Pc=Pc, MR=MR, eps=eps) def get_Isp(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia IspVac = self.cea_obj.get_Isp(Pc=Pc, MR=MR, eps=eps) IspVac = self.isp_U.dval_to_uval(IspVac) return IspVac def get_Cstar(self, Pc=100.0, MR=1.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Cstar = self.cea_obj.get_Cstar(Pc=Pc, MR=MR) Cstar = self.cstar_U.dval_to_uval(Cstar) return Cstar def get_Tcomb(self, Pc=100.0, MR=1.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Tcomb = self.cea_obj.get_Tcomb(Pc=Pc, MR=MR) Tcomb = self.temperature_U.dval_to_uval(Tcomb) return Tcomb def get_PcOvPe(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_PcOvPe(Pc=Pc, MR=MR, eps=eps) def get_eps_at_PcOvPe(self, Pc=100.0, MR=1.0, PcOvPe=1000.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_eps_at_PcOvPe(Pc=Pc, MR=MR, PcOvPe=PcOvPe) def get_Throat_PcOvPe(self, Pc=100.0, MR=1.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_Throat_PcOvPe(Pc=Pc, MR=MR) def get_MachNumber(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_MachNumber(Pc=Pc, MR=MR, eps=eps) def get_Temperatures(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0, frozenAtThroat=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia tempList = self.cea_obj.get_Temperatures(Pc=Pc, MR=MR, eps=eps, frozen=frozen, frozenAtThroat=frozenAtThroat) for i, T in enumerate(tempList): tempList[i] = self.temperature_U.dval_to_uval(T) return tempList # Tc, Tthroat, Texit def get_SonicVelocities(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia sonicList = self.cea_obj.get_SonicVelocities(Pc=Pc, MR=MR, eps=eps) for i, S in enumerate(sonicList): sonicList[i] = self.sonic_velocity_U.dval_to_uval(S) return sonicList # Chamber, Throat, Exit def get_Chamber_SonicVel(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia sonicVel = self.cea_obj.get_Chamber_SonicVel(Pc=Pc, MR=MR, eps=eps) sonicVel = self.sonic_velocity_U.dval_to_uval(sonicVel) return sonicVel def get_Enthalpies(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia hList = self.cea_obj.get_Enthalpies(Pc=Pc, MR=MR, eps=eps) for i, H in enumerate(hList): hList[i] = self.enthalpy_U.dval_to_uval(H) return hList def get_SpeciesMassFractions(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0, frozenAtThroat=0, min_fraction=0.000005): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia molWtD, massFracD = self.cea_obj.get_SpeciesMassFractions( Pc=Pc, MR=MR, eps=eps, frozenAtThroat=frozenAtThroat, min_fraction=min_fraction) return molWtD, massFracD def get_SpeciesMoleFractions(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0, frozenAtThroat=0, min_fraction=0.000005): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia molWtD, moleFracD = self.cea_obj.get_SpeciesMoleFractions( Pc=Pc, MR=MR, eps=eps, frozenAtThroat=frozenAtThroat, min_fraction=min_fraction) return molWtD, moleFracD def get_Chamber_H(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia H = self.cea_obj.get_Chamber_H(Pc=Pc, MR=MR, eps=eps) return self.enthalpy_U.dval_to_uval(H) def get_Densities(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia dList = self.cea_obj.get_Densities(Pc=Pc, MR=MR, eps=eps) for i, d in enumerate(dList): dList[i] = self.density_U.dval_to_uval(d) return dList def get_Chamber_Density(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia H = self.cea_obj.get_Chamber_Density(Pc=Pc, MR=MR, eps=eps) return self.density_U.dval_to_uval(H) def get_HeatCapacities(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia cpList = self.cea_obj.get_HeatCapacities(Pc=Pc, MR=MR, eps=eps, frozen=frozen) for i, cp in enumerate(cpList): cpList[i] = self.specific_heat_U.dval_to_uval(cp) return cpList def get_Chamber_Cp(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Cp = self.cea_obj.get_Chamber_Cp(Pc=Pc, MR=MR, eps=eps) return self.specific_heat_U.dval_to_uval(Cp) def get_Throat_Isp(self, Pc=100.0, MR=1.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Isp = self.cea_obj.get_Throat_Isp(Pc=Pc, MR=MR) Isp = self.isp_U.dval_to_uval(Isp) return Isp def get_Chamber_MolWt_gamma(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_Chamber_MolWt_gamma(Pc=Pc, MR=MR, eps=eps) def get_Throat_MolWt_gamma(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_Throat_MolWt_gamma(Pc=Pc, MR=MR, eps=eps) def get_exit_MolWt_gamma(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_exit_MolWt_gamma(Pc=Pc, MR=MR, eps=eps) def get_eqratio(self, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia return self.cea_obj.get_eqratio(Pc=Pc, MR=MR, eps=eps) def getMRforER(self, ERphi=None, ERr=None): return self.cea_obj.getMRforER(ERphi=ERphi, ERr=ERr) def get_description(self): return self.cea_obj.get_description() def estimate_Ambient_Isp(self, Pc=100.0, MR=1.0, eps=40.0, Pamb=14.7, frozen=0, frozenAtThroat=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Pamb = self.Pc_U.uval_to_dval(Pamb) # convert user units to psia IspAmb, mode = self.cea_obj.estimate_Ambient_Isp( Pc=Pc, MR=MR, eps=eps, Pamb=Pamb, frozen=frozen, frozenAtThroat=frozenAtThroat) IspAmb = self.isp_U.dval_to_uval(IspAmb) return IspAmb, mode def get_PambCf(self, Pamb=14.7, Pc=100.0, MR=1.0, eps=40.0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Pamb = self.Pc_U.uval_to_dval(Pamb) # convert user units to psia CFcea, CF, mode = self.cea_obj.get_PambCf(Pamb=Pamb, Pc=Pc, MR=MR, eps=eps) return CFcea, CF, mode def getFrozen_PambCf(self, Pamb=0.0, Pc=100.0, MR=1.0, eps=40.0, frozenAtThroat=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Pamb = self.Pc_U.uval_to_dval(Pamb) # convert user units to psia CFcea, CFfrozen, mode = self.cea_obj.getFrozen_PambCf( Pamb=Pamb, Pc=Pc, MR=MR, eps=eps, frozenAtThroat=frozenAtThroat) return CFcea, CFfrozen, mode def get_Chamber_Transport(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Cp, visc, cond, Prandtl = self.cea_obj.get_Chamber_Transport( Pc=Pc, MR=MR, eps=eps, frozen=frozen) #Cp = Cp * 8314.51 / 4184.0 # convert into BTU/lbm degR Cp = self.specific_heat_U.dval_to_uval(Cp) visc = self.viscosity_U.dval_to_uval(visc) cond = self.thermal_cond_U.dval_to_uval(cond) return Cp, visc, cond, Prandtl def get_Throat_Transport(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Cp, visc, cond, Prandtl = self.cea_obj.get_Throat_Transport( Pc=Pc, MR=MR, eps=eps, frozen=frozen) #Cp = Cp * 8314.51 / 4184.0 # convert into BTU/lbm degR Cp = self.specific_heat_U.dval_to_uval(Cp) visc = self.viscosity_U.dval_to_uval(visc) cond = self.thermal_cond_U.dval_to_uval(cond) return Cp, visc, cond, Prandtl def get_Exit_Transport(self, Pc=100.0, MR=1.0, eps=40.0, frozen=0): Pc = self.Pc_U.uval_to_dval(Pc) # convert user units to psia Cp, visc, cond, Prandtl = self.cea_obj.get_Exit_Transport( Pc=Pc, MR=MR, eps=eps, frozen=frozen) Cp = Cp * 8314.51 / 4184.0 # convert into BTU/lbm degR Cp = self.specific_heat_U.dval_to_uval(Cp) visc = self.viscosity_U.dval_to_uval(visc) cond = self.thermal_cond_U.dval_to_uval(cond) return Cp, visc, cond, Prandtl
import standard_fluid_config as std pcM = [50e5] ethanol90 = rocketcea.blends.newFuelBlend( fuelL=['C2H5OH', 'H2O'], fuelPcentL=[80, 20]) # new fule blend for CEA ispObj = CEA_Obj(propName='', oxName='LOX', fuelName=ethanol90) for Pc in pcM: ispArr = [] TArr = [] MR = 0.6 mrArr = [] while MR < 2: ispArr.append( ispObj.get_Isp(Pc=Pc * 0.000145038, MR=MR, eps=std.expansion_ratio)) TArr.append(ispObj.get_Tcomb(Pc=Pc * 0.000145038, MR=MR) * 0.555556) mrArr.append(MR) MR += 0.001 pl.plot(mrArr, ispArr, label='Pc=%g Pa' % Pc) pl.legend(loc='best') pl.grid(True) pl.title(ispObj.desc) pl.xlabel('Mixture Ratio [-]') pl.ylabel('Isp [s]') pl.show() pl.plot(mrArr, TArr, label='Pc=%g Pa' % Pc) pl.legend(loc='best') pl.grid(True)
class MR_Temperature_Limits(object): def __init__(self, oxName='N2O4', fuelName='MMH', oxPcentL=None, fuelPcentL=None, TC_LIMIT=1000.0, PcNominal=1000.0, epsNominal=10.0, MR_MIN=0.0, MR_MAX=1000.0): # degR, psia """ For the nominal Pc and Area Ratio, Find minimum and maximum mixture ratio where Tcombusion >= 1000 degR """ self.oxName = oxName self.oxPcentL = oxPcentL self.fuelName = fuelName self.fuelPcentL = fuelPcentL self.cea_fuelName = get_propellant_name(Name=fuelName, PcentL=fuelPcentL) self.cea_oxName = get_propellant_name(Name=oxName, PcentL=oxPcentL) self.TC_LIMIT = TC_LIMIT self.PcNominal = PcNominal self.epsNominal = epsNominal self.MR_MIN = MR_MIN self.MR_MAX = MR_MAX self.ispODEObj = CEA_Obj(fuelName=self.cea_fuelName, oxName=self.cea_oxName, useFastLookup=0, fac_CR=None) self.Stoich_MR = self.ispODEObj.getMRforER(ERphi=1.0) #print( 'Stoich MR =',self.Stoich_MR,'for %s/%s'%(self.cea_oxName, self.cea_fuelName) ) self.find_min_mr() self.find_max_mr() def find_min_mr(self): '''Find min mr where CEA Isp is Non-Zero AND Tc >= TC_LIMIT''' isp = self.ispODEObj.get_Isp(Pc=self.PcNominal, MR=0.0, eps=self.epsNominal) if isp > 0.0: self.min_MR = 0.0 isp, cstr, self.Tc_at_min_MR = self.ispODEObj.get_IvacCstrTc( Pc=self.PcNominal, MR=self.min_MR, eps=self.epsNominal) if isp > 0.1 and self.Tc_at_min_MR > self.TC_LIMIT: return mr_top = self.Stoich_MR mr_bot = 0.0 for i in range(40): mr = (mr_top + mr_bot) / 2.0 isp, cstr, tc = self.ispODEObj.get_IvacCstrTc(Pc=self.PcNominal, MR=mr, eps=self.epsNominal) if isp > 0.0 and tc > self.TC_LIMIT: mr_top = mr else: mr_bot = mr #print( 'Calculated Min MR = %g'%mr_top, ' Isp at Min MR =',self.ispODEObj.get_Isp( Pc=self.PcNominal, MR=mr_top, eps=eps) ) self.min_MR = mr_top isp, cstr, self.Tc_at_min_MR = self.ispODEObj.get_IvacCstrTc( Pc=self.PcNominal, MR=mr_top, eps=self.epsNominal) def find_max_mr(self): '''Find max mr where CEA Isp is Non-Zero AND Tc >= TC_LIMIT''' isp = self.ispODEObj.get_Isp(Pc=self.PcNominal, MR=self.MR_MAX, eps=self.epsNominal) if isp > 0.0: self.max_MR = self.MR_MAX isp, cstr, self.Tc_at_max_MR = self.ispODEObj.get_IvacCstrTc( Pc=self.PcNominal, MR=self.max_MR, eps=self.epsNominal) if isp > 0.0 and self.Tc_at_max_MR > self.TC_LIMIT: return mr_top = self.MR_MAX mr_bot = self.Stoich_MR for i in range(40): mr = (mr_top + mr_bot) / 2.0 isp, cstr, tc = self.ispODEObj.get_IvacCstrTc(Pc=self.PcNominal, MR=mr, eps=self.epsNominal) if isp > 0.0 and tc > self.TC_LIMIT: mr_bot = mr else: mr_top = mr #print( 'Calculated Max MR = %g'%mr_bot, ' Isp at Max MR =',self.ispODEObj.get_Isp( Pc=self.PcNominal, MR=mr_bot, eps=eps)) self.max_MR = mr_bot isp, cstr, self.Tc_at_max_MR = self.ispODEObj.get_IvacCstrTc( Pc=self.PcNominal, MR=mr_bot, eps=self.epsNominal) def __str__(self): return '''<%s/%s, Stoich_MR=%g, Min MR=%g, Max MR=%g, Tc Left=%g R, Tc Right=%g R>'''%\ (self.cea_oxName, self.cea_fuelName, self.Stoich_MR, self.min_MR, self.max_MR, self.Tc_at_min_MR, self.Tc_at_max_MR)
from rocketcea.cea_obj import CEA_Obj from pylab import * C = CEA_Obj(oxName='LOX', fuelName='LH2') for mr in range(2, 9): print(mr, C.get_Isp(Pc=100.0, MR=mr, eps=40.0)) Pc = 500.0 eps = 15.0 mrMin = 1.0 mrStep = 0.05 mrMax = 3.0 mrL = [mrMin + i * mrStep for i in range(int((mrMax - mrMin) / mrStep))] ispLL = [] # a list of lists of Isp data for oxName, fuelName in [('LOX', 'RP1'), ('LOX', 'RP1'), ('LOX', 'RP1'), ('LOX', 'RP1'), ('LOX', 'RP1')]: ispObj = CEA_Obj(oxName=oxName, fuelName=fuelName) ispL = [ispObj.get_Isp(Pc=Pc, MR=MR, eps=eps) for MR in mrL] ispLL.append([max(ispL), '%s/%s' % (oxName, fuelName), ispL]) ispLL.sort(reverse=True) # sort in-place from high to low for maxIsp, name, ispL in ispLL: plot(mrL, ispL, label=name, linewidth=2) legend(loc='best') grid(True)