Reputation: 25
I developed a code to interpret airfoil .dat files, in which I use one file at a time and do some mathematical operations.
Currrently, I define three values at the beginning of the code: the chord, the alpha (angle of attack), and the z-translation. Then I use those values to perform operations on a long series of data points read from the file. However, rather than hard coding the chord and alpha, I would like to read them from the first two lines of the .dat file. Once the inputs are used, I would like to save only the list of (modified) points to a new .dat file, discarding the parameters from the beginning of the original file.
I have attached my code and the .dat file I want to create. The idea is to use the two initial lines as input to use in math operations and save in the New.dat file with only the modified points.
import math
chord = 1.138
alpha = -3.427960
z_trans = -0.25*chord
with open('Airfoils/ffaw3241.dat') as data:
mylist = [line.rstrip('\n') for line in data]
zs = []
ys = []
for line in mylist:
if len(line) > 1:
z, y = line.split(None, 2)
zs.append(float(z))
ys.append(float(y))
data = tuple(zip(zs, ys))
print(chord)
#Scale the foil with provided chord
zs = []
ys = []
for point in data:
z, y = point
zs.append(float(z)*chord)
ys.append(float(y)*chord)
data = tuple(zip(zs, ys))
#print (data)
#rotate the airfoil with provided alpha
oz, oy = (0, 0)
zs = []
ys = []
for point in data:
z, y = point
zs.append(oz + math.cos(math.radians(alpha)) * (float(z) - oz) - math.sin(math.radians(alpha)) * (float(y) - oy))
ys.append(oy + math.sin(math.radians(alpha)) * (float(z) - oz) + math.cos(math.radians(alpha)) * (float(y) - oy))
data = tuple(zip(zs, ys))
#translate the airfoil to the center of pressure (25% of chord)
zs = []
ys = []
for point in data:
z, y = point
zs.append(round (float(z),5) + z_trans)
#ys.append(round (float(y),5) + y_trans)
data = tuple(zip(zs, ys))
with open("Airfoils/ffaw3241New.dat", "w") as output:
output.write(str(data))
1.138 #chord
-3.427960 #alpha
1.00000 -0.00360
0.98338 -0.00140
0.96457 0.00096
0.94365 0.00311
0.92072 0.00466
0.89589 0.00528
0.86928 0.00473
0.84102 0.00291
0.81124 -0.00030
0.78010 -0.00514
0.74772 -0.01183
0.71428 -0.02024
0.67994 -0.03015
0.64485 -0.04127
0.60918 -0.05308
0.57311 -0.06502
0.53681 -0.07651
0.50045 -0.08706
0.46422 -0.09623
0.42827 -0.10370
0.39279 -0.10938
0.35794 -0.11324
0.32389 -0.11531
0.29081 -0.11567
0.25885 -0.11441
0.22817 -0.11167
0.19891 -0.10754
0.17121 -0.10213
0.14522 -0.09560
0.12104 -0.08811
0.09880 -0.07985
0.07861 -0.07104
0.06056 -0.06188
0.04474 -0.05258
0.03122 -0.04334
0.02006 -0.03427
0.01133 -0.02550
0.00507 -0.01700
0.00130 -0.00903
0.00000 0.00000
0.00130 0.00956
0.00507 0.02005
0.01133 0.03033
0.02006 0.04087
0.03122 0.05135
0.04474 0.06170
0.06056 0.07176
0.07861 0.08139
0.09880 0.09044
0.12104 0.09873
0.14522 0.10613
0.17121 0.11247
0.19891 0.11764
0.22817 0.12153
0.25885 0.12409
0.29081 0.12526
0.32389 0.12504
0.35794 0.12350
0.39279 0.12076
0.42827 0.11696
0.46422 0.11223
0.50045 0.10670
0.53681 0.10052
0.57311 0.09382
0.60918 0.08672
0.64485 0.07935
0.67994 0.07187
0.71428 0.06441
0.74772 0.05707
0.78010 0.04996
0.81124 0.04316
0.84102 0.03673
0.86928 0.03070
0.89589 0.02510
0.92072 0.01996
0.94365 0.01529
0.96457 0.01107
0.98338 0.00727
1.00000 0.00391
Upvotes: 2
Views: 356
Reputation: 3518
You can use the next
function to "manually" consume the next item from a generator, such as a file. This is a handy way to grab the first (or in this case, first two) items before iterating through the rest. Here's a fairly simple way to do it, based on your code:
with open('input.dat') as file:
chord = next(file).split()[0]
alpha = next(file).split()[0]
data = []
for line in file:
line = line.split()
z = float(line[0])
y = float(line[1])
data.append((z, y))
This could be further condensed with a couple of list comprehensions (okay, technically one list comprehension and one generator expression):
with open('input.dat') as file:
chord = next(file).split()[0]
alpha = next(file).split()[0]
data = [tuple(float(i) for i in line.split()) for line in file]
Personally I think this is a case where I'd use map
for the float
conversion, but tastes differ. map
is handy when all you want to do to multiple things is apply the same function to all of them.
with open('input.dat') as file:
chord = next(file).split()[0]
alpha = next(file).split()[0]
data = [tuple(map(float, line.split())) for line in file]
Notes:
split()
, since that automatically removes any trailing whitespace.if not line.isspace()
at the end of the list comprehension to skip those.Upvotes: 1