Question

In: Mechanical Engineering

Develop MATLAB codes for Blade Element Momentum Theory for horizontal axis tidal turbine for airfoil NACA...

Develop MATLAB codes for Blade Element Momentum Theory for horizontal axis tidal turbine for airfoil NACA 0015, analyzing the performance of the turbine; power.

Solutions

Expert Solution

function [cl,cd,phi,aoa,a,ap]=BEM(airfoils,blade,turbine,fastout,vel)
%% [cl,cd,phi,aoa,a,ap]=BEM(airfoils,blade,turbine,fastout,vel) -> BEM theory.
%
% Function computes spanwise and rotor performance and loads via blade
% element momentum theory. Includes corrections for skewed flow and 
% heavily loaded rotors.
% 
% ****Input(s)****
% airfoils  Structure containing airfoil performance tables
% blade     Structure containing blade geometry
% turbine   Structure containing turbine geometry
% fastout   Structure containing time-dependent kinematics
% vel       Structure containing velocity components in inertial and blade
%           coordinate systems
% 
% ****Output(s)****
% cl        Spanwise lift coefficient
% cd        Spanwise drag coefficient
% phi       Spanwise inflow angle
% aoa       Spanwise angle of attack
% a         Spanwise axial induction factor
% ap        Spanwise tangential induction factor
%% Preallocate space for variables within loop
%Determine size of test vectors/arrays
ns=length(blade.RNodes);
nt=length(fastout.Time); %Number of timesteps
na=length(airfoils.Names);
RNodes=blade.RNodes;
Chord=blade.Chord;
NFoil=blade.NFoil;

a0=zeros(ns,nt); %Old (previous iteration) axial induction factor
ap0=zeros(ns,nt); %Old (previous iteration) tangential induction factor
phi=zeros(ns,nt); %Local inflow angle
aoa=zeros(ns,nt); %Local angle of attack
cl=zeros(ns,nt); %Local lift coefficient
cd=zeros(ns,nt); %Local drag coefficient
ct=zeros(ns,nt); %Local thrust coefficient
ftip=zeros(ns,nt); %Tip loss factor
fhub=zeros(ns,nt); %Hub loss factor
f=zeros(ns,nt); %Total loss corection factor
fiter=zeros(ns,nt); %Converence flag for gridpoints ('1' if converged, '9999' if not)

%% Define convergence criteria
tol=1e-6; %Convergence tolerance
da=ones(ns,nt); %Set initial value for axial induction factor residual equal to 1
dap=ones(ns,nt); %Set initial value for tangential induction factor residual equal to 1

ncv=find(da>tol | dap>tol); %Identify all nonconverged points (all initially)
miter=5000; %Maximum number of allowable iterations
wt=0.1; %Weighting factor on corrections to balance speed with stability (faster as you 
        %approach 1, but less stable)

%% Compute relevant velocity/angle components
Uinf=sqrt(sum(vel.relhub.^2,2));
Om=fastout.RotSpeed*(2*pi/60);

twst=-blade.AeroTwst*pi/180;
ptch=fastout.BldPitch1*pi/180;

rP=-fastout.PtfmPitch*pi/180; %Rotor pitch (vector, wrt time)
rY=(fastout.PtfmYaw+fastout.NacYaw)*pi/180; %Rotor yaw (vector, wrt time)
if sign(rP)==0
    sp=sign(rY);
elseif sign(rY)==0
    sp=sign(rP);
else
    sp=sign(rP).*sign(rY);
end
gamma=sp.*acos(cos(rP).*cos(rY)); %Total skew angle
psi=pi-atan2(cos(rP).*sin(rY),sin(rP)); %Total azimuthal angle of skew

%% Compute initial guesses of key variables
Om=repmat(Om',ns,1);
Uinf=repmat(Uinf',ns,1);
ptch=repmat(ptch',ns,1);
gamma=repmat(gamma',ns,1);
psi=repmat(psi',ns,1);
twst=repmat(twst,1,nt);
sigmap=repmat(turbine.NumBl.*Chord./(2.*pi.*RNodes),1,nt); %Local solidity
RNodes=repmat(RNodes,1,nt);
lambdar=Om.*RNodes./Uinf; %Local speed ratio


% Initial values for axial and tangential induction factors
a=real(0.25*(2+pi*lambdar.*sigmap-sqrt(4-4*pi*lambdar.*sigmap+pi*lambdar.^2.*sigmap.* ...
    (8*(twst+ptch)+pi*sigmap))));
ap=zeros(size(a));

%% Primary loop for BEM

for j=1:200
    
    % Save previous values of axial and tangential induction factors
    a0(ncv)=a(ncv);
    ap0(ncv)=ap(ncv);
    
    % Compute inflow angle and angle of attack
    phi(ncv)=atan2(Uinf(ncv).*(1-a(ncv)),Om(ncv).*RNodes(ncv).*(1+ap(ncv)));    
    aoa(ncv)=(phi(ncv)-(twst(ncv)+ptch(ncv)))*180/pi;
    
    % Interpolate over airfoil database for lift and drag coefficients
    for k=1:na
        cl(NFoil==k,:)=interp1(airfoils.profiles(k,1).AoA,airfoils.profiles(k,1).Cl, ...
            aoa(NFoil==k,:));
        cd(NFoil==k,:)=interp1(airfoils.profiles(k,1).AoA,airfoils.profiles(k,1).Cd, ...
            aoa(NFoil==k,:));
    end
    
    % Compute elemental thrust coefficient
    ct(ncv)=sigmap(ncv).*(1-a(ncv)).^2.*(cl(ncv).*cos(phi(ncv))+cd(ncv).*sin(phi(ncv)))./ ...
        sin(phi(ncv)).^2;
    
    % Compute loss correction factor due to tip and hub losses
    ftip(ncv)=2./pi.*acos(exp(-(turbine.NumBl.*(blade.TipRad-RNodes(ncv))./ ...
        (2.*RNodes(ncv).*sin(phi(ncv)))))); %Tip loss factor
    fhub(ncv)=2./pi.*acos(exp(-(turbine.NumBl.*(RNodes(ncv)-blade.HubRad)./ ...
        (2*blade.HubRad.*sin(phi(ncv)))))); %Hub loss factor
    f(ncv)=fhub(ncv).*ftip(ncv); %Total loss correction factor
    
    % Compute axial induction factor using conventional BEM theory
    a(ncv)=real((1+4.*f(ncv).*sin(phi(ncv)).^2./(sigmap(ncv).*(cl(ncv).*cos(phi(ncv))+ ...
        cd(ncv).*sin(phi(ncv))))).^-1);
    
    % Identify highly loaded gridpoints (requires use of modified Glauert correction for 
    % axial induction factor)
    ncvf=find(ct>0.96*f & (da>tol | dap>tol));
    
    % Compute axial induction factor using modified Glauert correction (on identified gridpoints)
    a(ncvf)=real((18.*f(ncvf)-20-3.*sqrt(ct(ncvf).*(50-36.*f(ncvf))+12.*f(ncvf).* ...
        (3.*f(ncvf)-4)))./(36.*f(ncvf)-50));
    
    % Compute tangential induction factor
    ap(ncv)=(4.*f(ncv).*cos(phi(ncv)).*sin(phi(ncv))./(sigmap(ncv).*(cl(ncv).*sin(phi(ncv)) ...
        -cd(ncv).*cos(phi(ncv))))-1).^-1;
    
    %  Apply skewed wake correction if flow is non-axial
    if abs(gamma)>1e-8;
        a(ncv)=a(ncv).*(1+15*pi/32.*RNodes(ncv)./blade.TipRad.*tan(0.5.*(0.6.*a(ncv)+1).* ...
            gamma(ncv)).*cos(psi(ncv)));
    end
    
    % Compute residuals
    da(ncv)=abs(a0(ncv)-a(ncv));
    dap(ncv)=abs(ap0(ncv)-ap(ncv));
    
    % Apply corrective weighting for convergence stability
    if wt>0
        a(ncv)=a0(ncv)+wt.*(a(ncv)-a0(ncv));
        ap(ncv)=ap0(ncv)+wt.*(ap(ncv)-ap0(ncv));
    end

    % Clear all gridpoint flags in preparation for next loop
    clear ncv ncvf ncvcl ida idap
    
    % Identify nonconverged gridpoints
    ncv=find(da>tol | dap>tol);
    
    % If all points meet convergence criteria, break loop
    if isempty(ncv)
        break
    end
    
    % If maximum allowable iterations has been reached, flag nonconverged gridpoints 
    % with '9999'
    if j==miter
        fiter(ncv)=9999;
    else
        fiter(ncv)=j;
    end
end

Related Solutions

An airfoil profile to be used on a wind turbine blade is tested in a wind...
An airfoil profile to be used on a wind turbine blade is tested in a wind tunnel. The prototype (full-scale) airfoil section has a chord length of 2m and moves at 50 m/s relative to the wind, the wind tunnel model has a chord length of 0.4m. The temperature for the model test is the same as for prototype operation. (a) What criterion should be used to obtain dynamic similarity in the experiment? (Write out the criterion in an equation.)...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT