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)
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-')
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)
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
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,