Example #1
0
class CEA():
    def __init__(self, fuel, oxidiser, chamber_pressure):
        """[summary]
		Calcualtes hot gas properties using CEA and converts to SI units. If errors occur with FORTRAN, resart and try again!
		:param chamber_pressure in [Pa]
		:type fuel = string
		:type oxidiser = string
		"""
        self.chamber_pressure = chamber_pressure
        self.imperial_pressure = 0.000145038 * self.chamber_pressure  #conversion to psia
        self.ispObj = CEA_Obj(oxName=oxidiser, fuelName=fuel)
        self.ispObj.get_full_cea_output()

    def chamber_gas_properties(self, mixture_ratio, expansion_ratio):
        self.Cp, self.visc, self.cond, self.Pr = self.ispObj.get_Chamber_Transport(
            Pc=self.imperial_pressure, MR=mixture_ratio, frozen=1)
        self.MW, self.gamma = self.ispObj.get_Chamber_MolWt_gamma(
            Pc=self.imperial_pressure, MR=mixture_ratio, eps=expansion_ratio)

    def throat_gas_properties(self, mixture_ratio, expansion_ratio):
        self.Cp, self.visc, self.cond, self.Pr = self.ispObj.get_Throat_Transport(
            Pc=self.imperial_pressure, MR=mixture_ratio, frozen=1)
        self.MW, self.gamma = self.ispObj.get_Throat_MolWt_gamma(
            Pc=self.imperial_pressure, MR=mixture_ratio, eps=expansion_ratio)

    def exit_gas_properties(self, mixture_ratio, expansion_ratio):
        self.Cp, self.visc, self.cond, self.Pr = self.ispObj.get_Exit_Transport(
            Pc=self.imperial_pressure, MR=mixture_ratio, frozen=1)
        self.MW, self.gamma = self.ispObj.get_exit_MolWt_gamma(
            Pc=self.imperial_pressure, MR=mixture_ratio, eps=expansion_ratio)

    def metric_cea_output(self, location, mixture_ratio, expansion_ratio):
        if location == 'chamber':
            self.chamber_gas_properties(mixture_ratio, expansion_ratio)
        elif location == 'throat':
            self.throat_gas_properties(mixture_ratio, expansion_ratio)
        elif location == 'exit':
            self.exit_gas_properties(mixture_ratio, expansion_ratio)
        else:
            raise ValueError(
                'Invalid location, use "chamber," "throat" or "exit"')

        self.isp, self.cstar, _ = self.ispObj.getFrozen_IvacCstrTc(
            Pc=self.imperial_pressure, MR=mixture_ratio, eps=expansion_ratio)

        self.cstar = self.cstar * 0.3048  # coversion to m/s
        self.mole_fractions = self.ispObj.get_SpeciesMoleFractions(
            Pc=self.imperial_pressure,
            MR=mixture_ratio,
            eps=expansion_ratio,
            frozen=0,
            frozenAtThroat=0,
            min_fraction=5e-05)
        self.Cp = self.Cp * 4186.8  # coversion to J/gk/K
        self.mu = self.visc * 0.0001  # coversion to Pa*s
        self.k = self.cond * 418.4e-3  # coversion to W/m/K
        self.T_static = self.ispObj.get_Tcomb(
            Pc=self.imperial_pressure,
            MR=mixture_ratio) * 0.555556  # coversion to K
Example #2
0
    def test_full_cea_output(self):
        C = CEA_Obj(oxName="LOX", fuelName="LH2", fac_CR=None)
        s = C.get_full_cea_output(Pc=1000.0, MR=6.0, eps=40.0)
        #print( s )

        ipos = s.find('Isp, LB-SEC/LB              154.4    431.2')
        self.assertGreater(ipos, 4000)

        del C
Example #3
0
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(oxName='LOX', fuelName='LH2', fac_CR=2.5)
s = ispObj.get_full_cea_output(Pc=1000.0, MR=6.0, eps=40.0)

print(s)
Example #4
0
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(oxName='LOX', fuelName='LH2')
s = ispObj.get_full_cea_output(Pc=1000.0,
                               MR=6.0,
                               eps=40.0,
                               frozen=1,
                               frozenAtThroat=0,
                               short_output=1)

print(s)
from rocketcea.cea_obj import CEA_Obj

Pc = 40.0
eps = 5.0

ispObj = CEA_Obj(oxName='GOX', fuelName='GH2')
s = ispObj.get_full_cea_output(Pc=Pc,
                               MR=5.0,
                               eps=eps,
                               frozen=0,
                               frozenAtThroat=0,
                               short_output=1,
                               show_transport=1)

print(s)

print("""==================================""")

print(ispObj.get_HeatCapacities(Pc=Pc, MR=.25, eps=eps))
print(ispObj.get_HeatCapacities(Pc=Pc, MR=5.0, eps=eps))
"""
    figure out Pcinj_face to get desired Pcomb_end (100 atm in example)
"""
from rocketcea.cea_obj import CEA_Obj

cr = 2.5  # contraction ratio
ispObj = CEA_Obj(oxName='LOX', fuelName='LH2', fac_CR=cr)

# Use 100 atm to make output easy to read
Pc = 100.0 * 14.6959

# use correlation to make 1st estimate of Pcinj_face / Pcomb_end
PinjOverPcomb = 1.0 + 0.54 / cr**2.2

# use RocketCEA to refine initial estimate
PinjOverPcomb = ispObj.get_Pinj_over_Pcomb(Pc=Pc * PinjOverPcomb, MR=6.0)

# print results (noting that "COMB END" == 100.00 atm)
s = ispObj.get_full_cea_output(Pc=Pc * PinjOverPcomb, MR=6.0, eps=40.0)
print(s)
Example #7
0
from rocketcea.cea_obj import CEA_Obj, add_new_fuel, add_new_oxidizer, add_new_propellant

# ==========
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")

s = C.get_full_cea_output(Pc=250.0, eps=40.0, short_output=1)

print(s)
Example #8
0
class CEA:
    def __init__(self, oxName, fuelName):
        self.oxName = oxName
        self.fuelName = fuelName
        # dictionary containing the standard heat of formation for all species in [kJ/mol]
        # you can find this data in thermo.inp in the rocketCEA library folder
        self.heatDict = {
            "ABS": 62.719,
            "Acrylic": 382.0,
            "N2O": 82.05,
            "LO2": 0,
            "*CO": -110.53,
            "*CO2": -393.5,
            "*H": 217.998,
            "HCO": 42.397,
            "HO2": 12.02,
            "*H2": 0,
            "C(gr)": 0,
            "H2O": -241.826,
            "*N": 472.680,
            "*NO": 91.271,
            "*N2": 0,
            "*O": 249.175,
            "*OH": 37.278,
            "*O2": 0,
            "COOH": -213,
            "H2O2": -135.88,
            "O3": 141.8,
            "CH3": 146.658,
            "CH4": -74.6,
            "C2H2,acetylene": 228.2,
            "CH2CO,ketene": -49.576,
            "C2H4": 52.5,
            "HCN": 133.082,
            "HNC": 194.378,
            "NH3": -54.752,
            "CH3CN": 31.38,
            "C4H2,butadiyne": 450,
            "C2N2": 283.209,
            "*CN": 438.683,
            "HNCO": -118.056,
            "C3H3,2-propynl": 331.8,
            "HNO": 102.032,
            "NO2": 34.193,
            "C2H6": -103.819,
            "HCHO,formaldehy": -108.58,
            "C3H6,propylene": 20.0
        }
        # Dictionary holding molar masses for reactants [g/mol]
        self.MMDict = {
            "LO2": 15.999,
            "N2O": 44.013,
            "ABS": 57.07,
            "Acrylic": 100.12
        }

        self.addCustomSpecies()
        self.C = CEA_Obj(oxName=oxName, fuelName=fuelName)



    def getOutput(self, Pc, OFRatio, ExpansionRatio, printOutput):
        output = self.C.get_full_cea_output(Pc=Pc, MR=OFRatio, eps=ExpansionRatio, short_output=0, output='siunits')
        if printOutput:
            print(output)

    def getChamberEquilibrium(self, Pc, OFRatio, ExpansionRatio, location):
        # gets all of the properties of the thingy (make sure not to ask for too much, you will upset him)
        # location: 0-injector (not supported) 1-chamber 2-throat 3-exit

        if location == 0:
            print("ERROR: properties at injector not supported")
        elif location == 1:
            self.Isp_Vac, self.C_star, self.T_flame, self.MW, self.gamma = self.C.get_IvacCstrTc_ChmMwGam(Pc=Pc, MR=OFRatio, eps=ExpansionRatio)  # get ISP [s], C* [ft/s], T [R], MW [g/mol], gamma [-]
            self.Cp, self.visc, self.thermCond, self.prandtl = self.C.get_Chamber_Transport(Pc, OFRatio, ExpansionRatio)  # get heat capacity [cal/g*K], viscosity[milliPoise], thermal conductivity [mcal/cm*s*K], Prandtl Number [-]

        elif location == 2:
            self.Isp_Vac, self.C_star, self.T_flame, self.MW, self.gamma = self.C.get_IvacCstrTc_ThtMwGam(Pc=Pc, MR=OFRatio, eps=ExpansionRatio)  # get ISP [s], C* [ft/s], T [R], MW [g/mol], gamma [-]
            self.Cp, self.visc, self.thermCond, self.prandtl = self.C.get_Throat_Transport(Pc, OFRatio, ExpansionRatio)  # get heat capacity [cal/g*K], viscosity[milliPoise], thermal conductivity [mcal/cm*s*K], Prandtl Number [-]
        elif location == 3:
            self.Isp_Vac, self.C_star, self.T_flame, self.MW, self.gamma = self.C.get_IvacCstrTc_exitMwGam(Pc=Pc, MR=OFRatio, eps=ExpansionRatio)  # get ISP [s], C* [ft/s], T [R], MW [g/mol], gamma [-]
            self.Cp, self.visc, self.thermCond, self.prandtl = self.C.get_Exit_Transport(Pc, OFRatio, ExpansionRatio)  # get heat capacity [cal/g*K], viscosity[milliPoise], thermal conductivity [mcal/cm*s*K], Prandtl Number [-]
        else:
            print("ERROR: location index out of bounds")
        self.T_flame = self.T_flame/1.8  # convert to Kelvin
        self.C_star = self.C_star / 3.28084  # convert characteristic velocity to [m/s]
        self.Cp = self.Cp * 4.186798  # get specific heat capacity [j/g*C]
        self.visc = self.visc/1000  # convert from milliPoise to Poise
        self.thermCond = self.thermCond * 418000  # convert to [W/m*K]

        return self.Isp_Vac, self.C_star, self.T_flame, self.MW, self.gamma, self.Cp, self.visc, self.thermCond, self.prandtl

    def getReactionHeat(self, Pc, OFRatio, ExpansionRatio, location):
        h_products = self.getProductsEnthalpy(Pc, OFRatio, ExpansionRatio, location)
        h_fuel = self.findHeatOfFormation(self.fuelName)/self.MMDict[self.fuelName]
        h_ox = self.findHeatOfFormation(self.oxName)/self.MMDict[self.oxName]

        X_fuel = 1/(OFRatio+1)  # fuel mass fraction
        X_ox = OFRatio/(OFRatio+1)  # oxidizer mass fraction

        h_reactants = X_fuel*h_fuel + X_ox*h_ox

        Q_total = h_products - h_reactants  # assuming adiabatic circumstances, Q_total = deltaH
        return Q_total

    def getProductsEnthalpy(self, Pc, OFRatio, ExpansionRatio, location):
        # calculates the enthalpy per gram of products
        # location: 0-injector 1-chamber 2-throat 3-exit

        molarMass, massFraction = self.C.get_SpeciesMassFractions(Pc=Pc, MR=OFRatio, eps=ExpansionRatio)

        # convert molarMass and massFraction into lists with species name in first column, and data in second
        molarMass = list(molarMass), list(molarMass.values())
        massFraction = list(massFraction), list(massFraction.values())

        # create an array containing the standard heat of formations of all species
        h_f = molarMass
        h_products = 0
        for i in range(len(molarMass[0])):
            h_f[1][i] = self.findHeatOfFormation(molarMass[0][i]) / molarMass[1][i]  # heat of formation [kJ/g]
            h_products += h_f[1][i] * massFraction[1][i][location]
        return h_products

    def findHeatOfFormation(self, species):
        try:
            return self.heatDict[species]
        except:
            print("ERROR:", species, "is not defined in heat of formation dictionary. Look in the init of the CEA class")

    def addCustomSpecies(self):
        # Add custom species to CEA
        card_str = """
                fuel ABS  C 3.85   H 4.85   N 0.43     wt%=100.00
                h,cal=14990    t(k)=298.15   rho=0.975
                """
        add_new_fuel('ABS', card_str)
        card_str = """
                fuel Acrylic  C 5   H 8   O 2     wt%=100.00
                h,cal=91396    t(k)=298.15   rho=1.18
                """
        add_new_fuel('Acrylic', card_str)
Example #9
0
print( 'cal_per_mole:%g'%cal_per_mole )

card_str = """
oxid Peroxide_90h2o2 H %g O %g  wt%%=100.0 
h,cal=%g  t(k)=298.15 rho,g/cc = 1.395  
"""%(frac_h, frac_ox, cal_per_mole)

print( card_str )

# ============== Add the new card to RocketCEA ==============
add_new_oxidizer( 'Peroxide_90h2o2', card_str )

# ============= Make a sample run at nominal conditions ==========
#            (gives exact same results as library Peroxide90) 
C = CEA_Obj(propName="Peroxide_90h2o2")
s = C.get_full_cea_output( Pc = 1000.0,eps=2.0,short_output = 1)
print( s )

# =============== make plot ================
TvalL = []
IspL  = []
for TdegR in range(500, 660, 10):
    
    new_card = makeCardForNewTemperature(ceaName='Peroxide_90h2o2', newTdegR=TdegR, CpAve=0.66, MolWt=MolWtMixture)
    ispObj = CEA_Obj( propName=new_card )
    
    TvalL.append( TdegR )
    IspL.append( ispObj(Pc=1000.0, eps=2.0 ) )
    
plot(TvalL, IspL, label='90% Peroxide', linewidth=2)
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(oxName='LOX', fuelName='LH2')
s = ispObj.get_full_cea_output(Pc=1000.0,
                               MR=6.0,
                               eps=40.0,
                               short_output=1,
                               show_transport=1)

print(s)
from rocketcea.cea_obj import CEA_Obj, add_new_fuel, add_new_oxidizer, add_new_propellant

card_str = """
fuel NASA_RP-1  C 1.0   H 1.95   wt%=100.00
h,cal=-5907.672     t(k)=298.15   rho=.773
"""
add_new_fuel( 'NASA_RP_1', card_str )

C = CEA_Obj(oxName="GOX", fuelName="NASA_RP_1")

s = C.get_full_cea_output( Pc=1000.0, MR=3.0, eps=40.0, short_output=1)

print( s )
Example #12
0
from rocketcea.cea_obj import CEA_Obj, add_new_fuel, add_new_oxidizer, add_new_propellant

card_str = """
oxid N2O4(L)   N 2 O 4   wt%=96.5
h,cal=-4676.0     t(k)=298.15
oxid SiO2  Si 1.0 O 2.0    wt%=3.5
h,cal=-216000.0     t(k)=298.15  rho=1.48
"""
add_new_oxidizer('GelN2O4', card_str)

# ==========
card_str = """
fuel CH6N2(L)  C 1.0   H 6.0   N 2.0     wt%=60.00
h,cal=12900.0     t(k)=298.15   rho=.874
fuel   AL AL 1.0   wt%=40.00
h,cal=0.0     t(k)=298.15   rho=0.1
"""
add_new_fuel('MMH_AL', card_str)

C = CEA_Obj(oxName="GelN2O4", fuelName="MMH_AL")

s = C.get_full_cea_output(Pc=1850.0, MR=0.7, eps=40.0, short_output=1)

print(s)
Example #13
0
def createPropellant(wt1,wt2,wt3):
	card_str = """
	name H2O   H 2 O 1   wt%={:.1f}
	h,kj/mol=-285.8       t(k)=293.15
	name Methanol   C 1 H 4 O 1   wt%={:.1f}
	h,kj/mol=-239.2       t(k)=293.15
	name ADN   H 4 N 4 O 4   wt%={:.1f}
	h,kj/mol=-134.6       t(k)=293.15
	""".format(wt1,wt2,wt3)
	add_new_propellant("WaterMethanolADN_Mix",card_str)
	
def bar2psi(bar):
	return bar*14.504
	
""" prepare fuel """
meth = 39
adn = 59
h2o = 2
createPropellant(h2o,meth,adn)

""" get full output """
chamber_pressure = 16
expansion_ratio = 60

temp = CEA_Obj(propName="WaterMethanolADN_Mix")
(isp,cstr,tc) = temp.getFrozen_IvacCstrTc(Pc=bar2psi(chamber_pressure),eps=expansion_ratio,frozenAtThroat=1)
print(isp,cstr,tc)
s = temp.get_full_cea_output( Pc=bar2psi(chamber_pressure), eps=expansion_ratio, frozen=1, frozenAtThroat=1)
with open("b4.out","w") as f:
	f.write(s)
print(s)
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(oxName='LOX', fuelName='LH2')
s = ispObj.get_full_cea_output(
    Pc=[1000, 2000],  # number or list of chamber pressures
    MR=[6.0, 7.0],  # number or list of mixture ratios
    PcOvPe=[100, 200],  # number or list of Pc/Pexit
    eps=[40.0, 60],  # number or list of supersonic area ratios
    subar=[3, 2],  # number or list of subsonic area ratios
    short_output=0,  # 0 or 1 to control output length
    pc_units='psia',  # pc_units = 'psia', 'bar', 'atm', 'mmh'
    output='siunits')  # output = 'calories' or 'siunits'
print(s)
from rocketcea.cea_obj import CEA_Obj

C = CEA_Obj(oxName='LOX', fuelName='RP1')

full_cea = C.get_full_cea_output(Pc=100,
                                 MR=1.0,
                                 eps=None,
                                 subar=None,
                                 PcOvPe=100,
                                 show_transport=1,
                                 pc_units='bar',
                                 output='KJ',
                                 short_output=1)
print(
    'this is the cea string:------------------------------------------------------------------------------------------------------------------'
)
print(full_cea)
Example #16
0
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(propName='Peroxide98')
s = ispObj.get_full_cea_output(Pc=1000.0, eps=10.0)

print(s)
from rocketcea.cea_obj import CEA_Obj

ispObj = CEA_Obj(oxName='LOX', fuelName='LH2')
s = ispObj.get_full_cea_output(Pc=1000.0,
                               MR=6.0,
                               eps=40.0,
                               frozen=1,
                               frozenAtThroat=0,
                               short_output=0,
                               pc_units='psia',
                               show_mass_frac=True)

print(s)