*ARCHIVED* development moved to aircraft-studio.
Stringer plotting & Coordinates __str__ method
Changed files
analysis.py
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)