Stringer plotting & Coordinates __str__ method

Commit
6e03a7184120cee7a4d3713936c97d64244c482a
Author
Marius Peter <blendoit@gmail.com>
Author date
Committer
Marius Peter <blendoit@gmail.com>
Committer date
Changed files
analysis.py
index 8ea15797..00000000 100644..000000
@@ -1,16 +0,0 @@
1 Removed: # This file is part of Marius Peter's airfoil analysis package (this program).
2 Removed: #
3 Removed: # This program is free software: you can redistribute it and/or modify
4 Removed: # it under the terms of the GNU General Public License as published by
5 Removed: # the Free Software Foundation, either version 3 of the License, or
6 Removed: # (at your option) any later version.
7 Removed: #
8 Removed: # This program is distributed in the hope that it will be useful,
9 Removed: # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 Removed: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Removed: # GNU General Public License for more details.
12 Removed: #
13 Removed: # You should have received a copy of the GNU General Public License
14 Removed: # along with this program. If not, see <https://www.gnu.org/licenses/>.
15 Removed:
16 Removed: import airfoil as af
creator.py
index 673cfe97..5ac4c06f 100644..100644
@@ -64,14 +64,17 @@
64 64 global parent
65 65 parent = self
66 66
67 Removed: def print_component(self, round):
67 Added: def __str__(self):
68 Added: return type(self).__name__
69 Added:
70 Added: def print_coord(self, round):
68 71 """
69 72 Print all the component's coordinates to the terminal.
70 73
71 74 This function's output is piped to the 'save_coord' function below.
72 75 """
73 76 print('============================')
74 Removed: print('Component:', type(self).__name__)
77 Added: print('Component:', str(self))
75 78 print('Chord length:', self.chord)
76 79 print('Semi-span:', self.semi_span)
77 80 print('============================')
@@ -94,7 +97,8 @@
94 97 """
95 98 Save all the object's coordinates (must be full path).
96 99 """
97 Removed: file_name = str(type(self).__name__)
100 Added:
101 Added: file_name = str(self)
98 102 full_path = os.path.join(save_dir_path, file_name + '.txt')
99 103 file = open(full_path, 'w')
100 104 sys.stdout = file
@@ -127,11 +131,11 @@
127 131 # Theta
128 132 self.theta = []
129 133
130 Removed: def naca(self, naca_num):
134 Added: def add_naca(self, naca_num):
131 135 """
132 Removed: This function generates geometry for our chosen NACA airfoil shape.\
133 Removed: The nested functions perform the required steps to generate geometry,\
134 Removed: and can be called to solve the geometry y-coordinate for any 'x' input.\
136 Added: This function generates geometry for our chosen NACA airfoil shape.
137 Added: The nested functions perform the required steps to generate geometry,
138 Added: and can be called to solve the geometry y-coordinate for any 'x' input.
135 139 Equation coefficients were retrieved from Wikipedia.org.
136 140
137 141 Parameters:
@@ -245,7 +249,7 @@
245 249 def __init__(self):
246 250 super().__init__(parent.chord, parent.semi_span)
247 251
248 Removed: def add_spar(self, coordinates, spar_x):
252 Added: def add(self, airfoil_coord, spar_x):
249 253 """
250 254 Add a single spar at the % chord location given to function.
251 255
@@ -258,11 +262,11 @@
258 262 None
259 263 """
260 264 # Airfoil surface coordinates
261 Removed: # unpacked from 'coordinates' (list of lists in 'Airfoil').
262 Removed: x_u = coordinates[0]
263 Removed: y_u = coordinates[1]
264 Removed: x_l = coordinates[2]
265 Removed: y_l = coordinates[3]
265 Added: # unpacked from 'coordinates' (list of lists in 'Coordinates').
266 Added: x_u = airfoil_coord[0]
267 Added: y_u = airfoil_coord[1]
268 Added: x_l = airfoil_coord[2]
269 Added: y_l = airfoil_coord[3]
266 270 # Scaled spar location with regards to chord
267 271 loc = spar_x * self.chord
268 272 # bisect_left: returns index of first value in x_u > loc.
@@ -279,14 +283,15 @@
279 283 return None
280 284
281 285
282 Removed: class Stringer():
286 Added: class Stringer(Coordinates):
283 287 """Contains the coordinates of stringer(s)."""
284 288 global parent
285 289
286 290 def __init__(self):
287 291 super().__init__(parent.chord, parent.semi_span)
288 292
289 Removed: def add_stringer(self, coordinates, den_u_1, den_u_2, den_l_1, den_l_2):
293 Added: def add(self, airfoil_coord, spar_coord, den_u_1, den_u_2, den_l_1,
294 Added: den_l_2):
290 295 """
291 296 Add stringers to the wing from their density distribution.
292 297
@@ -299,41 +304,53 @@
299 304 Returns:
300 305 None
301 306 """
307 Added:
302 308 # Airfoil surface coordinates
303 Removed: # unpacked from 'coordinates' (list of lists in 'Airfoil').
304 Removed: x_u = coordinates[0]
305 Removed: y_u = coordinates[1]
306 Removed: x_l = coordinates[2]
307 Removed: y_l = coordinates[3]
308 Removed: # Find interval between leading edge and first upper stringer,
309 Added: # unpacked from 'coordinates' (list of lists in 'Coordinates').
310 Added: airfoil_x_u = airfoil_coord[0]
311 Added: airfoil_y_u = airfoil_coord[1]
312 Added: airfoil_x_l = airfoil_coord[2]
313 Added: airfoil_y_l = airfoil_coord[3]
314 Added:
315 Added: # Spar coordinates
316 Added: # unpacked from 'coordinates' (list of lists in 'Coordinates').
317 Added: spar_x_u = spar_coord[0]
318 Added: spar_y_u = spar_coord[1]
319 Added: spar_x_l = spar_coord[2]
320 Added: spar_y_l = spar_coord[3]
321 Added:
322 Added: # Find distance between leading edge and first upper stringer,
309 323 # from density parameter den_u_1.
310 Removed: interval = self.spar_x_u[0] / (den_u_1 * self.spar_x_u[0])
324 Added: interval = den_u_1 * spar_x_u[0]
311 325 # initialise first self.stringer_x_u at first interval.
312 326 x = interval
313 327 # Add upper stringers until first spar.
314 Removed: while x < self.spar_x_u[0]:
315 Removed: # Index of the first value of self.x_u > x
316 Removed: x_u = bi.bisect_left(self.x_u, x)
317 Removed: self.stringer_x_u.append(self.x_u[x_u])
318 Removed: self.stringer_y_u.append(self.y_u[x_u])
328 Added: while x < spar_x_u[0]:
329 Added: # Index of the first value of airfoil_x_u > x
330 Added: index = bi.bisect_left(airfoil_x_u, x)
331 Added: # Append the value of airfoil_x_u at index to stringer's coordinates
332 Added: self.x_u.append(airfoil_x_u[index])
333 Added: self.y_u.append(airfoil_y_u[index])
319 334 x += interval
320 335
321 336 # Find interval between leading edge and first lower stringer,
322 337 # from density parameter den_l_1.
323 Removed: interval = self.spar_x_u[0] / (den_l_1 * self.spar_x_u[0])
338 Added: interval = den_l_1 * spar_x_u[0]
324 339 # initialise first self.stringer_x_l at first interval.
325 340 x = interval
326 341 # Add lower stringers until first spar.
327 Removed: while x < self.spar_x_l[0]:
342 Added: while x < spar_x_l[0]:
328 343 # Index of the first value of self.x_l > x
329 Removed: x_u = bi.bisect_left(self.x_l, x)
330 Removed: self.stringer_x_l.append(self.x_l[x_u])
331 Removed: self.stringer_y_l.append(self.y_l[x_u])
344 Added: index = bi.bisect_left(airfoil_x_l, x)
345 Added: self.x_u.append(airfoil_x_u[index])
346 Added: self.y_u.append(airfoil_y_u[index])
332 347 x += interval
348 Added:
349 Added: super().pack_coord()
333 350 return None
334 351
335 352
336 Removed: def plot(airfoil, spar):
353 Added: def plot(airfoil, spar, stringer):
337 354 """This function plots the elements passed as arguments."""
338 355
339 356 print('Plotting airfoil.')
@@ -352,6 +369,7 @@
352 369 plt.plot(airfoil.x_u, airfoil.y_u, '', color='b', linewidth='1')
353 370 # Plot lower surface
354 371 plt.plot(airfoil.x_l, airfoil.y_l, '', color='b', linewidth='1')
372 Added:
355 373 # Plot spars
356 374 try:
357 375 for _ in range(0, len(spar.x_u)):
@@ -361,14 +379,15 @@
361 379 plt.legend()
362 380 except:
363 381 print('Did not plot spars. Were they added?')
382 Added:
364 383 # Plot stringers
365 Removed: # if len(self.spar_x) != 0:
366 Removed: # for _ in range(0, len(self.stringer_x)):
367 Removed: # x = (self.stringer_x[_], self.stringer_x[_])
368 Removed: # y = (self.stringer_y_u[_], self.stringer_y_l[_])
369 Removed: # plt.scatter(x, y, color='y', linewidth='1',
370 Removed: # else:
371 Removed: # print('Unable to plot stringers. Were they created?')
384 Added: try:
385 Added: for _ in range(0, len(stringer.x_u)):
386 Added: x = (spar.x_u[_], spar.x_l[_])
387 Added: y = (spar.y_u[_], spar.y_l[_])
388 Added: except:
389 Added: print('Unable to plot stringers. Were they created?')
390 Added:
372 391 # Graph formatting
373 392 plt.gcf().set_size_inches(9, 2.2)
374 393 plt.xlabel('X axis')
evaluator.py
index 00000000..6a87b7ef 000000..100644
@@ -0,0 +1,16 @@
1 Added: # This file is part of Marius Peter's airfoil analysis package (this program).
2 Added: #
3 Added: # This program is free software: you can redistribute it and/or modify
4 Added: # it under the terms of the GNU General Public License as published by
5 Added: # the Free Software Foundation, either version 3 of the License, or
6 Added: # (at your option) any later version.
7 Added: #
8 Added: # This program is distributed in the hope that it will be useful,
9 Added: # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 Added: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Added: # GNU General Public License for more details.
12 Added: #
13 Added: # You should have received a copy of the GNU General Public License
14 Added: # along with this program. If not, see <https://www.gnu.org/licenses/>.
15 Added:
16 Added: import creator
generator.py
index 00000000..6a87b7ef 000000..100644
@@ -0,0 +1,16 @@
1 Added: # This file is part of Marius Peter's airfoil analysis package (this program).
2 Added: #
3 Added: # This program is free software: you can redistribute it and/or modify
4 Added: # it under the terms of the GNU General Public License as published by
5 Added: # the Free Software Foundation, either version 3 of the License, or
6 Added: # (at your option) any later version.
7 Added: #
8 Added: # This program is distributed in the hope that it will be useful,
9 Added: # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 Added: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Added: # GNU General Public License for more details.
12 Added: #
13 Added: # You should have received a copy of the GNU General Public License
14 Added: # along with this program. If not, see <https://www.gnu.org/licenses/>.
15 Added:
16 Added: import creator
genetic_algorithm.py
index 8ea15797..00000000 100644..000000
@@ -1,16 +0,0 @@
1 Removed: # This file is part of Marius Peter's airfoil analysis package (this program).
2 Removed: #
3 Removed: # This program is free software: you can redistribute it and/or modify
4 Removed: # it under the terms of the GNU General Public License as published by
5 Removed: # the Free Software Foundation, either version 3 of the License, or
6 Removed: # (at your option) any later version.
7 Removed: #
8 Removed: # This program is distributed in the hope that it will be useful,
9 Removed: # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 Removed: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 Removed: # GNU General Public License for more details.
12 Removed: #
13 Removed: # You should have received a copy of the GNU General Public License
14 Removed: # along with this program. If not, see <https://www.gnu.org/licenses/>.
15 Removed:
16 Removed: import airfoil as af
main.py
index bba67ceb..17d081ac 100644..100644
@@ -13,13 +13,15 @@
13 13 # You should have received a copy of the GNU General Public License
14 14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
15 15
16 Removed: import creator
16 Added: import creator # Create geometry
17 Added: import evaluator # Evaluate geometry
18 Added: import generator # Iteratevely evaluate instances of geometry
17 19 import random
18 20
19 21 import time
20 22 start_time = time.time()
21 23
22 Removed: CHORD_LENGTH = 10
24 Added: CHORD_LENGTH = 40
23 25 SEMI_SPAN = 200
24 26
25 27 POP_SIZE = 1
@@ -27,7 +29,7 @@
27 29
28 30
29 31 def main():
30 Removed: # Create coordinate system specific to airfoil dimensions.
32 Added: # Create coordinate system specific to our airfoil dimensions.
31 33 creator.Coordinates(CHORD_LENGTH, SEMI_SPAN)
32 34
33 35 # Interate through all wings in population.
@@ -35,27 +37,25 @@
35 37 # Create airfoil instance
36 38 af = creator.Airfoil()
37 39 # Define NACA airfoil coordinates
38 Removed: af.naca(2412)
40 Added: af.add_naca(2412)
39 41
40 Removed: print(af.coord)
41 Removed:
42 42 # Create spar instance
43 43 af.spar = creator.Spar()
44 Removed: # Define the spar coordinates
45 Removed: af.spar.add_spar(af.coord, 0.15)
46 Removed: af.spar.add_spar(af.coord, 0.55)
44 Added: # Define the spar coordinates, stored in single spar object
45 Added: af.spar.add(af.coord, 0.15)
46 Added: af.spar.add(af.coord, 0.55)
47 47 # Print coordinates of af.spar to terminal
48 48
49 Removed: # # Create stringer instance
50 Removed: # af.stringer = creator.Stringer()
51 Removed: # # Define the stringer coordinates
52 Removed: # af.stringer.add_stringer(af.coordinates, 0.15)
53 Removed: # af.stringer.add_stringer(af.coordinates, 0.55)
54 Removed: # # Print coordinates of af.stringer to terminal
55 Removed: # af.stringer.print_coord(4)
49 Added: # Create stringer instance
50 Added: af.stringer = creator.Stringer()
51 Added: # Define the stringer coordinates from airfoil's and spars'
52 Added: af.stringer.add(af.coord, af.spar.coord, 0.2, 0.2, 0.2, 0.2)
53 Added: # Print coordinates of af.stringer to terminal
54 Added: # af.stringer.print_coord(2)
56 55
56 Added: print(af.stringer.coord)
57 57 # Plot components with matplotlib
58 Removed: creator.plot(af, af.spar)
58 Added: creator.plot(af, af.spar, af.stringer)
59 59
60 60 # # Save component coordinates
61 61 # af.save_coord(SAVE_PATH)