Airfoil and Blade Geometry Examples

A class for airfoil geometries is provided in the fusedwind.turbine.geometry_vt.AirfoilShape class. The convention used for airfoil shapes is that the coordinates are defined as a continuous curve starting from the trailing edge pressure side, around the leading edge to the suction side trailing edge. The airfoil geometry can be oriented in any direction in the x-y-plane. The method computeLETE determines the trailing and leading edges. The trailing edge is defined as the mean of the first and last points on the airfoil and the leading edge is defined as the point along the curve with maximum distance to the trailing edge. The redistribute method can be used to redistribute the points on the airfoil with an arbitrary number of points. See the source docs for specific parameters for this method.

In the simple example below, which is located in src/fusedwind/examples/turbine/, we load in the FFA-W3-301 airfoil and distribute 200 points along its surface, letting the AirfoilShape class determine an appropriate leading edge cell size. Since the trailing edge is not closed, we do not need high clustering there, so we don’t have to specify any cell size. The easiest way to run the example and inspect the class is to run it inside iPython.

import os
import pkg_resources
import numpy as np
import matplotlib.pylab as plt

from fusedwind.turbine.geometry_vt import AirfoilShape

def redistribute_airfoil_example():

    af = AirfoilShape(np.loadtxt('data/ffaw3301.dat'))

    print 'number of points, ni: ',
    print 'Airfoil leading edge (x, y): ', af.LE
    print 'Airfoil leading edge curve fraction (s): ', af.sLE

    plt.plot(af.points[:, 0], af.points[:, 1], '-x', label='original')

    # redistribute 200 points along the surface
    # and let the LE cell size be determined based on curvature
    aff = af.redistribute(200, dLE=True)

    plt.plot(aff.points[:, 0], aff.points[:, 1], '-<', label='redistributed')

    plt.plot(aff.LE[0], aff.LE[1], 'o', label='LE')


The blade planform used in FUSED-Wind is described by spanwise distributions of chord, twist, relative thickness, and pitch axis aft leading edge, variables that are grouped in the fusedwind.turbine.geometry_vt.BladePlanformVT variable tree. A lofted shape is generated from this planform in combination with a series of airfoils covering the range of relative thicknesses used on the blade. The class fusedwind.turbine.geometry.LoftedBladeSurface can be used to generate to generate a smooth lofted shape, which uses method to interpolate in the airfoil family specified by the user is available available as a stand-alone class in fusedwind.turbine.airfoil_vt.BlendAirfoilShapes. The lofted blade surface is saved in the BladeSurfaceVT variable tree by the LoftedBladeSurface class. The configuration method configure_bladesurface configures an assembly with a splined blade planform and a lofted blade surface. In the example below we show how to use this method and plot some of the outputs. This example is also located in src/fusedwind/examples/turbine/

import os
from fusedwind.turbine.configurations import configure_bladesurface
from fusedwind.turbine.geometry import read_blade_planform
from openmdao.main.api import Assembly

def lofted_blade_shape_example():

    top = Assembly()

    configure_bladesurface(top, planform_nC=6)

    # load the planform file
    top.pf_splines.pfIn = read_blade_planform('data/DTU_10MW_RWT_blade_axis_prebend.dat')
    top.blade_length = 86.366
    top.span_ni = 50

    print 'planform variables: ', top.pf_splines.pfOut.list_vars()

    b = top.blade_surface

    # distribute 200 points evenly along the airfoil sections
    b.chord_ni = 200

    # load the airfoil shapes defining the blade
    for f in ['data/ffaw3241.dat',
              'data/ffaw3480.dat' ,
              'data/tc72.dat' ,


    b.blend_var = np.array([0.241, 0.301, 0.36, 0.48, 0.72, 1.])

    pf = top.pf_splines.pfOut

    plt.plot(pf.s, pf.chord)
    plt.plot(pf.s, pf.rot_z)
    plt.title('relative thickness')
    plt.plot(pf.s, pf.rthick)
    plt.title('pitch axis aft leading edge')
    plt.plot(pf.s, pf.p_le)

    for i in range(b.span_ni):
        plt.plot(b.surfout.surface[:, i, 0], b.surfout.surface[:, i, 1])

    return top
_images/chord.png _images/twist.png _images/rthick.png _images/p_le.png

Figure 1: Lofted blade shape.

Blade Structure Example

The blade structure parameterization is primarily aimed for conceptual analysis and optimization, where the geometric detail is fairly low to enable its use more efficiently in an optimization context.

On a cross sectional level, the internal structure is defined in a CrossSectionStructureVT VariableTree object. A cross-section is divided into a number of regions that each cover a fraction of the cross-section, defined in a Region VariableTree object. Each region, contains a stack of materials contained in a list of Layer vartrees. In each layer, the material type, thickness and layup angle can be specified. The materials used in the blade are specified in the MaterialProps variable tree, which holds a set of apparent material properties based on the properties of the constituent materials, which need to be pre-computed using simple micromechanics equations and classical lamination theory.

The figure below shows a blade cross section where the region division points (DPs) are indicated. The location of each DP is specified as a normalized arc length along the cross section starting at the trailing edge pressure side with a value of s=-1., and along the surface to the leading edge where s=0., along the suction side to the trailing edge where s=1. Any number of regions can thus be specified, distributed arbitrarily along the surface.


Figure 2: Blade cross section with region division points (DPs) indicated with red dots and shear webs drawn as green lines.

The spar caps are specified in the same way as other regions, which means that their widths and position along the chord are not default parameters. It is presently only possible to place shear webs at the location of a DP, which means that a single shear web topology would require the spar cap to be split into two regions.

The full blade parameterization is a simple extrusion of the cross-sectional denition, where every region covers the entire span of the blade. The DP curves marked with red dots in the plot below are simple 1-D arrays as function of span that as in the cross-sectional definition take a value between -1. and 1. The distribution of material and their layup angles along the blade are also specified as simple 1-D arrays as function of span. Often, a specific composite will not cover the entire span, and in this case the thickness of this material is simply specified to be zero at that given spanwise location.


Figure 3: Lofted blade with region division points indicated with red dots and shear webs drawn as green lines.

FUSED-Wind provides methods to easily parameterize and spline the structural definition of a wind turbine blade and build a list of cross-sectional definitions of the blade structure for use with cross-sectional structure codes such as PreComp or BECAS. The workflow contains a number of components:

  • Blade planform spliner component
  • Lofted blade surface component
  • Blade structural data reader component
  • Blade structural data spliner component
  • Blade cross-sectional structure builder component
  • Blade structural data writer component

In the example below, we show how to hook up an assembly with a complete lofted shape and structural definition of the DTU 10MW RWT. The example and data is located in src/fusedwind/examples/turbine/

import numpy as np

from openmdao.lib.datatypes.api import VarTree
from openmdao.main.api import Assembly, Component

from fusedwind.interface import implement_base
from fusedwind.turbine.geometry import read_blade_planform, redistribute_blade_planform
from fusedwind.turbine.configurations import configure_bladestructure
from fusedwind.turbine.blade_structure import SplinedBladeStructure
from fusedwind.turbine.structure_vt import BladeStructureVT3D

top = Assembly()

configure_bladestructure(top, 'data/DTU10MW', planform_nC=6, structure_nC=5)

top.st_writer.filebase = 'st_test'

top.blade_length = 86.366

top.pf_splines.pfIn = read_blade_planform('data/DTU_10MW_RWT_blade_axis_prebend.dat')
top.blade_surface.chord_ni = 300

for f in ['data/ffaw3241.dat',


top.blade_surface.blend_var = np.array([0.241, 0.301, 0.36, 0.48, 0.72, 1.])

# spanwise distribution of planform spline DVs
top.pf_splines.Cx = [0, 0.2, 0.4, 0.6, 0.8, 1.]

# spanwise distribution of sptructural spline DVs
top.st_splines.Cx = [0, 0.2, 0.4, 0.75, 1.]

# spanwise distribution of points where
# cross-sectional structure vartrees will be created
top.st_splines.x = np.linspace(0, 1, 12)

The configure_bladestructure method associates an FFD spline component to each of the material thickness and angle distributions and DP curves that defines the blade structure. The starting point of all the splines is zero, so if we add a pertubation to one of the splines, e.g. the spar cap uniax thickness, we can see how that changes the thickness distribution:

> top.st_splines.r04uniaxT_C[2]+=0.01

Figure 4: Blade spar cap uniax thickness pertubation.