From b47414d08a70749e84ccc925e9e3a9761c81e0e3 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sat, 22 Jun 2019 20:01:26 -0700 Subject: start work --- creator.py | 147 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 75 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 78c537d..d75661f 100644 --- a/creator.py +++ b/creator.py @@ -53,14 +53,9 @@ class Coordinates: self.area = float() # Component material self.material = str() - # Upper coordinates - self.x_u = [] - self.z_u = [] - # Lower coordinates - self.x_l = [] - self.z_l = [] - # Coordinates x_u, z_u, x_l, z_l packed in single list - self.coord = [] + # Coordinates + self.x = [] + self.z = [] # The airfoil components know the Coordinates instance's coords global parent @@ -85,10 +80,8 @@ class Coordinates: print('Semi-span:', self.semi_span) print('Mass:', self.mass) print(num_of_dashes * '-') - print('x_u the upper x-coordinates:\n', np.around(self.x_u, round)) - print('z_u the upper z-coordinates:\n', np.around(self.z_u, round)) - print('x_l the lower x-coordinates:\n', np.around(self.x_l, round)) - print('z_l the lower z-coordinates:\n', np.around(self.z_l, round)) + print('x-coordinates:\n', np.around(self.x, round)) + print('z-coordinates:\n', np.around(self.z, round)) return None def info_save(self, save_path, number): @@ -182,14 +175,14 @@ class Airfoil(Coordinates): return theta def get_upper_coord(x): - x_u = x - get_thickness(x) * sin(get_theta(x)) - z_u = get_camber(x) + get_thickness(x) * cos(get_theta(x)) - return (x_u, z_u) + x = x - get_thickness(x) * sin(get_theta(x)) + z = get_camber(x) + get_thickness(x) * cos(get_theta(x)) + return (x, z) def get_lower_coord(x): - x_l = x + get_thickness(x) * sin(get_theta(x)) - z_l = get_camber(x) - get_thickness(x) * cos(get_theta(x)) - return (x_l, z_l) + x = x + get_thickness(x) * sin(get_theta(x)) + z = get_camber(x) - get_thickness(x) * cos(get_theta(x)) + return (x, z) # Densify x-coordinates 10 times for first 1/4 chord length x_chord_25_percent = round(self.chord / 4) @@ -200,10 +193,13 @@ class Airfoil(Coordinates): for x in x_chord: self.x_c.append(x) self.y_c.append(get_camber(x)) - self.x_u.append(get_upper_coord(x)[0]) - self.z_u.append(get_upper_coord(x)[1]) - self.x_l.append(get_lower_coord(x)[0]) - self.z_l.append(get_lower_coord(x)[1]) + self.x.append(get_upper_coord(x)[0]) + self.z.append(get_upper_coord(x)[1]) + # Behold the true power of Python list slicing! + # (This special list index reverses the list.) + for x in x_chord[::-1]: + self.x.append(get_lower_coord(x)[0]) + self.z.append(get_lower_coord(x)[1]) return None def add_mass(self, mass): @@ -211,8 +207,8 @@ class Airfoil(Coordinates): def info_print(self, round): super().info_print(round) - print('x_c the camber x-coordinates:\n', np.around(self.x_u, round)) - print('z_c the camber z-coordinates:\n', np.around(self.x_u, round)) + print('x_c the camber x-coordinates:\n', np.around(self.x, round)) + print('z_c the camber z-coordinates:\n', np.around(self.x, round)) return None @@ -223,12 +219,12 @@ class Spar(Coordinates): def __init__(self): super().__init__(parent.chord, parent.semi_span) - def add_coord(self, airfoil, spar_x): + def add_coord(self, airfoil, x_loc_percent): ''' Add a single spar at the % chord location given to function. Parameters: - coordinates: provided by Airfoil.coordinates[x_u, z_u, x_l, z_l]. + coordinates: provided by Airfoil.coordinates[x, z, x, z]. material: spar's material. Assumes homogeneous material. spar_x: spar's location as a % of total chord length. @@ -237,21 +233,22 @@ class Spar(Coordinates): ''' # Airfoil surface coordinates # unpacked from 'coordinates' (list of lists in 'Coordinates'). - x_u = airfoil.x_u - z_u = airfoil.z_u - x_l = airfoil.x_l - z_l = airfoil.z_l + x = airfoil.x + z = airfoil.z # Scaled spar location with regards to chord - loc = spar_x * self.chord - # bisect_left: returns index of first value in x_u > loc. - # Ensures that the spar coordinates intersect with airfoil surface. - spar_x_u = bi.bisect_left(x_u, loc) # index of spar's x_u - spar_x_l = bi.bisect_left(x_l, loc) # index of spar's x_l + loc = x_loc_percent * self.chord + # bisect_left: returns index of first value in x > loc + # starting from [0] + # bisect_right: returns index of first value in x > loc + # starting from [-1] (last list element). + # This ensures that the spar geom intersects with airfoil geom. + spar_x = bi.bisect_left(x, loc) # index of spar's x + spar_x = bi.bisect_left(x, loc) # index of spar's x # These x and y coordinates are assigned to the spar, NOT airfoil. - self.x_u.append(x_u[spar_x_u]) - self.z_u.append(z_u[spar_x_u]) - self.x_l.append(x_l[spar_x_l]) - self.z_l.append(z_l[spar_x_l]) + self.x.append(x[spar_x]) + self.z.append(z[spar_x]) + self.x.append(x[spar_x]) + self.z.append(z[spar_x]) return None def add_spar_caps(self, spar_cap_area): @@ -259,7 +256,7 @@ class Spar(Coordinates): return None def add_mass(self, mass): - self.mass = len(self.x_u) * mass + self.mass = len(self.x) * mass return None @@ -291,44 +288,44 @@ class Stringer(Coordinates): ''' # Find distance between leading edge and first upper stringer - interval = airfoil.spar.x_u[0] / (stringer_u_1 + 1) - # initialise first self.stringer_x_u at first interval + interval = airfoil.spar.x[0] / (stringer_u_1 + 1) + # initialise first self.stringer_x at first interval x = interval # Add upper stringers from leading edge until first spar. for _ in range(0, stringer_u_1): - # Index of the first value of airfoil_x_u > x - index = bi.bisect_left(airfoil.x_u, x) - self.x_u.append(airfoil.x_u[index]) - self.z_u.append(airfoil.z_u[index]) + # Index of the first value of airfoil_x > x + index = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[index]) + self.z.append(airfoil.z[index]) x += interval # Add upper stringers from first spar until last spar # TODO: stringer placement if only one spar is created - interval = (airfoil.spar.x_u[-1] - - airfoil.spar.x_u[0]) / (stringer_u_2 + 1) - x = interval + airfoil.spar.x_u[0] + interval = (airfoil.spar.x[-1] + - airfoil.spar.x[0]) / (stringer_u_2 + 1) + x = interval + airfoil.spar.x[0] for _ in range(0, stringer_u_2): - index = bi.bisect_left(airfoil.x_u, x) - self.x_u.append(airfoil.x_u[index]) - self.z_u.append(airfoil.z_u[index]) + index = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[index]) + self.z.append(airfoil.z[index]) x += interval # Find distance between leading edge and first lower stringer - interval = airfoil.spar.x_l[0] / (stringer_l_1 + 1) + interval = airfoil.spar.x[0] / (stringer_l_1 + 1) x = interval # Add lower stringers from leading edge until first spar. for _ in range(0, stringer_l_1): - index = bi.bisect_left(airfoil.x_l, x) - self.x_l.append(airfoil.x_l[index]) - self.z_l.append(airfoil.z_l[index]) + index = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[index]) + self.z.append(airfoil.z[index]) x += interval # Add lower stringers from first spar until last spar - interval = (airfoil.spar.x_l[-1] - - airfoil.spar.x_l[0]) / (stringer_l_2 + 1) - x = interval + airfoil.spar.x_l[0] + interval = (airfoil.spar.x[-1] + - airfoil.spar.x[0]) / (stringer_l_2 + 1) + x = interval + airfoil.spar.x[0] for _ in range(0, stringer_l_2): - index = bi.bisect_left(airfoil.x_l, x) - self.x_l.append(airfoil.x_l[index]) - self.z_l.append(airfoil.z_l[index]) + index = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[index]) + self.z.append(airfoil.z[index]) x += interval return None @@ -337,7 +334,7 @@ class Stringer(Coordinates): return None def add_mass(self, mass): - self.mass = len(self.x_u) * mass + len(self.x_l) * mass + self.mass = len(self.x) * mass + len(self.x) * mass return None def info_print(self, round): @@ -361,34 +358,34 @@ def plot_geom(airfoil): '-.', color='r', linewidth='2', label='Mean camber line') # Plot upper surface - plt.plot(airfoil.x_u, airfoil.z_u, + plt.plot(airfoil.x, airfoil.z, '', color='b', linewidth='1') # Plot lower surface - plt.plot(airfoil.x_l, airfoil.z_l, + plt.plot(airfoil.x, airfoil.z, '', color='b', linewidth='1') # Plot spars - for _ in range(0, len(airfoil.spar.x_u)): - x = (airfoil.spar.x_u[_], airfoil.spar.x_l[_]) - y = (airfoil.spar.z_u[_], airfoil.spar.z_l[_]) + for _ in range(0, len(airfoil.spar.x)): + x = (airfoil.spar.x[_], airfoil.spar.x[_]) + y = (airfoil.spar.z[_], airfoil.spar.z[_]) plt.plot(x, y, '.-', color='b') # Plot upper stringers - for _ in range(0, len(airfoil.stringer.x_u)): - x = airfoil.stringer.x_u[_] - y = airfoil.stringer.z_u[_] + for _ in range(0, len(airfoil.stringer.x)): + x = airfoil.stringer.x[_] + y = airfoil.stringer.z[_] plt.plot(x, y, '.', color='y', markersize=12) # Plot lower stringers - for _ in range(0, len(airfoil.stringer.x_l)): - x = airfoil.stringer.x_l[_] - y = airfoil.stringer.z_l[_] + for _ in range(0, len(airfoil.stringer.x)): + x = airfoil.stringer.x[_] + y = airfoil.stringer.z[_] plt.plot(x, y, '.', color='y', markersize=12) # Graph formatting plt.xlabel('X axis') plt.ylabel('Z axis') - plot_bound = airfoil.x_u[-1] + plot_bound = airfoil.x[-1] plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound) plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2)) plt.gca().set_aspect('equal', adjustable='box') -- cgit v1.2.3 From 2c8e6e632eb03cd6545de51d72aaebe0df9bf7ee Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sat, 22 Jun 2019 21:07:02 -0700 Subject: airfoil coordinates --- creator.py | 85 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 37 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index d75661f..601e849 100644 --- a/creator.py +++ b/creator.py @@ -186,8 +186,16 @@ class Airfoil(Coordinates): # Densify x-coordinates 10 times for first 1/4 chord length x_chord_25_percent = round(self.chord / 4) - x_chord = [x / 10 for x in range(x_chord_25_percent * 10)] - x_chord.extend([x for x in range(x_chord_25_percent, self.chord + 1)]) + + x_chord = [i / 10 for i in range(x_chord_25_percent * 10)] + x_chord.extend(i for i in range(x_chord_25_percent, self.chord + 1)) + # Reversed list for our lower airfoil coordinate densification + x_chord_rev = [i for i in range( + self.chord, x_chord_25_percent, -1)] + ext = [i / 10 for i in range(x_chord_25_percent * 10, -1, -1)] + x_chord_rev.extend(ext) + print(len(x_chord)) + print(len(x_chord_rev)) # Generate our airfoil geometry from previous sub-functions. for x in x_chord: @@ -195,9 +203,7 @@ class Airfoil(Coordinates): self.y_c.append(get_camber(x)) self.x.append(get_upper_coord(x)[0]) self.z.append(get_upper_coord(x)[1]) - # Behold the true power of Python list slicing! - # (This special list index reverses the list.) - for x in x_chord[::-1]: + for x in x_chord_rev: self.x.append(get_lower_coord(x)[0]) self.z.append(get_lower_coord(x)[1]) return None @@ -232,7 +238,6 @@ class Spar(Coordinates): None ''' # Airfoil surface coordinates - # unpacked from 'coordinates' (list of lists in 'Coordinates'). x = airfoil.x z = airfoil.z # Scaled spar location with regards to chord @@ -242,13 +247,21 @@ class Spar(Coordinates): # bisect_right: returns index of first value in x > loc # starting from [-1] (last list element). # This ensures that the spar geom intersects with airfoil geom. - spar_x = bi.bisect_left(x, loc) # index of spar's x - spar_x = bi.bisect_left(x, loc) # index of spar's x + spar_x_u = bi.bisect_left(x, loc) # index of spar's x_u + spar_z_u = bi.bisect_left(z, loc) + spar_x_l = bi.bisect_left(x[::-1], loc) # index of spar's x_l + spar_z_l = bi.bisect_left(z[::-1], loc) + print(len(x)) + print(len(z)) # These x and y coordinates are assigned to the spar, NOT airfoil. - self.x.append(x[spar_x]) - self.z.append(z[spar_x]) - self.x.append(x[spar_x]) - self.z.append(z[spar_x]) + # print(spar_x_u) + # print(spar_z_u) + # print(spar_x_l) + # print(spar_z_l) + # self.x.append(x[spar_x_u]) + # self.z.append(z[spar_z_u]) + # self.x.append(x[spar_x_l]) + # self.z.append(z[spar_z_l]) return None def add_spar_caps(self, spar_cap_area): @@ -354,40 +367,38 @@ def plot_geom(airfoil): plt.plot(airfoil.chord / 4, 0, '.', color='g', markersize=24, label='Quarter-chord') # Plot mean camber line - plt.plot(airfoil.x_c, airfoil.y_c, - '-.', color='r', linewidth='2', + plt.plot(airfoil.x_c, airfoil.y_c, '-.', color='r', linewidth='2', label='Mean camber line') - # Plot upper surface - plt.plot(airfoil.x, airfoil.z, - '', color='b', linewidth='1') - # Plot lower surface - plt.plot(airfoil.x, airfoil.z, - '', color='b', linewidth='1') + # Plot airfoil surfaces + plt.fill(airfoil.x, airfoil.z, '', color='b', linewidth='1', fill=False) # Plot spars - for _ in range(0, len(airfoil.spar.x)): - x = (airfoil.spar.x[_], airfoil.spar.x[_]) - y = (airfoil.spar.z[_], airfoil.spar.z[_]) - plt.plot(x, y, '.-', color='b') - + try: + for _ in range(0, len(airfoil.spar.x)): + x = (airfoil.spar.x[_], airfoil.spar.x[_]) + y = (airfoil.spar.z[_], airfoil.spar.z[_]) + plt.plot(x, y, '.-', color='b') + except AttributeError: + print('No spars to plot.') # Plot upper stringers - for _ in range(0, len(airfoil.stringer.x)): - x = airfoil.stringer.x[_] - y = airfoil.stringer.z[_] - plt.plot(x, y, '.', color='y', markersize=12) - # Plot lower stringers - for _ in range(0, len(airfoil.stringer.x)): - x = airfoil.stringer.x[_] - y = airfoil.stringer.z[_] - plt.plot(x, y, '.', color='y', markersize=12) + try: + for _ in range(0, len(airfoil.stringer.x)): + x = airfoil.stringer.x[_] + y = airfoil.stringer.z[_] + plt.plot(x, y, '.', color='y', markersize=12) + except AttributeError: + print('No stringers to plot.') + # # Plot lower stringers + # for _ in range(0, len(airfoil.stringer.x)): + # x = airfoil.stringer.x[_] + # y = airfoil.stringer.z[_] + # plt.plot(x, y, '.', color='y', markersize=12) # Graph formatting plt.xlabel('X axis') plt.ylabel('Z axis') - plot_bound = airfoil.x[-1] - plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound) - plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2)) + # plot_bound = airfoil.x[-1] plt.gca().set_aspect('equal', adjustable='box') plt.gca().legend() plt.grid(axis='both', linestyle=':', linewidth=1) -- cgit v1.2.3 From 5de63cf149ba044444531e7a5eb5a40ec67dcaed Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 01:45:58 -0700 Subject: creator.py updated --- creator.py | 104 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 49 insertions(+), 55 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 601e849..210e502 100644 --- a/creator.py +++ b/creator.py @@ -105,7 +105,14 @@ class Coordinates: class Airfoil(Coordinates): - '''This class enables the creation of a single NACA airfoil.''' + ''' + This class enables the creation of a single NACA airfoil. + + Please note: the coordinates are saved as two lists + for the x- and z-coordinates. The coordinates start at + the leading edge, travel over the airfoil's upper edge, + then loops back to the leading edge via the lower edge. + ''' def __init__(self): global parent @@ -190,12 +197,9 @@ class Airfoil(Coordinates): x_chord = [i / 10 for i in range(x_chord_25_percent * 10)] x_chord.extend(i for i in range(x_chord_25_percent, self.chord + 1)) # Reversed list for our lower airfoil coordinate densification - x_chord_rev = [i for i in range( - self.chord, x_chord_25_percent, -1)] + x_chord_rev = [i for i in range(self.chord, x_chord_25_percent, -1)] ext = [i / 10 for i in range(x_chord_25_percent * 10, -1, -1)] x_chord_rev.extend(ext) - print(len(x_chord)) - print(len(x_chord_rev)) # Generate our airfoil geometry from previous sub-functions. for x in x_chord: @@ -237,31 +241,21 @@ class Spar(Coordinates): Return: None ''' - # Airfoil surface coordinates - x = airfoil.x - z = airfoil.z + # Scaled spar location with regards to chord loc = x_loc_percent * self.chord - # bisect_left: returns index of first value in x > loc - # starting from [0] - # bisect_right: returns index of first value in x > loc - # starting from [-1] (last list element). - # This ensures that the spar geom intersects with airfoil geom. - spar_x_u = bi.bisect_left(x, loc) # index of spar's x_u - spar_z_u = bi.bisect_left(z, loc) - spar_x_l = bi.bisect_left(x[::-1], loc) # index of spar's x_l - spar_z_l = bi.bisect_left(z[::-1], loc) - print(len(x)) - print(len(z)) - # These x and y coordinates are assigned to the spar, NOT airfoil. - # print(spar_x_u) - # print(spar_z_u) - # print(spar_x_l) - # print(spar_z_l) - # self.x.append(x[spar_x_u]) - # self.z.append(z[spar_z_u]) - # self.x.append(x[spar_x_l]) - # self.z.append(z[spar_z_l]) + # bi.bisect_left: returns index of first value in airfoil.x > loc + # This ensures that spar geom intersects with airfoil geom. + # Spar upper coordinates + spar_x = bi.bisect_left(airfoil.x, loc) - 1 + x = [airfoil.x[spar_x]] + z = [airfoil.z[spar_x]] + # Spar lower coordinates + spar_x = bi.bisect_left(airfoil.x[::-1], loc) - 1 + x += [airfoil.x[-spar_x]] + z += [airfoil.z[-spar_x]] + self.x.append(x) + self.z.append(z) return None def add_spar_caps(self, spar_cap_area): @@ -301,44 +295,44 @@ class Stringer(Coordinates): ''' # Find distance between leading edge and first upper stringer - interval = airfoil.spar.x[0] / (stringer_u_1 + 1) + interval = airfoil.spar.x[0][0] / (stringer_u_1 + 1) # initialise first self.stringer_x at first interval x = interval # Add upper stringers from leading edge until first spar. for _ in range(0, stringer_u_1): - # Index of the first value of airfoil_x > x - index = bi.bisect_left(airfoil.x, x) - self.x.append(airfoil.x[index]) - self.z.append(airfoil.z[index]) + # Index of the first value of airfoil.x > x + i = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[i]) + self.z.append(airfoil.z[i]) x += interval # Add upper stringers from first spar until last spar # TODO: stringer placement if only one spar is created - interval = (airfoil.spar.x[-1] - - airfoil.spar.x[0]) / (stringer_u_2 + 1) - x = interval + airfoil.spar.x[0] + interval = (airfoil.spar.x[-1][0] + - airfoil.spar.x[0][0]) / (stringer_u_2 + 1) + x = interval + airfoil.spar.x[0][0] for _ in range(0, stringer_u_2): - index = bi.bisect_left(airfoil.x, x) - self.x.append(airfoil.x[index]) - self.z.append(airfoil.z[index]) + i = bi.bisect_left(airfoil.x, x) + self.x.append(airfoil.x[i]) + self.z.append(airfoil.z[i]) x += interval # Find distance between leading edge and first lower stringer - interval = airfoil.spar.x[0] / (stringer_l_1 + 1) + interval = airfoil.spar.x[0][1] / (stringer_l_1 + 1) x = interval # Add lower stringers from leading edge until first spar. for _ in range(0, stringer_l_1): - index = bi.bisect_left(airfoil.x, x) - self.x.append(airfoil.x[index]) - self.z.append(airfoil.z[index]) + i = bi.bisect_left(airfoil.x[::-1], x) + self.x.append(airfoil.x[-i]) + self.z.append(airfoil.z[-i]) x += interval # Add lower stringers from first spar until last spar - interval = (airfoil.spar.x[-1] - - airfoil.spar.x[0]) / (stringer_l_2 + 1) - x = interval + airfoil.spar.x[0] + interval = (airfoil.spar.x[-1][1] + - airfoil.spar.x[0][1]) / (stringer_l_2 + 1) + x = interval + airfoil.spar.x[0][1] for _ in range(0, stringer_l_2): - index = bi.bisect_left(airfoil.x, x) - self.x.append(airfoil.x[index]) - self.z.append(airfoil.z[index]) + i = bi.bisect_left(airfoil.x[::-1], x) + self.x.append(airfoil.x[-i]) + self.z.append(airfoil.z[-i]) x += interval return None @@ -364,20 +358,20 @@ def plot_geom(airfoil): y_chord = [0, 0] plt.plot(x_chord, y_chord, linewidth='1') # Plot quarter chord - plt.plot(airfoil.chord / 4, 0, '.', color='g', + plt.plot(airfoil.chord / 4, 0, '', color='g', markersize=24, label='Quarter-chord') # Plot mean camber line plt.plot(airfoil.x_c, airfoil.y_c, '-.', color='r', linewidth='2', label='Mean camber line') # Plot airfoil surfaces - plt.fill(airfoil.x, airfoil.z, '', color='b', linewidth='1', fill=False) + plt.fill(airfoil.x, airfoil.z, color='b', linewidth='1', fill=False) # Plot spars try: - for _ in range(0, len(airfoil.spar.x)): - x = (airfoil.spar.x[_], airfoil.spar.x[_]) - y = (airfoil.spar.z[_], airfoil.spar.z[_]) - plt.plot(x, y, '.-', color='b') + for _ in range(len(airfoil.spar.x)): + x = (airfoil.spar.x[_]) + y = (airfoil.spar.z[_]) + plt.plot(x, y, '-', color='b') except AttributeError: print('No spars to plot.') # Plot upper stringers -- cgit v1.2.3 From 3074c4c8cbeac6a6e5a4d7fa4a8afe34ec39911d Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 02:09:34 -0700 Subject: finalised branch :) --- creator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 210e502..aa9fcbd 100644 --- a/creator.py +++ b/creator.py @@ -358,7 +358,7 @@ def plot_geom(airfoil): y_chord = [0, 0] plt.plot(x_chord, y_chord, linewidth='1') # Plot quarter chord - plt.plot(airfoil.chord / 4, 0, '', color='g', + plt.plot(airfoil.chord / 4, 0, '.', color='g', markersize=24, label='Quarter-chord') # Plot mean camber line plt.plot(airfoil.x_c, airfoil.y_c, '-.', color='r', linewidth='2', @@ -392,7 +392,9 @@ def plot_geom(airfoil): plt.xlabel('X axis') plt.ylabel('Z axis') - # plot_bound = airfoil.x[-1] + plot_bound = max(airfoil.x) + plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound) + plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2)) plt.gca().set_aspect('equal', adjustable='box') plt.gca().legend() plt.grid(axis='both', linestyle=':', linewidth=1) -- cgit v1.2.3 From 7a7c4840386adc45ed84985784d57fe3fc345c07 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 02:17:21 -0700 Subject: bugfix --- creator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index aa9fcbd..0bfe529 100644 --- a/creator.py +++ b/creator.py @@ -198,8 +198,8 @@ class Airfoil(Coordinates): x_chord.extend(i for i in range(x_chord_25_percent, self.chord + 1)) # Reversed list for our lower airfoil coordinate densification x_chord_rev = [i for i in range(self.chord, x_chord_25_percent, -1)] - ext = [i / 10 for i in range(x_chord_25_percent * 10, -1, -1)] - x_chord_rev.extend(ext) + extend = [i / 10 for i in range(x_chord_25_percent * 10, -1, -1)] + x_chord_rev.extend(extend) # Generate our airfoil geometry from previous sub-functions. for x in x_chord: -- cgit v1.2.3 From 3ce3509ea818c289d45de8264068791de91a1b99 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 12:17:37 -0700 Subject: bugfix: negative x-coord error for high-camber cases --- creator.py | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 0bfe529..3749bf7 100644 --- a/creator.py +++ b/creator.py @@ -122,7 +122,7 @@ class Airfoil(Coordinates): self.naca_num = int() # Mean camber line self.x_c = [] - self.y_c = [] + self.z_c = [] def add_naca(self, naca_num): ''' @@ -148,22 +148,22 @@ class Airfoil(Coordinates): def get_camber(x): ''' - Returns camber y-coordinate from 1 'x' along the airfoil chord. + Returns camber z-coordinate from 1 'x' along the airfoil chord. ''' - y_c = float() + z_c = float() if 0 <= x < p_c: - y_c = (m / (p ** 2)) * (2 * p * (x / self.chord) + z_c = (m / (p ** 2)) * (2 * p * (x / self.chord) - (x / self.chord) ** 2) elif p_c <= x <= self.chord: - y_c = (m / ((1 - p) ** 2)) * ((1 - 2 * p) + z_c = (m / ((1 - p) ** 2)) * ((1 - 2 * p) + 2 * p * (x / self.chord) - (x / self.chord) ** 2) - return (y_c * self.chord) + return (z_c * self.chord) def get_thickness(x): - ''' - Returns thickness from 1 'x' along the airfoil chord. - ''' + '''Returns thickness from 1 'x' along the airfoil chord.''' + + x = 0 if x < 0 else x y_t = 5 * t * self.chord * ( + 0.2969 * sqrt(x / self.chord) - 0.1260 * (x / self.chord) @@ -173,12 +173,12 @@ class Airfoil(Coordinates): return y_t def get_theta(x): - dy_c = float() + dz_c = float() if 0 <= x < p_c: - dy_c = ((2 * m) / p ** 2) * (p - x / self.chord) + dz_c = ((2 * m) / p ** 2) * (p - x / self.chord) elif p_c <= x <= self.chord: - dy_c = (2 * m) / ((1 - p) ** 2) * (p - x / self.chord) - theta = atan(dy_c) + dz_c = (2 * m) / ((1 - p) ** 2) * (p - x / self.chord) + theta = atan(dz_c) return theta def get_upper_coord(x): @@ -204,7 +204,7 @@ class Airfoil(Coordinates): # Generate our airfoil geometry from previous sub-functions. for x in x_chord: self.x_c.append(x) - self.y_c.append(get_camber(x)) + self.z_c.append(get_camber(x)) self.x.append(get_upper_coord(x)[0]) self.z.append(get_upper_coord(x)[1]) for x in x_chord_rev: @@ -361,7 +361,7 @@ def plot_geom(airfoil): plt.plot(airfoil.chord / 4, 0, '.', color='g', markersize=24, label='Quarter-chord') # Plot mean camber line - plt.plot(airfoil.x_c, airfoil.y_c, '-.', color='r', linewidth='2', + plt.plot(airfoil.x_c, airfoil.z_c, '-.', color='r', linewidth='2', label='Mean camber line') # Plot airfoil surfaces plt.fill(airfoil.x, airfoil.z, color='b', linewidth='1', fill=False) @@ -374,7 +374,7 @@ def plot_geom(airfoil): plt.plot(x, y, '-', color='b') except AttributeError: print('No spars to plot.') - # Plot upper stringers + # Plot stringers try: for _ in range(0, len(airfoil.stringer.x)): x = airfoil.stringer.x[_] @@ -382,11 +382,6 @@ def plot_geom(airfoil): plt.plot(x, y, '.', color='y', markersize=12) except AttributeError: print('No stringers to plot.') - # # Plot lower stringers - # for _ in range(0, len(airfoil.stringer.x)): - # x = airfoil.stringer.x[_] - # y = airfoil.stringer.z[_] - # plt.plot(x, y, '.', color='y', markersize=12) # Graph formatting plt.xlabel('X axis') -- cgit v1.2.3 From 70116a396caa2ae02b857f751a4df31886592795 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 12:21:32 -0700 Subject: Airfoil docstring --- creator.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 3749bf7..d378c35 100644 --- a/creator.py +++ b/creator.py @@ -112,6 +112,9 @@ class Airfoil(Coordinates): for the x- and z-coordinates. The coordinates start at the leading edge, travel over the airfoil's upper edge, then loops back to the leading edge via the lower edge. + This method was chosen for easier future exports + to 3D CAD packages like SolidWorks, which can import + geometry as coordinates written in a CSV file. ''' def __init__(self): -- cgit v1.2.3 From 84bc9ff5fd93a011cb05df7ccc0b2797f9d3847d Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 12:22:30 -0700 Subject: typos in Airfoil docstring --- creator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index d378c35..533f35e 100644 --- a/creator.py +++ b/creator.py @@ -111,7 +111,7 @@ class Airfoil(Coordinates): Please note: the coordinates are saved as two lists for the x- and z-coordinates. The coordinates start at the leading edge, travel over the airfoil's upper edge, - then loops back to the leading edge via the lower edge. + then loop back to the leading edge via the lower edge. This method was chosen for easier future exports to 3D CAD packages like SolidWorks, which can import geometry as coordinates written in a CSV file. -- cgit v1.2.3 From d9b627d06abe7f3d53aa3aebfecd9e392b3e276e Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 23 Jun 2019 12:24:23 -0700 Subject: Airfoil docstring --- creator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'creator.py') diff --git a/creator.py b/creator.py index 533f35e..6dd3c1c 100644 --- a/creator.py +++ b/creator.py @@ -112,8 +112,9 @@ class Airfoil(Coordinates): for the x- and z-coordinates. The coordinates start at the leading edge, travel over the airfoil's upper edge, then loop back to the leading edge via the lower edge. + This method was chosen for easier future exports - to 3D CAD packages like SolidWorks, which can import + to 3D CAD packages like SolidWorks, which can import such geometry as coordinates written in a CSV file. ''' -- cgit v1.2.3