示例#1
0
ispodfL = []  # list of IspODF  (frozen)
mrcoreL = []  # list of MRcore  (core stream tube mixture ratio)
for MRcore in np.linspace(mr_lo, mr_hi, num=60):
    C.reset_attr('MRcore', MRcore)
    R.scale_Rt_to_Thrust(Fvac, Pamb=0.0)

    ispodeL.append(C('IspODE'))
    ispodkL.append(C('IspODK'))
    ispodfL.append(C('IspODF'))
    mrcoreL.append(C('MRcore'))

# ========================================================
# ======= find peaks ======
mr_ode_terp = InterpProp(mrcoreL, ispodeL)
mr_ode_Peak, isp_ode_peak = gold_search_max(mr_ode_terp,
                                            mrcoreL[0],
                                            mrcoreL[-1],
                                            tol=1.0e-5)
isp_ode_peak = -isp_ode_peak
print('mr_ode_Peak, isp_ode_peak', mr_ode_Peak, isp_ode_peak)

mr_odk_terp = InterpProp(mrcoreL, ispodkL)
mr_odk_Peak, isp_odk_peak = gold_search_max(mr_odk_terp,
                                            mrcoreL[0],
                                            mrcoreL[-1],
                                            tol=1.0e-5)
isp_odk_peak = -isp_odk_peak
print('mr_odk_Peak, isp_odk_peak', mr_odk_Peak, isp_odk_peak)

mr_odf_terp = InterpProp(mrcoreL, ispodfL)
mr_odf_Peak, isp_odf_peak = gold_search_max(mr_odf_terp,
                                            mrcoreL[0],
示例#2
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()
示例#3
0
    def __init__(
        self,
        mrLimitsObj,
        pc=100.,
        eps=10.,
        ispType='CEAODE',  # ispType can be CEAODE, CEAFROZEN
        NterpSize=100):  # size of interpolation array

        self.mrLimitsObj = mrLimitsObj
        self.pc = pc
        self.eps = eps
        self.ispType = ispType

        self.mrL = [
        ]  # build lists of non-zero isp both above and below stoich_MR
        self.isL = []

        stoich_MR = self.mrLimitsObj.Stoich_MR
        #print( 'stoich_MR =',stoich_MR)
        stoich_fox = frac_ox(stoich_MR)
        #print( 'stoich_fox =',stoich_fox)
        self.stoich_fox = stoich_fox

        stoich_Isp = self.isp_at_mr(mr=stoich_MR)

        # build mr and isp lists from the stoich point to the left and right.
        # Only bother doing this because CEA frozen calc will often fail with condensed species.

        # build list from stoich towards MR=0
        mr_leftL = [stoich_MR]
        is_leftL = [stoich_Isp]
        df = 1.0 / float(NterpSize)
        fox = stoich_fox - df
        while fox > 0.0:
            mr = mr_of_fracox(fox)
            isp = self.isp_at_mr(mr=mr)
            if isp > 1.0:
                mr_leftL.append(mr)
                is_leftL.append(isp)
                fox = fox - df

                if isp < stoich_Isp * 0.9:
                    break
            else:
                break

        #print 'mr_leftL =',mr_leftL
        #print 'is_leftL =',is_leftL

        # build list from stoich towards ox fraction = 1.0
        mr_rightL = []
        is_rightL = []

        fox = stoich_fox + df
        while fox < 1.0:
            mr = mr_of_fracox(fox)
            isp = self.isp_at_mr(mr=mr)
            if isp > 1.0:
                mr_rightL.append(mr)
                is_rightL.append(isp)
                fox = fox + df

                if isp < stoich_Isp * 0.9:
                    break
            else:
                break
        #print 'mr_rightL =',mr_rightL
        #print 'is_rightL =',is_rightL
        # combine both lists
        mr_leftL.reverse()
        is_leftL.reverse()

        self.mrL = mr_leftL + mr_rightL
        self.isL = is_leftL + is_rightL

        if len(self.mrL) < 3:
            print('ERROR... len(mrL) < 3')

        #print 'Optimizing pc=%g, eps=%g'%(pc, eps)
        self.mr_isp_terp = InterpProp(self.mrL, self.isL)
        self.mrPeak, iterp_peak = gold_search_max(self.mr_isp_terp,
                                                  self.mrL[0],
                                                  self.mrL[-1],
                                                  tol=1.0e-5)

        self.ispPeak = self.isp_at_mr(mr=self.mrPeak)

        self.isp_min = min(self.isL)
        self.isp_max = max(self.isL)

        if self.ispPeak < 0.01 or self.mrPeak < 0.0:
            imin = 0
            for i in range(len(self.mrL)):
                if self.isL[i] < self.isL[imin]:
                    imin = i

            imax = min(len(self.mrL) - 1, imin + 2)
            imin = max(0, imin - 2)
            self.mrPeak, iterp_peak = gold_search_max(self.mr_isp_terp,
                                                      self.mrL[imin],
                                                      self.mrL[imax],
                                                      tol=1.0e-5)
            self.ispPeak = self.isp_at_mr(mr=self.mrPeak)

        if self.ispPeak < 0.01 or self.mrPeak < 0.0:
            print((
                '_______________BAD OPTIMUM at pc=%g and eps=%g   mrPeak=%g, ispPeak=%g'
                % (pc, eps, self.ispPeak, self.mrPeak)))

        # place holders for left and right of peak Isp
        self._mrLeftOfPeak = None
        self._mrRightOfPeak = None