def process_surface_adjoint(config_filename, filter_type='LAPLACE', marker_name='airfoil', chord_length=1.0): print('') print( '-------------------------------------------------------------------------' ) print( '| SU2 Suite (Process Surface Adjoint) |' ) print( '-------------------------------------------------------------------------' ) print('') # some other defaults c_clip = 0.01 # percent chord to truncate fft_copy = 5 # number of times to copy the fft signal smth_len = 0.05 # percent chord smoothing window length lapl_len = 1e-4 # laplace smoothing parameter # read config file config_data = libSU2.Get_ConfigParams(config_filename) surface_filename = config_data['SURFACE_ADJ_FILENAME'] + '.csv' print surface_filename mesh_filename = config_data['MESH_FILENAME'] gradient = config_data['ADJ_OBJFUNC'] print('Config filename = %s' % config_filename) print('Surface filename = %s' % surface_filename) print('Filter Type = %s' % filter_type) # read adjoint data adj_data = np.genfromtxt(surface_filename, dtype=float, delimiter=',', skip_header=1) # read mesh data mesh_data = libSU2_mesh.Read_Mesh(mesh_filename) # proces adjoint data P = map(int, adj_data[:, 0]) X = adj_data[:, 6].copy() Y = adj_data[:, 7].copy() Sens = adj_data[:, 1].copy() PsiRho = adj_data[:, 2].copy() I = range(0, len(P)) # important - for unsorting durring write # store in dict by point index adj_data_dict = dict(zip(P, zip(X, Y, Sens, PsiRho, I))) # sort airfoil points iP_sorted, _ = libSU2_mesh.sort_Airfoil(mesh_data, marker_name) assert (len(iP_sorted) == len(P)) # rebuild airfoil loop i = 0 for this_P in iP_sorted: # the adjoint data entry this_adj_data = adj_data_dict[this_P] # re-sort P[i] = this_P X[i] = this_adj_data[0] Y[i] = this_adj_data[1] Sens[i] = this_adj_data[2] PsiRho[i] = this_adj_data[3] I[i] = this_adj_data[4] # next i = i + 1 #: for each point # calculate arc length S = np.sqrt(np.diff(X)**2 + np.diff(Y)**2) / chord_length S = np.cumsum(np.hstack([0, S])) # tail trucating, by arc length I_clip_lo = S < S[0] + c_clip I_clip_hi = S > S[-1] - c_clip S_clip = S.copy() Sens_clip = Sens.copy() Sens_clip[I_clip_hi] = Sens_clip[I_clip_hi][0] Sens_clip[I_clip_lo] = Sens_clip[I_clip_lo][-1] # some edge length statistics dS_clip = np.diff(S_clip) min_dS = np.min(dS_clip) mean_dS = np.mean(dS_clip) max_dS = np.max(dS_clip) #print 'min_dS = %.4e ; mean_dS = %.4e ; max_dS = %.4e' % ( min_dS , mean_dS , max_dS ) # -------------------------------------------- # APPLY FILTER if filter_type == 'FOURIER': Freq_notch = [1 / max_dS, np.inf] # the notch frequencies Sens_filter, Frequency, Power = fft_filter(S_clip, Sens_clip, Freq_notch, fft_copy) #Sens_filter = smooth(S_clip,Sens_filter, 0.03,'blackman') # post smoothing elif filter_type == 'WINDOW': Sens_filter = window(S_clip, Sens_clip, smth_len, 'blackman') elif filter_type == 'LAPLACE': Sens_filter = laplace(S_clip, Sens_clip, lapl_len) elif filter_type == 'SHARPEN': Sens_smooth = smooth(S_clip, Sens_clip, smth_len / 5, 'blackman') # pre smoothing Sens_smoother = smooth(S_clip, Sens_smooth, smth_len, 'blackman') Sens_filter = Sens_smooth + (Sens_smooth - Sens_smoother) # sharpener else: raise Exception, 'unknown filter type' # -------------------------------------------- # PLOTTING if pylab_imported: # start plot fig = plt.figure(gradient) plt.clf() #if not fig.axes: # for comparing two filter calls #plt.subplot(1,1,1) #ax = fig.axes[0] #if len(ax.lines) == 4: #ax.lines.pop(0) #ax.lines.pop(0) # SENSITIVITY plt.plot(S, Sens, color='b') # original plt.plot(S_clip, Sens_filter, color='r') # filtered plt.xlim(-0.1, 2.1) plt.ylim(-5, 5) plt.xlabel('Arc Length') plt.ylabel('Surface Sensitivity') #if len(ax.lines) == 4: #seq = [2, 2, 7, 2] #ax.lines[0].set_dashes(seq) #ax.lines[1].set_dashes(seq) plot_filename = os.path.splitext(surface_filename)[0] + '.png' plt.savefig('Sens_' + plot_filename, dpi=300) # zoom in plt.ylim(-0.4, 0.4) plt.savefig('Sens_zoom_' + plot_filename, dpi=300) # SPECTRAL if filter_type == 'FOURIER': plt.figure('SPECTRAL') plt.clf() plt.plot(Frequency, Power) #plt.xlim(0,Freq_notch[0]+10) plt.xlim(0, 200) plt.ylim(0, 0.15) plt.xlabel('Frequency (1/C)') plt.ylabel('Surface Sensitivity Spectal Power') plt.savefig('Spectral_' + plot_filename, dpi=300) #: if spectral plot #: if plot # -------------------------------------------- # SAVE SURFACE FILE # reorder back to input surface points Sens_out = np.zeros(len(S)) Sens_out[I] = Sens_filter # left over from sort adj_data[:, 1] = Sens_out # get surface header surface_orig = open(surface_filename, 'r') header = surface_orig.readline() surface_orig.close() # get list of prefix names prefix_names = libSU2.get_AdjointPrefix(None) prefix_names = prefix_names.values() # add filter prefix, before adjoint prefix surface_filename_split = surface_filename.rstrip('.csv').split('_') if surface_filename_split[-1] in prefix_names: surface_filename_split = surface_filename_split[0:-1] + [ 'filtered' ] + [surface_filename_split[-1]] else: surface_filename_split = surface_filename_split + ['filtered'] surface_filename_new = '_'.join(surface_filename_split) + '.csv' # write filtered surface file (only updates Sensitivity) surface_new = open(surface_filename_new, 'w') surface_new.write(header) for row in adj_data: for i, value in enumerate(row): if i > 0: surface_new.write(', ') if i == 0: surface_new.write('%i' % value) else: surface_new.write('%.16e' % value) surface_new.write('\n') surface_new.close() print('') print( '----------------- Exit Success (Process Surface Adjoint) ----------------' ) print('') return
def process_surface_adjoint( config_filename , filter_type='LAPLACE' , marker_name='airfoil' , chord_length=1.0 ): print('') print('-------------------------------------------------------------------------') print('| SU2 Suite (Process Surface Adjoint) |') print('-------------------------------------------------------------------------') print('') # some other defaults c_clip = 0.01 # percent chord to truncate fft_copy = 5 # number of times to copy the fft signal smth_len = 0.05 # percent chord smoothing window length lapl_len = 1e-4 # laplace smoothing parameter # read config file config_data = libSU2.Get_ConfigParams(config_filename) surface_filename = config_data['SURFACE_ADJ_FILENAME'] + '.csv' print surface_filename mesh_filename = config_data['MESH_FILENAME'] gradient = config_data['OBJECTIVE_FUNCTION'] print('Config filename = %s' % config_filename) print('Surface filename = %s' % surface_filename) print('Filter Type = %s' % filter_type) # read adjoint data adj_data = np.genfromtxt( surface_filename , dtype = float , delimiter = ',' , skip_header = 1 ) # read mesh data mesh_data = libSU2_mesh.Read_Mesh(mesh_filename) # proces adjoint data P = map(int, adj_data[:,0] ) X = adj_data[:,6].copy() Y = adj_data[:,7].copy() Sens = adj_data[:,1].copy() PsiRho = adj_data[:,2].copy() I = range(0,len(P)) # important - for unsorting durring write # store in dict by point index adj_data_dict = dict( zip( P , zip(X,Y,Sens,PsiRho,I) ) ) # sort airfoil points iP_sorted,_ = libSU2_mesh.sort_Airfoil(mesh_data,marker_name) assert(len(iP_sorted) == len(P)) # rebuild airfoil loop i = 0 for this_P in iP_sorted: # the adjoint data entry this_adj_data = adj_data_dict[this_P] # re-sort P[i] = this_P X[i] = this_adj_data[0] Y[i] = this_adj_data[1] Sens[i] = this_adj_data[2] PsiRho[i] = this_adj_data[3] I[i] = this_adj_data[4] # next i = i+1 #: for each point # calculate arc length S = np.sqrt( np.diff(X)**2 + np.diff(Y)**2 ) / chord_length S = np.cumsum( np.hstack([ 0 , S ]) ) # tail trucating, by arc length I_clip_lo = S < S[0] + c_clip I_clip_hi = S > S[-1] - c_clip S_clip = S.copy() Sens_clip = Sens.copy() Sens_clip[I_clip_hi] = Sens_clip[I_clip_hi][0] Sens_clip[I_clip_lo] = Sens_clip[I_clip_lo][-1] # some edge length statistics dS_clip = np.diff(S_clip) min_dS = np.min ( dS_clip ) mean_dS = np.mean( dS_clip ) max_dS = np.max ( dS_clip ) #print 'min_dS = %.4e ; mean_dS = %.4e ; max_dS = %.4e' % ( min_dS , mean_dS , max_dS ) # -------------------------------------------- # APPLY FILTER if filter_type == 'FOURIER': Freq_notch = [ 1/max_dS, np.inf ] # the notch frequencies Sens_filter,Frequency,Power = fft_filter( S_clip,Sens_clip, Freq_notch, fft_copy ) #Sens_filter = smooth(S_clip,Sens_filter, 0.03,'blackman') # post smoothing elif filter_type == 'WINDOW': Sens_filter = window( S_clip, Sens_clip, smth_len, 'blackman' ) elif filter_type == 'LAPLACE': Sens_filter = laplace( S_clip, Sens_clip, lapl_len ) elif filter_type == 'SHARPEN': Sens_smooth = smooth( S_clip, Sens_clip , smth_len/5, 'blackman' ) # pre smoothing Sens_smoother = smooth( S_clip, Sens_smooth, smth_len , 'blackman' ) Sens_filter = Sens_smooth + (Sens_smooth - Sens_smoother) # sharpener else: raise Exception, 'unknown filter type' # -------------------------------------------- # PLOTTING if pylab_imported: # start plot fig = plt.figure(gradient) plt.clf() #if not fig.axes: # for comparing two filter calls #plt.subplot(1,1,1) #ax = fig.axes[0] #if len(ax.lines) == 4: #ax.lines.pop(0) #ax.lines.pop(0) # SENSITIVITY plt.plot(S ,Sens ,color='b') # original plt.plot(S_clip,Sens_filter,color='r') # filtered plt.xlim(-0.1,2.1) plt.ylim(-5,5) plt.xlabel('Arc Length') plt.ylabel('Surface Sensitivity') #if len(ax.lines) == 4: #seq = [2, 2, 7, 2] #ax.lines[0].set_dashes(seq) #ax.lines[1].set_dashes(seq) plot_filename = os.path.splitext(surface_filename)[0] + '.png' plt.savefig('Sens_'+plot_filename,dpi=300) # zoom in plt.ylim(-0.4,0.4) plt.savefig('Sens_zoom_'+plot_filename,dpi=300) # SPECTRAL if filter_type == 'FOURIER': plt.figure('SPECTRAL') plt.clf() plt.plot(Frequency,Power) #plt.xlim(0,Freq_notch[0]+10) plt.xlim(0,200) plt.ylim(0,0.15) plt.xlabel('Frequency (1/C)') plt.ylabel('Surface Sensitivity Spectal Power') plt.savefig('Spectral_'+plot_filename,dpi=300) #: if spectral plot #: if plot # -------------------------------------------- # SAVE SURFACE FILE # reorder back to input surface points Sens_out = np.zeros(len(S)) Sens_out[I] = Sens_filter # left over from sort adj_data[:,1] = Sens_out # get surface header surface_orig = open(surface_filename,'r') header = surface_orig.readline() surface_orig.close() # get list of prefix names prefix_names = libSU2.get_AdjointPrefix(None) prefix_names = prefix_names.values() # add filter prefix, before adjoint prefix surface_filename_split = surface_filename.rstrip('.csv').split('_') if surface_filename_split[-1] in prefix_names: surface_filename_split = surface_filename_split[0:-1] + ['filtered'] + [surface_filename_split[-1]] else: surface_filename_split = surface_filename_split + ['filtered'] surface_filename_new = '_'.join(surface_filename_split) + '.csv' # write filtered surface file (only updates Sensitivity) surface_new = open(surface_filename_new,'w') surface_new.write(header) for row in adj_data: for i,value in enumerate(row): if i > 0: surface_new.write(', ') if i == 0: surface_new.write('%i' % value ) else: surface_new.write('%.16e' % value ) surface_new.write('\n') surface_new.close() print('') print('----------------- Exit Success (Process Surface Adjoint) ----------------') print('') return