Skip to content
Snippets Groups Projects
Verified Commit efaaa5da authored by Thomas Lambert's avatar Thomas Lambert :helicopter:
Browse files

feat(data): add airfoil data

parent 8b5ef48b
No related branches found
No related tags found
No related merge requests found
File added
File added
# Airfoil data
Rotare requires the input of airfoil polars to properly interpolate the lift and
drag coefficient of each element. These polars can be directly provided or
generated using external tools such as XFOIL or XFLR5.
The following process explains how to generate such polars and transform them in
a structure to be imported in Rotare. A more complete description is provided in
the complete manual of Rotare.
## polargenerator.py
**polargenerator** is a small script that will run XFOIL in order to generate
the airfoil polars. This script uses the [aeropy] library, follow the
instructions on the Github to install it properly. (_Note: this is not the same
`aeropy` than the one installed through `pip`).
The usage is straightforward:
```bash
python polargenerator <airfoil>
```
It can either accept a NACA airfoil as input or a file with the airfoil
coordinates. Example:
```bash
python polargenerator 'naca0012'
python polargenerator 'myairfoil.dat'
```
Note that if the airfoil coordinates are provided though a DAT-file, the need to
be formatted according to the `Selig` convention (see "[Airfoil Format]" section
on the UIUC Airfoil Database). A Matlab utility is provided with the `af_tools`
library to convert the Ledneicer format into Selig format.
## MAT-file
Once the raw XFOIL data have been generated for a given airfoil, they need to be
converted into a structure that will be understood by Rotare. This is done using
the `xf2mat` function provided by the `af_tools` library.
[Airfoil Format]: https://m-selig.ae.illinois.edu/ads.html
[aeropy]: https://github.com/leal26/AeroPy
NACA 0012 AIRFOILS
66. 66.
0.000000 0.000000
0.000584 0.004260
0.002334 0.008429
0.005247 0.012501
0.009315 0.016471
0.014529 0.020330
0.020877 0.024071
0.028344 0.027683
0.036913 0.031156
0.046563 0.034479
0.057272 0.037641
0.069015 0.040631
0.081765 0.043437
0.095492 0.046049
0.110163 0.048457
0.125745 0.050651
0.142201 0.052625
0.159492 0.054372
0.177579 0.055886
0.196419 0.057164
0.215968 0.058205
0.236180 0.059008
0.257008 0.059576
0.278404 0.059910
0.300318 0.060017
0.322698 0.059903
0.345492 0.059575
0.368646 0.059042
0.392108 0.058314
0.415822 0.057403
0.439732 0.056320
0.463783 0.055077
0.487918 0.053687
0.512082 0.052162
0.536217 0.050516
0.560268 0.048762
0.584179 0.046912
0.607892 0.044980
0.631354 0.042978
0.654509 0.040917
0.677303 0.038811
0.699682 0.036670
0.721596 0.034506
0.742992 0.032329
0.763820 0.030152
0.784032 0.027983
0.803581 0.025834
0.822421 0.023714
0.840508 0.021635
0.857800 0.019605
0.874255 0.017635
0.889837 0.015735
0.904509 0.013914
0.918235 0.012182
0.930985 0.010549
0.942728 0.009022
0.953437 0.007611
0.963087 0.006324
0.971656 0.005169
0.979123 0.004152
0.985471 0.003280
0.990685 0.002560
0.994753 0.001994
0.997666 0.001587
0.999416 0.001342
1.000000 0.001260
0.000000 0.000000
0.000584 -0.004260
0.002334 -0.008429
0.005247 -0.012501
0.009315 -0.016471
0.014529 -0.020330
0.020877 -0.024071
0.028344 -0.027683
0.036913 -0.031156
0.046563 -0.034479
0.057272 -0.037641
0.069015 -0.040631
0.081765 -0.043437
0.095492 -0.046049
0.110163 -0.048457
0.125745 -0.050651
0.142201 -0.052625
0.159492 -0.054372
0.177579 -0.055886
0.196419 -0.057164
0.215968 -0.058205
0.236180 -0.059008
0.257008 -0.059576
0.278404 -0.059910
0.300318 -0.060017
0.322698 -0.059903
0.345492 -0.059575
0.368646 -0.059042
0.392108 -0.058314
0.415822 -0.057403
0.439732 -0.056320
0.463783 -0.055077
0.487918 -0.053687
0.512082 -0.052162
0.536217 -0.050516
0.560268 -0.048762
0.584179 -0.046912
0.607892 -0.044980
0.631354 -0.042978
0.654509 -0.040917
0.677303 -0.038811
0.699682 -0.036670
0.721596 -0.034506
0.742992 -0.032329
0.763820 -0.030152
0.784032 -0.027983
0.803581 -0.025834
0.822421 -0.023714
0.840508 -0.021635
0.857800 -0.019605
0.874255 -0.017635
0.889837 -0.015735
0.904509 -0.013914
0.918235 -0.012182
0.930985 -0.010549
0.942728 -0.009022
0.953437 -0.007611
0.963087 -0.006324
0.971656 -0.005169
0.979123 -0.004152
0.985471 -0.003280
0.990685 -0.002560
0.994753 -0.001994
0.997666 -0.001587
0.999416 -0.001342
1.000000 -0.001260
NACA 0015
1.0000 0.00158
0.9500 0.01008
0.9000 0.01810
0.8000 0.03279
0.7000 0.04580
0.6000 0.05704
0.5000 0.06617
0.4000 0.07254
0.3000 0.07502
0.2500 0.07427
0.2000 0.07172
0.1500 0.06682
0.1000 0.05853
0.0750 0.05250
0.0500 0.04443
0.0250 0.03268
0.0125 0.02367
0.0000 0.00000
0.0125 -0.02367
0.0250 -0.03268
0.0500 -0.04443
0.0750 -0.05250
0.1000 -0.05853
0.1500 -0.06682
0.2000 -0.07172
0.2500 -0.07427
0.3000 -0.07502
0.4000 -0.07254
0.5000 -0.06617
0.6000 -0.05704
0.7000 -0.04580
0.8000 -0.03279
0.9000 -0.01810
0.9500 -0.01008
1.0000 -0.00158
"""Generate airfoil polars automatically using XFOIL
Rotare requires the input of airfoil polars to interpolate properly the lift
and drag coefficient of the various elements.
This script automates the generation of these input polars to save some time.
Args:
- airfoil : str
Arfoil to use, either in the form of 'naca0012' or name of the DAT-file
with the coordinates
Script defaults:
- Reynolds : 1e5, 5e5, 1e6, 1.5e6, 2e6, 5e6, 1e7
- AOA : -25 to 25 with a step of 0.5
- Iter : 100
------------------------------------------------
(c) Copyright 2022 University of Liege
Author: Thomas Lambert <t.lambert@uliege.be>
ULiege - Aeroelasticity and Experimental Aerodynamics
MIT License
"""
# Imports
import sys
import os
import numpy as np
import aeropy.xfoil_module as xf
def main():
"""Creates polar files for each reynolds"""
airfoil = parse_inputs()
reynolds = [re * 1000000 for re in [0.2, 0.5, 1, 1.5, 2, 5, 10]]
aoa = list(np.arange(-20, 30, 0.5))
i = 1
for re in reynolds:
print("%d/%d - Calculating polar for Re=%ge6" % (i, len(reynolds), re / 1e6))
i = i + 1
if airfoil.startswith("naca"):
xf.call(
airfoil,
alfas=aoa,
output="Polar",
Reynolds=re,
plots=False,
NACA=True,
iteration=500,
)
else:
if os.path.exists(airfoil) or os.path.exists(airfoil + ".dat"):
xf.call(
airfoil,
alfas=aoa,
output="Polar",
Reynolds=re,
plots=False,
NACA=False,
iteration=500,
)
else:
raise ValueError("Airfoil file not foud")
cleanup(airfoil)
def parse_inputs():
"""Proper parsing of inputs"""
airfoil = sys.argv[1]
return airfoil
def cleanup(airfoil):
"""Remove temp files and rename files properly"""
cwd = os.getcwd()
# Remove useless files
safe_remove(":00.bl")
# Add proper extension to generated files
for file in os.listdir(cwd):
if file.startswith("Coordinates_"):
safe_rename(file, airfoil + ".dat")
elif file.startswith("Polar_"):
safe_rename(file, file + ".txt")
def safe_remove(file):
"""Safely remove a file"""
if os.path.exists(file):
os.remove(file)
def safe_rename(old, new):
"""Safely rename a file"""
if os.path.exists(new):
os.remove(new)
os.rename(old, new)
# Only run when file is directly executed
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment