module & class & function docstrings

Commit
6f88bb59dca6e36a1a4da56f573ba43858ad4cad
Author
Marius Peter <blendoit@gmail.com>
Author date
Committer
Marius Peter <blendoit@gmail.com>
Committer date
Changed files
creator.py
index 3a36bd85..3e360364 100644..100644
@@ -12,8 +12,19 @@
12 12 #
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 Added: """
16 Added: The 'creator' module contains class definitions for coordinates
17 Added: and various components we add to an airfoil (spars, stringers, and ribs.)
15 18
19 Added: Classes:
20 Added: Coordinates: always instantiated first, but never assigned to object.
21 Added: Airfoil: inherits from Coordinates & automatically aware of airfoil size.
22 Added: Spar: also inherits from Coordinates.
23 Added: Stringer: also inherits from Coordinates.
16 24
25 Added: Functions:
26 Added: plot_geom(airfoil): generates a 2D plot of the airfoil & any components.
27 Added: """
17 28 import sys
18 29 import os.path
19 30 import numpy as np
@@ -30,19 +41,19 @@
30 41
31 42
32 43 class Coordinates:
33 Removed: '''
44 Added: """
34 45 All airfoil components need the following:
35 46
36 47 Parameters:
37 Removed: * Component material
38 Removed: * Coordinates relative to the chord & semi-span
48 Added: Component material
49 Added: Coordinates relative to the chord & semi-span
39 50
40 51 Methods:
41 Removed: * Print component coordinates
42 Removed: * Save component coordinates to file specified in main.py
52 Added: Print component coordinates
53 Added: Save component coordinates to file specified in main.py
43 54
44 55 So, all component classes inherit from class Coordinates.
45 Removed: '''
56 Added: """
46 57
47 58 def __init__(self, chord, semi_span):
48 59 # Global dimensions
@@ -65,11 +76,11 @@
65 76 return type(self).__name__
66 77
67 78 def info_print(self, round):
68 Removed: '''
79 Added: """
69 80 Print all the component's coordinates to the terminal.
70 81
71 82 This function's output is piped to the 'save_coord' function below.
72 Removed: '''
83 Added: """
73 84 name = ' CREATOR DATA '
74 85 num_of_dashes = len(name)
75 86
@@ -85,10 +96,9 @@
85 96 return None
86 97
87 98 def info_save(self, save_path, number):
88 Removed: '''
99 Added: """
89 100 Save all the object's coordinates (must be full path).
90 Removed: '''
91 Removed:
101 Added: """
92 102 file_name = '{}_{}.txt'.format(str(self).lower(), number)
93 103 full_path = os.path.join(save_path, file_name)
94 104 try:
@@ -105,8 +115,8 @@
105 115
106 116
107 117 class Airfoil(Coordinates):
108 Removed: '''
109 Removed: This class enables the creation of a single NACA airfoil.
118 Added: """
119 Added: This class represents a single NACA airfoil.
110 120
111 121 Please note: the coordinates are saved as two lists
112 122 for the x- and z-coordinates. The coordinates start at
@@ -116,7 +126,7 @@
116 126 This method was chosen for easier future exports
117 127 to 3D CAD packages like SolidWorks, which can import such
118 128 geometry as coordinates written in a CSV file.
119 Removed: '''
129 Added: """
120 130
121 131 def __init__(self):
122 132 global parent
@@ -129,7 +139,7 @@
129 139 self.z_c = []
130 140
131 141 def add_naca(self, naca_num):
132 Removed: '''
142 Added: """
133 143 This function generates geometry for our chosen NACA airfoil shape.
134 144 The nested functions perform the required steps to generate geometry,
135 145 and can be called to solve the geometry y-coordinate for any 'x' input.
@@ -140,8 +150,7 @@
140 150
141 151 Return:
142 152 None
143 Removed: '''
144 Removed:
153 Added: """
145 154 # Variables extracted from 'naca_num' argument passed to the function
146 155 self.naca_num = naca_num
147 156 m = int(str(naca_num)[0]) / 100
@@ -151,9 +160,9 @@
151 160 p_c = p * self.chord
152 161
153 162 def get_camber(x):
154 Removed: '''
163 Added: """
155 164 Returns camber z-coordinate from 1 'x' along the airfoil chord.
156 Removed: '''
165 Added: """
157 166 z_c = float()
158 167 if 0 <= x < p_c:
159 168 z_c = (m / (p ** 2)) * (2 * p * (x / self.chord)
@@ -165,8 +174,7 @@
165 174 return (z_c * self.chord)
166 175
167 176 def get_thickness(x):
168 Removed: '''Returns thickness from 1 'x' along the airfoil chord.'''
169 Removed:
177 Added: """Returns thickness from 1 'x' along the airfoil chord."""
170 178 x = 0 if x < 0 else x
171 179 z_t = 5 * t * self.chord * (
172 180 + 0.2969 * sqrt(x / self.chord)
@@ -227,7 +235,7 @@
227 235
228 236
229 237 class Spar(Coordinates):
230 Removed: '''Contains a single spar's location.'''
238 Added: """Contains a single spar's location."""
231 239 global parent
232 240
233 241 def __init__(self):
@@ -243,7 +251,7 @@
243 251 self.dP_z = float()
244 252
245 253 def add_coord(self, airfoil, x_loc_percent):
246 Removed: '''
254 Added: """
247 255 Add a single spar at the % chord location given to function.
248 256
249 257 Parameters:
@@ -252,8 +260,7 @@
252 260
253 261 Return:
254 262 None
255 Removed: '''
256 Removed:
263 Added: """
257 264 # Scaled spar location with regards to chord
258 265 loc = x_loc_percent * self.chord
259 266 # bi.bisect_left: returns index of first value in airfoil.x > loc
@@ -279,8 +286,7 @@
279 286 return None
280 287
281 288 def add_webs(self, thickness):
282 Removed: '''Add webs to spars.'''
283 Removed:
289 Added: """Add webs to spars."""
284 290 for _ in range(len(self.x)):
285 291 self.x_start.append(self.x[_][0])
286 292 self.x_end.append(self.x[_][1])
@@ -291,7 +297,7 @@
291 297
292 298
293 299 class Stringer(Coordinates):
294 Removed: '''Contains the coordinates of all stringers.'''
300 Added: """Contains the coordinates of all stringers."""
295 301 global parent
296 302
297 303 def __init__(self):
@@ -310,7 +316,7 @@
310 316 def add_coord(self, airfoil,
311 317 stringer_u_1, stringer_u_2,
312 318 stringer_l_1, stringer_l_2):
313 Removed: '''
319 Added: """
314 320 Add equally distributed stringers to four airfoil locations
315 321 (upper nose, lower nose, upper surface, lower surface).
316 322
@@ -324,8 +330,7 @@
324 330
325 331 Returns:
326 332 None
327 Removed: '''
328 Removed:
333 Added: """
329 334 # Find distance between leading edge and first upper stringer
330 335 interval = airfoil.spar.x[0][0] / (stringer_u_1 + 1)
331 336 # initialise first self.stringer_x at first interval
@@ -377,8 +382,7 @@
377 382 return None
378 383
379 384 def add_webs(self, thickness):
380 Removed: '''Add webs to stringers.'''
381 Removed:
385 Added: """Add webs to stringers."""
382 386 for _ in range(len(self.x) // 2):
383 387 self.x_start.append(self.x[_])
384 388 self.x_end.append(self.x[_ + 1])
@@ -394,8 +398,7 @@
394 398
395 399
396 400 def plot_geom(airfoil):
397 Removed: '''This function plots the airfoil's + sub-components' geometry.'''
398 Removed:
401 Added: """This function plots the airfoil's + sub-components' geometry."""
399 402 # Plot chord
400 403 x_chord = [0, airfoil.chord]
401 404 y_chord = [0, 0]
evaluator.py
index 05900e95..44ed4349 100644..100644
@@ -12,8 +12,13 @@
12 12 #
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 Added: """
16 Added: The 'evaluator' module contains a single Evaluator class,
17 Added: which knows all the attributes of a specified Airfoil instance,
18 Added: and contains functions to analyse the airfoil's geometrical
19 Added: & structural properties.
20 Added: """
15 21
16 Removed:
17 22 import sys
18 23 import os.path
19 24 import numpy as np
@@ -22,7 +27,7 @@
22 27
23 28
24 29 class Evaluator:
25 Removed: '''Performs structural evaluations for the airfoil passed as argument.'''
30 Added: """Performs structural evaluations for the airfoil passed as argument."""
26 31
27 32 def __init__(self, airfoil):
28 33 # Evaluator knows all geometrical info from evaluated airfoil
@@ -32,8 +37,7 @@
32 37 # Global dimensions
33 38 self.chord = airfoil.chord
34 39 self.semi_span = airfoil.semi_span
35 Removed:
36 Removed: # mass and area
40 Added: # Mass & spanwise distribution
37 41 self.mass_total = float(airfoil.mass
38 42 + airfoil.spar.mass
39 43 + airfoil.stringer.mass)
@@ -50,18 +54,14 @@
50 54 # centroid
51 55 self.centroid = []
52 56 # Inertia terms:
53 Removed: # I_x = self.I_[0]
54 Removed: # I_z = self.I_[1]
55 Removed: # I_xz = self.I_[2]
56 Removed: self.I_ = []
57 Added: self.I_ = {'x': 0, 'z': 0, 'xz': 0}
57 58
58 59 def info_print(self, round):
59 Removed: '''
60 Added: """
60 61 Print all the component's evaluated data to the terminal.
61 62
62 63 This function's output is piped to the 'save_data' function below.
63 Removed: '''
64 Removed:
64 Added: """
65 65 name = ' EVALUATOR DATA '
66 66 num_of_dashes = len(name)
67 67
@@ -73,9 +73,9 @@
73 73 print('Total airfoil mass:', self.mass_total)
74 74 print('Centroid location:\n', np.around(self.centroid, 3))
75 75 print('Inertia terms:')
76 Removed: print('I_x:\n', np.around(self.I_[0], 3))
77 Removed: print('I_z:\n', np.around(self.I_[1], 3))
78 Removed: print('I_xz:\n', np.around(self.I_[2], 3))
76 Added: print('I_x:\n', np.around(self.I_['x'], 3))
77 Added: print('I_z:\n', np.around(self.I_['z'], 3))
78 Added: print('I_xz:\n', np.around(self.I_['xz'], 3))
79 79 print('Spar dP_x:\n', self.spar.dP_x)
80 80 print('Spar dP_z:\n', self.spar.dP_z)
81 81 print(num_of_dashes * '-')
@@ -91,8 +91,7 @@
91 91 return None
92 92
93 93 def info_save(self, save_path, number):
94 Removed: '''Save all the object's coordinates (must be full path).'''
95 Removed:
94 Added: """Save all the object's coordinates (must be full path)."""
96 95 file_name = 'airfoil_{}_eval.txt'.format(number)
97 96 full_path = os.path.join(save_path, file_name)
98 97 try:
@@ -102,22 +101,22 @@
102 101 sys.stdout = sys.__stdout__
103 102 print('Successfully wrote to file {}'.format(full_path))
104 103 except IOError:
105 Removed: print('Unable to write {} to specified directory.\n'
106 Removed: .format(file_name),
107 Removed: 'Was the full path passed to the function?')
104 Added: print(
105 Added: 'Unable to write {} to specified directory.\n'.format(
106 Added: file_name), 'Was the full path passed to the function?')
108 107 return None
109 108
110 109 # All these functions take integer arguments and return lists.
111 110
112 111 def get_lift_rectangular(self, lift):
113 Removed: L_prime = [lift / (self.semi_span * 2)
114 Removed: for x in range(self.semi_span)]
112 Added: L_prime = [lift / (self.semi_span * 2) for x in range(self.semi_span)]
115 113 return L_prime
116 114
117 115 def get_lift_elliptical(self, L_0):
118 Removed: L_prime = [L_0 / (self.semi_span * 2)
119 Removed: * sqrt(1 - (y / self.semi_span) ** 2)
120 Removed: for y in range(self.semi_span)]
116 Added: L_prime = [
117 Added: L_0 / (self.semi_span * 2) * sqrt(1 - (y / self.semi_span)**2)
118 Added: for y in range(self.semi_span)
119 Added: ]
121 120 return L_prime
122 121
123 122 def get_lift_total(self):
@@ -126,8 +125,7 @@
126 125 return F_z
127 126
128 127 def get_mass_distribution(self, total_mass):
129 Removed: F_z = [total_mass / self.semi_span
130 Removed: for x in range(0, self.semi_span)]
128 Added: F_z = [total_mass / self.semi_span for x in range(0, self.semi_span)]
131 129 return F_z
132 130
133 131 def get_drag(self, drag):
@@ -143,8 +141,7 @@
143 141 return F_x
144 142
145 143 def get_centroid(self):
146 Removed: '''Return the coordinates of the centroid.'''
147 Removed:
144 Added: """Return the coordinates of the centroid."""
148 145 stringer_area = self.stringer.area
149 146 cap_area = self.spar.cap_area
150 147
@@ -163,11 +160,11 @@
163 160 centroid_z = float(sum([z * cap_area for z in caps_z])
164 161 + sum([z * stringer_area for z in stringers_z]))
165 162 centroid_z = centroid_z / denominator
166 Removed: return(centroid_x, centroid_z)
167 163
168 Removed: def get_inertia_terms(self):
169 Removed: '''Obtain all inertia terms.'''
164 Added: return (centroid_x, centroid_z)
170 165
166 Added: def get_inertia_terms(self):
167 Added: """Obtain all inertia terms."""
171 168 stringer_area = self.stringer.area
172 169 cap_area = self.spar.cap_area
173 170
@@ -180,72 +177,75 @@
180 177 spar_count = range(len(self.spar.x))
181 178
182 179 # I_x is the sum of the contributions of the spar caps and stringers
183 Removed: I_x = (sum([cap_area * (z_spars[i] - self.centroid[1]) ** 2
184 Removed: for i in spar_count])
185 Removed: + sum([stringer_area * (z_stringers[i] - self.centroid[1]) ** 2
186 Removed: for i in stringer_count]))
180 Added: # TODO: replace list indices with dictionary value
181 Added: I_x = sum([cap_area * (z_spars[i] - self.centroid[1])**2
182 Added: for i in spar_count])
183 Added: I_x += sum([stringer_area * (z_stringers[i] - self.centroid[1])**2
184 Added: for i in stringer_count])
187 185
188 Removed: I_z = (sum([cap_area * (x_spars[i] - self.centroid[0]) ** 2
186 Added: I_z = sum([cap_area * (x_spars[i] - self.centroid[0])**2
187 Added: for i in spar_count])
188 Added: I_z += sum([stringer_area * (x_stringers[i] - self.centroid[0])**2
189 Added: for i in stringer_count])
190 Added:
191 Added: I_xz = sum([cap_area * (x_spars[i] - self.centroid[0])
192 Added: * (z_spars[i] - self.centroid[1])
189 193 for i in spar_count])
190 Removed: + sum([stringer_area * (x_stringers[i] - self.centroid[0]) ** 2
191 Removed: for i in stringer_count]))
194 Added: I_xz += sum([stringer_area * (x_stringers[i] - self.centroid[0])
195 Added: * (z_stringers[i] - self.centroid[1])
196 Added: for i in stringer_count])
197 Added: return (I_x, I_z, I_xz)
192 198
193 Removed: I_xz = (sum([cap_area * (x_spars[i] - self.centroid[0])
194 Removed: * (z_spars[i] - self.centroid[1])
195 Removed: for i in spar_count])
196 Removed: + sum([stringer_area * (x_stringers[i] - self.centroid[0])
197 Removed: * (z_stringers[i] - self.centroid[1])
198 Removed: for i in stringer_count]))
199 Added: def get_dx(self, component):
200 Added: return [x - self.centroid[0] for x in component.x_start]
199 201
200 Removed: return(I_x, I_z, I_xz)
202 Added: def get_dz(self, component):
203 Added: return [x - self.centroid[1] for x in component.x_start]
201 204
202 205 def analysis(self, V_x, V_z):
203 Removed: '''Perform all analysis calculations and store in class instance.'''
206 Added: """Perform all analysis calculations and store in class instance."""
204 207
205 Removed: def get_dp(xDist, zDist, V_x, V_z, I_x, I_z, I_xz, area):
208 Added: def get_dP(xDist, zDist, V_x, V_z, I_x, I_z, I_xz, area):
206 209 denom = float(I_x * I_z - I_xz ** 2)
207 210 z = float()
208 211 for _ in range(len(xDist)):
209 Removed: z += float(- area * xDist[_] * (I_x * V_x - I_xz * V_z)
212 Added: z += float(-area * xDist[_] * (I_x * V_x - I_xz * V_z)
210 213 / denom
211 214 - area * zDist[_] * (I_z * V_z - I_xz * V_x)
212 215 / denom)
213 216 return z
214 217
215 Removed: def get_dx(component):
216 Removed: return [x - self.centroid[0] for x in component.x_start]
217 Removed:
218 Removed: def get_dz(component):
219 Removed: return [x - self.centroid[1] for x in component.x_start]
220 Removed:
221 218 self.drag = self.get_drag(10)
222 Removed:
223 219 self.lift_rectangular = self.get_lift_rectangular(13.7)
224 220 self.lift_elliptical = self.get_lift_elliptical(15)
225 221 self.lift_total = self.get_lift_total()
226 Removed:
227 222 self.mass_dist = self.get_mass_distribution(self.mass_total)
228 223 self.centroid = self.get_centroid()
229 Removed: self.I_ = self.get_inertia_terms()
230 Removed: self.spar.dP_x = get_dp(get_dx(self.spar), get_dz(self.spar), V_x, 0,
231 Removed: self.I_[0], self.I_[1], self.I_[2],
224 Added: self.I_['x'] = self.get_inertia_terms()[0]
225 Added: self.I_['z'] = self.get_inertia_terms()[1]
226 Added: self.I_['xz'] = self.get_inertia_terms()[2]
227 Added: spar_dx = self.get_dx(self.spar)
228 Added: spar_dz = self.get_dz(self.spar)
229 Added: self.spar.dP_x = get_dP(spar_dx, spar_dz,
230 Added: V_x, 0,
231 Added: self.I_['x'], self.I_['z'], self.I_['xz'],
232 232 self.spar.cap_area)
233 Removed: self.spar.dP_z = get_dp(get_dx(self.spar), get_dz(self.spar), 0, V_z,
234 Removed: self.I_[0], self.I_[1], self.I_[2],
233 Added: self.spar.dP_z = get_dP(spar_dx, spar_dz,
234 Added: 0, V_z,
235 Added: self.I_['x'], self.I_['z'], self.I_['xz'],
235 236 self.spar.cap_area)
236 237 return None
237 238
238 239
239 240 def plot_geom(evaluator):
240 Removed: '''This function plots analysis results over the airfoil's geometry.'''
241 Removed:
241 Added: """This function plots analysis results over the airfoil's geometry."""
242 242 # Plot chord
243 243 x_chord = [0, evaluator.chord]
244 244 y_chord = [0, 0]
245 245 plt.plot(x_chord, y_chord, linewidth='1')
246 246 # Plot quarter chord
247 Removed: plt.plot(evaluator.chord / 4, 0, '.', color='g',
248 Removed: markersize=24, label='Quarter-chord')
247 Added: plt.plot(evaluator.chord / 4, 0,
248 Added: '.', color='g', markersize=24, label='Quarter-chord')
249 249 # Plot airfoil surfaces
250 250 x = [0.98 * x for x in evaluator.x]
251 251 y = [0.98 * z for z in evaluator.z]
@@ -281,8 +281,8 @@
281 281 plt.ylabel('Z axis')
282 282
283 283 plot_bound = max(evaluator.x)
284 Removed: plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound)
285 Removed: plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
284 Added: plt.xlim(-0.10 * plot_bound, 1.10 * plot_bound)
285 Added: plt.ylim(-(1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
286 286 plt.gca().set_aspect('equal', adjustable='box')
287 287 plt.gca().legend()
288 288 plt.grid(axis='both', linestyle=':', linewidth=1)
@@ -295,10 +295,8 @@
295 295 y_1 = evaluator.lift_rectangular
296 296 y_2 = evaluator.lift_elliptical
297 297 y_3 = evaluator.lift_total
298 Removed: plt.plot(x, y_1, '.', color='b', markersize=4,
299 Removed: label='Rectangular lift')
300 Removed: plt.plot(x, y_2, '.', color='g', markersize=4,
301 Removed: label='Elliptical lift')
298 Added: plt.plot(x, y_1, '.', color='b', markersize=4, label='Rectangular lift')
299 Added: plt.plot(x, y_2, '.', color='g', markersize=4, label='Elliptical lift')
302 300 plt.plot(x, y_3, '.', color='r', markersize=4, label='Total lift')
303 301
304 302 # Graph formatting
generator.py
index 7ad2cf37..0e8da8b1 100644..100644
@@ -12,25 +12,31 @@
12 12 #
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 Added: """
16 Added: The 'generator' module contains a single Population class,
17 Added: which represents a collection of randomized airfoils.
18 Added: """
15 19
16 Removed: import creator
20 Added: import creator as cr
17 21
18 22
19 Removed: class Population:
20 Removed: '''Collection of random airfoils.'''
23 Added: class Population(cr.Airfoil, cr.Spar, cr.Stringer):
24 Added: """Collection of random airfoils."""
21 25
22 26 def __init__(self, size):
27 Added: af = cr.Airfoil
28 Added: # print(af)
23 29 self.size = size
24 30 self.gen_number = 0 # incremented for every generation
25 31
26 32 def mutate(self, prob_mt):
27 Removed: '''Randomly mutate the genes of prob_mt % of the population.'''
33 Added: """Randomly mutate the genes of prob_mt % of the population."""
28 34
29 35 def crossover(self, prob_cx):
30 Removed: '''Combine the genes of prob_cx % of the population.'''
36 Added: """Combine the genes of prob_cx % of the population."""
31 37
32 38 def reproduce(self, prob_rp):
33 Removed: '''Pass on the genes of the fittest prob_rp % of the population.'''
39 Added: """Pass on the genes of the fittest prob_rp % of the population."""
34 40
35 41 def fitness():
36 Removed: '''Rate the fitness of an individual on a relative scale (0-100)'''
42 Added: """Rate the fitness of an individual on a relative scale (0-100)"""
main.py
index abbd3399..ec708948 100644..100644
@@ -52,12 +52,11 @@
52 52
53 53
54 54 def main():
55 Removed: '''
55 Added: """
56 56 Create an airfoil;
57 57 Evaluate an airfoil;
58 58 Generate a population of airfoils & optimize.
59 Removed: '''
60 Removed:
59 Added: """
61 60 # Create coordinate system specific to our airfoil dimensions.
62 61 # TODO: imperial + metric unit setting
63 62 creator.Coordinates(CHORD_LENGTH, SEMI_SPAN)
@@ -70,8 +69,8 @@
70 69 # Define NACA airfoil coordinates and mass
71 70 af.add_naca(NACA_NUM)
72 71 af.add_mass(AIRFOIL_MASS)
73 Removed: af.info_print(2)
74 Removed: af.info_save(SAVE_PATH, _)
72 Added: # af.info_print(2)
73 Added: # af.info_save(SAVE_PATH, _)
75 74
76 75 # Create spar instance
77 76 af.spar = creator.Spar()
@@ -82,8 +81,8 @@
82 81 af.spar.add_spar_caps(SPAR_CAP_AREA)
83 82 af.spar.add_mass(SPAR_MASS)
84 83 af.spar.add_webs(SPAR_THICKNESS)
85 Removed: af.spar.info_print(2)
86 Removed: af.spar.info_save(SAVE_PATH, _)
84 Added: # af.spar.info_print(2)
85 Added: # af.spar.info_save(SAVE_PATH, _)
87 86
88 87 # Create stringer instance
89 88 af.stringer = creator.Stringer()
@@ -96,20 +95,26 @@
96 95 af.stringer.add_area(STRINGER_AREA)
97 96 af.stringer.add_mass(STRINGER_MASS)
98 97 af.stringer.add_webs(SKIN_THICKNESS)
99 Removed: af.stringer.info_print(2)
100 Removed: af.stringer.info_save(SAVE_PATH, _)
101 Removed:
98 Added: # af.stringer.info_print(2)
99 Added: # af.stringer.info_save(SAVE_PATH, _)
100 Added: #
102 101 # Plot components with matplotlib
103 Removed: creator.plot_geom(af)
102 Added: # creator.plot_geom(af)
104 103
105 104 # Evaluator object contains airfoil analysis results.
106 105 eval = evaluator.Evaluator(af)
107 106 # The analysis is performed in the evaluator.py module.
108 107 eval.analysis(1, 1)
109 Removed: eval.info_print(2)
110 Removed: eval.info_save(SAVE_PATH, _)
108 Added: # eval.info_print(2)
109 Added: # eval.info_save(SAVE_PATH, _)
111 110 evaluator.plot_geom(eval)
112 Removed: evaluator.plot_lift(eval)
111 Added: # evaluator.plot_lift(eval)
112 Added:
113 Added: pop = generator.Population(10)
114 Added:
115 Added: # print(help(creator))
116 Added: # print(help(evaluator))
117 Added: # print(help(generator))
113 118
114 119 # Print final execution time
115 120 print("--- %s seconds ---" % (time.time() - start_time))