Beispiel #1
0
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
Beispiel #2
0
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