Beispiel #1
0
def fitting_shape_coefficients(filename,
                               bounds='Default',
                               n=5,
                               return_data=False,
                               return_error=False,
                               optimize_deltaz=False):
    """Fit shape parameters to given data points
        Inputs:
        - filename: name of the file where the original data is
        - bounds: bounds for the shape parameters. If not defined,
                    Default values are used.
        - n: order of the Bernstein polynomial. If bounds is default
                this input will define the order of the polynomial.
                Otherwise the length of bounds (minus one) is taken into 
                consideration"""

    from hausdorff_distance import hausdorff_distance_2D

    def shape_difference(inputs, optimize_deltaz=False):

        if optimize_deltaz == True or optimize_deltaz == [True]:
            y_u = CST(upper['x'],
                      1,
                      deltasz=inputs[-1] / 2.,
                      Au=list(inputs[:n + 1]))
            y_l = CST(lower['x'],
                      1,
                      deltasz=inputs[-1] / 2.,
                      Al=list(inputs[n + 1:-1]))
        else:
            y_u = CST(upper['x'],
                      1,
                      deltasz=deltaz / 2.,
                      Au=list(inputs[:n + 1]))
            y_l = CST(lower['x'],
                      1,
                      deltasz=deltaz / 2.,
                      Al=list(inputs[n + 1:]))
        # Vector to be compared with
        a_u = {'x': upper['x'], 'y': y_u}
        a_l = {'x': lower['x'], 'y': y_l}

        b_u = upper
        b_l = lower
        return hausdorff_distance_2D(a_u, b_u) + hausdorff_distance_2D(
            a_l, b_l)

    # def shape_difference_upper(inputs, optimize_deltaz = False):
    # if optimize_deltaz == True:
    # y = CST(x, 1, deltasz = inputs[-1]/2., Au = list(inputs[:-1]))
    # else:
    # y = CST(x, 1, deltasz = inputs[-1]/2., Au = list(inputs))
    # # Vector to be compared with
    # b = {'x': x, 'y': y}
    # return hausdorff_distance_2D(a, b)

    # def shape_difference_lower(inputs, optimize_deltaz = False):
    # if optimize_deltaz == True:
    # y = CST(x, 1, deltasz = inputs[-1]/2.,  Al = list(inputs[:-1]))
    # else:
    # y = CST(x, 1, deltasz = deltaz/2.,  Al = list(inputs))
    # # Vector to be compared with
    # b = {'x': x, 'y': y}
    # return hausdorff_distance_2D(a, b)

    def separate_upper_lower(data):
        for i in range(len(data['x'])):
            if data['y'][i] < 0:
                break
        upper = {'x': data['x'][0:i], 'y': data['y'][0:i]}
        lower = {'x': data['x'][i:], 'y': data['y'][i:]}
        return upper, lower

    # Order of Bernstein polynomial
    if bounds != 'Default':
        n = len(bounds) - 1

    # Obtaining data
    data = output_reader(filename, separator=', ', header=['x', 'y'])

    # Rotating airfoil
    x_TE = (data['x'][0] + data['x'][-1]) / 2.
    y_TE = (data['y'][0] + data['y'][-1]) / 2.

    theta_TE = math.atan(-y_TE / x_TE)

    # position trailing edge at the x-axis
    processed_data = {'x': [], 'y': []}
    for i in range(len(data['x'])):
        x = data['x'][i]
        y = data['y'][i]
        c_theta = math.cos(theta_TE)
        s_theta = math.sin(theta_TE)
        x_rotated = c_theta * x - s_theta * y
        y_rotated = s_theta * x + c_theta * y
        processed_data['x'].append(x_rotated)
        processed_data['y'].append(y_rotated)
    data = processed_data

    # determine what is the leading edge and the rotation angle beta
    processed_data = {'x': [], 'y': []}
    min_x_list = []
    min_y_list = []

    min_x = min(data['x'])
    min_index = data['x'].index(min_x)
    min_y = data['y'][min_index]

    chord = max(data['x']) - min(data['x'])
    beta = math.atan((y_TE - min_y) / (x_TE - min_x))

    for i in range(len(data['x'])):
        processed_data['x'].append((data['x'][i] - min_x) / chord)
        processed_data['y'].append(data['y'][i] / chord)
    data = processed_data

    #==============================================================================
    # Optimizing shape
    #==============================================================================
    # Determining default bounds
    if bounds == 'Default':
        upper_bounds = [[0, 1.]] * (n + 1)
        lower_bounds = [[0, 1]] + [[-1., 1.]] * n

    if optimize_deltaz:
        bounds = upper_bounds + lower_bounds + [[0, 0.1]]
    else:
        bounds = upper_bounds + lower_bounds
        deltaz = (data['y'][0] - data['y'][-1])
    print(bounds)
    upper, lower = separate_upper_lower(data)
    # a = data
    # x = data['x']
    result = differential_evolution(shape_difference,
                                    bounds,
                                    disp=True,
                                    popsize=10,
                                    args=[optimize_deltaz])
    print('order %i upper done' % n)
    # x = lower['x']
    # a = lower
    # result_lower = differential_evolution(shape_difference_lower, lower_bounds,
    # disp=True, popsize = 10,
    # args = (optimize_deltaz))
    # print 'order %i lower done' % n
    if optimize_deltaz:
        Au = list(result.x[:n + 1])
        Al = list(result.x[n + 1:-1])
        deltaz = result.x[-1]
    else:
        Au = list(result.x[:n + 1])
        Al = list(result.x[n + 1:])

    # Return Al, Au, and others
    if return_data:
        return data, deltaz, Al, Au
    elif return_error:
        return result.fun, deltaz, Al, Au
    else:
        return deltaz, Al, Au
Beispiel #2
0
if __name__ == '__main__':

    import numpy as np
    import matplotlib.pyplot as plt
    import math

#    print find_3D_coefficients(airfoil='naca0012', alpha=1.)
    alpha = 0.
    x_hinge = 0.25/0.6175
    deflection = -math.pi/2. #0.17453292519943295 #0.0010573527055

    # generate original airfoil
    airfoil = "naca0012"
    xf.call(airfoil, output='Coordinates')
    filename = xf.file_name(airfoil, output='Coordinates')
    Data = xf.output_reader(filename, output='Coordinates', header = ['x','y'])

    Cm = calculate_flap_moment(Data['x'], Data['y'], alpha, x_hinge, deflection)


    V = 10
    altitude = 10000 #feet

    Reynolds = ar.Reynolds(altitude, V, 1.0)

    deflection_list = list(np.linspace(5,30,4))
    alpha_list = list(np.linspace(0,15,20))

    # Calculate coefficients for without flap
    CL_list = []
    CD_list = []
Beispiel #3
0
from aeropy.geometry.parametric import poly
from aeropy.structural.stable_solution import (structure, mesh_1D, properties,
                                               boundary_conditions)
from aeropy.xfoil_module import output_reader

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import pickle

abaqus_primary = pickle.load(open("save.p", "rb"), encoding='latin1')
abaqus_secondary = output_reader('secondary_variables.txt')
# sort data
abaqus_data = np.array(
    sorted(
        zip(
            abaqus_primary['C_U']['x'],
            abaqus_primary['C_U']['y'],
            abaqus_primary['U'][:, 0],
            abaqus_primary['U'][:, 1],
        )))
abq_x, abq_y, abq_u1, abq_u2 = abaqus_data.T
abq_y = -abq_y + .005
abq_u2 = -abq_u2
# Convert log strains into engineering strain
abaqus_secondary['LE11'] = np.exp(np.array(abaqus_secondary['LE11'])) - 1
abaqus_secondary['LE12'] = np.exp(np.array(abaqus_secondary['LE12'])) - 1
abaqus_secondary['LE22'] = np.exp(np.array(abaqus_secondary['LE22'])) - 1
coefficients = np.array([0, 0, 0, 0])

bp = properties()
Beispiel #4
0
def fitting_shape_coefficients(filename,
                               bounds='Default',
                               n=5,
                               return_data=False,
                               return_error=False,
                               optimize_deltaz=False,
                               solver='gradient',
                               deltaz=None,
                               objective='hausdorf',
                               surface='both',
                               x0=None):
    """Fit shape parameters to given data points
        Inputs:
        - filename: name of the file where the original data is
        - bounds: bounds for the shape parameters. If not defined,
                    Default values are used.
        - n: order of the Bernstein polynomial. If bounds is default
                this input will define the order of the polynomial.
                Otherwise the length of bounds (minus one) is taken into
                consideration"""

    from optimization_tools.hausdorff_distance import hausdorff_distance_2D

    def shape_difference(inputs, optimize_deltaz=False, surface=surface):
        # Define deltaz
        if optimize_deltaz is True or optimize_deltaz == [True]:
            deltasz = inputs[-1] / 2.
        else:
            deltasz = deltaz / 2.

        # Calculate upper and lower surface
        if surface == 'both':
            y_u = CST(upper['x'], 1, deltasz=deltasz, Au=list(inputs[:n + 1]))
            y_l = CST(lower['x'],
                      1,
                      deltasz=deltasz,
                      Al=list(inputs[n + 1:-1]))
        elif surface == 'upper':
            y_u = CST(upper['x'], 1, deltasz=deltasz, Au=list(inputs[:n + 1]))
        elif surface == 'lower':
            y_l = CST(lower['x'], 1, deltasz=deltasz, Al=list(inputs[:n + 1]))

        # Vector to be compared with
        error = 0
        if surface == 'upper' or surface == 'both':
            a_u = {'x': upper['x'], 'y': y_u}
            if objective == 'hausdorf':
                error += hausdorff_distance_2D(a_u, upper)
            elif objective == 'squared_mean':
                error += np.mean(
                    (np.array(a_u['x']) - np.array(upper['x']))**2 +
                    (np.array(a_u['y']) - np.array(upper['y']))**2)

        if surface == 'lower' or surface == 'both':
            a_l = {'x': lower['x'], 'y': y_l}
            if objective == 'hausdorf':
                error += hausdorff_distance_2D(a_l, lower)
            elif objective == 'squared_mean':
                error += np.mean(
                    (np.array(a_l['x']) - np.array(lower['x']))**2 +
                    (np.array(a_l['y']) - np.array(lower['y']))**2)

        # plt.figure()
        # plt.scatter(a_u['x'], a_u['y'], c='k')
        # plt.scatter(a_l['x'], a_l['y'], c='b')
        # plt.scatter(upper['x'], upper['y'], c='r')
        # plt.scatter(lower['x'], lower['y'], c='g')
        # plt.show()
        return error

    def separate_upper_lower(data):
        for key in data:
            data[key] = np.array(data[key])

        index = np.where(data['y'] > 0)
        upper = {'x': data['x'][index], 'y': data['y'][index]}
        index = np.where(data['y'] <= 0)
        lower = {'x': data['x'][index], 'y': data['y'][index]}
        # x = data['x']
        # y = data['y']
        # for i in range(len(x)):
        #     if data['y'][i] < 0:
        #         break
        # upper = {'x': x[0:i],
        #          'y': y[0:i]}
        # lower = {'x': x[i:],
        #          'y': y[i:]}
        return upper, lower

    def _determine_bounds_x0(n, optimize_deltaz, bounds):
        if bounds == 'Default':
            upper_bounds = [[0, 1]] + [[-1., 1.]] * n
            lower_bounds = [[0, 1]] + [[-1., 1.]] * n

        if optimize_deltaz:
            if surface == 'both':
                bounds = upper_bounds + lower_bounds + [[0, 0.1]]
                x0 = (n + 1) * [
                    0.,
                ] + (n + 1) * [
                    0.,
                ] + [0.]
            elif surface == 'upper':
                bounds = upper_bounds + [[0, 0.1]]
                x0 = (n + 1) * [
                    0.,
                ] + [0.]
            elif surface == 'lower':
                bounds = lower_bounds + [[0, 0.1]]
                x0 = (n + 1) * [
                    0.,
                ] + [0.]
        else:
            bounds = upper_bounds + lower_bounds
            x0 = (n + 1) * [
                0.,
            ] + (n + 1) * [
                0.,
            ]
        return x0, bounds

    # Order of Bernstein polynomial
    if bounds != 'Default':
        n = len(bounds) - 1

    # Obtaining data
    if filename[-2:] == '.p':
        import pickle
        data = pickle.load(open(filename, "rb"), encoding='latin1')
        data = data['wing'][list(data['wing'].keys())[3]]
        x, y, z = data.T
    else:
        data = output_reader(filename, separator='\t', header=['x', 'z'])
        x = data['x']
        z = data['z']

    # Rotating airfoil
    x_TE = (x[0] + x[-1]) / 2.
    y_TE = (z[0] + z[-1]) / 2.

    theta_TE = math.atan(-y_TE / x_TE)

    # position trailing edge at the x-axis
    processed_data = {'x': [], 'y': []}
    for i in range(len(x)):
        x_i = x[i]
        z_i = z[i]
        c_theta = math.cos(theta_TE)
        s_theta = math.sin(theta_TE)
        x_rotated = c_theta * x_i - s_theta * z_i
        z_rotated = s_theta * x_i + c_theta * z_i
        processed_data['x'].append(x_rotated)
        processed_data['y'].append(z_rotated)
    data = processed_data

    # determine what is the leading edge and the rotation angle beta
    processed_data = {'x': [], 'y': []}

    min_x = min(x)
    # min_index = data['x'].index(min_x)
    # min_y = data['y'][min_index]

    chord = max(x) - min(x)
    # beta = math.atan((y_TE - min_y)/(x_TE - min_x))

    for i in range(len(x)):
        processed_data['x'].append((x[i] - min_x) / chord)
        processed_data['y'].append(z[i] / chord)
    data = processed_data

    # Determining default bounds
    x0_default, bounds = _determine_bounds_x0(n, optimize_deltaz, bounds)
    if x0 is None:
        x0 = x0_default

    if not optimize_deltaz and deltaz is None:
        deltaz = (data['y'][0] - data['y'][-1])

    if surface == 'both':
        upper, lower = separate_upper_lower(data)
    elif surface == 'upper':
        upper = data
    elif surface == 'lower':
        lower = data

    # Calculate original error
    error0 = shape_difference(x0,
                              optimize_deltaz=optimize_deltaz,
                              surface=surface)

    def f(x):
        return shape_difference(
            x, optimize_deltaz=optimize_deltaz, surface=surface) / error0

    # Optimize
    if solver == 'differential_evolution':

        result = differential_evolution(f, bounds, disp=True, popsize=10)
        x = result.x
        f = result.fun
    elif solver == 'gradient':

        solution = minimize(f,
                            x0,
                            bounds=bounds,
                            options={
                                'maxfun': 30000,
                                'eps': 1e-02
                            })
        x = solution['x']
        f = solution['fun']
    print('order %i  done' % n)

    # Unpackage data
    if surface == 'both' or surface == 'upper':
        Au = list(x[:n + 1])
    if surface == 'both':
        if optimize_deltaz:
            Al = list(x[n + 1:-1])
            deltaz = x[-1]
        else:
            Al = list(x[n + 1:])
    elif surface == 'lower':
        Al = list(x[:n + 1])

    # Return Al, Au, and others
    to_return = []
    if return_data:
        to_return.append(data)
    if return_error:
        to_return.append(f)
    to_return.append(deltaz)
    if surface == 'lower' or surface == 'both':
        to_return.append(Al)
    elif surface == 'upper' or surface == 'both':
        to_return.append(Au)
    print(to_return)
    return to_return
Beispiel #5
0
                                        return_error=True,
                                        deltaz=0,
                                        solver='differential_evolution',
                                        objective='squared_mean',
                                        surface=surface,
                                        x0=None)
    if surface == 'both':
        error, fitted_deltaz, fitted_Al, fitted_Au = output
        print(error)
        print(fitted_Al)
        print(fitted_Au)
    elif surface == 'lower':
        error, fitted_deltaz, fitted_Al = output
        print('Coefficients', fitted_Al)

    data = output_reader(filename, separator='\t', header=['x', 'z'])
    plt.scatter(data['x'], data['z'], c='r')
    x = np.linspace(0, 1, 100)
    # y_u = CST(x, 1, deltasz=0, Au=fitted_Au)
    y_l = CST(x, 1, deltasz=0, Al=fitted_Al)
    # plt.plot(x, y_u, 'b')
    plt.plot(x, y_l, 'b')
    plt.show()

    # ==============================================================================
    #   Shape parameter study
    # ==============================================================================
    n = 8
    Data = shape_parameter_study(filename,
                                 n=n,
                                 solver='gradient',
Beispiel #6
0
import matplotlib.pyplot as plt

from aeropy.airfoil_module import CST
from aeropy.xfoil_module import output_reader

data = pickle.load(open('shape_study.p', 'rb'))

n = 5
print('For n=', n, ': ')
print('\t error: ', data['error'][n - 1])
print('\t deltaz: ', data['deltaz'][n - 1])
print('\t Au: ', data['Au'][n - 1])
print('\t Al: ', data['Al'][n - 1])

filename = 'sampled_airfoil_data.csv'
raw_data = output_reader(filename, separator=', ', header=['x', 'y'])

# Rotating airfoil
x_TE = (raw_data['x'][0] + raw_data['x'][-1]) / 2.
y_TE = (raw_data['y'][0] + raw_data['y'][-1]) / 2.

theta_TE = math.atan(-y_TE / x_TE)

# position trailing edge at the x-axis
processed_data = {'x': [], 'y': []}
for i in range(len(raw_data['x'])):
    x = raw_data['x'][i]
    y = raw_data['y'][i]
    c_theta = math.cos(theta_TE)
    s_theta = math.sin(theta_TE)
    x_rotated = c_theta * x - s_theta * y