def __cost_end_func(self,
                        no_alt_range_int,
                        spike,
                        CEA,
                        downstream_factor=1.2,
                        chr_mesh_n=120,
                        no_core=1):
        alt_range = np.linspace(0, 9144, no_alt_range_int)

        # shuffle arrays so each core computes similar complexity on average
        np.random.shuffle(alt_range)
        (p_atm_r, T_atm_r, rho_atm_r) = gd.standard_atmosphere(alt_range)

        thrust_range = self.__multicore_thrust_compute(spike,
                                                       alt_range,
                                                       CEA.gamma,
                                                       downstream_factor=1.2,
                                                       chr_mesh_n=chr_mesh_n,
                                                       no_core=no_core)

        # unshuffle arrays
        ordered_idx = np.argsort(alt_range)
        alt_range = alt_range[ordered_idx]
        thrust_range = thrust_range[ordered_idx]

        work = np.trapz(thrust_range, alt_range)
        # plt.plot(alt_range,thrust_range,'o')
        # plt.show()
        print('work = ' + str(work))

        ## heat transfer required
        total_heat_flux = heat_flux(CEA.Pr, CEA.cp, CEA.gamma, CEA.c, CEA.w,
                                    CEA.T_c, T_w, spike)

        return (work, total_heat_flux)
    def __design_angelino_nozzle(self, design_alt, truncate_ratio, CEA, r_e):
        """ Can be a class function, will edit going forwards
		"""
        (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])

        PR = CEA.p_c / p_atm

        M_e = gd.PR_expansion_mach(PR, CEA.gamma)

        expansion_ratio = gd.expansion_ratio(1, M_e, CEA.gamma)  #6.64 #8.1273
        # print('Exp. ratio: ' + str(expansion_ratio))
        # print('PR: ' + str(PR))

        A_t = r_e**2 * np.pi / expansion_ratio  # max expansion (r_b = 0, r_e**2 >= A_t*expansion_ratio/np.pi)

        return plug_nozzle(expansion_ratio,
                           A_t,
                           r_e,
                           CEA.gamma,
                           CEA.T_c,
                           CEA.p_c,
                           CEA.a_c,
                           CEA.rho_c,
                           1500,
                           truncate_ratio=truncate_ratio)
Beispiel #3
0
def ideal_thrust(A_t,A_e,gamma,p_c,T_c,rho_c,a_c,altitude,m_dot):

	p_atm,T_atm,rho_atm = gd.standard_atmosphere([altitude])

	epsilon = A_e/A_t
	
	M_e = optimize.fsolve(lambda M: gd.expansion_ratio_zero(1,M,gamma,epsilon),5)
	# print(M_e)
	# throat conditions
	T_ratio,p_ratio,rho_ratio,a_ratio = gd.isentropic_ratios(0,1,gamma)
	T_t = T_ratio*T_c; p_t = p_ratio*p_c; rho_t = rho_ratio*rho_c; a_t = a_ratio*a_c;
	
	# exit conditions
	T_ratio,p_ratio,rho_ratio,a_ratio = gd.isentropic_ratios(0,M_e,gamma)
	T_e = T_ratio*T_c; p_e = p_ratio*p_c; rho_e = rho_ratio*rho_c; a_e = a_ratio*a_c;

	# mass flow rate (constant in ideal case)
	# m_dot = rho_t*A_t*a_t*1 
	# print(m_dot)

	# print('rho calc ' + str(rho_t))
	# print('a_t calc ' + str(a_t))
	# print('V_e calc ' + str(M_e*a_e))
	# print('p_e - p_atm' + str(p_e - p_atm))
	# print('M_e ' + str(M_e))

	return m_dot*M_e*a_e #+ (p_e - p_atm)*A_e
    def __init__(self,
                 design_alt,
                 r_e,
                 gamma,
                 T_c,
                 p_c,
                 a_c,
                 rho_c,
                 n,
                 truncate_ratio=1):
        # input design parameters

        (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])

        PR = p_c / p_atm

        M_e = gd.PR_expansion_mach(PR, gamma)

        expansion_ratio = gd.expansion_ratio(1, M_e, gamma)
        print('Expansion ratio: ' + str(expansion_ratio))

        self.expansion_ratio = expansion_ratio
        self.A_t = r_e**2 * np.pi / expansion_ratio
        self.r_e = r_e
        self.gamma = gamma
        self.n = n
        self.truncate_ratio = truncate_ratio

        self.T_c = T_c
        self.p_c = p_c
        self.a_c = a_c
        self.rho_c = rho_c

        # calculated design parameters
        self.A_e = self.A_t * self.expansion_ratio
        self.r_b = np.sqrt(-self.A_e / np.pi + self.r_e**2)
        self.M_e = optimize.fsolve(
            lambda M: gd.expansion_ratio_zero(1, M, self.gamma, self.
                                              expansion_ratio), 5)

        # DESIGN OF NOZZLE, FUNCTION ORDER IS IMPORTANT
        # NON-OPTIONAL FUNCTION RUNS
        self.design_nozzle()

        self.truncate_nozzle()

        self.calc_flow_properties()

        self.arc_length_coord()

        # OPTIONAL FUNCTION CONSTANTS
        self.converge_section = 0  # whether the converging section has been designed
def cost_func_contour_params(params,
                             spike,
                             T_w,
                             CEA,
                             alpha,
                             beta,
                             chr_mesh_n=145,
                             no_core=4):
    params = np.asarray(params)
    if len(params.shape) > 1:
        raise ValueError('Input params not correct shape. Should be 1D array')
    x_vals, y_vals = np.split(params, 2)

    spike.x = x_vals
    spike.y = y_vals

    ##	thurst estimation over altitude
    alt_range = np.linspace(0, 9144, 3 * no_core)

    # shuffle arrays so each core computes similar complexity on average
    np.random.shuffle(alt_range)
    (p_atm_r, T_atm_r, rho_atm_r) = gd.standard_atmosphere(alt_range)

    thrust_range = multicore_thrust_compute(spike,
                                            alt_range,
                                            CEA.gamma,
                                            downstream_factor=1.2,
                                            chr_mesh_n=chr_mesh_n,
                                            no_core=no_core)

    # unshuffle arrays
    ordered_idx = np.argsort(alt_range)
    alt_range = alt_range[ordered_idx]
    thrust_range = thrust_range[ordered_idx]

    work = np.trapz(alt_range, thrust_range)
    # plt.plot(alt_range,thrust_range,'o')
    # plt.show()

    ## heat transfer required
    total_heat_flux = heat_flux(CEA.Pr, CEA.cp, CEA.gamma, CEA.c, CEA.w,
                                CEA.T_c, T_w, spike)

    return -alpha * work + beta * total_heat_flux
def COST_FNC(params, spike, T_w, CEA, alpha, beta, chr_mesh_n=145, no_core=4):
    try:
        x_vals, y_vals = params
    except ValueError:
        x_vals, y_vals = np.split(params, 2)

    spike.x = x_vals
    spike.y = y_vals

    ### CALCULATING COST
    ##	thurst estimation over altitude
    alt_range = np.linspace(0, 9144, 3 * no_core)
    np.random.shuffle(alt_range)
    (p_atm_r, T_atm_r, rho_atm_r) = gd.standard_atmosphere(alt_range)
    #print(CEA.p_c/p_atm_r)
    #thrust_range = multicore_thrust_compute(spike,alt_range,CEA.gamma,downstream_factor=1.2,chr_mesh_n=50,no_core=4)
    thrust_range = multicore_thrust_compute(spike,
                                            alt_range,
                                            CEA.gamma,
                                            downstream_factor=1.2,
                                            chr_mesh_n=chr_mesh_n,
                                            no_core=no_core)

    # unshuffle of arrays
    ordered_idx = np.argsort(alt_range)
    alt_range = alt_range[ordered_idx]
    thrust_range = thrust_range[ordered_idx]

    work = np.trapz(thrust_range, alt_range)
    print("work = " + str(work) + ". Bounds [" + str(alt_range[0]) + ', ' +
          str(alt_range[-1]) + ']')
    plt.plot(alt_range, thrust_range, 'o')
    plt.show()
    ## heat transfer required

    #total_heat_flux = heat_flux(CEA.Pr,CEA.cp,CEA.gamma,CEA.c,CEA.w,CEA.T_c,T_w,spike)

    # print('Work*alpha: ' + str(work*alpha))
    # print('Heat flux*beta: ' + str(total_heat_flux*beta))
    return -alpha * work  #+ total_heat_flux*beta
R = (1 - 1 / gamma) * 1.8292 * 1000  #1.8292 1.6196
a_c = np.sqrt(gamma * (1 - 1 / gamma) * 200.07 * T_c)
n = 1000

spike = plug_nozzle(expansion_ratio,
                    A_t,
                    r_e,
                    gamma,
                    T_c,
                    p_c,
                    a_c,
                    rho_c,
                    n,
                    truncate_ratio=1.0)
alts = np.linspace(0, 15000, 100)
p_atms, T_atms, rho_atms = gd.standard_atmosphere(alts)

thrusts = np.zeros(p_atms.shape)

for i in range(len(p_atms)):
    thrusts[i] = spike.calc_ideal_thrust(p_atms[i])

plt.plot(alts, thrusts)

# MOC_mesh = chr_mesh(spike,gamma,0,50,downstream_factor=1.2,plot_chr=1)

#plt.plot(MOC_mesh.x,MOC_mesh.y,'ro')

#plt.plot(MOC_mesh.x[MOC_mesh.ID_jet_boundary],MOC_mesh.y[MOC_mesh.ID_jet_boundary],'go-')
# MOC_mesh.compute_thrust('nearest',10)
#plt.plot(MOC_mesh.x[MOC_mesh.ID_contour_chr],MOC_mesh.y[MOC_mesh.ID_contour_chr],'bo-')
Beispiel #8
0
                                      beta,
                                      design_alt_init,
                                      truncate_ratio_init,
                                      chr_mesh_n=120,
                                      no_alt_range=30,
                                      no_core=1)
except:
    pass
#design diverging section, 20% truncation

plug1 = opt_aero.spike_init

plug1.define_compression(1.15 / 1000, 4.51 / 1000, 1, 12.91 / 1000, 10000)

print('Thrust = ' +
      str(plug1.calc_ideal_thrust(gd.standard_atmosphere([9144])[0])))
print('Throat area = ' + str(plug1.A_t))
print('Expansion ratio = ' + str(plug1.expansion_ratio))
#plug1.plot_contour(plt)
#plt.axis('equal')

tck = interpolate.splrep(plug1.x, plug1.y)

plt.plot(plug1.x, plug1.y, plug1.x, interpolate.splev(plug1.x, tck), 'ro')

init_angle = np.arctan(interpolate.splev(plug1.x[0], tck, der=1))

print("inital angle: " + str(init_angle * 180 / np.pi))
plt.show()

plug1.save_to_csv()
    def record_breaker_nozzle():
        r_e = 0.027  # r_e = 0.056 #0.034 # likely too large

        ## CONSTANTS OF DESIGN FOR HEAT FLUX
        #user input variable in metric units:
        T_w = 600  #[K] desired temperature of nozzle

        ## CONSTANTS OF SIM
        alpha = 1  #0.07/8 # 0.07/8 : 1 ratio of alpha : beta gives very similar weights
        beta = 0  #1
        design_alt = 9144
        truncate_ratio = 1  # bounds on truncate < 0.1425

        gamma = 1.237  #np.mean([1.2534,1.2852])
        T_c = 2831.47  # combustion chamber temperature
        p_c = 3102640.8  # combustion chamber pressure
        rho_c = 3.3826  # combustion chamber density
        a_c = np.sqrt(gamma * (1 - 1 / gamma) * 200.07 *
                      T_c)  # combustion chamber sound speed

        plug1 = plug_nozzle(design_alt,
                            r_e,
                            gamma,
                            T_c,
                            p_c,
                            a_c,
                            rho_c,
                            100,
                            truncate_ratio=truncate_ratio)

        # zero_x = np.linspace(plug1.x[-1],plug1.length,20)
        # zero_y = np.zeros(zero_x.shape)

        (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])
        print('Ideal thrust: ' + str(plug1.calc_ideal_thrust(p_atm)))

        fig, ax1 = plt.subplots(1, 1)
        plug1.plot_contour(ax1)

        ax1.set_title('Mach Isentropic Expansion Contour Plot')

        # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
        # print("Mass flow rate: " + str(m_dot))
        plug1.plot_exhaust_contourf(ax1, plug1.M, n=100)

        ax1.set_xlabel('x (m)')
        ax1.set_ylabel('y (m)')
        # plug1.save_to_csv()
        name = "final_report/mach_isentropic_plot"
        fig.set_size_inches(18.5, 10.5)

        plt.savefig(name, dpi=100)
        plt.show()
        plt.close()
        # print(plug1.alpha)

        ## OTHER PLOTS
        fig, (ax2, ax3, ax4) = plt.subplots(3, 1)
        plug1.plot_contour(ax2)

        ax2.set_title('Temperature Isentropic Expansion Contour Plot')

        # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
        # print("Mass flow rate: " + str(m_dot))
        plug1.plot_exhaust_contourf(ax2, plug1.T, n=100)

        ax2.set_xlabel('x (m)')
        ax2.set_ylabel('y (m)')
        # plug1.save_to_csv()
        fig.set_size_inches(18.5, 10.5)

        ####
        plug1.plot_contour(ax3)

        ax3.set_title('Pressure Isentropic Expansion Contour Plot')

        # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
        # print("Mass flow rate: " + str(m_dot))
        plug1.plot_exhaust_contourf(ax3, plug1.p, n=100)

        ax3.set_xlabel('x (m)')
        ax3.set_ylabel('y (m)')
        # plug1.save_to_csv()
        fig.set_size_inches(18.5, 10.5)

        plug1.plot_contour(ax4)

        ax4.set_title('Density Isentropic Expansion Contour Plot')

        # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
        # print("Mass flow rate: " + str(m_dot))
        plug1.plot_exhaust_contourf(ax4, plug1.rho, n=100)

        ax4.set_xlabel('x (m)')
        ax4.set_ylabel('y (m)')
        # plug1.save_to_csv()
        name = "final_report/T_p_rho"
        fig.set_size_inches(18.5, 10.5)

        plt.savefig(name, dpi=100)
        plt.show()
        plt.close()
    def test_stand_nozzle():
        r_e = 0.027  #0.034 # likely too large

        ## CONSTANTS OF DESIGN FOR HEAT FLUX
        #user input variable in metric units:
        T_w = 600  #[K] desired temperature of nozzle

        ## CONSTANTS OF SIM
        alpha = 1  #0.07/8 # 0.07/8 : 1 ratio of alpha : beta gives very similar weights
        beta = 0  #1
        design_alt = 9144
        truncate_ratio = 1  # bounds on truncate < 0.1425

        gamma = 1.237  #np.mean([1.2534,1.2852])
        T_c = 2831.47  # combustion chamber temperature
        p_c = 3102640.8  # combustion chamber pressure
        rho_c = 3.3826  # combustion chamber density
        a_c = np.sqrt(gamma * (1 - 1 / gamma) * 200.07 *
                      T_c)  # combustion chamber sound speed

        plug1 = plug_nozzle(design_alt,
                            r_e,
                            gamma,
                            T_c,
                            p_c,
                            a_c,
                            rho_c,
                            100,
                            truncate_ratio=1)
        print('Throat area: ' + str(plug1.A_t))
        (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])

        def make_isentropic_plots(plug1, p_atm):
            print('Ideal thrust: ' + str(plug1.calc_ideal_thrust(p_atm)))

            fig, ax1 = plt.subplots(1, 1)
            plug1.plot_contour(ax1)

            ax1.set_title('Mach Isentropic Expansion Contour Plot')

            # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
            # print("Mass flow rate: " + str(m_dot))
            plug1.plot_exhaust_contourf(ax1, plug1.M, n=100)

            ax1.set_xlabel('x (m)')
            ax1.set_ylabel('y (m)')
            # plug1.save_to_csv()
            name = "final_report/mach_isen_plot_lab"
            fig.set_size_inches(18.5, 10.5)

            plt.savefig(name, dpi=100)
            plt.show()
            plt.close()
            # print(plug1.alpha)

            ## OTHER PLOTS
            fig, (ax2, ax3, ax4) = plt.subplots(3, 1)
            plug1.plot_contour(ax2)

            ax2.set_title('Temperature Isentropic Expansion Contour Plot')

            # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
            # print("Mass flow rate: " + str(m_dot))
            plug1.plot_exhaust_contourf(ax2, plug1.T, n=100)

            ax2.set_xlabel('x (m)')
            ax2.set_ylabel('y (m)')
            # plug1.save_to_csv()
            fig.set_size_inches(18.5, 10.5)

            ####
            plug1.plot_contour(ax3)

            ax3.set_title('Pressure Isentropic Expansion Contour Plot')

            # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
            # print("Mass flow rate: " + str(m_dot))
            plug1.plot_exhaust_contourf(ax3, plug1.p, n=100)

            ax3.set_xlabel('x (m)')
            ax3.set_ylabel('y (m)')
            # plug1.save_to_csv()
            fig.set_size_inches(18.5, 10.5)

            plug1.plot_contour(ax4)

            ax4.set_title('Density Isentropic Expansion Contour Plot')

            # m_dot = plug1.rho[0]*plug1.A_t*plug1.V[0]
            # print("Mass flow rate: " + str(m_dot))
            plug1.plot_exhaust_contourf(ax4, plug1.rho, n=100)

            ax4.set_xlabel('x (m)')
            ax4.set_ylabel('y (m)')
            # plug1.save_to_csv()
            name = "final_report/isen_plots_lab"
            fig.set_size_inches(18.5, 10.5)

            plt.savefig(name, dpi=100)
            plt.show()
            plt.close()

        def make_MOC_plot(plug1, design_alt, gamma, n):

            #mesh plot
            plug1.plot_contour(plt)
            plt.xlabel('x (m)')
            plt.ylabel('y (m)')
            plt.title('Mesh generated by M.O.C.')
            plug_mesh = chr_mesh(plug1,
                                 gamma,
                                 design_alt,
                                 30,
                                 downstream_factor=1.1,
                                 plot_chr=1)

            # plug1.save_to_csv()
            name = "final_report/MOC_mesh"
            plt.axis('equal')

            plt.savefig(name, dpi=100)
            plt.show()
            plt.close()

            # mach plot
            plug_mesh = chr_mesh(plug1,
                                 gamma,
                                 design_alt,
                                 120,
                                 downstream_factor=1.0,
                                 plot_chr=0)

            thrust = plug_mesh.compute_thrust('linear', 100)
            print('MOC thrust: ' + str(thrust))
            tck = interpolate.splrep(plug_mesh.x[plug_mesh.ID_contour_chr],
                                     plug_mesh.y[plug_mesh.ID_contour_chr])
            fig, (ax1) = plt.subplots(1, 1)
            plug1.plot_contour(ax1)
            ax1.axes.get_xaxis().set_ticklabels([])
            ax1.axes.get_yaxis().set_ticklabels([])
            X_plt = np.linspace(0, plug_mesh.x.max(), 100)
            Y_plt = np.linspace(0, plug_mesh.y.min(), 100)
            X_plt, Y_plt = np.meshgrid(X_plt, Y_plt)

            invalid_grid = interpolate.splev(X_plt.flatten(),
                                             tck) < Y_plt.flatten()
            invalid_grid = invalid_grid.reshape(X_plt.shape)

            M_contour = interpolate.griddata((plug_mesh.x, plug_mesh.y),
                                             plug_mesh.M, (X_plt, Y_plt),
                                             method='linear')

            #ax1.plot(X_plt[valid_grid],Y_plt[invalid_grid],'.')

            M_contour[invalid_grid] = np.nan
            # ax1.plot(X_plt.flatten(),interpolate.splev(X_plt.flatten(),tck),'.')
            ax1.set_aspect('equal', 'box')
            for item in ([ax1.title, ax1.xaxis.label, ax1.yaxis.label] +
                         ax1.get_xticklabels() + ax1.get_yticklabels()):
                item.set_fontsize(20)
            M_fill = ax1.contourf(X_plt, -Y_plt, M_contour, cmap=cm.jet)
            cbar = plt.colorbar(M_fill, ax=ax1, orientation='horizontal')
            cbar.ax.tick_params(labelsize=20)
            name = "final_report/M_contour_MOC"
            fig.set_size_inches(18.5, 10.5)
            # ax1.set_xlabel('x (m)')
            # ax1.set_ylabel('y (m)')
            # ax1.set_title('M Contour Plot for M.O.C.')
            ax1.set_aspect('equal', 'box')
            plt.savefig(name, dpi=100)
            plt.show()
            plt.close()

            fig, (ax2) = plt.subplots(1, 1)

            ax2.axes.get_xaxis().set_ticklabels([])
            ax2.axes.get_yaxis().set_ticklabels([])

            for item in ([ax2.title, ax2.xaxis.label, ax2.yaxis.label] +
                         ax2.get_xticklabels() + ax2.get_yticklabels()):
                item.set_fontsize(20)
            # velocity plot
            U = np.cos(plug_mesh.theta) * plug_mesh.V
            V = np.sin(plug_mesh.theta) * plug_mesh.V
            x_grid, y_grid = np.meshgrid(np.linspace(0, plug_mesh.x.max(), 30),
                                         np.linspace(0, plug_mesh.y.min(), 20))
            invalid_grid = interpolate.splev(x_grid.flatten(),
                                             tck) < y_grid.flatten()
            invalid_grid = invalid_grid.reshape(x_grid.shape)

            u_grid = interpolate.griddata((plug_mesh.x, plug_mesh.y),
                                          U, (x_grid, y_grid),
                                          method='linear')
            v_grid = interpolate.griddata((plug_mesh.x, plug_mesh.y),
                                          V, (x_grid, y_grid),
                                          method='linear')
            mag_grid = interpolate.griddata((plug_mesh.x, plug_mesh.y),
                                            plug_mesh.V, (x_grid, y_grid),
                                            method='linear')

            mag_grid[invalid_grid] = np.nan

            plug1.plot_contour(ax2)
            fig.set_size_inches(18.5, 10.5)
            Q = ax2.quiver(x_grid,
                           -y_grid,
                           u_grid,
                           -v_grid,
                           mag_grid,
                           cmap=cm.jet,
                           alpha=0.5)
            cbar = plt.colorbar(Q, ax=ax2, orientation="horizontal")
            cbar.ax.tick_params(labelsize=20)
            ax2.set_aspect('equal', 'box')
            # ax2.set_title('Velocity Vector Plot (m/s)')
            # ax2.set_xlabel('x (m)')
            # ax2.set_ylabel('y (m)')
            name = "final_report/V_vec"
            plt.savefig(name, dpi=100)
            plt.show()

            # other property contours

        make_MOC_plot(plug1, design_alt, gamma, 10)
Beispiel #11
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()
def COST_FNC(design_alt, truncate_ratio, T_w, CEA, r_e, alpha, beta, n):

    ### DESIGNING NOZZLE
    (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])

    PR = CEA.p_c / p_atm

    M_e = gd.PR_expansion_mach(PR, CEA.gamma)

    expansion_ratio = gd.expansion_ratio(1, M_e, CEA.gamma)  #6.64 #8.1273
    # print('Exp. ratio: ' + str(expansion_ratio))
    # print('PR: ' + str(PR))

    A_t = r_e**2 * np.pi / expansion_ratio  # max expansion (r_b = 0, r_e**2 >= A_t*expansion_ratio/np.pi)

    spike = plug_nozzle(expansion_ratio,
                        A_t,
                        r_e,
                        CEA.gamma,
                        CEA.T_c,
                        CEA.p_c,
                        CEA.a_c,
                        CEA.rho_c,
                        n,
                        truncate_ratio=truncate_ratio)

    ### CALCULATING COST
    ##	thurst estimation over altitude
    alt_range = np.linspace(0, 12000, 30)
    (p_atm_r, T_atm_r, rho_atm_r) = gd.standard_atmosphere(alt_range)
    #print(CEA.p_c/p_atm_r)
    thrust_range = np.zeros(alt_range.shape)
    for i in range(alt_range.shape[0]):
        if i == 10:
            MOC_mesh = MOC.chr_mesh(spike,
                                    gamma,
                                    alt_range[i],
                                    50,
                                    downstream_factor=1.2,
                                    plot_chr=0)
        else:
            MOC_mesh = MOC.chr_mesh(spike,
                                    gamma,
                                    alt_range[i],
                                    50,
                                    downstream_factor=1.2,
                                    plot_chr=0)

        thrust_range[i] = MOC_mesh.compute_thrust('nearest', 10)

    work = np.trapz(thrust_range, alt_range)
    plt.plot(alt_range, thrust_range, 'o')
    plt.show()
    ## heat transfer required

    total_heat_flux = heat_flux(CEA.Pr, CEA.cp, CEA.gamma, CEA.c, CEA.w,
                                CEA.T_c, T_w, spike)

    # print('Work*alpha: ' + str(work*alpha))
    # print('Heat flux*beta: ' + str(total_heat_flux*beta))
    return -alpha * work + total_heat_flux * beta
Beispiel #13
0
if __name__ == '__main__':


	# engine constants
	r_e = 0.027
	A_e = np.pi*r_e**2
	gamma = 1.237 #np.mean([1.2534,1.2852])
	T_c = 2831.47 # combustion chamber temperature
	p_c = 3102640.8 # combustion chamber pressure
	rho_c = 3.3826 # combustion chamber density 
	a_c = np.sqrt(gamma*(1-1/gamma)*200.07*T_c) # combustion chamber sound speed

	altitude = 9144

	p_atm,T_atm,rho_atm = gd.standard_atmosphere([altitude])

	plug1 = plug_nozzle(altitude,r_e,gamma,T_c,p_c,a_c,rho_c,100,truncate_ratio = 1)

	m = (plug1.lip_y - plug1.y[0])/(plug1.lip_x - plug1.x[0])

	# simulation constant 
	num_t = 10

	t_vec = np.linspace(0,4,num_t)
	
	alpha = 0.03/1000
	beta = 0.05/1000


	thrust_vector_alpha = ideal_thrust_vector(alpha,t_vec,plug1,A_e,gamma,p_c,T_c,rho_c,a_c,altitude)
    #user input variable in metric units:
    T_w = 600  #[K] desired temperature of nozzle

    ## CONSTANTS OF SIM
    alpha = 1  #0.07/8 # 0.07/8 : 1 ratio of alpha : beta gives very similar weights
    beta = 0  #1
    design_alt = 9144
    truncate_ratio = 1  # bounds on truncate < 0.1425

    gamma = 1.237  #np.mean([1.2534,1.2852])
    T_c = 2831.47  # combustion chamber temperature
    p_c = 3102640.8  # combustion chamber pressure
    rho_c = 3.3826  # combustion chamber density
    a_c = np.sqrt(gamma * (1 - 1 / gamma) * 200.07 *
                  T_c)  # combustion chamber sound speed
    (p_atm, T_atm, rho_atm) = gd.standard_atmosphere([design_alt])

    PR = p_c / p_atm

    M_e = gd.PR_expansion_mach(PR, gamma)

    expansion_ratio = gd.expansion_ratio(1, M_e, gamma)  #6.64 #8.1273
    # print('Exp. ratio: ' + str(expansion_ratio))
    # print('PR: ' + str(PR))

    A_t = r_e**2 * np.pi / expansion_ratio  # max expansion (r_b = 0, r_e**2 >= A_t*expansion_ratio/np.pi)

    plug1 = plug_nozzle(expansion_ratio,
                        A_t,
                        r_e,
                        gamma,