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 +++++++++++++++++++++++++++++++++++--------------------------- main.py | 68 ++++++++++++++++++++++++------------------------- 2 files changed, 82 insertions(+), 71 deletions(-) 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) diff --git a/main.py b/main.py index fd8855f..09d33e6 100644 --- a/main.py +++ b/main.py @@ -24,8 +24,8 @@ start_time = time.time() # Airfoil dimensions NACA_NUM = 2412 -CHORD_LENGTH = 40 -SEMI_SPAN = 50 +CHORD_LENGTH = 12 +SEMI_SPAN = 20 # Airfoil thickness T_UPPER = 0.1 @@ -41,9 +41,9 @@ SPAR_CAP_AREA = 0.3 # sqin STRINGER_AREA = 0.1 # sqin # Amount of stringers -TOP_STRINGERS = 0 +TOP_STRINGERS = 2 BOTTOM_STRINGERS = 18 -NOSE_TOP_STRINGERS = 0 +NOSE_TOP_STRINGERS = 5 NOSE_BOTTOM_STRINGERS = 5 # population information & save path @@ -71,42 +71,42 @@ def main(): af.add_naca(NACA_NUM) af.add_mass(AIRFOIL_MASS) # af.info_print(2) - # af.info_save(SAVE_PATH, _) - - # Create spar instance - af.spar = creator.Spar() - # Define the spar coordinates and mass, stored in single spar object - af.spar.add_coord(af, 0.15) - af.spar.add_coord(af, 0.55) - # Automatically adds spar caps for all spars previously defined - af.spar.add_spar_caps(SPAR_CAP_AREA) - af.spar.add_mass(SPAR_MASS) - # af.spar.info_print(2) - # af.spar.info_save(SAVE_PATH, _) - - # Create stringer instance - af.stringer = creator.Stringer() - # Compute the stringer coordinates from their quantity in each zone - af.stringer.add_coord(af, - NOSE_TOP_STRINGERS, - TOP_STRINGERS, - NOSE_BOTTOM_STRINGERS, - BOTTOM_STRINGERS) - af.stringer.add_area(STRINGER_AREA) - af.stringer.add_mass(STRINGER_MASS) - # af.stringer.info_print(2) - # af.stringer.info_save(SAVE_PATH, _) + af.info_save(SAVE_PATH, _) + + # # Create spar instance + # af.spar = creator.Spar() + # # Define the spar coordinates and mass, stored in single spar object + # af.spar.add_coord(af, 0.15) + # af.spar.add_coord(af, 0.55) + # # Automatically adds spar caps for all spars previously defined + # af.spar.add_spar_caps(SPAR_CAP_AREA) + # af.spar.add_mass(SPAR_MASS) + # # af.spar.info_print(2) + # # af.spar.info_save(SAVE_PATH, _) + # + # # Create stringer instance + # af.stringer = creator.Stringer() + # # Compute the stringer coordinates from their quantity in each zone + # af.stringer.add_coord(af, + # NOSE_TOP_STRINGERS, + # TOP_STRINGERS, + # NOSE_BOTTOM_STRINGERS, + # BOTTOM_STRINGERS) + # af.stringer.add_area(STRINGER_AREA) + # af.stringer.add_mass(STRINGER_MASS) + # # af.stringer.info_print(2) + # # af.stringer.info_save(SAVE_PATH, _) # Plot components with matplotlib - # creator.plot_geom(af) + creator.plot_geom(af) # Evaluator object contains airfoil analysis results. - eval = evaluator.Evaluator(af) + # eval = evaluator.Evaluator(af) # The analysis is performed in the evaluator.py module. - eval.analysis() + # eval.analysis() # eval.info_print(2) - eval.info_save(SAVE_PATH, _) - evaluator.plot_geom(eval) + # eval.info_save(SAVE_PATH, _) + # evaluator.plot_geom(eval) # evaluator.plot_lift(eval) # Print final execution time -- cgit v1.2.3