예제 #1
0
 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)
예제 #2
0
 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)
예제 #3
0
    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)
예제 #4
0
    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
예제 #6
0
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()
예제 #7
0
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())
예제 #8
0
        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)
예제 #9
0
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))