-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathairfoil.py
156 lines (117 loc) · 4.36 KB
/
airfoil.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from math import sin, cos, pi
from glob import glob
import os
from collections import defaultdict
import linecache
import numpy as np
import warnings
class Airfoil:
def __init__(self, reynolds, ncrit):
self.reynolds = reynolds
self.ncrit = ncrit
self._alphas = None
self._optimal_alpha = None
self.min_alpha = None
self.max_alpha = None
self._lift_coefficients = None
self._drag_coefficients = None
self.name = 'Airfoil Who Wishes to Remain Anonymous'
def lift_coefficient(self, alpha):
if alpha > self.max_alpha:
warnings.warn('Extrapolating lift_coefficient')
return self._lift_coefficients[-1]
elif alpha < self.min_alpha:
warnings.warn('Extrapolating lift_coefficient')
return self._lift_coefficients[0]
else:
return np.interp(alpha, self._alphas, self._lift_coefficients)
def drag_coefficient(self, alpha):
if alpha > self.max_alpha:
result = self._drag_coefficients[-1]
print('Warning: Extrapolating drag_coefficient:')
print('\t', 'alpha={}, max_alpha={}, result={}\n'.format(alpha, self.max_alpha, result))
return result
elif alpha < self.min_alpha:
print('Warning: Extrapolating drag_coefficient:')
result = self._drag_coefficients[0]
print('\t', 'alpha={}, min_alpha={}, result={}\n'.format(alpha, self.min_alpha, result))
return result
else:
return np.interp(alpha, self._alphas, self._drag_coefficients)
def _find_optimal_alpha(self):
step = 0.1
alpha = np.arange(self.min_alpha, self.max_alpha + step, step)
lift_coefficients = np.interp(alpha, self._alphas, self._lift_coefficients)
drag_coefficients = np.interp(alpha, self._alphas, self._drag_coefficients)
ratio = lift_coefficients / drag_coefficients
ideal_index = np.argmax(ratio)
self._optimal_alpha = alpha[ideal_index]
@property
def optimal_alpha(self):
if self._optimal_alpha is None:
self._find_optimal_alpha()
return self._optimal_alpha
def normal_component(self, alpha, angle):
C_L = self.lift_coefficient(alpha)
C_D = self.drag_coefficient(alpha)
return C_L * cos(angle) + C_D * sin(angle)
def tangential_component(self, alpha, angle):
C_L = self.lift_coefficient(alpha)
C_D = self.drag_coefficient(alpha)
return C_L * sin(angle) - C_D * cos(angle)
@classmethod
def from_folder(cls, path, reynolds, ncrit):
txt_paths = glob(os.path.join(path, '*.txt'))
csv_paths = glob(os.path.join(path, '*.csv'))
assert(len(txt_paths) == 1 and len(csv_paths) > 0)
traces_by_ncrit = defaultdict(dict)
for csv_path in csv_paths:
reynolds_line = linecache.getline(csv_path, 4).strip()
reynolds_value = float(reynolds_line.split(',')[1])
ncrit_line = linecache.getline(csv_path, 5).strip()
ncrit_value = float(ncrit_line.split(',')[1])
traces_by_ncrit[ncrit_value][reynolds_value] = csv_path
if ncrit not in traces_by_ncrit:
print(path)
raise FileNotFoundError('Cannot find files for ncrit of ' + str(ncrit))
traces = traces_by_ncrit[ncrit]
files = ()
weights = ()
if reynolds in traces:
files = (traces[reynolds],)
weights = (1,)
else:
closest_above = min(r for r in traces if r > reynolds)
closest_below = max(r for r in traces if r < reynolds)
norm_dist = (reynolds - closest_below) / (closest_above - closest_below)
weights = (1 - norm_dist, norm_dist)
files = (traces[closest_below], traces[closest_above])
alphas = []
lift_coefficients = []
drag_coefficients = []
for file in files:
data = np.genfromtxt(file, skip_header=11, usecols=(0, 1, 2), delimiter=',')
alpha = data[:, 0] * (pi / 180)
alphas.append(alpha)
lift_coefficients.append(data[:, 1])
drag_coefficients.append(data[:, 2])
airfoil = cls(reynolds, ncrit)
if len(files) == 1:
airfoil._alphas = alphas[0]
airfoil._lift_coefficients = lift_coefficients[0]
airfoil._drag_coefficients = drag_coefficients[0]
else:
assert(alphas[0] == alphas[1])
airfoil._alphas = alphas[0]
part1 = lift_coefficients[0] * weights[0]
part2 = lift_coefficients[1] * weights[1]
lift_coefficients = part1 + part2
airfoil._lift_coefficients = lift_coefficients
part1 = drag_coefficients[0] * weights[0]
part2 = drag_coefficients[1] * weights[1]
drag_coefficients = part1 + part2
airfoil._drag_coefficients = drag_coefficients
airfoil.min_alpha = min(airfoil._alphas)
airfoil.max_alpha = max(airfoil._alphas)
airfoil.name = path.split('\\')[-1].split('/')[-1]
return airfoil