def test_calculate_p_rho_h(self):
        # Let's use figure 14.5a p. 610 Anderson to choose a good test point.
        # Let's look at the 35900 ft curve at u1 = 10000 ft/s = 3048 m/s
        # Looking at sentence above table IV in Huber (reference [165] in Anderson) we see that
        # at 35900 ft then p1 = 0.2250 atm = 0.2250 * 1.013 Pa and T1 = 217 K.
        # Air can be approximated pretty precisely as perfect at these conditions so let's
        # use the perfect gas law to calculate rho1.
        # Also, calculate h1 under the perfect gas assumption, h1 = c_p * T1.
        u1 = 3048.
        p1 = 0.2250 * 1.013E5
        T1 = 217.
        c_p = 1003.5
        h1 = c_p * T1
        R = 287.
        rho1 = p1 / (R * T1)
        rho2_guess = 10. * rho1
        calculated_properties = calculators.calculate_p_rho_h(u1, p1, rho1, T1, h1, rho2_guess)
        rho2_calculated = calculated_properties['density']
        p2_calculated = calculated_properties['pressure']
        h2_calculated = calculated_properties['enthalpy']
        
        # Reading off figure 14.5a we estimate rho2_known as:
        rho2_known = 7.8 * rho1

        # Errors could be introduced through rho1 and h1 and reading of figure 14.5a.
        # Allow for these error sources when choosing a value for rho_tolerance.
        # A print statement on rho1 in a previous supplied rho1 = 0.366, which means that
        # rho2 = 2.855. Allow for 5% error, i.e. 0.15 * 2.855 = 0.14.
        rho_tolerance = 0.14
        self.assertTrue(numpy.abs(rho2_known - rho2_calculated) < rho_tolerance)
def create_figures(u1_list_feet, engauge_list, figure_name, figure_type):
    """    
    Create one temperature figure and one density ratio figure (like in figures 14.4 and 14.5b
    in Anderson pages 609 and 610), for a given input of upstream velocity absicca values.
    

    :param u1_list_feet: A numpy array of upstream velocity values, in ft/s, to use as abscissa values
    on the figures. Each line in the array corresponds to the velocity range of a single curve.
    :param engauge_list: A list of n by 2 numpy arrays, where each array has n datapoints, generated by
    Engauge, for one curve.
    :param figure_type: 'temperature' or 'density' depending on which type of figure is to be plotted.
    :param figure_name: The name of the output png file (excluding the .png ending).
    """
    # Note: Altitude is in ft.
    altitude = constants.altitude
    number_of_curves = len(altitude)
    # Pressure and temperature values are obtained from tables from Huber 1963
    # (Anderson reference [165]).
    p1_vector = constants.p1_upstream
    T1_vector = constants.T1_upstream

    # We can assume perfect gas before shock to calculate upstream properties.
    rho1_vector = p1_vector / (constants.R * T1_vector)
    h1_vector = constants.c_p * T1_vector
    density_increase_guess = 10.
    rho2_guess_vector = density_increase_guess * rho1_vector
    
    # Need upstream velocity values in m/s to use in calculations.
    # Also create a list of vectors to store computation results for temperature and density ratio.
    # Since each curve has a different range of upstream velocities the number of  values
    # computed for temperature and density ratios is different for different curves.
    u1_list = []
    T2_list = []
    rho_ratio_list = []
    for i, u1_vector_feet in enumerate(u1_list_feet):
        u1_vector = u1_vector_feet * constants.feet_to_m
        u1_list.append(u1_vector)
        vector_length = len(u1_vector_feet)
        T2_vector = numpy.empty(vector_length)
        T2_list.append(T2_vector)
        rho_ratio_vector = numpy.empty(vector_length)
        rho_ratio_list.append(rho_ratio_vector)

    # Outer loop decides at what altitude we are at on the figure and so data for one curve is 
    # created for each passing through the outer loop.
    # T2_array = numpy.empty([number_of_curves, vector_length])
    # rho_ratio_array = numpy.empty([number_of_curves, vector_length])
    for u1_vector, p1, rho1, h1, rho2_guess, T2_vector, rho_ratio_vector in \
            zip(u1_list, p1_vector, rho1_vector, h1_vector, rho2_guess_vector, T2_list, rho_ratio_list):
            # The inner loop loops over all the u1 velocities on the abscissa of the figure.
            for j, u1 in enumerate(u1_vector):
                out_dict = calculators.calculate_p_rho_h(u1, p1, rho1, h1, rho2_guess)
                p2 = out_dict['pressure']
                rho2 = out_dict['density']
                T2 = calculators.srinivasan_T(p2, rho2)
                T2_vector[j] = T2
                rho_ratio_vector[j] = rho2 / rho1

    if figure_type == 'temperature':
        figure = pyplot.figure()
        axes = figure.add_subplot(111)
        for u1_vector_feet, T2_vector in zip(u1_list_feet, T2_list):
            pyplot.plot(u1_vector_feet, T2_vector, 'b')
        for engauge_array in engauge_list:
            pyplot.plot(engauge_array[:,0], engauge_array[:,1], 'r')
        # for i in range(engauge_list.shape[1]-1):
        #     curve_index = i+1
        #     pyplot.plot(engauge_list[:,0], engauge_list[:,curve_index], 'r')                        
        xlabel = r'$u_{1}, ft/s$'
        axes.set_xlabel(xlabel)
        ylabel = r'$T_{2}, K$'
        axes.set_ylabel(ylabel)
        print 'Figure ' + figure_name + '.png' + ' has been created.'
        pylab.savefig(figure_name+'.png')

    if figure_type == 'density':
        figure = pyplot.figure()
        axes = figure.add_subplot(111)
        for u1_vector_feet, rho_ratio_vector in zip(u1_list_feet, rho_ratio_list):
            pyplot.plot(u1_vector_feet, rho_ratio_vector, 'b')
        for engauge_array in engauge_list:
            pyplot.plot(engauge_array[:,0], engauge_array[:,1], 'r')
        xlabel = r'$u_{1}, ft/s$'
        axes.set_xlabel(xlabel)
        ylabel = r'$\frac{\rho_{2}}{\rho_{1}}$'
        axes.set_ylabel(ylabel, rotation='horizontal')
        print 'Figure ' + figure_name + '.png' + ' has been created.'
        pylab.savefig(figure_name+'.png')