*ARCHIVED* development moved to aircraft-studio.
evaluator.Airfoil class & class methods
Changed files
creator.py
@@ -75,6 +75,7 @@
75
75
This function's output is piped to the 'save_coord' function below.
76
76
"""
77
77
print('============================')
78
Added:
print(' CREATOR DATA ')
78
79
print('Component:', str(self))
79
80
print('Chord length:', self.chord)
80
81
print('Semi-span:', self.semi_span)
evaluator.py
@@ -13,60 +13,129 @@
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
Added:
import sys
17
Added:
import os.path
18
Added:
import numpy as np
16
19
from math import sin, cos, atan, sqrt
17
20
18
21
19
Removed:
def get_total_mass(*component):
20
Removed:
total_mass = float()
21
Removed:
for _ in component:
22
Removed:
total_mass += _.mass
23
Removed:
return total_mass
22
Added:
class Airfoil:
23
Added:
'''Performs structural evaluations for the airfoil passed as argument.'''
24
24
25
Added:
def __init__(self, airfoil):
26
Added:
self.airfoil = airfoil
27
Added:
# Global dimensions
28
Added:
self.chord = airfoil.chord
29
Added:
self.semi_span = airfoil.semi_span
30
Added:
# mass and area
31
Added:
self.mass_total = float()
32
Added:
self.mass_dist = []
25
33
26
Removed:
# All these functions take integer arguments and return lists.
34
Added:
self.lift_rectangular = []
35
Added:
self.lift_elliptical = []
36
Added:
self.lift = []
27
37
28
Removed:
def get_lift_rectangular(airfoil, lift):
29
Removed:
L_prime = [lift / (airfoil.semi_span * 2)
30
Removed:
for x in range(airfoil.semi_span)]
31
Removed:
return L_prime
38
Added:
self.drag = []
32
39
40
Added:
def __str__(self):
41
Added:
return type(self).__name__
33
42
34
Removed:
def get_lift_elliptical(airfoil, L_0):
35
Removed:
L_prime = [L_0 * sqrt(1 - (y / airfoil.semi_span) ** 2)
36
Removed:
for y in range(airfoil.semi_span)]
37
Removed:
return L_prime
43
Added:
def print_info(self, round):
44
Added:
"""
45
Added:
Print all the component's evaluated data to the terminal.
38
46
47
Added:
This function's output is piped to the 'save_data' function below.
48
Added:
"""
49
Added:
print('============================')
50
Added:
print(' EVALUATOR DATA ')
51
Added:
print('Evaluating:', str(self.airfoil))
52
Added:
print('Chord length:', self.chord)
53
Added:
print('Semi-span:', self.semi_span)
54
Added:
print('Total airfoil mass:', self.mass_total)
55
Added:
print('============================')
56
Added:
print('Rectangular lift:\n', np.around(self.lift_rectangular, round))
57
Added:
print('Elliptical lift:\n', np.around(self.lift_elliptical, round))
58
Added:
print('Combined lift:\n', np.around(self.lift, round))
59
Added:
print('Distribution of mass:\n', np.around(self.mass_dist, round))
60
Added:
print('Drag:\n', np.around(self.drag, round))
61
Added:
return None
39
62
40
Removed:
def get_lift(rectangular, elliptical):
41
Removed:
F_z = [(rectangular[_] + elliptical[_]) / 2
42
Removed:
for _ in range(len(rectangular))]
43
Removed:
return F_z
63
Added:
def save_info(self, save_dir_path, number):
64
Added:
"""
65
Added:
Save all the object's coordinates (must be full path).
66
Added:
"""
44
67
68
Added:
file_name = '{}_{}.txt'.format(self, number)
69
Added:
full_path = os.path.join(save_dir_path, file_name)
70
Added:
try:
71
Added:
with open(full_path, 'w') as sys.stdout:
72
Added:
self.print_info(2)
73
Added:
# This line required to reset behavior of sys.stdout
74
Added:
sys.stdout = sys.__stdout__
75
Added:
print('Successfully wrote to file {}'.format(full_path))
76
Added:
except IOError:
77
Added:
print('Unable to write {} to specified directory.\n'
78
Added:
.format(file_name),
79
Added:
'Was the full path passed to the function?')
80
Added:
return None
45
81
46
Removed:
def get_mass_distribution(airfoil, total_mass):
47
Removed:
F_z = [total_mass / airfoil.semi_span
48
Removed:
for x in range(0, airfoil.semi_span)]
49
Removed:
return F_z
82
Added:
def get_mass_total(airfoil):
83
Added:
total_mass = airfoil.mass + airfoil.spar.mass + airfoil.stringer.mass
84
Added:
return total_mass
50
85
86
Added:
# All these functions take integer arguments and return lists.
51
87
52
Removed:
def get_drag(airfoil, drag):
53
Removed:
# Transform semi-span integer into list
54
Removed:
semi_span = [x for x in range(0, airfoil.semi_span)]
55
Removed:
cutoff = round(0.8 * airfoil.semi_span)
88
Added:
def get_lift_rectangular(airfoil, lift):
89
Added:
L_prime = [lift / (airfoil.semi_span * 2)
90
Added:
for x in range(airfoil.semi_span)]
91
Added:
return L_prime
56
92
57
Removed:
F_x = [drag for x in semi_span[0:cutoff]]
58
Removed:
F_x.extend([1.25 * drag for x in semi_span[cutoff:]])
59
Removed:
# for x in semi_span[cutoff:]:
60
Removed:
# drag_distribution.append(1.25 * drag)
61
Removed:
return F_x
93
Added:
def get_lift_elliptical(airfoil, L_0):
94
Added:
L_prime = [L_0 * sqrt(1 - (y / airfoil.semi_span) ** 2)
95
Added:
for y in range(airfoil.semi_span)]
96
Added:
return L_prime
62
97
98
Added:
def get_lift(rectangular, elliptical):
99
Added:
F_z = [(rectangular[_] + elliptical[_]) / 2
100
Added:
for _ in range(len(rectangular))]
101
Added:
return F_z
63
102
64
Removed:
def get_centroid(airfoil):
65
Removed:
area = airfoil.stringer.area
66
Removed:
numerator = float()
67
Removed:
for _ in airfoil.stringer.x_u:
68
Removed:
numerator += _ * area
69
Removed:
for _ in airfoil.stringer.x_l:
70
Removed:
numerator += _ * area
103
Added:
def get_mass_distribution(airfoil, total_mass):
104
Added:
F_z = [total_mass / airfoil.semi_span
105
Added:
for x in range(0, airfoil.semi_span)]
106
Added:
return F_z
107
Added:
108
Added:
def get_drag(airfoil, drag):
109
Added:
# Transform semi-span integer into list
110
Added:
semi_span = [x for x in range(0, airfoil.semi_span)]
111
Added:
112
Added:
# Drag increases after 80% of the semi_span
113
Added:
cutoff = round(0.8 * airfoil.semi_span)
114
Added:
115
Added:
# Drag increases by 25% after 80% of the semi_span
116
Added:
F_x = [drag for x in semi_span[0:cutoff]]
117
Added:
F_x.extend([1.25 * drag for x in semi_span[cutoff:]])
118
Added:
return F_x
119
Added:
120
Added:
def evaluate(self):
121
Added:
self.drag = self.get_drag(self.airfoil, 10)
122
Added:
123
Added:
self.lift_rectangular = self.get_lift_rectangular(10)
124
Added:
self.lift_elliptical = self.get_lift_elliptical(15)
125
Added:
self.lift = self.get_lift(self.lift_rectangular, self.lift_elliptical)
126
Added:
127
Added:
self.mass_total = self.get_mass_total()
128
Added:
self.mass_dist = self.get_mass_distribution(self.total_mass)
129
Added:
return None
130
Added:
131
Added:
# def get_centroid(airfoil):
132
Added:
# area = airfoil.stringer.area
133
Added:
# top_stringers = airfoil.stringer
134
Added:
# bottom_stringers =
135
Added:
# nose_top_stringers =
136
Added:
# nose_bottom_stringers =
137
Added:
# for _ in airfoil.stringer[1]:
138
Added:
# centroid.x +=
139
Added:
71
140
# denominator
72
141
# z_c =
main.py
@@ -76,21 +76,6 @@
76
76
af.stringer.add_mass(STRINGER_MASS)
77
77
# af.stringer.print_info(2)
78
78
79
Removed:
# print(evaluator.get_total_mass(af, af.spar, af.stringer))
80
Removed:
drag = evaluator.get_drag(af, 10)
81
Removed:
82
Removed:
lift_rectangular = evaluator.get_lift_rectangular(af, 10)
83
Removed:
lift_elliptical = evaluator.get_lift_elliptical(af, 15)
84
Removed:
lift = evaluator.get_lift(lift_rectangular, lift_elliptical)
85
Removed:
86
Removed:
total_mass = evaluator.get_total_mass(af, af.spar, af.stringer)
87
Removed:
dist_mass = evaluator.get_mass_distribution(af, total_mass)
88
Removed:
print('rect', len(lift_rectangular))
89
Removed:
print('ellipse', len(lift_elliptical))
90
Removed:
print('lift', len(lift))
91
Removed:
print(len(drag))
92
Removed:
print(len(dist_mass))
93
Removed:
94
79
# Plot components with matplotlib
95
80
# creator.plot(af, af.spar, af.stringer)
96
81
@@ -99,8 +84,10 @@
99
84
# af.spar.save_info(SAVE_PATH, _)
100
85
# af.stringer.save_info(SAVE_PATH, _)
101
86
102
Removed:
# Evaluate previously created airfoil(s).
103
Removed:
# total_mass = evaluator.get_total_mass(af, af.spar, af.stringer)
87
Added:
# evaluator.Airfoil instance contains the results of the airfoil analysis.
88
Added:
# The analysis itself takes place in the evaluator.py module.
89
Added:
eval = evaluator.Airfoil(af)
90
Added:
eval.print_info(2)
104
91
105
92
# Print final execution time
106
93
print("--- %s seconds ---" % (time.time() - start_time))