Aifroil, построенный по данным без строки суда в Spyder python - PullRequest
0 голосов
/ 23 января 2020

Я использую коды Aero Python от Barba Group;

#import libraries and modules needed
import os
import numpy
from scipy import integrate, linalg
from matplotlib import pyplot


# load geometry from data file
naca_filepath = os.path.join('resources', 'naca0012.dat')
with open(naca_filepath, 'r') as infile:
    x, y = numpy.loadtxt(infile, dtype=float, unpack=True)

# plot geometry
width = 10
pyplot.figure(figsize=(width, width))
pyplot.grid()
pyplot.xlabel('x', fontsize=16)
pyplot.ylabel('y', fontsize=16)
pyplot.plot(x, y, color='k', linestyle='-', linewidth=2)
pyplot.axis('scaled', adjustable='box')
pyplot.xlim(-0.1, 1.1)
pyplot.ylim(-0.1, 0.1);

и использую с airfoil.com файл данных naca0012 (изменить имя " n0012.dat "to" naca0012.dat "и удалите Tittle внутри файла, потому что программа не использует строки в файле данных)

в уроке выглядит примерно так

image

но я использую кодовый участок, который включает в себя линию суда

image

Что-то не так, но что это?

1 Ответ

1 голос
/ 25 февраля 2020

Ссылка на базу данных аэродинамического профиля содержит координаты 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
...