You are on page 1of 14

% ------------------------------------------------% Aersp 312 - Honors Option

% Laminar Flow over a Flat Plate
% ------------------------------------------------clc
clear all;
close all;
% ------------------------------------------------% Constants
U = 50; % velocity [m/s]
nu = 2e-4; % kinematic viscosity [m^2/s]
rho = 1.225; % density [kg/m^3]
mu = rho*nu; % dinamic viscosity [mkg/s]
% Parameters for grid
dx = 0.0001;
x = 0.25;
nx = x/dx+1;
dy = dx;
y = 0.010;
ny = y/dy+1;
[x0,y0] = meshgrid(0:dx:x,0:dy:y);
% u and v velocities - initialization
u = zeros(nx,ny);
v = zeros(nx,ny);
% Tridiagonal Matrix Coefficients - initialization
A = ones(nx-1,ny-2);
B = ones(nx-1,ny-2);
C = ones(nx-1,ny-2);
D = ones(nx-1,ny-2);
% Temporary u-velocity - initialization
u_temp = zeros(nx,ny-2);
% Boundary conditions (flat plate starts at i=3; before it's all
% freestream)
u(1,:) = U*ones(1,ny);
u(2,:) = u(1,:);
u(:,1) = 0*ones(nx,1);
u(1,1) = U;
u(2,1) = U;
u(:,ny) = U*ones(nx,1);
% Spacial Coefficients (these are for uniform grid spacing)
Y1 = 1/(2*dy^2);
Y2 = 1/(2*dy);
Y3 = 1/(2*dy^2);
Z1 = 3/(2*dx);
Z2 = 2/dx;
Z3 = 1/(2*dx);
Z4 = 2;
Z5 = 1;
% Dynamic Pressure based upon U
q = 1/2*rho*U^2;
% BL Thickness initialization
delta = zeros(nx);
% Skin Friction coefficient initialization
Cf = zeros(nx);
% du/d initialization
dudy = zeros(nx);
nDelta=zeros(1,nx-2);
% Pressure Term (constant dp/dx)
dpdx = 0; % arbitrary pressure gradient
% Initialization of separation at zero (i.e. no separation)
separation = 0;
% Compute u and v velocities (this is where the magic happens)
for i=2:(nx-1)
iterations = 4; % number of iterations
counter = 0; % used to iterate 4 times for fixed i-position/x-position
while counter<iterations
for j=2:(ny-1)
if counter==0
% Linear Interpolation to guess u and v velocities

j)/(2*dy) + nu/(2*(dy)^2))*(u(i+1.j)) + ..j+1) = -(v(i+1.nu/(2*(dy)^2). C.B(i-1. D since the Thomas Algorithm should not change the lower and % upper B.99*U or 99% of freestream velocity if ((u(i+1.j)/(2*dx))*(u(i-1. % goes to the next iteration end j = 1. else C(i-1..*(dudy(i+1)). Cf(i+1) = mu.j)/(2*dx))*(u(i-1. delta(i+1)=j*dy. (-v(i+1. for i=2:(nx-2) .k).j-1) = -(u(i+1.j).j)-Z5*u(i-1.:).1)).j+1) = v(i+1. k = 1..j)-Z2*u(i.C(i-1.j)>=0. end counter = counter + 1.j)-Z2*u(i.j-1) = 3*u(i+1.j) = u_temp(i+1. (v(i+1.j-1)-(Z1*u(i+1.:) = ThomasAlg(A(i-1. % used to match right indices of u_temp and u for j=2:(ny-1) % Compute horizontal velocity u(i+1.j)/(2*dx) + (nu)/(dy)^2. % Computation of BL for numerical solution % Limit of BL is set at 0.j-1) = 0.. v(i+1. % C-coefficient if j==(ny-1) C(i-1.nx).j)+Z3*u(i-1.j)-4*u(i.'s for the uvelocity u_temp(i+1./q.j)/(2*dy) + nu/(2*(dy)^2))*(u(i+1.:).j)).% This assumption is used for the first iteration only u(i+1. dudy(i+1) = (-3*u(i+1. else A(i-1. B.1) = 0.j+2))/(2*dy).ny)).j-1)-(Z1*u(i+1..j-1) = -(u(i+1.j)/(2*dx))*(u(i-1. u_temp. else D(i-1. % v(i+1.:). End % Displacement and Momentum Thicknesses dispTh=zeros(1.D(i-1.j-1) = -(u(i+1.j)/(2*dy) . end end for j=2:(ny-1) % Compute vertical velocity v(i+1. end if ((u(i+1. end end % Call ThomasAlg function % Note: used a dummy variable.C.j)+Z3*u(i-1.j)/(2*dy) .99*50)&&delta(i+1)==0) nDelta(i+1)=j.:)). k = k+1..j))/Y2).j)+4*u(i+1.j-1) = v(i+1.j-1) = -v(i+1.j))/Y2.j) = Z4*u(i.j)-4*u(i.nu/(2*(dy)^2). end % Tridiagonal Matrix Coefficients % A-coefficient if j==2 A(i-1. momTh=zeros(1.j)-4*u(i.j+1)-u(i+1.j).j)-Z5*v(i-1. end if j==(ny-1) D(i-1. end % B-coefficient B(i-1.j) = Z4*v(i.j)) + .j)<=0)&&separation==0) separation=i*dx. to match dimensions of % A.nx). end % D-coefficient if j==2 D(i-1. -1/rho*dpdx.

Y0] = meshgrid(0:dx:x.721. momThBS = 0. Numerical Solution') xlabel('Flat Plate Distance from LE [m]') ylabel('Cf [unitless]') hold on % Percentage Error for BL errorBL = zeros(1..'Numerical Solution') title('BL Thickness .Y0.Z) hold on length = 0:dx:x. errormt = zeros(1.1)-temp2(1.664.*length+0.664.0:dy:y). Y = y0'.Blasius Solution vs.1)-temp1(1.i) = 0.i) = 0. % length of flat plate discretized into nx points % Blasius Solution vs.dispTh./nu). figure(2) Z = u'.lim = nDelta(i)./((U.lim). for i=1:nx errorBL(1. temp1 = zeros(1.i) = 0.'Momentum Thickness Blasius') xlabel('Flat Plate Distance from LE [m]') ylabel('thickness [m]') % Skin Friction Coefficient plot % Skin Friction Coefficient for the Blasius Solution CfBS = 0. contour(X0.nx).length.nx).length. V0 = v./(dispThBS(i)))*100. if(lim>1) for j=1:lim temp1(1.0000001 is used to avoid discontinuities at the leading edge dispThBS = 1.0000001).length.1)/(lim-1))*(2*sum(temp2)-temp2(1. figure(5) plot(length.Cf) legend('Blasius Solution'./((U.lim)).j) = (u(i.'Momentum Thickness Numerical'..*length.0000001).nx).lim)).j) = 1-(u(i./((U. % the 0. errorCf = zeros(1./(deltaBS(i)))*100./((U. end dispTh(1. figure(3) plot(length. momTh(1.momTh.V0) hold on % Contour Plot of u velocity (should be able to see result better with % this contour plot) [X0.^(1/2).*length+0.*length. temp2(1.*length+0. figure(1) quiver(X.Blasius Solution vs.deltaBS.length.momThBS) legend('Displacement Thickness Numerical'.j))/U)/U.*length. end end % Velocity Plots % Vector Plot of u velocity (may not be able to visualize result very well) X = x0'. .j))/U.j))*(1-(u(i.0000001).U0./nu)./nu).^(1/2). U0 = u.i) = abs((deltaBS(i)-delta(i)). Numerical Solution') xlabel('Flat Plate Distance from LE [m]') ylabel('BL thickness [m]') hold on figure(4) plot(length.5*(delta(i.1). Numerical Solution Plot % BL thickness calculated using the Blasius Solution (BS) deltaBS = 5.length.i) = abs((dispThBS(i)-dispTh(i)).lim). errordt = zeros(1. 'Displacement Thickness Blasius'.CfBS..dispThBS.^(1/2).nx).1)/(lim-1))*(2*sum(temp1)-temp1(1.^(1/2). temp2 = zeros(1. errordt(1.'Numerical Solution') title('Skin Friction Coefficient .delta) legend('Blasius Solution'. else dispTh(1.Y./nu).5*(delta(i.*length+0. momTh(1.i) = 0.

for i=N-1:-1:1 u(i) = D(i)-C(i)*u(i+1).. C.. % Modify the first-row coefficients C(1) = C(1)/B(1). Numerical Solution') xlabel('Flat Plate Distance from LE [m]') ylabel('Percent Error') % code ends here ThomasAlg.errormt.'Momentum Thickness'.. % Division by zero risk.Blasius Solution vs.length. errorCf(1. end end Option Explicit Option Base 1 Public oplist As Variant Public global_x() As Single Public global_y() As Single Public global_u() As Single Public global_v() As Single Public global_Cf() As Single Public global_St() As Single Public global_gamma() As Single Public global_T() As Single Public global_rho() As Single . D ) %THOMASALG executes the Thomas Algorithm on a tridiagonal matrix N = length(A).m: function [ u ] = ThomasAlg( A. 'Skin Friction Coefficient') title('Percent Error . B. D(i) = (D(i)-A(i)*D(i-1))/temp.errorCf) legend('BL Thickness'.'Displacement Thickness'. C(i) = C(i)/temp. for i=2:(N-1) temp = B(i)-A(i)*C(i-1).errorBL. D(1) = D(1)/B(1). end hold off % Percentage Error Graphs figure(6) plot(length. % Back substitution u(N) = D(N).i) = abs((momThBS(i)-momTh(i))./(CfBS(i)))*100.errordt.length. end D(N) = (D(N)-A(N)*D(N-1))/(B(N)-A(N)*C(N-1)).length./(momThBS(i)))*100.i) = abs((CfBS(i)-Cf(i)).errormt(1.

u() As Single. dx As Single. _ rho As Single. delta() As Single. xi As Single. yod As Single 'Calculate kinematic viscosity nu = mu / rho 'm is number of stations in streamwise (x) direction m = UBound(vxy0) 'n is number of stations across boundary layer (y) n = UBound(ux0y) 'Allocate space for arrays . c() As Single. deltind() As Single. v() As Single. REx As Single. n As Integer. '********************************************* 'Declare variables '********************************************* Dim m As Integer. j As Integer Dim z As Integer. vx0y() As Single. check As Integer Dim turb As Boolean. dy As Single. d() As Single Dim u_iter() As Single. 'Implicit scheme is implemented. nu As Single Dim a() As Single. b() As Single. wallshear() As Single Dim a1 As Single. cn As Single. x() As Single. Ue() As Single. msg As String Dim del As Single.Public global_delta() As Single Public global_T_delta() As Single Public Sub SIL_UV(ux0y() As Single. Incompressible. cf() As Single. y() As Single. i As Integer. mu As Single. auto As Boolean) '********************************************* 'Solution for Steady. vxy0() As Single. 'Solution for temperature distribution is implemented separately. Laminar boundary layer flow 'Velocity solution only.

ReDim u(n. cf(m) ReDim a(n . wallshear(m). m).3).1) * dy / del If yod > 1 Then u(j.5 * yod . delta(m). d(n . inlet conditions If auto Then 'If user asks for auto velocity profile use cubic 'If starting at x=0.2). 1) = Ue(1) Else u(j. Ue(1).5 * yod ^ 3) End If v(j. u_iter(n . then no profile If xi > 0 Then del = EST_DELTA(xi. m). 1) = 0 Next j Else . i) = 0 v(1.3). v(n.2). nu) For j = 1 To n yod = (j . b(n . deltind(m). i) = Ue(i) Next i 'Next.0. c(n . 1) = Ue(1) * (1. i) = vxy0(i) u(n.2) '********************************************* 'Insert boundary conditions in matrices '********************************************* 'First. wall conditions and free-stream conditions For i = 1 To m u(1.

1) = Ue(1) v(j.For j = 1 To n u(j.value = i '********************************************* 'NSLx yields streamwise velocity (u) distribution.2 'lower diagonal . x(i + 1) = x(i) + dx 'matrix elements for TDMA For j = 2 To n . 1) = vx0y(j) Next j End If 'initialize x and y arrays x(1) = xi y(1) = 0 '********************************************* 'Start moving downstream '********************************************* For i = 1 To m . 1) = ux0y(j) v(j.progbar.1 'Update progress bar fm_progress. 1) = 0 Next j End If Else For j = 1 To n u(j.

b. i) / (2 * dy) .cn * u(n. Results beyond that point may not be valid.nu / dy ^ 2 d(n . d) '********************************************* 'Check for transition to turbulence REx<10^6 REx = Ue(i) * x(i) / nu If REx > 1000000# And Not turb Then turb = True msg = "Warning! Transition to turbulence at x = " & x(i) _ & ".2) = (u(n .Ue(i) ^ 2) / (2 * dx) .a1 * u(1. i) ^ 2) / dx + (Ue(i + 1) ^ 2 . i) / (2 * dy) .nu / ((dy) ^ 2) 'main diagonal b(j . i) / (2 * dy) . i) / dx + 2 * nu / ((dy) ^ 2) 'modify first element and add last element to 'right side vector a1 = -1 * v(2.1) = (u(j.1. a.Ue(i) ^ 2) / (2 * dx) Next j 'add last element to main diagonal b(n .2) = u(n .1. i) ^ 2) / dx + (Ue(i + 1) ^ 2 .1) = -1 * v(j + 1. i + 1) 'Solve for u(i+1) using TDMA u_iter = TDMA(c.nu / ((dy) ^ 2) 'upper diagonal c(j . i + 1) cn = v(n . vbOKCancel) .1. i) / dx + 2 * nu / ((dy) ^ 2) 'right side vector d(j .nu / dy ^ 2 d(1) = d(1) .a(j .1) = v(j. i) / (2 * dy) .1) = u(j." check = MsgBox(msg.

u(j .If check = 2 Then Exit Sub End If '********************************************* 'Record wall shear.1) * dx Unload fm_progress Exit Sub End If '********************************************* 'Transfer values into u matrix and record boundary layer thickness For z = 2 To n .5 * rho * Ue(i) ^ 2) If wallshear(i) < 0.1) > 0. i + 1) .1) If u_iter(z . i + 1) = v(j . i)) y(j) = y(j . For j = 2 To n v(j. i) + u(j .u(3.1 u(z.99 * Ue(i) And deltind(i + 1) = 0 Then deltind(i + 1) = z delta(i + 1) = z * dy End If Next z '********************************************* 'COM yields transverse velocity (v) distribution. skin friction and check for separation wallshear(i) = mu / (2 * dy) * (4 * u(2. i + 1) = u_iter(z . i + 1) .1) + dy . i)) cf(i) = wallshear(i) / (0.u(j.1.dy / (2 * dx) * _ (u(j.1.1.0001 Then MsgBox "Separation occurs at x=" & (i . i) . i + 1) .

nu As Single. rho As Single.Next j Next i '********************************************* 'Store the data '********************************************* 'store_uv_data x. delta. Txy0() As Single. cf Erase a. dy As Single) '********************************************* 'Solution for Steady. b. dx As Single. Incompressible. v() As Single. cp As Single. 'Solution for velocity distribution is implemented separately. 'Implicit scheme is implemented. y End Sub Public Sub SIL_T(u() As Single. Requires velocity solution as input. y. u_iter Erase x. c. wallshear. 'Temperature solution only. deltind. Tx0y() As Single. . d. v. v. u. cf global_x = x global_y = y global_u = u global_v = v global_delta = delta global_Cf = cf '********************************************* 'Recover memory '********************************************* Erase u. Laminar boundary layer flow. _ xi As Single. delta. k As Single. Te() As Single.

'********************************************* Dim m As Integer.3). T_delta() As Single Dim x() As Single. T_del_flag As Boolean Dim T_deltaind() As Integer.2) ReDim T_deltaind(m). n As Integer. d(n . alpha As Single. cn As Single Dim T_iter() As Single. T_delta(m) ReDim x(m). b(n . m) ReDim a(n . c() As Single. T_iter(n . y() As Single 'alpha is thermal diffusivity alpha = k / (rho * cp) 'm is number of stations in streamwise (x) direction m = UBound(Txy0) 'n is number of stations across boundary layer (y) n = UBound(Tx0y) 'Dimension arrays ReDim T(n. j As Integer Dim T() As Single. y(n) 'Construct x and y arrays x(1) = xi For i = 2 To m x(i) = x(i . c(n .1) + dx Next i y(1) = 0 For j = 2 To n .2). b() As Single.3). z As Integer Dim a() As Single.2). d() As Single Dim a1 As Single. i As Integer.

value = m + i '********************************************* 'COE yields temperature distribution. 'matrix elements For j = 2 To n . 1) = Tx0y(j) Next j '********************************************* 'Start moving downstream '********************************************* For i = 1 To m .y(j) = y(j . wall conditions and free-stream conditions For i = 1 To m T(1.2 'lower diagonal a(j .1 fm_progress.alpha / dy ^ 2 'upper diagonal .progbar. inlet conditions For j = 1 To n T(j. i) = Txy0(i) T(n.1) + dy Next j '********************************************* 'Insert boundary conditions in matrix '********************************************* 'First. i) = Te(i) Next i 'Next. i) / (2 * dy) .1) = -1 * v(j + 1.

a.c(j . i + 1) cn = v(n . i) / dx + nu / cp * ((u(n.1.1)) < 0. i) .1.T_iter(j . b.2) = u(n . i) / (2 * dy) .alpha / dy ^ 2 d(n . i) / dx + nu / cp * ((u(j + 1.T_iter(j .1. i) .2. i + 1) = T_iter(j .2) = u(n .1.1)) >= 0. d) 'Transfer values into T matrix and mark position of boundary layer T_del_flag = False For j = 2 To n .1) = v(j.01 * Te(i) Then T_del_flag = True ElseIf T_del_flag And Abs(Te(i) . i + 1) 'Solve for T(i+1) using TDMA T_iter = TDMA(c. i) / (2 * dy) .a1 * T(1. i)) / (2 * dy)) ^ 2 cn * T(n. i)) / (2 * dy)) ^ 2 Next j 'add last element to main diagonal b(n .alpha / dy ^ 2 'main diagonal b(j .1) = u(j.01 * Te(i) And T_deltaind(i + 1) = 0 Then T_deltaind(i + 1) = j T_delta(i + 1) = j * dy .u(n .1) = u(j. i) / dx + 2 * alpha / dy ^ 2 'modify first element and add last element to 'right side vector a1 = -1 * v(2. i) * T(j.1. i) * T(n . i) / dx + 2 * alpha / dy ^ 2 'right side vector d(j . i) / (2 * dy) .u(j .1) If Abs(Te(i) .1 T(j.alpha / dy ^ 2 d(1) = d(1) .

d As Single 'Esimate boundary layer thickness using Blasius equation REx = u * x / nu d = x * 5 / Sqr(REx) EST_DELTA = d End Function . b.End If Next j Next i '********************************************* 'Store the data '********************************************* 'store_T_data x. nu As Single) As Single Dim REx As Single. T_delta Erase x. T_delta global_T = T global_T_delta = T_delta '********************************************* 'Recover memory '********************************************* Erase T Erase a. d. y. u As Single. T_iter Erase T_deltaind. y End Sub Public Function EST_DELTA(x As Single. T. c.