/
aclab3.py
121 lines (109 loc) · 4.14 KB
/
aclab3.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
import aclabtools as tools
import aclab1 as lab1
import aclab2 as lab2
import numpy as np
import matplotlib.pyplot as plt
import os
import myvars as v
plot = plt.plot
serialize_array = lab2.serialize_array
def parametric_aerofoil(w, file_path):
"""
Generates and saves a parametric bezier spline aerofoil.
w -- weighting of points
If w is a float it is used as the weighting of point u(2)
If w is an array it must contain four values, used as weighitngs of
points u(1), u(2), l(1), l(2) respectively.
file_path -- path to write aerofoil.dat within
"""
lower = np.array([[1.0, 0.0],
[0.5, 0.08],
[0.0, -0.05]])
n = float(len(lower))
upper = np.array([[0.0, 0.1],
[0.4, 0.2],
[1.0, 0.0]])
m = float(len(upper))
connect = np.add(np.multiply(upper[0], m / (m + n)),
np.multiply(lower[n - 1], n / (m + n)))
lower = np.concatenate((lower, [connect]))
upper = np.concatenate(([connect], upper))
if type(w) is float or type(w) is np.float64:
l_bez = lab1.rational_bezier(lower, [1, 1, 1, 1])
u_bez = lab1.rational_bezier(upper, [1, 1, w, 1])
else:
l_bez = lab1.rational_bezier(lower, [1, w[2], w[3], 1])
u_bez = lab1.rational_bezier(upper, [1, w[0], w[1], 1])
u_bez = np.delete(u_bez, 0, axis=0)
aero_spline = np.concatenate((l_bez, u_bez), axis=0)
aerofoil_file = open(file_path + "aerofoil.dat", "w")
aerofoil_file.write("MyFoil\n" + serialize_array(aero_spline).strip())
def run_xfoil_wcl(w, cl, file_path, xfoil_path, mode="dl", Re=v.Re, M=v.M):
"""
Runs XFoil using predefined configuration and an aerofoil generated from
given values.
w -- weightings, see parametric_aerofoil for details.
cl -- target coefficient of lift for XFoil.
file_path -- path containing aerofoil.dat [NO SPACES ALLOWED]
xfoil_path -- path containing xfoil.exe
mode -- output mode, if mode contains d it returns the coefficient of drag,
if mode contains l it returns the coefficient of lift. If both it
returns a tuple of (cd, cl).
returns values from XFoil as per mode
"""
parametric_aerofoil(w, file_path)
command = "load " + file_path + "aerofoil.dat" + "\n" + \
"panel\n" + \
"oper\n" + \
"visc " + str(Re) + "\n" + \
"M " + str(M) + "\n" + \
"type 1\n" + \
"pacc\n" + \
file_path + "polar.dat" + "\n\n" + \
"iter\n" + \
"5000\n" + \
"cl " + str(cl) + "\n\n\n" + \
"quit\n"
commands_in = open(file_path + "commands.in", "w")
commands_in.write(command)
commands_in.close()
command = '"' + xfoil_path + 'xfoil.exe" < ' + file_path + "commands.in"
os.system(command)
polar = open(file_path + "polar.dat", "r")
values = polar.readlines()[-1].split()
polar.close()
os.remove(file_path + "polar.dat")
out = []
try:
if mode.count("d") > 0:
out.append(float(values[2]))
if mode.count("l") > 0:
out.append(float(values[1]))
if len(out) == 1:
return out[0]
else:
return tuple(out)
except ValueError:
return False
def parameter_sweep(w_array, cl, file_path, xfoil_path, Re=v.Re, M=v.M):
"""
Performs and graphs a parameter sweep of different weightings.
w_array -- an array of weightings, see parametric_aerofoil for details.
cl -- target coefficient of lift for XFoil
file_path -- path containing aerofoil.dat [NO SPACES ALLOWED]
xfoil_path -- path containing xfoil.exe
returns array of values for cd
"""
cd = []
plt.figure(0)
for w in w_array:
xfoil_out = run_xfoil_wcl(w, cl, file_path, xfoil_path, "d", Re, M)
if xfoil_out:
cd.append(xfoil_out)
else:
w_array = np.delete(w_array, w)
print("XFoil failed to solve at w=" + str(w))
plt.figure(1)
plot(w_array, cd, 'o')
tools.mls_curve_fit(w_array, cd, np.linspace(1.15, 1.85, 101))
return cd