Ссылка на базу данных аэродинамического профиля содержит координаты NACA0012 в формате Lednicer, а код в Aero Python Урок был написан для аэродинамического профиля в формате Селига. ( Notebook вычисляет обтекание аэродинамического профиля, используя метод панели источника.)
Формат Селига начинается с заднего края аэродинамического профиля, проходит над верхним поверхности, затем над нижней поверхностью, до go назад к задней кромке.
Формат Ледникера перечисляет точки на верхней поверхности (от передней кромки до задней кромки), затем указывает на нижняя поверхность (от переднего края к заднему).
Вы можете загрузить формат Селига (пропуская заголовок «САМОЛЕТЫ NACA 0012» с skiprows=1
в numpy.loadtxt
) следующим образом:
import urllib
# Retrieve and save geometry to file.
selig_url = 'http://airfoiltools.com/airfoil/seligdatfile?airfoil=n0012-il'
selig_path = 'naca0012-selig.dat'
urllib.request.urlretrieve(selig_url, selig_path)
# Load coordinates from file.
with open(selig_path, 'r') as infile:
x1, y1 = numpy.loadtxt(infile, unpack=True, skiprows=1)
Аэродинамический профиль NACA0012 здесь содержит 131
точек, и вы увидите, что задняя кромка имеет конечную толщину:
print('Number of points:', x1.size) # -> 131
print(f'First point: ({x1[0]}, {y1[0]})') # -> (1.0, 0.00126)
print(f'Last point: ({x1[-1]}, {y1[-1]})') # -> (1.0, -0.00126)
Если вы сделаете то же самое с форматом Ледникера (с skiprows=2
для заголовок), вы загрузите 132
точек (точка переднего края дублируется) с переворачиваемыми точками на верхней поверхности (от переднего края к заднему краю). (Вот почему вы наблюдаете эту линию посередине с pyplot.plot
; линия соединяет задний край от верхней поверхности к переднему краю от нижней поверхности.)
Один из способов переориентировать точки на Следуйте формату Селига, чтобы пропустить передний край на верхней поверхности (т.е. пропустить дублированную точку) и перевернуть точки на верхней поверхности. Вот возможное решение:
import numpy
# Retrieve and save geometry to file.
lednicer_url = 'http://airfoiltools.com/airfoil/lednicerdatfile?airfoil=n0012-il'
lednicer_path = 'naca0012-lednicer.dat'
urllib.request.urlretrieve(lednicer_url, lednicer_path)
# Load coordinates from file (re-orienting points in Selig format).
with open(lednicer_path, 'r') as infile:
# Second line of the file contains the number of points on each surface.
_, info = (next(infile) for _ in range(2))
# Get number of points on upper surface (without the leading edge).
num = int(info.split('.')[0]) - 1
# Load coordinates, skipping the first point (leading edge on upper surface).
x2, y2 = numpy.loadtxt(infile, unpack=True, skiprows=2)
# Flip points on the upper surface.
x2[:num], y2[:num] = numpy.flip(x2[:num]), numpy.flip(y2[:num])
В итоге вы получите 131
точек, ориентированных так же, как формат Селига.
print('Number of points:', x2.size) # -> 131
print(f'First point: ({x2[0]}, {y2[0]})') # -> (1.0, 0.00126)
print(f'Last point: ({x2[-1]}, {y2[-1]})') # -> (1.0, -0.00126)
Наконец, мы также можем проверить, что координаты совпадают с numpy.allclose
:
assert numpy.allclose(x1, x2, rtol=0.0, atol=1e-6) # -> True
assert numpy.allclose(y1, y2, rtol=0.0, atol=1e-6) # -> True