*ARCHIVED* development moved to aircraft-studio.
square plots + shorter info_print() + enforce minimum chord length
Changed files
creator.py
@@ -64,7 +64,11 @@
64
64
65
65
@classmethod
66
66
def from_dimensions(cls, chord, semi_span):
67
Removed:
cls.chord = chord
67
Added:
if chord > 20:
68
Added:
cls.chord = chord
69
Added:
else:
70
Added:
cls.chord = 20
71
Added:
print('Chord too small, using minimum value of 20.')
68
72
cls.semi_span = semi_span
69
73
return Airfoil()
70
74
@@ -163,24 +167,20 @@
163
167
self.mass = mass
164
168
165
169
def info_print(self, round):
166
Removed:
"""
167
Removed:
Print all the component's coordinates to the terminal.
170
Added:
# TODO: implement this info getting method!
171
Added:
"""Print all the component's coordinates to the terminal."""
168
172
169
Removed:
This function's output is piped to the 'save_coord' function below.
170
Removed:
"""
171
Removed:
172
Removed:
name = ' CREATOR DATA '
173
Added:
name = ' CREATOR DATA FOR {} '.format(str(self).upper())
173
174
num_of_dashes = len(name)
174
Removed:
175
175
print(num_of_dashes * '-')
176
176
print(name)
177
Removed:
print('Component:', str(self))
178
Removed:
print('Chord length:', self.chord)
179
Removed:
print('Semi-span:', self.semi_span)
180
Removed:
print('Mass:', self.mass)
177
Added:
for k, v in self.__dict__.items():
178
Added:
if type(v) != list:
179
Added:
print('{}:\n'.format(k), v)
181
180
print(num_of_dashes * '-')
182
Removed:
print('x-coordinates:\n', np.around(self.x, round))
183
Removed:
print('z-coordinates:\n', np.around(self.z, round))
181
Added:
for k, v in self.__dict__.items():
182
Added:
if type(v) == list:
183
Added:
print('{}:\n'.format(k), np.around(v, round))
184
184
return None
185
185
186
186
def info_save(self, save_path, number):
@@ -398,9 +398,13 @@
398
398
print('No stringers to plot.')
399
399
400
400
# Graph formatting
401
Added:
plot_bound = max(airfoil.x)
401
402
ax.set(title='NACA ' + str(airfoil.naca_num) + ' airfoil',
402
403
xlabel='X axis',
403
Removed:
ylabel='Z axis', ylim=[-50, 50])
404
Added:
xlim=[- 0.10 * plot_bound, 1.10 * plot_bound],
405
Added:
ylabel='Z axis',
406
Added:
ylim=[- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2)])
407
Added:
404
408
plt.grid(axis='both', linestyle=':', linewidth=1)
405
409
plt.gca().set_aspect('equal', adjustable='box')
406
410
plt.gca().legend(bbox_to_anchor=(1, 1),
evaluator.py
@@ -53,46 +53,27 @@
53
53
# Inertia terms:
54
54
self.I_ = {'x': 0, 'z': 0, 'xz': 0}
55
55
56
Removed:
def info_print(self, round):
57
Removed:
"""
58
Removed:
Print all the component's evaluated data to the terminal.
56
Added:
def __str__(self):
57
Added:
return type(self).__name__
59
58
60
Removed:
This function's output is piped to the 'save_data' function below.
61
Removed:
"""
62
Removed:
name = ' EVALUATOR DATA '
59
Added:
def info_print(self, round):
60
Added:
"""Print all the component's evaluated data to the terminal."""
61
Added:
name = ' EVALUATOR DATA FOR {} '.format(str(self).upper())
63
62
num_of_dashes = len(name)
64
Removed:
65
Removed:
try:
66
Removed:
print(num_of_dashes * '-')
67
Removed:
print(name)
68
Removed:
print('Evaluating:', self.airfoil)
69
Removed:
print('Chord length:', self.chord)
70
Removed:
print('Semi-span:', self.semi_span)
71
Removed:
print('Total airfoil mass:', self.mass_total)
72
Removed:
print('Centroid location:\n', np.around(self.centroid, 3))
73
Removed:
print('Inertia terms:')
74
Removed:
print('I_x:\n', np.around(self.I_['x'], 3))
75
Removed:
print('I_z:\n', np.around(self.I_['z'], 3))
76
Removed:
print('I_xz:\n', np.around(self.I_['xz'], 3))
77
Removed:
print('Spar dP_x:\n', self.spar.dP_x)
78
Removed:
print('Spar dP_z:\n', self.spar.dP_z)
79
Removed:
print(num_of_dashes * '-')
80
Removed:
print('Rectangular lift along semi-span:\n',
81
Removed:
np.around(self.lift_rectangular, round))
82
Removed:
print('Elliptical lift along semi-span:\n',
83
Removed:
np.around(self.lift_elliptical, round))
84
Removed:
print('Combined lift along semi-span:\n',
85
Removed:
np.around(self.lift_total, round))
86
Removed:
print('Distribution of mass along semi-span:\n',
87
Removed:
np.around(self.mass_dist, round))
88
Removed:
print('Drag along semi-span:\n', np.around(self.drag, round))
89
Removed:
except AttributeError:
90
Removed:
print(num_of_dashes * '-')
91
Removed:
print('Cannot print full evaluation. Was the airfoil analyzed?')
63
Added:
print(num_of_dashes * '-')
64
Added:
print(name)
65
Added:
for k, v in self.__dict__.items():
66
Added:
if type(v) != list:
67
Added:
print('{}:\n'.format(k), v)
68
Added:
print(num_of_dashes * '-')
69
Added:
for k, v in self.__dict__.items():
70
Added:
if type(v) == list:
71
Added:
print('{}:\n'.format(k), np.around(v, round))
92
72
return None
93
73
94
74
def info_save(self, save_path, number):
95
75
"""Save all the object's coordinates (must be full path)."""
76
Added:
96
77
file_name = 'airfoil_{}_eval.txt'.format(number)
97
78
full_path = os.path.join(save_path, file_name)
98
79
try:
gui.py
@@ -41,9 +41,9 @@
41
41
frame_2 = ttk.Frame(root)
42
42
fig, ax = creator.plot_geom(af, False)
43
43
plot = FigureCanvasTkAgg(fig, frame_2)
44
Removed:
plot.draw()
44
Added:
# plot.draw()
45
45
toolbar = NavigationToolbar2Tk(plot, frame_2)
46
Removed:
toolbar.update()
46
Added:
# toolbar.update()
47
47
48
48
# Layout
49
49
# User input
@@ -53,7 +53,7 @@
53
53
e_chord.grid(row=1, column=1, padx=4)
54
54
frame_1.pack(side=tk.LEFT)
55
55
# Graph window
56
Removed:
plot.get_tk_widget().pack(fill=tk.BOTH)
56
Added:
plot.get_tk_widget().pack(expand=1, fill=tk.BOTH)
57
57
toolbar.pack()
58
58
frame_2.pack(side=tk.LEFT)
59
59
main.py
@@ -24,7 +24,7 @@
24
24
25
25
# Airfoil dimensions
26
26
NACA_NUM = 2412
27
Removed:
CHORD_LENGTH = 68 # inches
27
Added:
CHORD_LENGTH = 2 # inches
28
28
SEMI_SPAN = 150 # inches
29
29
30
30
# Thicknesses
@@ -67,7 +67,7 @@
67
67
af.add_naca(NACA_NUM)
68
68
af.add_mass(AIRFOIL_MASS)
69
69
# af.info_print(2)
70
Removed:
# af.info_save(SAVE_PATH, _)
70
Added:
af.info_save(SAVE_PATH, _)
71
71
72
72
# Create spar instance
73
73
af.spar = creator.Spar()
@@ -79,7 +79,7 @@
79
79
af.spar.add_mass(SPAR_MASS)
80
80
af.spar.add_webs(SPAR_THICKNESS)
81
81
# af.spar.info_print(2)
82
Removed:
# af.spar.info_save(SAVE_PATH, _)
82
Added:
af.spar.info_save(SAVE_PATH, _)
83
83
84
84
# Create stringer instance
85
85
af.stringer = creator.Stringer()
@@ -93,17 +93,17 @@
93
93
af.stringer.add_mass(STRINGER_MASS)
94
94
af.stringer.add_webs(SKIN_THICKNESS)
95
95
# af.stringer.info_print(2)
96
Removed:
# af.stringer.info_save(SAVE_PATH, _)
96
Added:
af.stringer.info_save(SAVE_PATH, _)
97
97
98
98
# Plot components with matplotlib
99
Removed:
creator.plot_geom(af, True)
99
Added:
# creator.plot_geom(af, True)
100
100
101
101
# Evaluator object contains airfoil analysis results.
102
102
eval = evaluator.Evaluator(af)
103
103
# The analysis is performed in the evaluator.py module.
104
104
eval.analysis(1, 1)
105
105
# eval.info_print(2)
106
Removed:
# eval.info_save(SAVE_PATH, _)
106
Added:
eval.info_save(SAVE_PATH, _)
107
107
# evaluator.plot_geom(eval)
108
108
# evaluator.plot_lift(eval)
109
109