示例#1
0
def get_specific_heat_ratio_pressure_temperature(pressure, temperature):
    pressure = convert.pa_to_bar(pressure)  # Convert to bar
    # Usually gets out of range because of the guessing algorithm
    if pressure < properties.pressure_min: pressure = properties.pressure_min
    if pressure > properties.pressure_max: pressure = properties.pressure_max

    if temperature < properties.temperature_min or temperature >= properties.temperature_max:
        raise ValueError('Temperature out of range:' + str(temperature))

    # Get isothermal water Cv and Cp for given temperature (interpolate)
    data_low, data_high = dataContainer.get_data(temperature)
    fraction = (temperature % properties.temperature_step) / float(properties.temperature_step)
    cv = [data_low.cv[i] + fraction * (data_high.cv[i] - data_low.cv[i]) for i in range(len(data_low.cv))]
    cp = [data_low.cp[i] + fraction * (data_high.cp[i] - data_low.cp[i]) for i in range(len(data_low.cp))]

    # Cv and Cp are known for the exact temperature, calculate at exact pressure (interpolate)
    for i, p in enumerate(data_low.pressure):
        if p == pressure:
            return cp[i] / cv[i]
        if p > pressure:
            # We're in between two pressures that are listed, i and i-1
            fraction = (pressure - data_low.pressure[i - 1]) / (data_low.pressure[i] - data_low.pressure[i - 1])
            gamma_low = cp[i - 1] / cv[i - 1]
            gamma_high = cp[i] / cv[i]
            return gamma_low + fraction * (gamma_high - gamma_low)
示例#2
0
def get_specific_heat_ratio(pressure, data):
    pressure = convert.pa_to_bar(pressure)  # Convert to bar
    for i, p in enumerate(data.pressure):
        if p == pressure:
            return data.gamma[i]
        if p > pressure:
            # We're in between two pressures that are listed
            fraction = (pressure - data.pressure[i - 1]) / (data.pressure[i] - data.pressure[i - 1])
            return data.gamma[i - 1] + fraction * (data.gamma[i] - data.gamma[i - 1])
示例#3
0
def get_density_pressure_temperature(pressure, temperature):
    pressure = convert.pa_to_bar(pressure)  # Convert to bar
    if pressure < properties.pressure_min or pressure > properties.pressure_max:
        raise ValueError('Pressure out of range:' + str(pressure))
    if temperature < properties.temperature_min: temperature = properties.temperature_min
    if temperature > properties.temperature_max: temperature = properties.temperature_max - 1

    # Get enthalpy for given temperature (interpolate)
    data_low, data_high = dataContainer.get_data(temperature)
    fraction = (temperature % properties.temperature_step) / float(properties.temperature_step)
    density = [data_low.density[i] + fraction * (data_high.density[i] - data_low.density[i]) for i in
               range(len(data_low.density))]

    # Enthalpy known for the exact temperature, calculate at exact pressure (interpolate)
    for i, p in enumerate(data_low.pressure):
        if p == pressure:
            return density[i] * 1000  # g/ml to kg/m3
        if p > pressure:
            # We're in between two pressures that are listed, i and i-1
            fraction = (pressure - data_low.pressure[i - 1]) / (data_low.pressure[i] - data_low.pressure[i - 1])
            return density[i - 1] + fraction * (density[i] - density[i - 1]) * 1000  # g/ml to kg/m3
示例#4
0
def performance_by_throat_diameter_area_ratio(power,
                                              mass_flow,
                                              Dt,
                                              De=None,
                                              Tc=None,
                                              AreaRatio=None,
                                              print_results=False):
    if not De and not AreaRatio:
        raise StandardError("Either 'De' or 'AreaRatio' has to be defined!")
    if De is not None and AreaRatio is not None:
        raise StandardError("Only 'De' OR 'AreaRatio' may be defined!")

    enthalpy = (power / mass_flow
                ) / 1000. + H_sto  # Enthalpy of the propellant in the chamber

    def calculate_pc(T):
        # Guess a chamber pressure
        Pc = convert.bar_to_pa(1)  # 1 bar
        step = convert.bar_to_pa(0.5)  # 0.5 bar
        direction = 0
        while step / Pc > 0.0001:  # When the change in stepsize is less then 0.01%, Pc is very accurate
            gamma = get_specific_heat_ratio_pressure_temperature(Pc, T)
            At = AreaThroat(mass_flow, gamma, Pc, T)
            temp_Dt = convert.area_to_diameter(At)
            difference = temp_Dt - Dt

            if difference > 0:
                if direction == -1:
                    step /= 2
                if direction == 1:
                    step *= 1.5
                direction = 1
                Pc += step
            elif difference < 0:
                if direction == -1:
                    step *= 1.5
                if direction == 1:
                    step /= 2
                direction = -1
                Pc -= step
            if Pc <= 0:  # Pe can't be negative
                Pc = 1e-20
        return Pc

    if Tc:
        Pc = calculate_pc(Tc)
    else:
        Tc = Pc = 0
        H_min = 1E100
        for t in range(temperature_min, temperature_max):
            Pc_temp = calculate_pc(t)
            if Pc_temp > convert.bar_to_pa(
                    pressure_max
            ):  # Can't calculate pressures above pressure_max
                pass
            enthalpy_temp = get_enthalpy_pressure_temperature(Pc_temp, t)
            enthalpy_diff = abs(enthalpy - enthalpy_temp)
            if enthalpy_diff < H_min:
                Pc = Pc_temp
                Tc = t
                H_min = enthalpy_diff
    if Pc == 0: raise ValueError("Pressure too high!")
    if Tc == temperature_min: raise ValueError("Temperature too low!")
    if Tc == temperature_max - 1: raise ValueError("Temperature too high!")

    gamma = get_specific_heat_ratio_pressure_temperature(Pc, Tc)
    At = convert.diameter_to_area(Dt)
    if De is not None:
        Ae = convert.diameter_to_area(De)
    elif AreaRatio is not None:
        Ae = AreaRatio * At
        De = convert.area_to_diameter(Ae)

    Pe = ExitPressure(gamma, Ae, At, Pc)
    Ue = ExhaustVelocity(gamma, Pe, Pc, Tc)
    Thrust = RocketThrustEquation(mass_flow, Ue, Pe, Pa, Ae)
    c_star = Pc * At / mass_flow
    CF = Thrust / (Pc * At)
    Isp = CF * c_star / g0

    if print_results:
        print "Thrust:", Thrust * 1000, "mN", '\t\t', performance_difference(
            2.31386612509, Thrust * 1000)
        print "Isp:", Isp, "s", '\t\t', performance_difference(
            131.082600134, Isp)
        print "Specific Heat Ratio:", gamma
        print "Exhaust Velocity:", Ue, "m/s"
        print "Effective Exhaust Velocity", Thrust / mass_flow, "m/s"
        print "c*:", c_star, "m/s", '\t\t', performance_difference(
            691.043939954, c_star)
        print "Thrust Coefficient:", CF, '\t\t', performance_difference(
            1.86020179945, CF)
        print "Chamber Temperature:", Tc, "K", '\t\t', performance_difference(
            465, Tc)
        print "Chamber Pressure:", convert.pa_to_bar(
            Pc), "bar", '\t\t', performance_difference(0.703891577199,
                                                       convert.pa_to_bar(Pc))
        print "Exit Pressure:", convert.pa_to_bar(Pe), "bar"
        print "Pressure Ratio: 1/" + str(round(Pc / Pe, 2))
        print "Throat Diameter:", Dt * 1000, "mm"
        print "Exit Diameter:", De * 1000, "mm"
        print "Area Ratio: 1/" + str(Ae / At)
        print "Mass flow:", mass_flow * 1E6, "mg/s"
        print "Enthalpy:", enthalpy

    return Thrust * 1000, Isp, gamma, convert.pa_to_bar(Pc)