pfh.glidersim.airfoil#
Models for the geometry and aerodynamic coefficients of 2D wing sections.
Geometry models are for computing mass distributions (for moments of inertia), points on reference lines (such as the quarter-chord position, frequently used by lifting line methods), and graphical purposes.
Coefficient models are for querying the section coefficients for lift, drag, and pitching moment.
Classes
|
Interface for classes that provide airfoil coefficients. |
|
A class for describing wing section profiles. |
|
Simple airfoil geometry interpolator. |
|
Loads a set of polars from a CSV file. |
|
Generate an airfoil using a NACA4 or NACA5 parameterization. |
|
Loads a set of XFLR5 polars (.txt) from a directory. |
- class pfh.glidersim.airfoil.AirfoilCoefficientsInterpolator(*args, **kwargs)#
Bases:
Protocol
Interface for classes that provide airfoil coefficients.
Aerodynamic coefficients for a single airfoil are typicall calculated over a range of angle of attack and Reynolds number. For wings with control surfaces, the section profiles are variable; the control inputs choose the section profile from a set of airfoils by specifying their unique “airfoil index”. The definition of airfoil index is up to the user, but common choices are deflection angle, normalized vertical deflection distance, etc.
Coefficients interpolators calculate the aerodynamic coefficients over the range of airfoil index, angle of attack, and Reynolds number.
Methods
Cd
(ai, alpha, Re[, clamp])Compute the drag coefficient of the airfoil.
Cl
(ai, alpha, Re[, clamp])Compute the lift coefficient of the airfoil.
Cl_alpha
(ai, alpha, Re[, clamp])Compute the derivative of the lift coefficient versus angle of attack.
Cm
(ai, alpha, Re[, clamp])Compute the pitching coefficient of the airfoil.
- abstract Cl(ai, alpha, Re, clamp=False)#
Compute the lift coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Clfloat
- abstract Cd(ai, alpha, Re, clamp=False)#
Compute the drag coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cdfloat
- abstract Cm(ai, alpha, Re, clamp=False)#
Compute the pitching coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cmfloat
- abstract Cl_alpha(ai, alpha, Re, clamp=False)#
Compute the derivative of the lift coefficient versus angle of attack.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to return 0 if alpha exceeds the the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cl_alphafloat
- __init__(*args, **kwargs)#
- class pfh.glidersim.airfoil.GridCoefficients(file: str | pathlib.Path | TextIO, ai: str = 'delta_d')#
Bases:
pfh.glidersim.airfoil.AirfoilCoefficientsInterpolator
Loads a set of polars from a CSV file.
- The CSV must contain a header with the following columns:
delta_d
alpha [degrees]
Re
Cl
Cd
Cm
Cl_alpha
All values must lie on a grid over delta, alpha, and Re. The points must be on a grid, but the spacing in each dimension is not required to be uniform. If the grid has uniform spacing in each dimension, the GridCoefficients2 class is faster.
FIXME: requires a valid ai column name
Methods
Cd
(ai, alpha, Re[, clamp])Compute the drag coefficient of the airfoil.
Cl
(ai, alpha, Re[, clamp])Compute the lift coefficient of the airfoil.
Cl_alpha
(ai, alpha, Re[, clamp])Compute the derivative of the lift coefficient versus angle of attack.
Cm
(ai, alpha, Re[, clamp])Compute the pitching coefficient of the airfoil.
- __init__(file: str | pathlib.Path | TextIO, ai: str = 'delta_d') None #
- Cl(ai, alpha, Re, clamp=False)#
Compute the lift coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Clfloat
- Cd(ai, alpha, Re, clamp=False)#
Compute the drag coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cdfloat
- Cm(ai, alpha, Re, clamp=False)#
Compute the pitching coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cmfloat
- Cl_alpha(ai, alpha, Re, clamp=False)#
Compute the derivative of the lift coefficient versus angle of attack.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to return 0 if alpha exceeds the the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cl_alphafloat
- class pfh.glidersim.airfoil.XFLR5Coefficients(dirname: str, flapped: bool)#
Bases:
pfh.glidersim.airfoil.AirfoilCoefficientsInterpolator
Loads a set of XFLR5 polars (.txt) from a directory.
Requirements:
All .txt files in the directory are valid XFLR5 polar files, generated using a single test configuration over a range of Reynolds numbers.
Filenames must use <…>_ReN.NNN_<…> to encode the Reynolds number in units of millions (so 920,000 is encoded as 0.920).
All polars will be included.
FIXME: doesn’t support clamping
Methods
Cd
(ai, alpha, Re[, clamped])Compute the drag coefficient of the airfoil.
Cl
(ai, alpha, Re[, clamped])Compute the lift coefficient of the airfoil.
Cl_alpha
(ai, alpha, Re[, clamped])Compute the derivative of the lift coefficient versus angle of attack.
Cm
(ai, alpha, Re[, clamped])Compute the pitching coefficient of the airfoil.
- __init__(dirname: str, flapped: bool) None #
- Cl(ai, alpha, Re, clamped=None)#
Compute the lift coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Clfloat
- Cd(ai, alpha, Re, clamped=None)#
Compute the drag coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cdfloat
- Cm(ai, alpha, Re, clamped=None)#
Compute the pitching coefficient of the airfoil.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to clamp alpha to the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cmfloat
- Cl_alpha(ai, alpha, Re, clamped=None)#
Compute the derivative of the lift coefficient versus angle of attack.
- Parameters
- ai
Airfoil index
- alphafloat [radians]
The angle of attack
- Refloat [unitless]
The Reynolds number
- clampbool
Whether to return 0 if alpha exceeds the the highest non-nan value supported by the (ai, Re) pair.
- Returns
- Cl_alphafloat
- class pfh.glidersim.airfoil.AirfoilGeometry(profile_curve: Callable[[float], Any], camber_curve: Callable[[float], Any], thickness: Callable[[float], Any], convention: str, theta: float = 0, scale: float = 1)#
Bases:
object
A class for describing wing section profiles.
Provides the surface curve, mean camber curve, thickness, and dimensionless mass properties of the airfoil.
- Parameters
- profile_curvecallable
Profile xy-coordinates as a curve parametrized by the normalized arc-length -1 <= r <= 1, where r = 0 is the leading edge, r = 1 is the tip of the upper surface, and r = -1 is the tip of the lower surface. Midpoints by length of the upper and lower surface curves are given by r = 0.5 and r = -0.5.
- camber_curvecallable
Mean camber curve xy-coordinates as a function of normalized arc-length 0 <= r <= 1, where r = 0 is the leading edge, r = 1 is the trailing edge, and r = 0.5 is the midpoint by length.
- thicknesscallable
Airfoil thickness as a function of r.
- convention{“perpendicular”, “vertical”}
Whether the airfoil thickness is measured perpendicular to the mean camber line or vertically (perpendicular to the chord).
- thetafloat [radians]
The angle between the chord and the x-axis that was removed during derotation. Useful for converting alpha of the derotated airfoil into alpha of the reference foil.
- scalefloat [unitless]
The rescaling factor due to normalization. Useful for adjusting an existing set of coefficients for the original foil to account for the normalization.
Methods
camber_curve
(r)Compute points on the camber curve.
from_points
(points, convention[, center, ...])Construct an AirfoilGeometry from a set of airfoil xy-coordinates.
Compute points on the profile curve.
Compute the normal unit vector at points on the profile curve.
Compute the tangent unit vector at points on the profile curve.
thickness
(r)Compute airfoil thickness.
- __init__(profile_curve: Callable[[float], Any], camber_curve: Callable[[float], Any], thickness: Callable[[float], Any], convention: str, theta: float = 0, scale: float = 1) None #
- classmethod from_points(points, convention: str, center: bool = False, derotate: bool = False, normalize: bool = False) pfh.glidersim.airfoil.AirfoilGeometry #
Construct an AirfoilGeometry from a set of airfoil xy-coordinates.
By default, the input coordinates will be centered, normalized, and derotated so the leading edge is at the origin and the chord lies on the x-axis between 0 and 1.
The input coordinates are treated as the “reference” airfoil. If the user provides coefficient data to FoilSections, then it will be assumed that those coefficients were computed for the reference airfoil. If the reference coordinates are rotated and/or normalized by this function, the theta and scale properties allow those reference coefficients to be used with the modified airfoil. For example, if the lift coefficient for the reference airfoil was given by Cl(alpha), then the lift coefficient for the modified airfoil can be computed as scale * Cl(alpha + theta). (Centering has no effect on the coefficients.)
- Parameters
- pointsarray of float, shape (N,2)
The xy-coordinates of the airfoil in counter-clockwise order.
- convention{“perpendicular”, “vertical”}
Whether the airfoil thickness is measured perpendicular to the mean camber line or vertically (the y-axis distance).
- centerbool
Translate the curve leading edge to the origin. Default: False
- derotatebool
Rotate the the chord parallel to the x-axis. Default: False
- normalizebool
Scale the curve so the chord is unit length. Default: False
- Returns
- AirfoilGeometry
- profile_curve(r)#
Compute points on the profile curve.
- Parameters
- rarray_like of float, shape (N,)
The curve parameter from -1..1, with -1 the lower surface trailing edge, 0 is the leading edge, and +1 is the upper surface trailing edge
- Returns
- pointsarray of float, shape (N, 2)
The (x, y) coordinates of points on the airfoil at r.
- profile_curve_tangent(r)#
Compute the tangent unit vector at points on the profile curve.
- Parameters
- rarray_like of float
The profile curve parameter.
- Returns
- dxdyarray, shape (N, 2)
The unit tangent lines at the specified points, oriented with increasing r, so the tangents trace from the lower surface to the upper surface.
- profile_curve_normal(r)#
Compute the normal unit vector at points on the profile curve.
- Parameters
- rarray_like of float
The profile curve parameter.
- Returns
- dxdyarray, shape (N, 2)
The unit normal vectors at the specified points, oriented with increasing r, so the normals point “out” of the airfoil.
- camber_curve(r)#
Compute points on the camber curve.
- Parameters
- rarray_like of float [percentage]
Fractional position on the camber line, where 0 <= r <= 1
- Returns
- array of float, shape (N, 2)
The xy coordinate pairs of the camber line.
- thickness(r)#
Compute airfoil thickness.
- Parameters
- rarray_like of float [percentage]
Fractional position on the camber line, where 0 <= r <= 1
- Returns
- thicknessarray_like of float
- class pfh.glidersim.airfoil.AirfoilGeometryInterpolator(airfoils: dict[float, pfh.glidersim.airfoil.AirfoilGeometry])#
Bases:
object
Simple airfoil geometry interpolator.
- Attributes
- index_bounds
Methods
camber_curve
profile_curve
thickness
- __init__(airfoils: dict[float, pfh.glidersim.airfoil.AirfoilGeometry]) None #
- property index_bounds: tuple[float, float]#
- profile_curve(ai, r)#
- camber_curve(ai, r)#
- thickness(ai, r)#
- class pfh.glidersim.airfoil.NACA(code: int | str, *, open_TE: bool = False, convention: str = 'perpendicular', N_points: int = 300)#
Bases:
pfh.glidersim.airfoil.AirfoilGeometry
Generate an airfoil using a NACA4 or NACA5 parameterization.
- Parameters
- codeinteger or string
A 4- or 5-digit NACA code. If the code is an integer less than 1000, leading zeros are implicitly added; for example, 12 becomes the NACA4 code 0012.
Only a subset of NACA5 codes are supported. A NACA5 code can be expressed as LPSTT; valid codes for this implementation are restricted to
L = 2
,1 <= P <= 5
, andS = 0
.- open_TEbool, optional
Generate airfoils with an open trailing edge. Default: False.
- convention{“perpendicular”, “vertical”}, optional
The convention to use for defining the airfoil thickness. Default: “perpendicular”.
The “perpendicular” convention (sometimes called the “American” convention) measures airfoil thickness perpendicular to the mean camber line. The “vertical” convention (sometimes called the “British” convention) measures airfoil thickness in vertical strips (the y-axis distance between points on the upper and lower surfaces).
The “American” convention is used here since it was the original definition (see [0]), but the “British” convention is available in case the output needs to match the popular tool “XFOIL”.
- N_pointsinteger
The number of sample points from each surface. Default: 300
References
- 0
Jacobs, Eastman N., Ward, Kenneth E., Pinkerton, Robert M. “The characteristics of 78 related airfoil sections from tests in the variable-density wind tunnel”. NACA Technical Report 460. 1933.
Methods
camber_curve
(r)Compute points on the camber curve.
from_points
(points, convention[, center, ...])Construct an AirfoilGeometry from a set of airfoil xy-coordinates.
Compute points on the profile curve.
Compute the normal unit vector at points on the profile curve.
Compute the tangent unit vector at points on the profile curve.
thickness
(r)Compute airfoil thickness.
- __init__(code: int | str, *, open_TE: bool = False, convention: str = 'perpendicular', N_points: int = 300) None #
- camber_curve(r)#
Compute points on the camber curve.
- Parameters
- rarray_like of float [percentage]
Fractional position on the camber line, where 0 <= r <= 1
- Returns
- array of float, shape (N, 2)
The xy coordinate pairs of the camber line.
- classmethod from_points(points, convention: str, center: bool = False, derotate: bool = False, normalize: bool = False) pfh.glidersim.airfoil.AirfoilGeometry #
Construct an AirfoilGeometry from a set of airfoil xy-coordinates.
By default, the input coordinates will be centered, normalized, and derotated so the leading edge is at the origin and the chord lies on the x-axis between 0 and 1.
The input coordinates are treated as the “reference” airfoil. If the user provides coefficient data to FoilSections, then it will be assumed that those coefficients were computed for the reference airfoil. If the reference coordinates are rotated and/or normalized by this function, the theta and scale properties allow those reference coefficients to be used with the modified airfoil. For example, if the lift coefficient for the reference airfoil was given by Cl(alpha), then the lift coefficient for the modified airfoil can be computed as scale * Cl(alpha + theta). (Centering has no effect on the coefficients.)
- Parameters
- pointsarray of float, shape (N,2)
The xy-coordinates of the airfoil in counter-clockwise order.
- convention{“perpendicular”, “vertical”}
Whether the airfoil thickness is measured perpendicular to the mean camber line or vertically (the y-axis distance).
- centerbool
Translate the curve leading edge to the origin. Default: False
- derotatebool
Rotate the the chord parallel to the x-axis. Default: False
- normalizebool
Scale the curve so the chord is unit length. Default: False
- Returns
- AirfoilGeometry
- profile_curve(r)#
Compute points on the profile curve.
- Parameters
- rarray_like of float, shape (N,)
The curve parameter from -1..1, with -1 the lower surface trailing edge, 0 is the leading edge, and +1 is the upper surface trailing edge
- Returns
- pointsarray of float, shape (N, 2)
The (x, y) coordinates of points on the airfoil at r.
- profile_curve_normal(r)#
Compute the normal unit vector at points on the profile curve.
- Parameters
- rarray_like of float
The profile curve parameter.
- Returns
- dxdyarray, shape (N, 2)
The unit normal vectors at the specified points, oriented with increasing r, so the normals point “out” of the airfoil.
- profile_curve_tangent(r)#
Compute the tangent unit vector at points on the profile curve.
- Parameters
- rarray_like of float
The profile curve parameter.
- Returns
- dxdyarray, shape (N, 2)
The unit tangent lines at the specified points, oriented with increasing r, so the tangents trace from the lower surface to the upper surface.
- thickness(r)#
Compute airfoil thickness.
- Parameters
- rarray_like of float [percentage]
Fractional position on the camber line, where 0 <= r <= 1
- Returns
- thicknessarray_like of float