Course Rotor and Wake Aerodynamics
Press right arrow to continue.
On the bottom right there are four directional arrows.
At the lower right corner, you can find the slide number (horizontal number. vertical number).
Press ESC-key to see map of the presentation. Press ESC-key or press slide again to return to slide.
Press bottom arrow to test the vertical slide motion.
Use the side arrows to move horizontally.
To be able to program a lifting line model for application to an horizontal axis wind turbine...
This tutorial is supported by the study of the following references:
Source: Katz, Joseph, and Allen Plotkin. Low-speed aerodynamics. Vol. 13., Cambridge university press, 2001.
Source: Anderson, John D. Fundamentals of aerodynamics. , McGraw-Hill., 2001.
The lifting line model allows us to calculate the loads on a blade and the flow field at any point in space.
It uses a blade element approach, where the blade is segmented in section in the spanwise direction. At each section, the loads are determined by using the velocity perceived at the control point (usually the quarter-chord point), and 2D airfoil theory.
The velocity at the control point is calculated using potential flow theory, linearly adding the unperturbed wind field with the velocity field generated by the vorticity distribution.
The vorticity distribution is generated by the loads on the blade. The method of solution is iterative in our approach.
Model setup
Solution iteration.
Calculate and output the results.
The force field over the surface of the blades generates vorticity, which is convected over the surface and with the flow. We call the vorticity located over the surface of the blade as "bound vorticity". We call the vortices convected in the flow as "wake vorticity".
The presence of vorticy implies that there is a component of the velocity field which has a rotational character, even in irrotational potential flow.
The flow field can be linearly decomposed in a component associated with the vortices, and an additional flow field associated with other elements (for example, the unperturbed flow field).
To calculate the velocity component associated with the vorticity, we employ a concept from electromagnetism, appyling the Biot-Savart law to calculate the velocity "induced" by the vortex.
The velocity →uω at a point xp associated with the existing vorticity →ω can be calculated using the Bio-Savart law, expressed by the integral below.
→uω=14π∫V→ω×→r|r3|dV
Press bottom arrow for Biot-Savart law applied to a vortex filament
If the vorticity is concentrated in a curve from a point a to a point b with constant circulation Γ, the velocity →uω at a point xp can be calculated by the integral below.
→uω=Γ4π∫ba→dl×→r|r3|
The curve can be discretized in straight segments. If the vortex segment is straight, the integral below becomes a simple geometric relation.
Press right arrow for Biot-Savart law applied to a vortex filament
Change values below to change the direction and magnitude of the vortex filament. Change the location of the point to evaluate the induced velocity Xp.
Press bottom arrow for algorithm to calculate the velocity induced by a straight vortex filament.
Consider a vortex filament from point X1 to point X2, with strength Γ. The velocity at a point Xp can be calculated by the algorithm below.
R1=√(XP−X1)2+(YP−Y1)2+(ZP−Z1)2
R2=√(XP−X2)2+(YP−Y2)2+(ZP−Z2)2
R1−2X=(YP−Y1)(ZP−Z2)−(ZP−Z1)(YP−Y2)
R1−2Y=−(XP−X1)∗(ZP−Z2)+(ZP−Z1)∗(XP−X2)
R1−2Z=(XP−X1)∗(YP−Y2)−(YP−Y1)∗(XP−X2)
R1−2sqr=R1−2X2+R1−2Y2+R1−2Z2
R0−1=(X2−X1)(XP−X1)+(Y2−Y1)(YP−Y1)+(Z2−Z1)(ZP−Z1)
R0−2=(X2−X1)(XP−X2)+(Y2−Y1)(YP−Y2)+(Z2−Z1)(ZP−Z2)
K=Γ4πR1−2sqr(R0−1R1−R0−2R2)
U=K∗R1−2X ; V=K∗R1−2Y ; W=K∗R1−2Z
Source: Katz, Joseph, and Allen Plotkin. Low-speed aerodynamics. Vol. 13. Cambridge university press, 2001.
Press bottom arrow for example of code implementation of this algorithm.
// 3D velocity induced by a vortex filament
function velocity_3D_from_vortex_filament(GAMMA,XV1, XV2, XVP1,CORE){
// function to calculate the velocity induced by a straight 3D vortex filament
// with circulation GAMMA at a point VP1. The geometry of the vortex filament
// is defined by its edges: the filament starts at XV1 and ends at XV2.
// the input CORE defines a vortex core radius, inside which the velocity
// is defined as a solid body rotation.
// The function is adapted from the algorithm presented in:
// Katz, Joseph, and Allen Plotkin. Low-speed aerodynamics.
// Vol. 13. Cambridge university press, 2001.
// read coordinates that define the vortex filament
var X1 =XV1[0]; var Y1 =XV1[1]; var Z1 =XV1[2]; // start point of vortex filament
var X2 =XV2[0]; var Y2 =XV2[1]; var Z2 =XV2[2]; // end point of vortex filament
// read coordinates of target point where the velocity is calculated
var XP =XVP1[0]; var YP =XVP1[1]; var ZP =XVP1[2];
// calculate geometric relations for integral of the velocity induced by filament
var R1=Math.sqrt(Math.pow((XP-X1), 2) + Math.pow((YP-Y1), 2) + Math.pow((ZP-Z1), 2) );
var R2=Math.sqrt( Math.pow((XP-X2), 2) + Math.pow((YP-Y2), 2) + Math.pow((ZP-Z2), 2) );
var R1XR2_X=(YP-Y1)*(ZP-Z2)-(ZP-Z1)*(YP-Y2);
var R1XR2_Y=-(XP-X1)*(ZP-Z2)+(ZP-Z1)*(XP-X2);
var R1XR2_Z=(XP-X1)*(YP-Y2)-(YP-Y1)*(XP-X2);
var R1XR_SQR=Math.pow(R1XR2_X, 2)+ Math.pow(R1XR2_Y, 2)+ Math.pow(R1XR2_Z, 2);
var R0R1 = (X2-X1)*(XP-X1)+(Y2-Y1)*(YP-Y1)+(Z2-Z1)*(ZP-Z1);
var R0R2 = (X2-X1)*(XP-X2)+(Y2-Y1)*(YP-Y2)+(Z2-Z1)*(ZP-Z2);
// check if target point is in the vortex filament core,
// and modify to solid body rotation
if (R1XR_SQR < Math.pow(CORE,2)) {
R1XR_SQR=Math.pow(CORE,2);
// GAMMA = 0;
};
if (R1 < CORE) {
R1=CORE;
// GAMMA = 0;
};
if (R2 < CORE) {
R2=CORE;
// GAMMA = 0;
};
// determine scalar
var K=GAMMA/4/Math.PI/R1XR_SQR*(R0R1/R1 -R0R2/R2 );
// determine the three velocity components
var U=K*R1XR2_X;
var V=K*R1XR2_Y;
var W=K*R1XR2_Z;
// output results, vector with the three velocity components
var results = [U, V, W];
return(results) };
The blade is segmented in spanwise direction. A horseshoe vortex is colocated at each blade segment. The bound vortex is located at the quarter-chord position. At the blade, vortex segments trail the chord up to 1/4 chord, and then convect with flow velocity.
Press bottom arrow for further information on "Discretization and grid generation".
Each horseshoe is discretized in straight vortex filaments. The blade elements are discretized by three filaments: one bound at the quarter-chord line, two trailing in chord direction. According to Helmholtz theorem, the circulation Γ is constant for all filaments that compose the horseshoe. The direction of the filament defines the direction of the circulation.
Press bottom arrow for further information on "Discretization and grid generation".
Two common strategies for spanwise discretization: uniform distribution and uniform cosine distribution.
Uniform distribution: segments are equally distant. Provides a solution with faster convergence.
Uniform cosine distribution: segments are define at the cosine of a uniform angle distribution. Provides a solution with higher resolution at the root and tip, where circulation gradients are higher.
Press bottom arrow for further information on "Discretization and grid generation".
When defining the geometry of the fixed wake, you need to define the convection and expansion of the wake. We will only consider an axial convection velocity Uwake=U∞(1−aw). Assume in a first approach that aw is equal to the average induction at the rotor.
Consider that the wake is aligned in axial direction x. The location of the nodes of a filament released from a radial position r, at a given past time of t, is defined by:
xw=t⋅Uwake
yw=r⋅sinΩt
zw=r⋅cosΩt
Scroll the button below to vary the axial convection speed. aw= 0.20
Potential flow allows for a linear solution of the velocity field. Therefore, we can define a linear system to calculate the velocity induced by all horseshoe vortex rings at all control points.
Consider that we have a total of N blade sections with N controlpoints, releasing N horseshoe vortex rings. We define icp as the index of a control point at a blade element, and jring as the index of the vortex ring.
We now define the velocity "induced" by a horseshoevortex ring jring at point icp as →uicp−jring
The three velocity components of →uicp−jring in x, y and z-direction are uicp−jring, vicp−jring and wicp−jring
Because the velocity induced by a vortex is linear with the strength of the vortex, →uicp−jring=→uicp−jring|Γ=1∗Γjring, where →uicp−jring|Γ=1 is the velocity induced by a horseshoe vortex of unit strength.
The total velocity by all horseshoe vortices at one controlpoint →uicp is given by →uicp=N∑jring=1→uicp−jring=N∑jring=1→uicp−jring|Γ=1∗Γjring
Press bottom arrow to see remaining formulation of velocity components.
uicp=[uicp−1|Γ=1⋯uicp−N|Γ=1]⋅[Γ1⋮ΓN] vicp=[vicp−1|Γ=1⋯vicp−N|Γ=1]⋅[Γ1⋮ΓN] wicp=[wicp−1|Γ=1⋯wicp−N|Γ=1]⋅[Γ1⋮ΓN]
Press bottom arrow to see matrix formulation.
[u1⋮uN]=[u1−1|Γ=1…u1−N|Γ=1⋮⋱⋮uN−1|Γ=1…uN−N|Γ=1]⋅[Γ1⋮ΓN] [v1⋮vN]=[v1−1|Γ=1…v1−N|Γ=1⋮⋱⋮vN−1|Γ=1…vN−N|Γ=1]⋅[Γ1⋮ΓN] [w1⋮wN]=[w1−1|Γ=1…w1−N|Γ=1⋮⋱⋮wN−1|Γ=1…wN−N|Γ=1]⋅[Γ1⋮ΓN]
Velocity perceived at blade element: axial, tangential and total.
Circulation and forces at blade element (two dimensional): lift, drag, axial and azimuthal.
Note that all forces are in 2D, and have dimensions N/m.
Cl and Cd can be retrieved from airfoil polar data, as a function of angle of attack α.
Press bottom arrow to see an example of an airfoil polar.
function solve_lifting_line_system_matrix_approach(rotor_wake_system,wind, Omega, rotorradius) {
// this codes solves a lifting line model of a horizontal axis rotor
// as inputs, it takes
// rotor_wake_system: data structure that contains the geometry of the horseshoe vortex rings,
// and the control points at the blade
// wind: unperturbed wind velocity, also known as U_infinity
// Omega: rotational velocity of the rotor
// rotorradius: the radius of the rotor
// get controlpoints data structure
var controlpoints = rotor_wake_system.controlpoints;
// get horseshoe vortex rings data structure
var rings = rotor_wake_system.rings;
//
// initialize variables that we will use during the calculation
var velocity_induced =[]; // velocity induced by a horse vortex ring at a control point
var up = []; var vp = []; var wp = []; // components of the velocity induced by one horseshoe vortex ring
var u = 0; var v = 0; var w = 0; // total velocity induced at one control point
var radialposition; var azimdir; // radial position of the control point
var alpha; // angle of attack
var GammaNew=[]; // new estimate of bound circulation
var Gamma=[]; // current solution of bound circulation
for (var i = 0; i < controlpoints.length; i++) { GammaNew.push(0);}; // initialize as zeros
var vel1; var vmag; var vaxial; var vazim; var temploads; // velocities and loads at controlpoint
var MatrixU = new Array(); // matrix of induction, for velocity component in x-direction
var MatrixV = new Array(); // matrix of induction, for velocity component in y-direction
var MatrixW = new Array(); // matrix of induction, for velocity component in z-direction
// output variables
var a_temp = new Array(); // output vector for axial induction
var aline_temp = new Array(); // output vector for azimuthal induction
var r_R_temp = new Array(); // output vector for radial position
var Fnorm_temp = new Array(); // output vector for axial force
var Ftan_temp = new Array(); // output vector for tangential force
var Gamma_temp = new Array(); // output vector for circulation
// the variables below are to setup the maximum number of iterations and convergence criteria
var Niterations =1200;
var errorlimit = 0.01;
var error = 1.0; var refererror;
var ConvWeight =0.3;
// initalize and calculate matrices for velocity induced by horseshoe vortex rings
// two "for cicles", each line varying wind controlpoint "icp", each column varying with
// horseshoe vortex ring "jring"
for (var icp= 0; icp < controlpoints.length; icp++) {
MatrixU[icp] = new Array(); // new line of matrix
MatrixV[icp] = new Array(); // new line of matrix
MatrixW[icp] = new Array(); // new line of matrix
for (var jring = 0; jring < rings.length; jring++) {
// set ring strenth to unity, to calculate velocity induced by horseshoe vortex ring "jring"
// at controlpoint "icp"
rings[jring] = update_Gamma_sinle_ring(rings[jring],1,1);
velocity_induced = velocity_induced_single_ring(rings[jring], controlpoints[icp].coordinates);
// add compnent of velocity per unit strength of circulation to induction matrix
MatrixU[icp][jring] = velocity_induced[0];
MatrixV[icp][jring] = velocity_induced[1];
MatrixW[icp][jring] = velocity_induced[2];
};
};
// calculate solution through an iterative process
for (var kiter = 0; kiter < Niterations; kiter++) {
for (var ig = 0; ig < GammaNew.length; ig++) {
Gamma[ig] = GammaNew[ig]; //update current bound circulation with new estimate
}
// calculate velocity, circulation and loads at the controlpoints
for (var icp= 0; icp < controlpoints.length; icp++) {
// determine radial position of the controlpoint;
radialposition = Math.sqrt(math.dot(controlpoints[icp].coordinates, controlpoints[icp].coordinates));
u=0; v=0; w=0; // initialize velocity
// multiply icp line of Matrix with vector of circulation Gamma to calculate velocity at controlpoint
for (var jring = 0; jring < rings.length; jring++) {
u = u + MatrixU[icp][jring]*Gamma[jring]; // axial component of velocity
v= v + MatrixV[icp][jring]*Gamma[jring]; // y-component of velocity
w= w + MatrixW[icp][jring]*Gamma[jring]; // z-component of velocity
};
// calculate total perceived velocity
vrot = math.cross([-Omega, 0 , 0] , controlpoints[icp].coordinates ); // rotational velocity
vel1 = [wind[0]+ u + vrot[0], wind[1]+ v + vrot[1] , wind[2]+ w + vrot[2]]; // total perceived velocity at section
// calculate azimuthal and axial velocity
azimdir = math.cross([-1/radialposition, 0 , 0] , controlpoints[icp].coordinates ); // rotational direction
vazim = math.dot(azimdir , vel1); // azimuthal direction
vaxial = math.dot([1, 0, 0] , vel1); // axial velocity
// calculate loads using blade element theory
temploads = loadBladeElement(vaxial, vazim, radialposition/rotorradius);
// new point of new estimate of circulation for the blade section
GammaNew[icp] = temploads[2];
// update output vector
a_temp[icp] =(-(u + vrot[0])/wind[0]);
aline_temp[icp] =(vazim/(radialposition*Omega)-1);
r_R_temp[icp] =(radialposition/rotorradius);
Fnorm_temp[icp] =(temploads[0]);
Ftan_temp[icp] =(temploads[1]);
Gamma_temp[icp] =(temploads[2]);
}; // end loop control points
// check convergence of solution
refererror =math.max(math.abs(GammaNew));
refererror =Math.max(refererror,0.001); // define scale of bound circulation
error =math.max(math.abs(math.subtract(GammaNew, Gamma))); // difference betweeen iterations
error= error/refererror; // relative error
if (error < errorlimit) {
// if error smaller than limit, stop iteration cycle
kiter=Niterations;
}
// set new estimate of bound circulation
for (var ig = 0; ig < GammaNew.length; ig++) {
GammaNew[ig] = (1-ConvWeight)*Gamma[ig] + ConvWeight*GammaNew[ig];
}
}; // end iteration loop
// output results of converged solution
return({a: a_temp , aline: aline_temp, r_R: r_R_temp, Fnorm: Fnorm_temp, Ftan: Ftan_temp , Gamma: Gamma_temp});
};
Scroll the button below to change tip speed ratio. Tip speed ratio = 6.00
Rotor performance:
BEM | Lifting Line | |
---|---|---|
CT | 0.49 | 0.48 |
CP | 0.39 | 0.39 |
Note: The circulation Γ is non-dimensioned by U2∞πNBladesΩ
Press bottom arrow to see other examples.
Scroll the button below to change tip speed ratio. Tip speed ratio = 6.00
Rotor performance:
BEM | Lifting Line | |
---|---|---|
CT | 0.49 | 0.48 |
CP | 0.39 | 0.39 |
Note: Faxial and Fazim are non-dimensioned by 12ρU2∞R
Press bottom arrow to see other examples.
Scroll the button below to change tip speed ratio. Tip speed ratio = 6.00
Rotor performance:
BEM | Lifting Line | |
---|---|---|
CT | 0.49 | 0.48 |
CP | 0.39 | 0.39 |
While defining and placing the geometry of the vorticy system, the distribution of the vorticity system is defined by:
Press bottom arrow to see examples of the effect of discretization.
Scroll the button below to change number of spanwise elements. N = 16
Rotor performance:
BEM | Lifting Line | |
---|---|---|
CT | 0.49 | 0.48 |
CP | 0.39 | 0.39 |
Note: The circulation Γ is non-dimensioned by U2∞NBladesπΩ. Solution at tip speed ratio = 6.
Press bottom arrow to see other examples.
Scroll the button below to vary the length of the wake Lw in diameters D downstream. Lw/D = 1.29
Rotor performance:
BEM | Lifting Line | |
---|---|---|
CT | 0.49 | 0.49 |
CP | 0.39 | 0.40 |
The model of a rotor is a difficult case to verify some of the key elements of your code. As a suggestion, you can first model a single wing in straight flight. In this section, we present the case of a rectangular straight wing, at a geometric angle of attack of 5∘. The lift coefficient at each section is given by Cl=2πsinα. The effective angle of attack α is plotted below, over the span of the wing.
Scroll the button below to vary the wing's aspect ratio AR=Wingspanchord= 56.0
Number of spanwise elements = 29
To be able to program a lifting line model for application to an horizontal axis wind turbine...
Use the simulation tools to compare the two models and the terms of induction, loading, circulation, and tip speed ratio.
Use the lifting line model to calculate the 3D flow field, including the velocity at the wake.