예제 #1
0
def test_condensing_equil(pypropep):
    kno3 = pypropep.PROPELLANTS['POTASSIUM NITRATE']
    sugar = pypropep.PROPELLANTS['SUCROSE (TABLE SUGAR)']
    p = pypropep.Equilibrium()
    p.add_propellants([(kno3, 0.65 / kno3.mw), (sugar, 0.35 / sugar.mw)])
    p.set_state(P=30)
    assert len(p.composition_condensed) > 0
예제 #2
0
def test_simp_equil(pypropep):
    e = pypropep.Equilibrium()
    o2 = pypropep.PROPELLANTS['OXYGEN (GAS)']
    ch4 = pypropep.PROPELLANTS['METHANE']
    e.add_propellants([(o2, 1.), (ch4, 1.)])
    e.set_state(P=1.0, T=3000., type='TP')
    assert e.equilibrated is True
    assert e.properties_computed is True
예제 #3
0
def test_equil_modes(pypropep):
    e = pypropep.Equilibrium()
    with pytest.raises(ValueError):
        e.set_state(P=1., type='TP')

    with pytest.raises(ValueError):
        e.set_state(P=1., T=300., type='HP')

    with pytest.raises(ValueError):
        e.set_state(P=1., T=300., type='SP')
예제 #4
0
def test_TP_composition(pypropep):
    e = pypropep.Equilibrium()
    n2 = pypropep.PROPELLANTS['NITROGEN (GASEOUS)']
    e.add_propellant(n2, 1.0)
    with pytest.raises(RuntimeError):
        print(e._compute_product_composition())

    # Compostion should be None prior to equilibration
    assert e.composition is None
    assert e.composition_sorted is None
    assert e.composition_condensed is None

    # equilibrate
    e.set_state(P=1.0, T=273., type='TP')
    assert e.equilibrated is True
    assert e.properties_computed is True
    assert 'N2' in e.composition
    for k, v in list(e.composition.items()):
        if k == 'N2':
            assert v == pytest.approx(1.0, 1e-6)
        else:
            assert v == pytest.approx(0.0, 1e-6)
예제 #5
0
def test_properties(pypropep):
    p = pypropep.FrozenPerformance()
    ps = pypropep.ShiftingPerformance()
    e = pypropep.Equilibrium()
    lh2 = pypropep.PROPELLANTS['RP-1 (RPL)']
    lox = pypropep.PROPELLANTS['OXYGEN (LIQUID)']
    OF = 0.13
    p.add_propellants_by_mass([(lh2, 1.0), (lox, OF)])
    p.set_state(P=30, Ae_At=25.)
    ps.add_propellants_by_mass([(lh2, 1.0), (lox, OF)])
    ps.set_state(P=30, Ae_At=25.)
    e.add_propellants_by_mass([(lh2, 1.0), (lox, OF)])
    e.set_state(P=30, type='HP')
    assert p.properties[0].T == pytest.approx(ps.properties[0].T, 1e-2)
    assert p.properties[0].Cp == pytest.approx(ps.properties[0].Cp, 1e-2)
    assert p.properties[0].Isex == pytest.approx(ps.properties[0].Isex, 1e-2)
    assert p.properties[0].Cv == pytest.approx(ps.properties[0].Cv, 1e-2)

    assert p.properties[0].T == pytest.approx(e.properties.T, 1e-2)
    assert p.properties[0].Cp == pytest.approx(e.properties.Cp, 1e-2)
    assert p.properties[0].Isex == pytest.approx(e.properties.Isex, 1e-2)
    assert p.properties[0].Cv == pytest.approx(e.properties.Cv, 1e-2)
예제 #6
0
R = 8.314
Tref = 298.15
Pref = 1e5
Rref = Pref / R / Tref
T = np.linspace(500, 6000, 30)

# O2 <-> 2O
N_O = 2
N_O2 = 1
log_K_p = (N_O * f_T(o_tbl, T, 'log Kf') + N_O2 * f_T(o2_tbl, T, 'log Kf'))
K_p = 10**log_K_p
n_o = 0.5 * (np.sqrt(K_p) * np.sqrt(K_p + 4) - K_p)
n_o2 = 1. - n_o

equil = ppp.Equilibrium()
equil.add_propellants([(ppp.PROPELLANTS['OXYGEN (GAS)'], N_O2)])
comp = {'O2': [], 'O': []}
for i, Ti in enumerate(T):
    equil.set_state(P=1, T=Ti, type='TP')
    for k in comp:
        comp[k].append(equil.composition[k])

f = plt.figure()
for k in comp:
    plt.plot(T, comp[k], label=k)
plt.legend()

f = plt.figure()
plt.plot(T, n_o, label='O')
plt.plot(T, n_o2, label='O2')
예제 #7
0
def test_add_propellants_by_mass(pypropep):
    e = pypropep.Equilibrium()
    o2 = pypropep.PROPELLANTS['OXYGEN (GAS)']
    ch4 = pypropep.PROPELLANTS['METHANE']
    e.add_propellants_by_mass([(o2, 1.), (ch4, 1.)])
    print(e)
예제 #8
0
def test_simp_equilibrium(pypropep):
    e = pypropep.Equilibrium()
    return e.__str__()
예제 #9
0
def white_dwarf_cooling_data(water_mass_fraction):
    '''Engine dimensions'''
    Ac = np.pi*0.1**2               #Chamber cross-sectional area (m^2)
    L_star = 1.5                    #L_star = Volume_c/Area_t
    wall_thickness = 2e-3

    '''Chamber conditions'''
    pc = 15e5               #Chamber pressure (Pa)
    p_tank = 20e5           #Tank / inlet coolant stagnation pressure (Pa) - used for cooling jacket
    mdot = 5.4489           #Mass flow rate (kg/s)
    p_amb = 1.01325e5       #Ambient pressure (Pa). 1.01325e5 is sea level atmospheric.
    OF_ratio = 3.5          #Oxidiser/fuel mass ratio

    '''Coolant jacket'''
    wall_material = bam.materials.CopperC700
    mdot_coolant = mdot/(OF_ratio + 1) 
    inlet_T = 298.15                    #Coolant inlet temperature

    '''Get combustion properties from pypropep'''
    #Initialise and get propellants
    ppp.init()
    e =  ppp.Equilibrium()
    p =  ppp.ShiftingPerformance()

    ipa = ppp.PROPELLANTS['ISOPROPYL ALCOHOL']
    water = ppp.PROPELLANTS['WATER']
    n2o = ppp.PROPELLANTS['NITROUS OXIDE']

    #Add propellants by mass fractions (note the mass fractions can add up to more than 1)
    e.add_propellants_by_mass([(ipa, 1), 
                            (water, water_mass_fraction), 
                            (n2o, OF_ratio)])

    p.add_propellants_by_mass([(ipa, 1), 
                            (water, water_mass_fraction), 
                            (n2o, OF_ratio)])

    #Adiabatic combustion
    e.set_state(P = pc/p_amb, type = 'HP')  

    #Set chamber pressure and exit pressure in atmospheres                           
    p.set_state(P = pc/p_amb, Pe = 1)           

    gamma = e.properties.Isex   #I don't know why they use 'Isex' for gamma. 
    cp = 1000*e.properties.Cp   #Cp is given in kJ/kg/K, we want J/kg/K
    Tc = e.properties.T

    '''Choose the models we want to use for transport properties of the coolant and exhaust gas'''
    thermo_coolant = thermo.mixture.Mixture(['isopropanol', 'water'], ws = [1 - water_mass_fraction, water_mass_fraction])
    thermo_gas = thermo.mixture.Mixture(['N2', 'H2O', 'CO2'], zs = [e.composition['N2'], e.composition['H2O'], e.composition['CO2']])   

    gas_transport = cool.TransportProperties(model = "thermo", thermo_object = thermo_gas, force_phase = 'g')
    coolant_transport = cool.TransportProperties(model = "thermo", thermo_object = thermo_coolant, force_phase = 'l')

    '''Create the engine object'''
    perfect_gas = bam.PerfectGas(gamma = gamma, cp = cp)    #Gas for frozen flow
    chamber_conditions = bam.ChamberConditions(pc, Tc, mdot)
    nozzle = bam.Nozzle.from_engine_components(perfect_gas, chamber_conditions, p_amb, type = "rao", length_fraction = 0.8)
    white_dwarf = bam.Engine(perfect_gas, chamber_conditions, nozzle)
    chamber_length = L_star*nozzle.At/Ac

    '''Add the cooling system to the engine'''
    white_dwarf.add_geometry(chamber_length, Ac, wall_thickness)
    white_dwarf.add_exhaust_transport(gas_transport)

    #Spiral channels
    #white_dwarf.add_cooling_jacket(wall_material, inlet_T, p_tank, coolant_transport, mdot_coolant, 
    #                               configuration = "spiral", channel_shape = "semi-circle", channel_width = 0.020)

    #Or vertical channels
    white_dwarf.add_cooling_jacket(wall_material, inlet_T, p_tank, coolant_transport, mdot_coolant, configuration = "vertical", channel_height = 0.001)

    '''Run the heating analysis'''
    cooling_data = white_dwarf.steady_heating_analysis(number_of_points = 250, to_json = False)

    return cooling_data, white_dwarf.isp(p_amb)