*ARCHIVED* development moved to aircraft-studio.
Merge pull request #4 from Blendoit/2_coord_vs_4
2 coord vs 4
Changed files
creator.py
@@ -53,14 +53,9 @@
53
53
self.area = float()
54
54
# Component material
55
55
self.material = str()
56
Removed:
# Upper coordinates
57
Removed:
self.x_u = []
58
Removed:
self.z_u = []
59
Removed:
# Lower coordinates
60
Removed:
self.x_l = []
61
Removed:
self.z_l = []
62
Removed:
# Coordinates x_u, z_u, x_l, z_l packed in single list
63
Removed:
self.coord = []
56
Added:
# Coordinates
57
Added:
self.x = []
58
Added:
self.z = []
64
59
65
60
# The airfoil components know the Coordinates instance's coords
66
61
global parent
@@ -85,10 +80,8 @@
85
80
print('Semi-span:', self.semi_span)
86
81
print('Mass:', self.mass)
87
82
print(num_of_dashes * '-')
88
Removed:
print('x_u the upper x-coordinates:\n', np.around(self.x_u, round))
89
Removed:
print('z_u the upper z-coordinates:\n', np.around(self.z_u, round))
90
Removed:
print('x_l the lower x-coordinates:\n', np.around(self.x_l, round))
91
Removed:
print('z_l the lower z-coordinates:\n', np.around(self.z_l, round))
83
Added:
print('x-coordinates:\n', np.around(self.x, round))
84
Added:
print('z-coordinates:\n', np.around(self.z, round))
92
85
return None
93
86
94
87
def info_save(self, save_path, number):
@@ -112,8 +105,19 @@
112
105
113
106
114
107
class Airfoil(Coordinates):
115
Removed:
'''This class enables the creation of a single NACA airfoil.'''
108
Added:
'''
109
Added:
This class enables the creation of a single NACA airfoil.
116
110
111
Added:
Please note: the coordinates are saved as two lists
112
Added:
for the x- and z-coordinates. The coordinates start at
113
Added:
the leading edge, travel over the airfoil's upper edge,
114
Added:
then loop back to the leading edge via the lower edge.
115
Added:
116
Added:
This method was chosen for easier future exports
117
Added:
to 3D CAD packages like SolidWorks, which can import such
118
Added:
geometry as coordinates written in a CSV file.
119
Added:
'''
120
Added:
117
121
def __init__(self):
118
122
global parent
119
123
# Run 'Coordinates' super class init method with same chord & 1/2 span.
@@ -122,7 +126,7 @@
122
126
self.naca_num = int()
123
127
# Mean camber line
124
128
self.x_c = []
125
Removed:
self.y_c = []
129
Added:
self.z_c = []
126
130
127
131
def add_naca(self, naca_num):
128
132
'''
@@ -148,22 +152,22 @@
148
152
149
153
def get_camber(x):
150
154
'''
151
Removed:
Returns camber y-coordinate from 1 'x' along the airfoil chord.
155
Added:
Returns camber z-coordinate from 1 'x' along the airfoil chord.
152
156
'''
153
Removed:
y_c = float()
157
Added:
z_c = float()
154
158
if 0 <= x < p_c:
155
Removed:
y_c = (m / (p ** 2)) * (2 * p * (x / self.chord)
159
Added:
z_c = (m / (p ** 2)) * (2 * p * (x / self.chord)
156
160
- (x / self.chord) ** 2)
157
161
elif p_c <= x <= self.chord:
158
Removed:
y_c = (m / ((1 - p) ** 2)) * ((1 - 2 * p)
162
Added:
z_c = (m / ((1 - p) ** 2)) * ((1 - 2 * p)
159
163
+ 2 * p * (x / self.chord)
160
164
- (x / self.chord) ** 2)
161
Removed:
return (y_c * self.chord)
165
Added:
return (z_c * self.chord)
162
166
163
167
def get_thickness(x):
164
Removed:
'''
165
Removed:
Returns thickness from 1 'x' along the airfoil chord.
166
Removed:
'''
168
Added:
'''Returns thickness from 1 'x' along the airfoil chord.'''
169
Added:
170
Added:
x = 0 if x < 0 else x
167
171
y_t = 5 * t * self.chord * (
168
172
+ 0.2969 * sqrt(x / self.chord)
169
173
- 0.1260 * (x / self.chord)
@@ -173,37 +177,43 @@
173
177
return y_t
174
178
175
179
def get_theta(x):
176
Removed:
dy_c = float()
180
Added:
dz_c = float()
177
181
if 0 <= x < p_c:
178
Removed:
dy_c = ((2 * m) / p ** 2) * (p - x / self.chord)
182
Added:
dz_c = ((2 * m) / p ** 2) * (p - x / self.chord)
179
183
elif p_c <= x <= self.chord:
180
Removed:
dy_c = (2 * m) / ((1 - p) ** 2) * (p - x / self.chord)
181
Removed:
theta = atan(dy_c)
184
Added:
dz_c = (2 * m) / ((1 - p) ** 2) * (p - x / self.chord)
185
Added:
theta = atan(dz_c)
182
186
return theta
183
187
184
188
def get_upper_coord(x):
185
Removed:
x_u = x - get_thickness(x) * sin(get_theta(x))
186
Removed:
z_u = get_camber(x) + get_thickness(x) * cos(get_theta(x))
187
Removed:
return (x_u, z_u)
189
Added:
x = x - get_thickness(x) * sin(get_theta(x))
190
Added:
z = get_camber(x) + get_thickness(x) * cos(get_theta(x))
191
Added:
return (x, z)
188
192
189
193
def get_lower_coord(x):
190
Removed:
x_l = x + get_thickness(x) * sin(get_theta(x))
191
Removed:
z_l = get_camber(x) - get_thickness(x) * cos(get_theta(x))
192
Removed:
return (x_l, z_l)
194
Added:
x = x + get_thickness(x) * sin(get_theta(x))
195
Added:
z = get_camber(x) - get_thickness(x) * cos(get_theta(x))
196
Added:
return (x, z)
193
197
194
198
# Densify x-coordinates 10 times for first 1/4 chord length
195
199
x_chord_25_percent = round(self.chord / 4)
196
Removed:
x_chord = [x / 10 for x in range(x_chord_25_percent * 10)]
197
Removed:
x_chord.extend([x for x in range(x_chord_25_percent, self.chord + 1)])
198
200
201
Added:
x_chord = [i / 10 for i in range(x_chord_25_percent * 10)]
202
Added:
x_chord.extend(i for i in range(x_chord_25_percent, self.chord + 1))
203
Added:
# Reversed list for our lower airfoil coordinate densification
204
Added:
x_chord_rev = [i for i in range(self.chord, x_chord_25_percent, -1)]
205
Added:
extend = [i / 10 for i in range(x_chord_25_percent * 10, -1, -1)]
206
Added:
x_chord_rev.extend(extend)
207
Added:
199
208
# Generate our airfoil geometry from previous sub-functions.
200
209
for x in x_chord:
201
210
self.x_c.append(x)
202
Removed:
self.y_c.append(get_camber(x))
203
Removed:
self.x_u.append(get_upper_coord(x)[0])
204
Removed:
self.z_u.append(get_upper_coord(x)[1])
205
Removed:
self.x_l.append(get_lower_coord(x)[0])
206
Removed:
self.z_l.append(get_lower_coord(x)[1])
211
Added:
self.z_c.append(get_camber(x))
212
Added:
self.x.append(get_upper_coord(x)[0])
213
Added:
self.z.append(get_upper_coord(x)[1])
214
Added:
for x in x_chord_rev:
215
Added:
self.x.append(get_lower_coord(x)[0])
216
Added:
self.z.append(get_lower_coord(x)[1])
207
217
return None
208
218
209
219
def add_mass(self, mass):
@@ -211,8 +221,8 @@
211
221
212
222
def info_print(self, round):
213
223
super().info_print(round)
214
Removed:
print('x_c the camber x-coordinates:\n', np.around(self.x_u, round))
215
Removed:
print('z_c the camber z-coordinates:\n', np.around(self.x_u, round))
224
Added:
print('x_c the camber x-coordinates:\n', np.around(self.x, round))
225
Added:
print('z_c the camber z-coordinates:\n', np.around(self.x, round))
216
226
return None
217
227
218
228
@@ -223,35 +233,33 @@
223
233
def __init__(self):
224
234
super().__init__(parent.chord, parent.semi_span)
225
235
226
Removed:
def add_coord(self, airfoil, spar_x):
236
Added:
def add_coord(self, airfoil, x_loc_percent):
227
237
'''
228
238
Add a single spar at the % chord location given to function.
229
239
230
240
Parameters:
231
Removed:
coordinates: provided by Airfoil.coordinates[x_u, z_u, x_l, z_l].
241
Added:
coordinates: provided by Airfoil.coordinates[x, z, x, z].
232
242
material: spar's material. Assumes homogeneous material.
233
243
spar_x: spar's location as a % of total chord length.
234
244
235
245
Return:
236
246
None
237
247
'''
238
Removed:
# Airfoil surface coordinates
239
Removed:
# unpacked from 'coordinates' (list of lists in 'Coordinates').
240
Removed:
x_u = airfoil.x_u
241
Removed:
z_u = airfoil.z_u
242
Removed:
x_l = airfoil.x_l
243
Removed:
z_l = airfoil.z_l
248
Added:
244
249
# Scaled spar location with regards to chord
245
Removed:
loc = spar_x * self.chord
246
Removed:
# bisect_left: returns index of first value in x_u > loc.
247
Removed:
# Ensures that the spar coordinates intersect with airfoil surface.
248
Removed:
spar_x_u = bi.bisect_left(x_u, loc) # index of spar's x_u
249
Removed:
spar_x_l = bi.bisect_left(x_l, loc) # index of spar's x_l
250
Removed:
# These x and y coordinates are assigned to the spar, NOT airfoil.
251
Removed:
self.x_u.append(x_u[spar_x_u])
252
Removed:
self.z_u.append(z_u[spar_x_u])
253
Removed:
self.x_l.append(x_l[spar_x_l])
254
Removed:
self.z_l.append(z_l[spar_x_l])
250
Added:
loc = x_loc_percent * self.chord
251
Added:
# bi.bisect_left: returns index of first value in airfoil.x > loc
252
Added:
# This ensures that spar geom intersects with airfoil geom.
253
Added:
# Spar upper coordinates
254
Added:
spar_x = bi.bisect_left(airfoil.x, loc) - 1
255
Added:
x = [airfoil.x[spar_x]]
256
Added:
z = [airfoil.z[spar_x]]
257
Added:
# Spar lower coordinates
258
Added:
spar_x = bi.bisect_left(airfoil.x[::-1], loc) - 1
259
Added:
x += [airfoil.x[-spar_x]]
260
Added:
z += [airfoil.z[-spar_x]]
261
Added:
self.x.append(x)
262
Added:
self.z.append(z)
255
263
return None
256
264
257
265
def add_spar_caps(self, spar_cap_area):
@@ -259,7 +267,7 @@
259
267
return None
260
268
261
269
def add_mass(self, mass):
262
Removed:
self.mass = len(self.x_u) * mass
270
Added:
self.mass = len(self.x) * mass
263
271
return None
264
272
265
273
@@ -291,44 +299,44 @@
291
299
'''
292
300
293
301
# Find distance between leading edge and first upper stringer
294
Removed:
interval = airfoil.spar.x_u[0] / (stringer_u_1 + 1)
295
Removed:
# initialise first self.stringer_x_u at first interval
302
Added:
interval = airfoil.spar.x[0][0] / (stringer_u_1 + 1)
303
Added:
# initialise first self.stringer_x at first interval
296
304
x = interval
297
305
# Add upper stringers from leading edge until first spar.
298
306
for _ in range(0, stringer_u_1):
299
Removed:
# Index of the first value of airfoil_x_u > x
300
Removed:
index = bi.bisect_left(airfoil.x_u, x)
301
Removed:
self.x_u.append(airfoil.x_u[index])
302
Removed:
self.z_u.append(airfoil.z_u[index])
307
Added:
# Index of the first value of airfoil.x > x
308
Added:
i = bi.bisect_left(airfoil.x, x)
309
Added:
self.x.append(airfoil.x[i])
310
Added:
self.z.append(airfoil.z[i])
303
311
x += interval
304
312
# Add upper stringers from first spar until last spar
305
313
# TODO: stringer placement if only one spar is created
306
Removed:
interval = (airfoil.spar.x_u[-1]
307
Removed:
- airfoil.spar.x_u[0]) / (stringer_u_2 + 1)
308
Removed:
x = interval + airfoil.spar.x_u[0]
314
Added:
interval = (airfoil.spar.x[-1][0]
315
Added:
- airfoil.spar.x[0][0]) / (stringer_u_2 + 1)
316
Added:
x = interval + airfoil.spar.x[0][0]
309
317
for _ in range(0, stringer_u_2):
310
Removed:
index = bi.bisect_left(airfoil.x_u, x)
311
Removed:
self.x_u.append(airfoil.x_u[index])
312
Removed:
self.z_u.append(airfoil.z_u[index])
318
Added:
i = bi.bisect_left(airfoil.x, x)
319
Added:
self.x.append(airfoil.x[i])
320
Added:
self.z.append(airfoil.z[i])
313
321
x += interval
314
322
315
323
# Find distance between leading edge and first lower stringer
316
Removed:
interval = airfoil.spar.x_l[0] / (stringer_l_1 + 1)
324
Added:
interval = airfoil.spar.x[0][1] / (stringer_l_1 + 1)
317
325
x = interval
318
326
# Add lower stringers from leading edge until first spar.
319
327
for _ in range(0, stringer_l_1):
320
Removed:
index = bi.bisect_left(airfoil.x_l, x)
321
Removed:
self.x_l.append(airfoil.x_l[index])
322
Removed:
self.z_l.append(airfoil.z_l[index])
328
Added:
i = bi.bisect_left(airfoil.x[::-1], x)
329
Added:
self.x.append(airfoil.x[-i])
330
Added:
self.z.append(airfoil.z[-i])
323
331
x += interval
324
332
# Add lower stringers from first spar until last spar
325
Removed:
interval = (airfoil.spar.x_l[-1]
326
Removed:
- airfoil.spar.x_l[0]) / (stringer_l_2 + 1)
327
Removed:
x = interval + airfoil.spar.x_l[0]
333
Added:
interval = (airfoil.spar.x[-1][1]
334
Added:
- airfoil.spar.x[0][1]) / (stringer_l_2 + 1)
335
Added:
x = interval + airfoil.spar.x[0][1]
328
336
for _ in range(0, stringer_l_2):
329
Removed:
index = bi.bisect_left(airfoil.x_l, x)
330
Removed:
self.x_l.append(airfoil.x_l[index])
331
Removed:
self.z_l.append(airfoil.z_l[index])
337
Added:
i = bi.bisect_left(airfoil.x[::-1], x)
338
Added:
self.x.append(airfoil.x[-i])
339
Added:
self.z.append(airfoil.z[-i])
332
340
x += interval
333
341
return None
334
342
@@ -337,7 +345,7 @@
337
345
return None
338
346
339
347
def add_mass(self, mass):
340
Removed:
self.mass = len(self.x_u) * mass + len(self.x_l) * mass
348
Added:
self.mass = len(self.x) * mass + len(self.x) * mass
341
349
return None
342
350
343
351
def info_print(self, round):
@@ -357,38 +365,33 @@
357
365
plt.plot(airfoil.chord / 4, 0, '.', color='g',
358
366
markersize=24, label='Quarter-chord')
359
367
# Plot mean camber line
360
Removed:
plt.plot(airfoil.x_c, airfoil.y_c,
361
Removed:
'-.', color='r', linewidth='2',
368
Added:
plt.plot(airfoil.x_c, airfoil.z_c, '-.', color='r', linewidth='2',
362
369
label='Mean camber line')
363
Removed:
# Plot upper surface
364
Removed:
plt.plot(airfoil.x_u, airfoil.z_u,
365
Removed:
'', color='b', linewidth='1')
366
Removed:
# Plot lower surface
367
Removed:
plt.plot(airfoil.x_l, airfoil.z_l,
368
Removed:
'', color='b', linewidth='1')
370
Added:
# Plot airfoil surfaces
371
Added:
plt.fill(airfoil.x, airfoil.z, color='b', linewidth='1', fill=False)
369
372
370
373
# Plot spars
371
Removed:
for _ in range(0, len(airfoil.spar.x_u)):
372
Removed:
x = (airfoil.spar.x_u[_], airfoil.spar.x_l[_])
373
Removed:
y = (airfoil.spar.z_u[_], airfoil.spar.z_l[_])
374
Removed:
plt.plot(x, y, '.-', color='b')
374
Added:
try:
375
Added:
for _ in range(len(airfoil.spar.x)):
376
Added:
x = (airfoil.spar.x[_])
377
Added:
y = (airfoil.spar.z[_])
378
Added:
plt.plot(x, y, '-', color='b')
379
Added:
except AttributeError:
380
Added:
print('No spars to plot.')
381
Added:
# Plot stringers
382
Added:
try:
383
Added:
for _ in range(0, len(airfoil.stringer.x)):
384
Added:
x = airfoil.stringer.x[_]
385
Added:
y = airfoil.stringer.z[_]
386
Added:
plt.plot(x, y, '.', color='y', markersize=12)
387
Added:
except AttributeError:
388
Added:
print('No stringers to plot.')
375
389
376
Removed:
# Plot upper stringers
377
Removed:
for _ in range(0, len(airfoil.stringer.x_u)):
378
Removed:
x = airfoil.stringer.x_u[_]
379
Removed:
y = airfoil.stringer.z_u[_]
380
Removed:
plt.plot(x, y, '.', color='y', markersize=12)
381
Removed:
# Plot lower stringers
382
Removed:
for _ in range(0, len(airfoil.stringer.x_l)):
383
Removed:
x = airfoil.stringer.x_l[_]
384
Removed:
y = airfoil.stringer.z_l[_]
385
Removed:
plt.plot(x, y, '.', color='y', markersize=12)
386
Removed:
387
390
# Graph formatting
388
391
plt.xlabel('X axis')
389
392
plt.ylabel('Z axis')
390
393
391
Removed:
plot_bound = airfoil.x_u[-1]
394
Added:
plot_bound = max(airfoil.x)
392
395
plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound)
393
396
plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
394
397
plt.gca().set_aspect('equal', adjustable='box')
evaluator.py
@@ -38,17 +38,17 @@
38
38
+ airfoil.spar.mass
39
39
+ airfoil.stringer.mass)
40
40
self.mass_dist = []
41
Removed:
# Upper coordinates
42
Removed:
self.x_u = airfoil.x_u
43
Removed:
self.z_u = airfoil.z_u
44
Removed:
# Lower coordinates
45
Removed:
self.x_l = airfoil.x_l
46
Removed:
self.z_l = airfoil.z_l
41
Added:
# Coordinates
42
Added:
self.x = airfoil.x
43
Added:
self.z = airfoil.z
44
Added:
# Lift
47
45
self.lift_rectangular = []
48
46
self.lift_elliptical = []
49
47
self.lift_total = []
50
48
# Drag
51
49
self.drag = []
50
Added:
# centroid
51
Added:
self.centroid = []
52
52
# Inertia terms:
53
53
# I_x = self.I_[0]
54
54
# I_z = self.I_[1]
@@ -137,21 +137,27 @@
137
137
138
138
def get_centroid(self):
139
139
'''Return the coordinates of the centroid.'''
140
Added:
140
141
stringer_area = self.stringer.area
141
142
caps_area = self.spar.cap_area
142
143
143
Removed:
x_spars = self.spar.x_u + self.spar.x_l
144
Removed:
x_stringers = self.stringer.x_u + self.stringer.x_l
145
Removed:
z_stringers = self.stringer.z_u + self.stringer.z_l
146
Removed:
denom = float(len(x_spars) * caps_area
147
Removed:
+ len(x_stringers) * stringer_area)
144
Added:
caps_x = [value for spar in self.spar.x for value in spar]
145
Added:
caps_z = [value for spar in self.spar.z for value in spar]
146
Added:
stringers_x = self.stringer.x
147
Added:
stringers_z = self.stringer.z
148
148
149
Removed:
x_ctr = (sum([i * caps_area for i in self.spar.x_u])
150
Removed:
+ sum([i * stringer_area for i in x_stringers])) / denom
151
Removed:
z_ctr = (sum([i * caps_area for i in self.spar.z_u])
152
Removed:
+ sum([i * stringer_area for i in z_stringers])) / denom
153
Removed:
return(x_ctr, z_ctr)
149
Added:
denominator = float(len(caps_x) * caps_area
150
Added:
+ len(stringers_x) * stringer_area)
154
151
152
Added:
centroid_x = float(sum([x * caps_area for x in caps_x])
153
Added:
+ sum([x * stringer_area for x in stringers_x]))
154
Added:
centroid_x = centroid_x / denominator
155
Added:
156
Added:
centroid_z = float(sum([z * caps_area for z in caps_z])
157
Added:
+ sum([z * stringer_area for z in stringers_z]))
158
Added:
centroid_z = centroid_z / denominator
159
Added:
return(centroid_x, centroid_z)
160
Added:
155
161
def get_inertia_terms(self):
156
162
'''Obtain all inertia terms.'''
157
163
@@ -159,12 +165,12 @@
159
165
caps_area = self.spar.cap_area
160
166
161
167
# Adds upper and lower components' coordinates to list
162
Removed:
x_stringers = self.stringer.x_u + self.stringer.x_l
163
Removed:
z_stringers = self.stringer.z_u + self.stringer.z_l
164
Removed:
x_spars = self.spar.x_u + self.spar.x_l
165
Removed:
z_spars = self.spar.z_u + self.spar.z_l
168
Added:
x_stringers = self.stringer.x
169
Added:
z_stringers = self.stringer.z
170
Added:
x_spars = self.spar.x[:][0] + self.spar.x[:][1]
171
Added:
z_spars = self.spar.z[:][0] + self.spar.z[:][1]
166
172
stringer_count = range(len(x_stringers))
167
Removed:
spar_count = range(len(self.spar.x_u))
173
Added:
spar_count = range(len(self.spar.x))
168
174
169
175
# I_x is the sum of the contributions of the spar caps and stringers
170
176
I_x = (sum([caps_area * (z_spars[i] - self.centroid[1]) ** 2
@@ -209,31 +215,32 @@
209
215
y_chord = [0, 0]
210
216
plt.plot(x_chord, y_chord, linewidth='1')
211
217
# Plot quarter chord
212
Removed:
q = evaluator.chord / 4
213
Removed:
plt.plot(q, 0, '.', color='g', markersize=24, label='Quarter-chord')
214
Removed:
# Plot upper surface
215
Removed:
plt.plot(evaluator.x_u, evaluator.z_u,
216
Removed:
'', color='b', linewidth='1')
217
Removed:
# Plot lower surface
218
Removed:
plt.plot(evaluator.x_l, evaluator.z_l,
219
Removed:
'', color='b', linewidth='1')
218
Added:
plt.plot(evaluator.chord / 4, 0, '.', color='g',
219
Added:
markersize=24, label='Quarter-chord')
220
Added:
# Plot airfoil surfaces
221
Added:
plt.fill(evaluator.x, evaluator.z, color='b', linewidth='1', fill=False)
220
222
221
223
# Plot spars
222
Removed:
for _ in range(0, len(evaluator.spar.x_u)):
223
Removed:
x = (evaluator.spar.x_u[_], evaluator.spar.x_l[_])
224
Removed:
y = (evaluator.spar.z_u[_], evaluator.spar.z_l[_])
225
Removed:
plt.plot(x, y, '.-', color='b')
226
Removed:
224
Added:
try:
225
Added:
for _ in range(len(evaluator.spar.x)):
226
Added:
x = (evaluator.spar.x[_])
227
Added:
y = (evaluator.spar.z[_])
228
Added:
plt.plot(x, y, '-', color='b')
229
Added:
except AttributeError:
230
Added:
print('No spars to plot.')
227
231
# Plot upper stringers
228
Removed:
for _ in range(0, len(evaluator.stringer.x_u)):
229
Removed:
x = evaluator.stringer.x_u[_]
230
Removed:
y = evaluator.stringer.z_u[_]
231
Removed:
plt.plot(x, y, '.', color='y', markersize=12)
232
Removed:
# Plot lower stringers
233
Removed:
for _ in range(0, len(evaluator.stringer.x_l)):
234
Removed:
x = evaluator.stringer.x_l[_]
235
Removed:
y = evaluator.stringer.z_l[_]
236
Removed:
plt.plot(x, y, '.', color='y', markersize=12)
232
Added:
try:
233
Added:
for _ in range(0, len(evaluator.stringer.x)):
234
Added:
x = evaluator.stringer.x[_]
235
Added:
y = evaluator.stringer.z[_]
236
Added:
plt.plot(x, y, '.', color='y', markersize=12)
237
Added:
except AttributeError:
238
Added:
print('No stringers to plot.')
239
Added:
# # Plot lower stringers
240
Added:
# for _ in range(0, len(evaluator.stringer.x)):
241
Added:
# x = evaluator.stringer.x[_]
242
Added:
# y = evaluator.stringer.z[_]
243
Added:
# plt.plot(x, y, '.', color='y', markersize=12)
237
244
238
245
# Plot centroid
239
246
x = evaluator.centroid[0]
@@ -244,7 +251,7 @@
244
251
plt.xlabel('X axis')
245
252
plt.ylabel('Z axis')
246
253
247
Removed:
plot_bound = evaluator.x_u[-1]
254
Added:
plot_bound = max(evaluator.x)
248
255
plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound)
249
256
plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
250
257
plt.gca().set_aspect('equal', adjustable='box')
main.py
@@ -24,8 +24,8 @@
24
24
25
25
# Airfoil dimensions
26
26
NACA_NUM = 2412
27
Removed:
CHORD_LENGTH = 40
28
Removed:
SEMI_SPAN = 50
27
Added:
CHORD_LENGTH = 101
28
Added:
SEMI_SPAN = 40
29
29
30
30
# Airfoil thickness
31
31
T_UPPER = 0.1
@@ -37,14 +37,14 @@
37
37
STRINGER_MASS = 5 # lbs
38
38
39
39
# Area
40
Removed:
SPAR_CAP_AREA = 0.3 # sqin
40
Added:
SPAR_CAP_AREA = 0.0 # sqin
41
41
STRINGER_AREA = 0.1 # sqin
42
42
43
43
# Amount of stringers
44
Removed:
TOP_STRINGERS = 0
45
Removed:
BOTTOM_STRINGERS = 18
46
Removed:
NOSE_TOP_STRINGERS = 0
47
Removed:
NOSE_BOTTOM_STRINGERS = 5
44
Added:
TOP_STRINGERS = 3
45
Added:
BOTTOM_STRINGERS = 4
46
Added:
NOSE_TOP_STRINGERS = 3
47
Added:
NOSE_BOTTOM_STRINGERS = 6
48
48
49
49
# population information & save path
50
50
POP_SIZE = 1
@@ -71,18 +71,18 @@
71
71
af.add_naca(NACA_NUM)
72
72
af.add_mass(AIRFOIL_MASS)
73
73
# af.info_print(2)
74
Removed:
# af.info_save(SAVE_PATH, _)
74
Added:
af.info_save(SAVE_PATH, _)
75
75
76
76
# Create spar instance
77
77
af.spar = creator.Spar()
78
78
# Define the spar coordinates and mass, stored in single spar object
79
Removed:
af.spar.add_coord(af, 0.15)
80
Removed:
af.spar.add_coord(af, 0.55)
79
Added:
af.spar.add_coord(af, 0.20)
80
Added:
af.spar.add_coord(af, 0.65)
81
81
# Automatically adds spar caps for all spars previously defined
82
82
af.spar.add_spar_caps(SPAR_CAP_AREA)
83
83
af.spar.add_mass(SPAR_MASS)
84
84
# af.spar.info_print(2)
85
Removed:
# af.spar.info_save(SAVE_PATH, _)
85
Added:
af.spar.info_save(SAVE_PATH, _)
86
86
87
87
# Create stringer instance
88
88
af.stringer = creator.Stringer()
@@ -95,10 +95,10 @@
95
95
af.stringer.add_area(STRINGER_AREA)
96
96
af.stringer.add_mass(STRINGER_MASS)
97
97
# af.stringer.info_print(2)
98
Removed:
# af.stringer.info_save(SAVE_PATH, _)
98
Added:
af.stringer.info_save(SAVE_PATH, _)
99
99
100
100
# Plot components with matplotlib
101
Removed:
# creator.plot_geom(af)
101
Added:
creator.plot_geom(af)
102
102
103
103
# Evaluator object contains airfoil analysis results.
104
104
eval = evaluator.Evaluator(af)