def design_nozzle(self):
        # discrete contour design variables
        self.M = np.linspace(1, self.M_e, self.n)
        self.A = self.A_t * gd.expansion_ratio(1, self.M, self.gamma)
        self.alpha = gd.prandtl_meyer(self.M_e, self.gamma) - gd.prandtl_meyer(
            self.M, self.gamma) + gd.mach_angle(self.M)
        self.l = (self.r_e - np.sqrt(
            np.abs(self.r_e**2 -
                   (self.A * self.M * np.sin(self.alpha) / np.pi)))) / np.sin(
                       self.alpha)

        self.x = self.l * np.cos(self.alpha)
        self.y = self.l * np.sin(self.alpha)

        self.centre_spike()

        self.length = self.x.max()
Example #2
0
    def compute_initial_expansion_fan(self):
        M_max = gd.PR_expansion_mach(self.PR, self.gamma)
        # print('M_max: ' + str(M_max))
        mach_fan = np.linspace(1.1, M_max, self.n)

        (T_ratio, p_ratio, rho_ratio,
         a_ratio) = gd.isentropic_ratios(0, mach_fan, self.gamma)

        V_fan = a_ratio * self.spike.a_c * mach_fan

        W_fan = V_fan / self.V_l

        theta_fan = -gd.prandtl_meyer(mach_fan, self.gamma) + self.slope_init

        angle_fan = gd.mach_angle(mach_fan)

        # print(180/np.pi*np.arcsin(np.sqrt((gamma-1)/2*(1/W_fan**2-1))))
        # print(W_fan)

        # print(angle_fan*180/np.pi)

        x_fan = np.ones(angle_fan.shape) * self.spike.lip_x

        y_fan = np.ones(angle_fan.shape) * self.spike.lip_y

        #print(theta_fan*180/np.pi)
        # print(gd.mach_angle_velocity_ratio(gd.prandtl_meyer(2.3,gamma),0.3,gamma))

        initial_point = self.contour_point(chr_point(self.gamma, x_fan[0],
                                                     y_fan[0], theta_fan[0],
                                                     W_fan[0], 'N/A'),
                                           plot_chr=self.plot_chr)
        self.ID += 1
        self.ID_contour_chr.pop(0)
        self.chr_array = np.append(self.chr_array, initial_point)

        for point in x_fan[1:-1]:
            temp_point = chr_point(self.gamma, x_fan[self.ID], y_fan[self.ID],
                                   theta_fan[self.ID], W_fan[self.ID], 'N/A')
            new_point = self.general_point(temp_point,
                                           self.chr_array[self.ID - 1],
                                           plot_chr=self.plot_chr)
            # adding to arrays
            self.chr_array = np.append(self.chr_array, new_point)
            self.ID += 1

        first_jet = chr_point(self.gamma, x_fan[-1], y_fan[-1], theta_fan[-1],
                              W_fan[-1], 'N/A')
        second_jet = self.jet_boundary_point(first_jet,
                                             self.chr_array[self.ID - 1],
                                             plot_chr=self.plot_chr)
        self.chr_array = np.append(self.chr_array, second_jet)
        #self.ID_jet_boundary.append(self.ID)
        self.ID += 1
        self.add_break_ID()
Example #3
0
    def __init__(self,spike,gamma,altitude,n,downstream_factor=1.1,plot_chr=0,clean_mesh=1):

        self.spike =copy.copy(spike); self.gamma = gamma; self.altitude =altitude; self.n = n

        self.downstream_factor = downstream_factor # percentage down after mesh cross with centre to continue meshing
        # constants of iteration

        self.plot_chr = plot_chr


        self.flip_plug() # flips sign of plug if required

        self.slope_init = np.arctan(-(self.spike.lip_x-self.spike.x[0])/(self.spike.lip_y-self.spike.y[0])); 
        #print(self.slope_init*180/np.pi)

        self.tck = interpolate.splrep(self.spike.x,self.spike.y,full_output=0)
        (self.p_atm,self.T_atm,self.rho_atm) = gd.standard_atmosphere([altitude])
        self.gamma = gamma
        self.PR = self.spike.p_c/(self.p_atm)
        self.V_l = np.sqrt(2/(self.gamma-1))*self.spike.a_c

        # Point storage

        self.chr_array = np.array([]) # array for storing points based on ID

        # logs characteristics that have not been intercepted
        self.ID_left_chr = [] 
        self.ID_right_chr = []
        self.ID_jet_boundary = []
        self.ID_contour_chr = []
        #self.ID_next_chr_jet = []
        #self.ID_compression_chr = []

        self.ID = 0 # ID of next point, not yet computed 
        # COMPUTE EXPANSION FAN POINTS (initial data line)
        # construction of initial expansion fan
       
        self.compute_initial_expansion_fan()
        # TODO: COMPUTE CHAR. NET DOWN TO NOZZLE BASE (when A.x > spike.x[-1], switch centre point jet boundary)
        ## after computing initial fan, load all point id's into ordered list showing right and left running characteristics that have not been used to compute a downstream point
        # TODO: COMPUTE NOZZLE BASE PRESSURE
        # while (self.chr_array[self.ID_contour_chr[0]].x <= spike.x.max()):
        #     pass
        # TODO: COMPUTE PLUME DOWNSTREAM OF BASE
        # TODO: COMPUTE THRUST PRODUCED 
        # for point in self.chr_array:
        #     plt.plot(point.x,point.y,'rX')       
        # print(self.ID_left_chr)
        # print(self.ID_right_chr)
        # print(self.ID_jet_boundary)
        # print(self.ID_contour_chr)

        # base conditions
        self.p_b = self.base_pressure()




        self.contour_fan = 1
        self.new_fan = 1
        self.first_base_intercept = 1
        self.centre_line_intercept = 0
        self.END_SIM = 0
        #while (self.chr_array[self.ID_contour_chr[-1]].x <= spike.x.max()):
        while self.chr_point_less_zero() and self.contour_converge():
        ## TODO: COMPUTE EXPANSION FAN UNTIL POINT IS > spike.length in which case, remove from all tracking lists and do not add to chr_array
            ## CONTOUR FAN
            # if (self.contour_fan):
            ID_temp = self.ID_right_chr.pop(0)
            #print(ID_temp)
            if(self.new_fan):
                # intersection
                self.new_fan = 0
                if (self.on_nozzle_contour(self.chr_array[ID_temp])):
                    new_point = self.contour_point(self.chr_array[ID_temp],plot_chr=self.plot_chr)
                    self.chr_array = np.append(self.chr_array,new_point)
                    self.ID += 1
                    # first point
                    ID_temp = self.ID_right_chr.pop(0)
                    new_point = self.general_point(self.chr_array[ID_temp],self.chr_array[self.ID-1],plot_chr=self.plot_chr)
                    self.chr_array = np.append(self.chr_array,new_point)
                    self.ID += 1     
                else:
                    if (self.first_base_intercept):
                        self.first_base_intercept = 0 
                        first_base_point = self.chr_array[self.ID_contour_chr[-1]]
                        #print(self.spike.p_c/self.p_b)
                        M_b = gd.PR_expansion_mach(self.spike.p_c/self.p_b,self.gamma)
                        #print(M_b)
                        theta_b = gd.prandtl_meyer(M_b,self.gamma) - gd.prandtl_meyer(first_base_point.M,self.gamma)
                        W_b = first_base_point.W

                        first_base_point = chr_point(self.gamma,self.spike.x[-1],self.spike.y[-1],theta_b,W_b,'contour')
                        new_point = self.internal_jet_point(first_base_point,self.chr_array[ID_temp],plot_chr=self.plot_chr)
                        self.chr_array = np.append(self.chr_array,new_point)
                        self.ID += 1

                    else: 
                        new_point = self.internal_jet_point(self.chr_array[self.ID_contour_chr[-1]],self.chr_array[ID_temp],plot_chr=self.plot_chr)
                        self.chr_array = np.append(self.chr_array,new_point)

                        self.ID += 1
            elif(ID_temp==-1):
                # self.ID_next_chr_jet.append(self.ID_left_chr.pop(0))   
                # plt.plot(self.chr_array[self.ID_jet_boundary[-1]].x,self.chr_array[self.ID_jet_boundary[-1]].y,'gx')

                new_point = self.general_point(self.chr_array[self.ID_jet_boundary[-1]],self.chr_array[self.ID-1],plot_chr=self.plot_chr)

                self.chr_array = np.append(self.chr_array,new_point)
                #self.ID_left_chr.append(self.ID)

                self.ID += 1
                new_point = self.jet_boundary_point(self.chr_array[self.ID_jet_boundary[-1]],self.chr_array[self.ID-1],plot_chr=self.plot_chr)

                self.chr_array = np.append(self.chr_array,new_point)
                #plt.plot(new_point.x,new_point.y,'gx')
                #self.ID_jet_boundary.append(self.ID)
                self.ID +=1
                self.contour_fan = 0   
                self.add_break_ID()
                self.new_fan = 1
                # if (self.centre_line_intercept):
                #     self.END_SIM = 1 
            else:
                if(self.chr_array[ID_temp].pt_type!="same_fam"):
                    temp1 = self.same_fam_point(self.chr_array[self.ID_right_chr[0]],self.chr_array[ID_temp])
                    temp2 = self.general_point(self.chr_array[ID_temp],self.chr_array[self.ID-1]) 
                    if (temp1.x < temp2.x) and (temp1.x>self.chr_array[ID_temp].x) :
                        #self.ID_right_chr.pop(-1); self.ID_left_chr.pop(-1)
                        #self.compression_offset += 1
                        #self.plot_chr=1
                        self.ID_left_chr.pop(-1)
                        self.ID_right_chr.pop(-1)
                        #print(temp1.x)
                        if (self.plot_chr):
                            plt.plot(self.chr_array[self.ID_right_chr[0]].x,self.chr_array[self.ID_right_chr[0]].y,'bx',self.chr_array[ID_temp].x,self.chr_array[ID_temp].y,'rx')
                            plt.plot(temp1.x,temp1.y,'go')

                            #plt.plot([self.chr_array[ID_temp].x, temp1.x],[self.chr_array[ID_temp].y, temp1.y])
                        self.chr_array = np.append(self.chr_array,temp1)
                  
                        new_point = self.general_point(self.chr_array[-1],self.chr_array[self.ID-1],plot_chr=self.plot_chr) 
                        #plt.plot(self.chr_array[self.ID-1].x,self.chr_array[self.ID-1].y,'ro')
                        self.ID += 1      
                    else:
                        new_point = temp2
                        if (new_point.x<=self.spike.length):
                            pass
                        if (self.plot_chr):
                            plt.plot([self.chr_array[ID_temp].x, temp2.x],[self.chr_array[ID_temp].y, temp2.y],'k',[self.chr_array[self.ID-1].x, temp2.x],[self.chr_array[self.ID-1].y, temp2.y],'k')                    
                    self.ID += 1
                    self.chr_array = np.append(self.chr_array,new_point)
                
            # ## JET BOUNDARY FAN
            # else:
            #     ID_temp = self.ID_right_chr.pop(0)
            #     if(self.new_fan):

            #         new_point = self.general_point(self.chr_array[ID_temp],self.chr_array[self.ID_contour_chr[-1]])
            #         self.chr_array = np.append(self.chr_array,new_point)
            #         self.ID += 1
            #         self.new_fan = 0
            #     elif (ID_temp == -1):

            #         new_point=self.jet_boundary_point(self.chr_array[self.ID_next_chr_jet[-1]],self.chr_array[ID_temp -1])
            #         self.chr_array = np.append(self.chr_array, new_point)
            #         self.ID += 1
            #         self.contour_fan = 1
            #         self.new_fan = 1
            #         self.add_break_ID()
            #     else:
            #         new_point = self.general_point(self.chr_array[ID_temp],self.chr_array[ID_temp-1]) 
            #         self.chr_array = np.append(self.chr_array,new_point)

            #         self.ID += 1                   

        ## END OF MOC SECTION #####
        # function order is important
        if(clean_mesh):
            self.clean_data()
        self.to_arrays()
        self.calc_flow_properties()