コード例 #1
0
    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)
コード例 #2
0
def calculate_spar_distance(psi_baseline, Au_baseline, Au_goal, Al_goal,
                            deltaz, c_goal):
    """Calculate spar distance (dimensional)"""
    def f(psi_lower_goal):
        y_lower_goal = CST(psi_lower_goal * c_goal, c_goal,
                           [deltaz / 2., deltaz / 2.], Au_goal, Al_goal)
        y_lower_goal = y_lower_goal['l']
        return psi_upper_goal + (s[0] / s[1]) * (y_lower_goal -
                                                 y_upper_goal) / c_goal

    # Calculate cruise chord
    c_baseline = calculate_c_baseline(c_goal, Au_baseline, Au_goal, deltaz)

    # Calculate upper psi at goal airfoil
    psi_upper_goal = calculate_psi_goal(psi_baseline, Au_baseline, Au_goal,
                                        deltaz, c_baseline, c_goal)
    y_upper_goal = CST(psi_upper_goal * c_goal, c_goal,
                       [deltaz / 2., deltaz / 2.], Au_goal, Al_goal)
    y_upper_goal = y_upper_goal['u']

    # Spar direction
    s = calculate_spar_direction(psi_baseline, Au_baseline, Au_goal, deltaz,
                                 c_goal)

    # Calculate lower psi and xi at goal airfoil
    #Because the iterative method can lead to warningdivision by zero after converging, we ignore
    #the warning
    np.seterr(divide='ignore', invalid='ignore')
    psi_lower_goal = optimize.fixed_point(
        f, [psi_upper_goal])  #, args=(c_L, Au_C, Au_L, deltaz)
    x_lower_goal = psi_lower_goal * c_goal
    y_lower_goal = CST(x_lower_goal, c_goal, [deltaz / 2., deltaz / 2.],
                       Au_goal, Al_goal)
    y_lower_goal = y_lower_goal['l']

    return (y_upper_goal - y_lower_goal[0]) / s[1]
コード例 #3
0
def calculate_average_camber(Au, Al, delta_xi):
    psi = np.linspace(0, 1, 1000)
    xi = CST(psi, 1., [delta_xi / 2., delta_xi / 2.], Au, Al)
    camber = (xi['u'] + xi['l']) / 2.
    return np.average(np.absolute(camber))
コード例 #4
0
def calculate_camber(psi, Au, Al, delta_xi):
    xi = CST(psi, 1., [delta_xi / 2., delta_xi / 2.], Au, Al)
    return (xi['u'] + xi['l']) / 2.
コード例 #5
0
 def f(psi_lower_goal):
     y_lower_goal = CST(psi_lower_goal * c_goal, c_goal,
                        [deltaz / 2., deltaz / 2.], Au_goal, Al_goal)
     y_lower_goal = y_lower_goal['l']
     return psi_upper_goal + (s[0] / s[1]) * (y_lower_goal -
                                              y_upper_goal) / c_goal
コード例 #6
0
        Au_C[0] = x_i
        c_i = calculate_c_baseline(c_L, Au_C, Au_L, deltaz)
        c.append(c_i)
    plt.plot(x, c)
    plt.xlabel('$A_{u_0}^C$', fontsize=14)
    plt.ylabel('$c^C$', fontsize=14)
    plt.grid()
    plt.show()

    # Plot airfoils for different Au
    plt.figure()
    psi = np.linspace(0, 1, 500)
    i = 0
    for c_i in c:
        Au_C[0] = x[i]
        y = CST(psi, 1, [deltaz / 2., deltaz / 2.], Au_C, Al_C)
        x_plot = np.linspace(0, c_i, 500)
        plt.plot(x_plot, c_i * y['u'], label='$A_{u_0}$ = %.1f' % x[i])
        y_psi = CST(psi_i, 1, [deltaz / 2., deltaz / 2.], Au_C, Al_C)
        i += 1
    plt.xlabel(r'$\psi^C$', fontsize=14)
    plt.ylabel(r'$\xi^C$', fontsize=14)
    plt.legend()
    plt.gca().set_aspect('equal', adjustable='box')
    plt.grid()
    plt.show()

    # Plot for several testing calculat_psi_goal
    plt.figure()
    x = np.linspace(0., 1., 6)
    psi_goal_list = []
コード例 #7
0
        AC_u4,
        AC_u5,
        psi_spars,
        Au_P,
        Al_P,
        deltaz,
        c_P,
        morphing=morphing_direction)

    #==============================================================================
    #  Plot results
    #==============================================================================
    np.set_printoptions(precision=20)
    # Print shape for children
    x = np.linspace(0, c_C, 100000)
    y = CST(x, c_C, deltasz=[deltaz / 2., deltaz / 2.], Al=Al_C, Au=Au_C)

    plt.plot(x, y['u'], 'b', label='Children', lw=2)
    plt.plot(x, y['l'], 'b', label=None, lw=2)

    # Print shape for parent
    x = np.linspace(0, c_P, 100000)
    y = CST(x, c_P, deltasz=[deltaz / 2., deltaz / 2.], Al=Al_P, Au=Au_P)
    plt.plot(x, y['u'], 'r--', label='Parent', lw=2)
    plt.plot(x, y['l'], 'r--', label=None, lw=2)

    if morphing_direction == 'forwards':
        psi_flats = []
        intersections_x_children = [0]
        intersections_y_children = [0]
        intersections_x_parent = [0]
コード例 #8
0
def calculate_dependent_shape_coefficients(BP_p,
                                           BA_p,
                                           BP_c,
                                           chord_p,
                                           sweep_p,
                                           twist_p,
                                           delta_TE_p,
                                           sweep_c,
                                           twist_c,
                                           eta_sampling,
                                           psi_spars,
                                           morphing='camber'):
    """Calculate  dependent shape coefficients for children configuration for a 4 order
    Bernstein polynomial and return the children upper, lower shape 
    coefficients, children chord and spar thicknesses. _P denotes parent parameters"""
    def calculate_BP_c0(BP_c0, c_P, deltaz, j):
        Au_C = extract_A(BP_c, j)
        Au_P = extract_A(BP_p, j)
        c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz)
        BP_c[0][j] = np.sqrt(c_P / c_C) * Au_P[0]
        return BP_c[0][j], c_C

    def extract_A(B, j):
        # Extracting shape coefficient data for column j
        A = []
        for i in range(n + 1):
            A.append(B[i][j])
        return A

    # Bersntein Polynomial
    def K(r, n):
        K = math.factorial(n) / (math.factorial(r) * math.factorial(n - r))
        return K

    # Bernstein Polynomial orders (n is for psi, and m for eta)
    n = len(BP_p) - 1
    m = len(BP_p[0]) - 1
    p = len(psi_spars)
    q = len(eta_sampling)
    # print p,q,n,m
    # Define chord, sweep, and twist functions for parent
    chord_p = CST(eta_sampling,
                  chord_p['eta'][1],
                  chord_p['initial'],
                  Au=chord_p['A'],
                  N1=chord_p['N1'],
                  N2=chord_p['N2'],
                  deltasLE=chord_p['final'])
    sweep_p = CST(eta_sampling,
                  sweep_p['eta'][1],
                  deltasz=sweep_p['final'],
                  Au=sweep_p['A'],
                  N1=sweep_p['N1'],
                  N2=sweep_p['N2'])
    chord_p = chord_p[::-1]
    sweep_p = sweep_p
    twist_p = CST(eta_sampling,
                  twist_p['eta'][1],
                  twist_p['initial'],
                  Au=twist_p['A'],
                  N1=twist_p['N1'],
                  N2=twist_p['N2'],
                  deltasLE=twist_p['final'])
    delta_TE_p = CST(eta_sampling,
                     delta_TE_p['eta'][1],
                     delta_TE_p['initial'],
                     Au=delta_TE_p['A'],
                     N1=delta_TE_p['N1'],
                     N2=delta_TE_p['N2'],
                     deltasLE=delta_TE_p['final'])
    # Initialize chord, sweep, and twist functions for child
    chord_c = []
    # Initialize child active matrix
    BA_c = []
    for i in range(n + 1):
        temp = []
        for j in range(m + 1):
            temp.append(0)
        BA_c.append(temp, )
    # Find upper shape coefficient though iterative method since Au_0 is unknown
    # via fixed point iteration
    for k in range(q):
        error = 9999
        BP_c0 = BP_p[0][k]
        while error > 1e-9:
            before = BP_c0
            c_P = chord_p[k]
            deltaz = delta_TE_p[k]
            [BP_c0, c_c] = calculate_BP_c0(BP_c0, c_P, deltaz, k)
            error = abs(BP_c0 - before)
        BP_c[0][k] = BP_c0
        BA_c[0][k] = np.sqrt(c_P / c_c) * BA_p[0][k]
        chord_c.append(c_c)
        print(c_c, BP_c0, np.sqrt(c_P / c_c) * BA_p[0][k])
    # Calculate thicknessed and tensor C for the constraint linear system problem
    psi_A_c = []

    if morphing == 'camber':
        f = np.zeros((q, p))
        for l in range(q):
            # Converting everything from 3D to 2D framework
            Au_P = extract_A(BP_p, l)
            Al_P = extract_A(BA_p, l)
            Au_C = extract_A(BP_c, l)
            c_P = chord_p[l]
            c_C = chord_c[l]
            deltaz = delta_TE_p[l]

            # psi/xi coordinates for lower surface of the children configuration
            psi_lower_children = []
            xi_upper_children = []

            # psi_baseline, Au_baseline, Au_goal, deltaz, c_baseline, c_goal
            psi_upper_children = []
            for j in range(len(psi_spars)):
                psi_upper_children.append(
                    calculate_psi_goal(psi_spars[j], Au_P, Au_C, deltaz, c_P,
                                       c_C))
            # Calculate xi for upper children. Do not care about lower so just gave it random shape coefficients
            xi_upper_children = CST(
                psi_upper_children,
                1.,
                deltasz=[deltaz / 2. / c_C, deltaz / 2. / c_C],
                Al=Au_C,
                Au=Au_C)
            xi_upper_children = xi_upper_children['u']

            # print xi_upper_children

            #Debugging section
            x = np.linspace(0, 1)
            y = CST(x,
                    1.,
                    deltasz=[deltaz / 2. / c_C, deltaz / 2. / c_C],
                    Al=Au_C,
                    Au=Au_C)
            # plt.plot(x,y['u'])
            # plt.scatter(psi_upper_children, xi_upper_children)
            # plt.grid()
            # plt.show()
            # BREAK
            for k in range(len(psi_spars)):
                xi_parent = CST(psi_spars,
                                1.,
                                deltasz=[deltaz / 2. / c_P, deltaz / 2. / c_P],
                                Al=Al_P,
                                Au=Au_P)
                delta_k_P = xi_parent['u'][k] - xi_parent['l'][k]
                t_k = c_P * (delta_k_P)
                # Claculate orientation for children
                s_k = calculate_spar_direction(psi_spars[k], Au_P, Au_C,
                                               deltaz, c_C)
                psi_l_k = psi_upper_children[k] - delta_k_P / c_C * s_k[0]
                xi_l_k = xi_upper_children[k] - delta_k_P / c_C * s_k[1]

                psi_lower_children.append(psi_l_k)

                f_y = 0
                for j in range(m + 1):
                    f_y += BA_c[0][j] * (
                        1 - psi_l_k)**n * (K(j, m) * eta_sampling[l]**j *
                                           (1 - eta_sampling[l])**(m - j))
                    # print j, eta_sampling[l]**j*(1-eta_sampling[l])**(m-j), BA_c[0][j]
                f[l][k] = (2 * xi_l_k +
                           psi_l_k * deltaz / c_C) / (2 * (psi_l_k**0.5) *
                                                      (psi_l_k - 1)) - f_y

                # print 'f_y',f_y, eta_sampling[l],m,j
            # Store new children psi values
            psi_A_c.append(psi_lower_children)

        # Initialize F (avoiding using numpy)
        F = np.zeros([q, p, m + 1, n])
        # F = []
        # for l in range(q):
        # tempk = []
        # for k in range(p):
        # tempj = []
        # for j in range(m+1):
        # tempi = []
        # for i in range(n):
        # tempi.append(0.0)
        # tempj.append(tempi)
        # tempk.append(tempj)
        # F.append(tempk)

        #j is the row dimension and i the column dimension in this case
        for l in range(q):
            for k in range(p):
                for j in range(m + 1):
                    for i in range(n):
                        #Because in Python counting starts at 0, need to add 1 to be
                        #coherent for equations
                        ii = i + 1
                        Sx = K(ii, n) * (psi_A_c[l][k]**
                                         ii) * (1 - psi_A_c[l][k])**(n - ii)
                        Sy = K(j, m) * (eta_sampling[l]**
                                        j) * (1 - eta_sampling[l])**(m - j)
                        F[l][k][j][i] = Sx * Sy

        # print len(F), len(F[0]), len(F[0][0]), len(F[0][0][0])

        # Unfolding tensor
        F_matrix = np.zeros((n**2, n**2))
        f_vector = np.zeros((n**2, 1))
        for l in range(q):
            for k in range(p):
                for j in range(m + 1):
                    for i in range(n):
                        ii = n * (l) + k
                        jj = n * (j) + i

                        F_matrix[ii][jj] = F[l][k][j][i]
                        f_vector[ii] = f[l][k]

        solution = np.linalg.solve(F_matrix, f_vector)

        for j in range(m + 1):
            for i in range(n):
                jj = n * (j) + i
                BA_c[i + 1][j] = solution[jj][0]
        print(BA_c)
    return BA_c, chord_c
コード例 #9
0
def calculate_dependent_shape_coefficients(Au_C_1_to_n,
                                           psi_spars,
                                           Au_P,
                                           Al_P,
                                           deltaz,
                                           c_P,
                                           morphing='backwards'):
    """Calculate  dependent shape coefficients for children configuration for a 4 order
    Bernstein polynomial and return the children upper, lower shape 
    coefficients, children chord and spar thicknesses. _P denotes parent parameters"""
    def calculate_AC_u0(AC_u0):
        Au_C = [AC_u0] + Au_C_1_to_n
        c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz)
        return np.sqrt(c_P / c_C) * Au_P[0]

    # Bersntein Polynomial
    def K(r, n):
        K = math.factorial(n) / (math.factorial(r) * math.factorial(n - r))
        return K

    # Bernstein Polynomial order
    n = len(Au_C_1_to_n)

    # Find upper shape coefficient though iterative method since Au_0 is unknown
    # via fixed point iteration
    #AC_u0 = optimize.fixed_point(calculate_AC_u0, Au_P[0])
    #print AC_u0
    error = 9999
    AC_u0 = Au_P[0]
    while error > 1e-9:
        before = AC_u0
        AC_u0 = calculate_AC_u0(AC_u0)
        error = abs(AC_u0 - before)

    # Because the output is an array, need the extra [0]
    Au_C = [AC_u0] + Au_C_1_to_n

    # Now that AC_u0 is known we can calculate the actual chord and AC_l0
    c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz)
    AC_l0 = np.sqrt(c_P / c_C) * Al_P[0]
    print(Au_C)
    print(Au_P)
    print(Al_P)
    print(c_C, AC_l0, AC_u0)
    # print '0 lower shape coefficient: ',AC_l0
    # Calculate thicknessed and tensor B for the constraint linear system problem
    spar_thicknesses = []
    A0 = AC_u0 + AC_l0

    if morphing == 'backwards':
        b_list = np.zeros((n, 1))
        for j in range(len(psi_spars)):
            psi_j = psi_spars[j]
            #Calculate the spar thickness in meters from parent, afterwards, need to
            #adimensionalize for the goal airfoil by dividing by c_goal
            t_j = calculate_spar_distance(psi_spars[j], Au_C, Au_P, Al_P,
                                          deltaz, c_P)

            spar_thicknesses.append(t_j)
            b_list[j] = (t_j / c_C - psi_j * deltaz / c_C) / (
                (psi_j**0.5) * (1 - psi_j)) - A0 * (1 - psi_j)**n

        B = np.zeros((n, n))
        #j is the row dimension and i the column dimension in this case
        for j in range(n):
            for i in range(n):
                #Because in Python counting starts at 0, need to add 1 to be
                #coherent for equations
                r = i + 1
                B[j][i] = K(r, n) * (psi_spars[j]**
                                     r) * (1 - psi_spars[j])**(n - r)

        A_bar = np.dot(inv(B), b_list)

        Al_C = [AC_l0]
        for i in range(len(A_bar)):
            Al_C.append(A_bar[i][0] -
                        Au_C[i + 1])  #extra [0] is necessary because of array

    elif morphing == 'forwards':
        f = np.zeros((n, 1))
        # psi/xi coordinates for lower surface of the children configuration
        psi_lower_children = []
        xi_lower_children = []
        xi_upper_children = []

        c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz)
        print(c_C, AC_u0, AC_l0)
        # psi_baseline, Au_baseline, Au_goal, deltaz, c_baseline, c_goal
        psi_upper_children = []
        for j in range(len(psi_spars)):
            psi_upper_children.append(
                calculate_psi_goal(psi_spars[j], Au_P, Au_C, deltaz, c_P, c_C))
        # Calculate xi for upper children. Do not care about lower so just gave it random shape coefficients
        xi_upper_children = CST(psi_upper_children,
                                1.,
                                deltasz=[deltaz / 2. / c_C, deltaz / 2. / c_C],
                                Al=Au_C,
                                Au=Au_C)
        xi_upper_children = xi_upper_children['u']

        # print xi_upper_children

        #Debugging section
        x = np.linspace(0, 1)
        y = CST(x,
                1.,
                deltasz=[deltaz / 2. / c_C, deltaz / 2. / c_C],
                Al=Au_C,
                Au=Au_C)
        # plt.plot(x,y['u'])
        # plt.scatter(psi_upper_children, xi_upper_children)
        # plt.grid()
        # plt.show()
        # BREAK
        for j in range(len(psi_spars)):
            xi_parent = CST(psi_spars,
                            1.,
                            deltasz=[deltaz / 2. / c_P, deltaz / 2. / c_P],
                            Al=Al_P,
                            Au=Au_P)
            delta_j_P = xi_parent['u'][j] - xi_parent['l'][j]
            t_j = c_P * (delta_j_P)
            # Claculate orientation for children
            s_j = calculate_spar_direction(psi_spars[j], Au_P, Au_C, deltaz,
                                           c_C)
            psi_l_j = psi_upper_children[j] - delta_j_P / c_C * s_j[0]
            xi_l_j = xi_upper_children[j] - delta_j_P / c_C * s_j[1]

            spar_thicknesses.append(t_j)
            psi_lower_children.append(psi_l_j)
            xi_lower_children.append(xi_l_j)

            f[j] = (2 * xi_l_j + psi_l_j * deltaz / c_C) / (
                2 * (psi_l_j**0.5) * (psi_l_j - 1)) - AC_l0 * (1 - psi_l_j)**n
        print(psi_lower_children)
        F = np.zeros((n, n))
        #j is the row dimension and i the column dimension in this case
        for j in range(n):
            for i in range(n):
                #Because in Python counting starts at 0, need to add 1 to be
                #coherent for equations
                r = i + 1
                F[j][i] = K(r, n) * (psi_lower_children[j]**
                                     r) * (1 - psi_lower_children[j])**(n - r)
                print(
                    K(r, n) * (psi_lower_children[j]**r) *
                    (1 - psi_lower_children[j])**(n - r))
        A_lower = np.dot(inv(F), f)

        Al_C = [AC_l0]
        for i in range(len(A_lower)):
            Al_C.append(
                A_lower[i][0])  #extra [0] is necessary because of array
    return Au_C, Al_C, c_C, spar_thicknesses
コード例 #10
0
def plot_airfoil(AC,
                 psi_spars,
                 c_L,
                 deltaz,
                 Au_L,
                 Al_L,
                 image='plot',
                 iteration=0,
                 return_coordinates=True,
                 dir='current'):
    import matplotlib.pyplot as plt

    plt.figure()
    n = len(Au_L) - 1
    Au_C, Al_C, c_C, spar_thicknesses = calculate_dependent_shape_coefficients(
        AC, psi_spars, Au_L, Al_L, deltaz, c_L, morphing=morphing_direction)

    #==============================================================================
    #  Plot results
    #==============================================================================
    np.set_printoptions(precision=20)
    x = np.linspace(0, c_C, 1000)
    y = CST(x, c_C, deltasz=[deltaz / 2., deltaz / 2.], Al=Al_C, Au=Au_C)
    plt.plot(x, y['u'], 'b', label='Children')
    plt.plot(x, y['l'], '-b', label=None)

    # store variables in case return_coordinates is True
    x = list(x[::-1]) + list(x[1:])
    y = list(y['u'][::-1]) + list(y['l'][1:])

    children_coordinates = {'x': x, 'y': y}
    x = np.linspace(0, c_L, 1000)
    y = CST(x, c_L, deltasz=[deltaz / 2., deltaz / 2.], Al=Al_L, Au=Au_L)
    plt.plot(x, y['u'], 'r--', label='Parent')
    plt.plot(x, y['l'], 'r--', label=None)

    y_limits = y

    for i in range(len(psi_spars)):
        psi_i = psi_spars[i]
        # Calculate psi at landing
        psi_goal_i = calculate_psi_goal(psi_i, Au_C, Au_L, deltaz, c_C, c_L)
        x_goal_i = psi_goal_i * c_L
        # Calculate xi at landing
        temp = CST(x_goal_i, c_L, [deltaz / 2., deltaz / 2.], Al=Al_L, Au=Au_L)
        y_goal_i = temp['u']

        #calculate spar direction
        s = calculate_spar_direction(psi_i, Au_C, Au_L, deltaz, c_L)

        plt.plot([x_goal_i, x_goal_i - spar_thicknesses[i] * s[0]],
                 [y_goal_i, y_goal_i - spar_thicknesses[i] * s[1]], 'r--')

        y = CST(np.array([psi_i * c_C]),
                c_C,
                deltasz=[deltaz / 2., deltaz / 2.],
                Al=Al_C,
                Au=Au_C)
        plt.plot([psi_i * c_C, psi_i * c_C],
                 [y['u'], y['u'] - spar_thicknesses[i]],
                 'b',
                 label=None)

    plt.xlabel('$\psi$', fontsize=16)
    plt.ylabel(r'$\xi$', fontsize=16)
    plt.grid()
    plt.legend(loc="upper right")
    plt.gca().set_aspect('equal', adjustable='box')
    x1, x2, y1, y2 = plt.axis()
    plt.axis((x1, x2, y1, 2 * y2))

    # plt.axis([-0.005, c_L+0.005, min(y_limits['l'])-0.005, max(y_limits['l'])+0.01])
    if image == 'plot':
        plt.show()
    elif image == 'save':
        if dir == 'current':
            plt.savefig('%03i.png' % (iteration), bbox_inches='tight')
        else:
            cwd = os.getcwd()
            directory = os.path.join(cwd, dir)
            if not os.path.exists(directory):
                os.makedirs(directory)

            filename = os.path.join(directory, '%05i.png' % (iteration))
            plt.savefig(filename, bbox_inches='tight')
    if return_coordinates:
        return children_coordinates
コード例 #11
0
            if y_i >= tip_displacement['y']:
                print('Y value out of bounds!')
        A = calculate_shape_coefficients_tracing(
            A0,
            other_points['y'],
            other_points['x'],
            N1,
            N2,
            chord=tip_displacement['y'],
            EndThickness=tip_displacement['x'])

        #plotting
        y = np.linspace(0, tip_displacement['y'], 100000)
        x = CST(y,
                tip_displacement['y'],
                deltasz=tip_displacement['x'],
                Au=A,
                N1=N1,
                N2=N2)
        plt.plot(x, y)
        plt.scatter(other_points['x'] + [tip_displacement['x']],
                    other_points['y'] + [tip_displacement['y']])
        plt.gca().set_aspect('equal', adjustable='box')
        plt.show()

    elif testing == 'structurally_consistent':

        #==============================================================================
        # Inputs
        #==============================================================================
        # Parameter
        c_P = 1.  #m
コード例 #12
0
def calculate_dependent_shape_coefficients(Au_C_1_to_n,
                                           psi_spars,
                                           Au_P,
                                           Al_P,
                                           deltaz,
                                           c_P,
                                           morphing='backwards',
                                           l_LE=0,
                                           eps_LE=0):
    """Calculate  dependent shape coefficients for children configuration for a 4 order
    Bernstein polynomial and return the children upper, lower shape
    coefficients, children chord and spar thicknesses. _P denotes parent parameters"""
    def calculate_AC_u0(AC_u0, constant_LE=True):
        Au_C = [AC_u0] + Au_C_1_to_n
        if constant_LE:
            return np.sqrt(c_P / c_C) * Au_P[0]
        else:
            return calculate_A0_moving_LE(psi_spars, psi_lower_children[0],
                                          Au_P, Au_C, deltaz, c_P, l_LE,
                                          eps_LE)

    # Bersntein Polynomial

    def K(r, n):
        K = math.factorial(n) / (math.factorial(r) * math.factorial(n - r))
        return K

    # Bernstein Polynomial order
    # In case of leading edge radius constraint
    n = len(Au_C_1_to_n)

    # Find upper shape coefficient though iterative method since Au_0 is unknown
    # via fixed point iteration
    #AC_u0 = optimize.fixed_point(calculate_AC_u0, Au_P[0])
    # print AC_u0
    error = 9999

    psi_lower_children = psi_spars
    Au_C = [Au_P[0]] + Au_C_1_to_n  # [Au_P[0]] +

    former_chord = c_P
    while error > 1e-5:
        former_Au_C = []
        for i in range(len(Au_C)):
            former_Au_C.append(Au_C[i])

        # Because the output is an array, need the extra [0]
        error_A0 = 999
        # Now that AC_u0 is known we can calculate the actual chord and AC_l0
        # c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz/c_P, l_LE, eps_LE, psi_spars[0])
        Au_C[0] = calculate_AC_u0(Au_C[0], constant_LE=False)
        Al_C0 = Au_C[0]
        c_C = calculate_c_baseline(c_P, Au_C, Au_P, deltaz / c_P, l_LE, eps_LE,
                                   psi_spars[0])
        #Al_C0 = Au_C[0]
        # print '0 lower shape coefficient: ',AC_l0
        # Calculate thicknessed and tensor B for the constraint linear system problem
        spar_thicknesses = []

        if morphing == 'forwards':
            f = np.zeros((n, 1))
            # psi/xi coordinates for lower surface of the children configuration
            psi_lower_children = []
            xi_lower_children = []
            xi_upper_children = []

            # psi_baseline, Au_baseline, Au_goal, deltaz, c_baseline, c_goal
            psi_upper_children = []
            for j in range(len(psi_spars)):
                print(j)
                psi_upper_children.append(
                    calculate_psi_goal(psi_spars[j], Au_P, Au_C, deltaz, c_P,
                                       c_C, l_LE, eps_LE, psi_spars[0]))

            # Calculate xi for upper children. Do not care about lower so just gave it random shape coefficients
            xi_upper_children = CST(
                psi_upper_children,
                1.,
                deltasz=[deltaz / 2. / c_C, deltaz / 2. / c_C],
                Al=Au_C,
                Au=Au_C)
            xi_upper_children = xi_upper_children['u']

            # print xi_upper_children

            # Debugging section
            # x = np.linspace(0,1)
            # y = CST(x, 1., deltasz= [deltaz/2./c_C, deltaz/2./c_C],  Al= Au_C, Au =Au_C)
            # plt.plot(x,y['u'])
            # plt.scatter(psi_upper_children, xi_upper_children)
            # plt.grid()
            # plt.show()
            # BREAK
            print(Au_P, Au_C, len(psi_spars), n)
            for j in range(len(psi_spars)):
                xi_parent = CST(psi_spars,
                                1.,
                                deltasz=[deltaz / 2. / c_P, deltaz / 2. / c_P],
                                Al=Al_P,
                                Au=Au_P)
                delta_j_P = xi_parent['u'][j] - xi_parent['l'][j]
                t_j = c_P * (delta_j_P)
                # Claculate orientation for children
                s_j = calculate_spar_direction(psi_spars[j], Au_P, Au_C,
                                               deltaz, c_C, l_LE, eps_LE,
                                               psi_spars)
                psi_l_j = psi_upper_children[j] - delta_j_P / c_C * s_j[0]
                xi_l_j = xi_upper_children[j] - delta_j_P / c_C * s_j[1]

                spar_thicknesses.append(t_j)
                psi_lower_children.append(psi_l_j)
                xi_lower_children.append(xi_l_j)

                f[j] = (2*xi_l_j + psi_l_j*deltaz/c_C) / \
                    (2*(psi_l_j**0.5)*(psi_l_j-1)) - Al_C0*(1-psi_l_j)**n

            F = np.zeros((n, n))
            # j is the row dimension and i the column dimension in this case
            for j in range(n):
                for i in range(n):
                    # Because in Python counting starts at 0, need to add 1 to be
                    # coherent for equations
                    r = i + 1
                    F[j][i] = K(r, n) * (psi_lower_children[j]**r) * (
                        1 - psi_lower_children[j])**(n - r)
            print(F)
            print(f)
            A_lower = np.dot(inv(F), f)
            print('result', A_lower)
            Al_C = [Al_C0]
            for i in range(len(A_lower)):
                Al_C.append(
                    A_lower[i][0])  # extra [0] is necessary because of array
        error_denominator = 0
        print('before', former_Au_C, Au_C)
        for i in range(len(Au_C)):
            error_denominator += Au_C[i]**2
        error = 0
        for i in range(len(Al_C)):
            error += (former_Au_C[i] - Au_C[i])**2 / error_denominator
        error = math.sqrt(error)
        # error = abs(c_C-former_chord)/c_C
        # AC_u0 = calculate_AC_u0(AC_u0, constant_LE=False)
        print(error, Al_C, Au_C)
        # former_chord = c_C
    return Au_C, Al_C, c_C, spar_thicknesses
コード例 #13
0
ファイル: nosecone.py プロジェクト: belac626/AeroPy
def CST_3D(Bu, Bl, span, N={'eta':[0,1], 'N1':[.5, .5], 'N2':[1., 1.], 'chord':[1., 0]},
           mesh = (100,100), chord = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial_chord':1.}, 
           sweep = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'x_LE_initial':0, 'x_LE_final':0}):
    """
    - Bu: upper shape coefficients
    - Bl: lower shape coefficients
    - mesh: list of number of points in x and y
    """
    def S(B, psi, eta):
        """ Cross section shape function. Validated for high dimensions.
           To debug just verify if it turns all ones when B=ones"""
        def S_i(r, n, psi):
            """Shape function"""
            value = K(r,n)*(psi**r)*(1.-psi)**(n-r)
            return value

        # Bersntein Polynomial
        def K(r,n):
            K=math.factorial(n)/(math.factorial(r)*math.factorial(n-r))
            return K

        Nx = len(B)-1
        Ny = len(B[0])-1

        output = 0
        for i in range(Nx+1):
            for j in range(Ny+1):
                output += B[i][j]*S_i(i, Nx, psi)*S_i(j, Ny, eta)
        return output

    def C(N, psi, eta):
        """Class function"""
        N1 = interp1d(N['eta'], N['N1'])
        N2 = interp1d(N['eta'], N['N2'])
        output = ((psi)**N1(eta))*((1.-psi)**N2(eta))
        return output

    psi = np.linspace(0,1,mesh[0])
    eta = np.linspace(0,1,mesh[1])

    zeta_u = np.zeros(mesh)
    zeta_l = np.zeros(mesh)
    for i in range(mesh[0]):
        for j in range(mesh[1]):
            zeta_u[j][i] = C(N, psi[i], eta[j])*S(Bu, psi[i], eta[j])
            zeta_l[j][i] = -C(N, psi[i], eta[j])*S(Bl, psi[i], eta[j])
    print(eta)
    print(chord['initial_chord'])
    print(chord['A'])
    print(chord['N1'], chord['N2'])
    chord_distribution = CST(eta, chord['eta'][1], chord['initial_chord'], Au=chord['A'], N1=chord['N1'], N2=chord['N2'])
    sweep_distribution = CST(eta, sweep['eta'][1], deltasz = sweep['x_LE_final']-.5*chord['initial_chord'], Au=sweep['A'], N1=sweep['N1'], N2=sweep['N2'])
    chord_distribution = chord_distribution[::-1]
    sweep_distribution = sweep_distribution
    # taper_function(eta, shape = 'linear', N)
    x = np.zeros(len(psi))
    for i in range(len(x)):
        x[i] = psi[i]*chord_distribution[i]
    print(chord_distribution)
    print(sweep_distribution)
    print(x)
    print(psi)
    y = eta

    X = np.zeros(mesh)
    Y = np.zeros(mesh)
    Z_u = np.zeros(mesh)
    Z_l = np.zeros(mesh)
    for i in range(mesh[0]):
        for j in range(mesh[1]):
            X[j][i] = psi[i]*chord_distribution[j] - sweep_distribution[j] -.5*chord['initial_chord']
        
            Y[j][i] = span*eta[j]
            Z_u[j][i] = zeta_u[j][i]*chord_distribution[j]
            Z_l[j][i] = zeta_l[j][i]*chord_distribution[j]
    return [X,Y,Z_u,Z_l]
コード例 #14
0
ファイル: test_inflections.py プロジェクト: tnet/AeroPy
import aeropy.xfoil_module as xf
from aeropy.CST.module_2D import *
from aeropy.aero_module import Reynolds
from aeropy.airfoil_module import CST, create_x

Au = [0.23993240191629417, 0.34468227138908186, 0.18125405377549103, 
        0.35371349126072665, 0.2440815012119143, 0.25724974995738387]
Al = [0.18889012559339036, -0.24686758992053115, 0.077569769493868401,
        -0.547827192265256, -0.0047342206759065641, -0.23994805474814629]
c_avian = .36                  #m
deltaz = 0.0093943568219451313*c_avian

airfoil = 'avian'
x = create_x(c_avian, distribution = 'linear')
y = CST(x, c_avian, [deltaz/2., deltaz/2.], Au = Au, Al= Al)
# Create file for Xfoil to read coordinates
xf.create_input(x, y['u'], y['l'], airfoil, different_x_upper_lower = False)

Data = xf.find_coefficients(airfoil, 2., Reynolds=Reynolds(10000, 30, c_avian), iteration=100, NACA=False)
print(Data)


psi_u_inflection, psi_l_inflection = find_inflection_points(Au, Al)
print('upper: ', psi_u_inflection)
print('lower: ', psi_l_inflection)
psi = np.linspace(0.001,0.999,100)
xi = CST(psi, 1, [deltaz/2., deltaz/2.], Au, Al)
plt.plot(psi, xi['u'], 'b', label = 'Upper outer mold line')
plt.plot(psi, xi['l'],'b--', label = 'Lower outer mold line')
コード例 #15
0
ファイル: plotting.py プロジェクト: tnet/AeroPy
min_x = min(raw_data['x'])
min_index = raw_data['x'].index(min_x)
min_y = raw_data['y'][min_index]

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

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

psi = np.linspace(0, 1, 200)
xi = CST(psi,
         1., [data['deltaz'][n - 1] / 2., data['deltaz'][n - 1] / 2.],
         Au=data['Au'][n - 1],
         Al=data['Al'][n - 1])
plt.figure()
plt.plot(psi, xi['u'], psi, xi['l'])
plt.scatter(raw_data['x'], raw_data['y'])
n = 8
plt.xlim(0, 1)
x = np.linspace(2, 2 * n, n)
plt.gca().set_aspect('equal', adjustable='box')
plt.show()

plt.figure()
plt.plot(x, data['error'])
plt.scatter(x, data['error'])
plt.xlabel('Number of shape functions')
plt.ylabel('Hausdorff distance (adimensional)')