Airfoil toolbox
A list of functions and script used for analysis of airfoils and related data with Matlab.
Disclaimer
This toolbox was mainly developed under Matlab R2018a. The various functions were not tested on older versions. A code compatibility analysis showed no errors, so in theory it should work properly with any other versions of Matlab as well. If for some reason it does not work on your version, please open an issue.
The functions in this repository are intended to be used as a Matlab package (see Matlab documentation for more details).
Documentation
Each function contains a complete description in its preamble. Type help <function>
in Matlab command window to print it.
Install and use
Installation
- Either clone this repository or download a
.zip
version of the source code. - Place the
+af_tools/
folder somewhere on your Matlab Path such as:- in you current project
- in a folder that is already in Matlab's path (e.g.
/Documents/Matlab/
). - somewhere else, but then explicitly add it to Matlab's Path.
Remark
Unfortunately, Matlab packages have a few limitations. Hence, you should avoid changing the package name if you do not know what you are doing.
- The
+
in the folder's name is required for Matlab to treat it as a package. - Some functions of this package are interconnected (e.g., nacaairfoil calls nacacamber). In that situation, Matlab forces the main function to re-import explicitly all sub-functions before using them, even if they are part of the same package (people have complained about that design choice for quite some time, to no avail). If you rename the package, these links will be broken and Matlab will not find the connected functions.
- All functions that import other functions will have an import line at the beginning. If you rename the package, you must therefore update these imports.
Use
Once the +af_tools/
folder is placed somewhere where Matlab will find
it, you can start using its features.
- If you are only interested in a single function of the package, use
import af_tools.<functionName>
functionName(args)
- If you want to import all functions, use
import af_tools.*
xf2mat(args)
nacacamber(args)
...
- If you want to use functions on-the-fly without importing them, call them directly
af_tools.xf2mat(args)
Functions
- All functions can be used as standalone functions and give meaningful output on their own (they are not sub-routines used to perform intermediary tasks).
- All functions can be called without arguments. If that is the case, they will prompt the user to manually enter or select the few mandatory arguments. The rest will be set to default values.
List of functions:
- xf2mat: Aggregates multiple XFOIL or XFLR5 polar results into a single structure.
- uiuccleaner: Re-formats airfoil coordinates obtained from UIUC Airfoil database.
-
Airfoil generation
- nacacamber: Generates the coordinates of the camberline for a NACA 4 or 5 digits airfoil.
- nacaairfoil: Generates the full coordinates of a NACA 4 or 5 digits airfoil.
-
Polar manipulation
-
extendpolar: Extends polars to the full range of
\alpha
([-180, 180] deg). -
findstall: Finds the stall point and returns the corresponding
\alpha
,C_l
andC_d
. -
findzerolift: Finds the zero-lift angle and the associate
C_d
. - findcllinearrange: Finds the linear range of the lift coefficient and returns the range and lift slope.
- plotpolars: Plot various polars.
-
extendpolar: Extends polars to the full range of
xf2mat
Aggregates airfoil polars obtained using XFOIL v6.99 of XFLR5 v6.55 into a single Matlab structure.
This function can either aggregate multiple polar files into a single structure (e.g. same airfoil at different Reynolds) or simply convert a single polar data into a Matlab-ready structure.
import af_tools.xf2mat
Polar = xf2mat
Polar = xf2mat(inputDir, inputFiles, 'autosave', true)
Polar = xf2mat(inputDir, inputFiles, 'trimAoas', true)
Polar = xf2mat(inputDir, inputFiles, 'autosave', true, 'trimAoas', true)
Input | Example | Default |
---|---|---|
inputDir |
'.' , 'xf_results'
|
- |
inputFiles |
'*' , '*0012*' , '{'*0012_1*', '*0012_2*'}
|
'*' |
'autosave' |
false , true
|
false |
'trimAoas' |
false , true
|
false |
The output is a structure with the following fields, where M is the number of angles of attack and N is the number of input files.
Field | Data | Size |
---|---|---|
origin |
Program from which the polars came (XFOIL/XFLR5) | [1 x N] |
airfoil |
Airfoil name (parsed from XFOIL/XFLR5 results) | [1 x N] |
alpha |
Angles of attacks | [M x N] |
reynolds |
Reynolds numbers | [1 x N] |
mach |
Mach number | [1 x N] |
nCrit |
BL transition factor | [1 x N] |
cl |
Lift coefficient | [M x N] |
cd |
Drag coefficient | [M x N] |
cm |
Moment coefficient | [M x N] |
uiuccleaner
The UIUC airfoil database from the University of Illinois gathers the coordinates for more than 1600 airfoils. However, there is a few discrepancies between the format and ordering of these coordinates. This scripts alleviates that by re-formatting any input file from the original database. The main use of this function is to make the coordinates files compliant with other existing tools, such as XFOIL.
The output format of this script follows the "labeled coordinates" file, used originally by Selig on the UIUC Airfoil Database. The first line contains the name of the airfoil, and each line after that is a set of coordinates. The coordinates are ordered from the trailing edge, along the upper surface to the leading edge and back around the lower surface to trailing edge.
import af_tools.xf2mat
Polar = uiuccleaner
Polar = uiuccleaner(inputDir, inputFiles, 'autosave', true)
Polar = uiuccleaner(inputDir, inputFiles, 'overwrite', true)
Input | Example | Default |
---|---|---|
inputDir |
'.' , 'xf_results'
|
- |
inputFiles |
'*' , '*0012*' , '{'*0012_1*', '*0012_2*'}
|
'*' |
'autosave' |
false , true
|
false |
'overwrite' |
false , true
|
false |
'refine' |
false , true
|
false |
Airfoil generation
The following functions use the same two main input arguments.
Input | Example | Default |
---|---|---|
digits |
'0012' , '24012'
|
- |
nPoints |
100 , 130
|
100 |
nacacamber
Determines the camber line of a NACA 4 or 5 digits airfoil. The output is ordered from the leading edge to the trailing edge.
import af_tools.nacacamber
[xc, yc, gradY] = nacacamber
[xc, yc, gradY] = nacacamber(digits)
[xc, yc, gradY] = nacacamber(digits, nPoints)
[xc, yc, gradY] = nacacamber(digits, nPoints, 'spacing', 'halfcosine')
Options | Example | Default |
---|---|---|
'spacing' |
halfcosine , cosine , linear
|
'halfcosine' |
nacaairfoil
Generates the full coordinates of a NACA 4 or 5 digits airfoil. The output coordinates follow the most usual order. They start at the trailing edge, along the upper surface to the leading edge and back around the lower surface to trailing edge.
import af_tools.nacaairfoil
[x, y] = nacaairfoil
[x, y] = nacaairfoil(digits)
[x, y] = nacaairfoil(digits, nPoints)
[x, y] = nacaairfoil(digits, nPoints, 'spacing', spacing, 'zerote', true)
[x, y] = nacaairfoil(digits, nPoints, 'savedat', true)
Options | Example | Default |
---|---|---|
'spacing' |
halfcosine , cosine , linear
|
'halfcosine' |
'zerote' |
true , false
|
true |
'savedat' |
true , false
|
true |
Polar manipulation
The following functions all share the same main inputs arguments in the exact same order. These arguments can be of two types:
-
Polar
: A Polar structure, as the one given by [xf2mat][xf2mat]; -
alpha
,cl
,cd
,cm
: Arrays representing the different polars. Some functions only allow the first two or three arrays.
Some functions then extend these inputs by using various optional arguments.
extendpolar
This function extends known C_l
and C_d
polars to the full range of
angle of attacks [-180; 180]. This is especially useful when studying rotors and
propellers in off-design configuration (with the Blade Element Momentum Theory
for instance).
import af_tools.extendpolar
[alphaExt, clExt, cdExt] = extendpolar
[alphaExt, clExt, cdExt] = extendpolar(Polar)
[alphaExt, clExt, cdExt] = extendpolar(Polar, 'method', 'Viterna')
[alphaExt, clExt, cdExt] = extendpolar(Polar, 'limit', 'stall')
[alphaExt, clExt, cdExt] = extendpolar(alpha, cl, cd, 'method', 'Viterna')
Options | Example | Default |
---|---|---|
'method' | 'Viterna' |
'Viterna' |
'limit' | 'stall','limit' |
'last' |
plotpolars
Plots the following polars: C_l-\alpha
, C_d-\alpha
, C_m-\alpha
, C_l/C_d-\alpha
, C_l-C_d
.
import af_tools.plotpolars
plotpolars
plotpolars(Polar)
plotpolars(alpha, cl, cd, cm)
findstall
Finds the stall angle of attack and the associated C_l
and C_d
.
import af_tools.findstall
[alpha_s, cl_s, cd_s] = findstall
[alpha_s, cl_s, cd_s] = findstall(Polar)
[alpha_s, cl_s, cd_s] = findstall(alpha, cl, cd)
findzerolift
Finds the zero-lift angle of attack and the associated C_d
.
import af_tools.findzerolift
[alpha_zeroL, cd_zeroL] = findzerolift
[alpha_zeroL, cd_zeroL] = findzerolift(Polar)
[alpha_zeroL, cd_zeroL] = findzerolift(alpha, cl, cd)
findcllinearrange
Finds the range of angles of attack for which the C_l
can be considered
linear.
import af_tools.findcllinearrange
[alphaRange, clRange, clSlope] = findcllinearrange
[alphaRange, clRange, clSlope] = findcllinearrange(Polar)
[alphaRange, clRange, clSlope] = findcllinearrange(alpha,cl)
Licence
Copyright (c) 2022 Thomas Lambert, University of Liège.
All functions and scripts of the af_tools code are licensed under the Apache 2.0 Licence.