Sunteți pe pagina 1din 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

% This assumption is used for the first iteration only


u(i+1,j) = Z4*u(i,j)-Z5*u(i-1,j);
v(i+1,j) = Z4*v(i,j)-Z5*v(i-1,j);
end
% Tridiagonal Matrix Coefficients
% A-coefficient
if j==2
A(i-1,1) = 0;
else
A(i-1,j-1) = -v(i+1,j)/(2*dy) - nu/(2*(dy)^2);
end
% B-coefficient
B(i-1,j-1) = 3*u(i+1,j)/(2*dx) + (nu)/(dy)^2;

% C-coefficient
if j==(ny-1)

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

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

errormt(1,i) = abs((momThBS(i)-momTh(i))./(momThBS(i)))*100;
errorCf(1,i) = abs((CfBS(i)-Cf(i))./(CfBS(i)))*100;
end
hold off
% Percentage Error Graphs
figure(6)
plot(length,errorBL,length,errordt,length,errormt,length,errorCf)
legend('BL Thickness','Displacement Thickness','Momentum Thickness',...
'Skin Friction Coefficient')
title('Percent Error - Blasius Solution vs. Numerical Solution')
xlabel('Flat Plate Distance from LE [m]')
ylabel('Percent Error')
% code ends here

ThomasAlg.m:

function [ u ] = ThomasAlg( A, B, C, D )
%THOMASALG executes the Thomas Algorithm on a tridiagonal matrix

N = length(A);
% Modify the first-row coefficients
C(1) = C(1)/B(1); % Division by zero risk.
D(1) = D(1)/B(1);
for i=2:(N-1)
temp = B(i)-A(i)*C(i-1);
C(i) = C(i)/temp;
D(i) = (D(i)-A(i)*D(i-1))/temp;
end
D(N) = (D(N)-A(N)*D(N-1))/(B(N)-A(N)*C(N-1));
% Back substitution
u(N) = D(N);
for i=N-1:-1:1
u(i) = D(i)-C(i)*u(i+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

Public global_delta() As Single


Public global_T_delta() As Single
Public Sub SIL_UV(ux0y() As Single, vx0y() As Single, vxy0() As Single, Ue() As
Single, mu As Single, _
rho As Single, xi As Single, dx As Single, dy As Single, auto As Boolean)
'*********************************************
'Solution for Steady, Incompressible, Laminar boundary layer flow
'Velocity solution only.
'Solution for temperature distribution is implemented separately.
'Implicit scheme is implemented.
'*********************************************
'Declare variables
'*********************************************
Dim m As Integer, n As Integer, i As Integer, j As Integer
Dim z As Integer, u() As Single, v() As Single, nu As Single
Dim a() As Single, b() As Single, c() As Single, d() As Single
Dim u_iter() As Single, deltind() As Single, delta() As Single, wallshear() As Single
Dim a1 As Single, cn As Single, cf() As Single, REx As Single, check As Integer
Dim turb As Boolean, x() As Single, y() As Single, msg As String
Dim del 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

ReDim u(n, m), v(n, m), deltind(m), delta(m), wallshear(m), cf(m)


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

For j = 1 To n
u(j, 1) = Ue(1)
v(j, 1) = 0
Next j
End If
Else
For j = 1 To n
u(j, 1) = ux0y(j)
v(j, 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
'Update progress bar
fm_progress.progbar.value = i
'*********************************************
'NSLx yields streamwise velocity (u) distribution.
x(i + 1) = x(i) + dx
'matrix elements for TDMA
For j = 2 To n - 2
'lower diagonal

a(j - 1) = -1 * v(j + 1, i) / (2 * dy) - nu / ((dy) ^ 2)


'upper diagonal
c(j - 1) = v(j, i) / (2 * dy) - nu / ((dy) ^ 2)
'main diagonal
b(j - 1) = u(j, i) / dx + 2 * nu / ((dy) ^ 2)
'right side vector
d(j - 1) = (u(j, i) ^ 2) / dx + (Ue(i + 1) ^ 2 - Ue(i) ^ 2) / (2 * dx)
Next j
'add last element to main diagonal
b(n - 2) = u(n - 1, i) / dx + 2 * nu / ((dy) ^ 2)
'modify first element and add last element to
'right side vector
a1 = -1 * v(2, i) / (2 * dy) - nu / dy ^ 2
d(1) = d(1) - a1 * u(1, i + 1)
cn = v(n - 1, i) / (2 * dy) - nu / dy ^ 2
d(n - 2) = (u(n - 1, i) ^ 2) / dx + (Ue(i + 1) ^ 2 - Ue(i) ^ 2) / (2 * dx) - cn * u(n, i + 1)
'Solve for u(i+1) using TDMA
u_iter = TDMA(c, a, b, 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) _
& ". Results beyond that point may not be valid."
check = MsgBox(msg, vbOKCancel)

If check = 2 Then Exit Sub


End If
'*********************************************
'Record wall shear, skin friction and check for separation
wallshear(i) = mu / (2 * dy) * (4 * u(2, i) - u(3, i))
cf(i) = wallshear(i) / (0.5 * rho * Ue(i) ^ 2)
If wallshear(i) < 0.0001 Then
MsgBox "Separation occurs at x=" & (i - 1) * dx
Unload fm_progress
Exit Sub
End If
'*********************************************
'Transfer values into u matrix and record boundary layer thickness
For z = 2 To n - 1
u(z, i + 1) = u_iter(z - 1)
If u_iter(z - 1) > 0.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.
For j = 2 To n
v(j, i + 1) = v(j - 1, i + 1) - dy / (2 * dx) * _
(u(j, i + 1) - u(j, i) + u(j - 1, i + 1) - u(j - 1, i))
y(j) = y(j - 1) + dy

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

'*********************************************
Dim m As Integer, n As Integer, i As Integer, j As Integer
Dim T() As Single, alpha As Single, z As Integer
Dim a() As Single, b() As Single, c() As Single, d() As Single
Dim a1 As Single, cn As Single
Dim T_iter() As Single, T_del_flag As Boolean
Dim T_deltaind() As Integer, T_delta() As Single
Dim x() As Single, 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, m)
ReDim a(n - 3), b(n - 2), c(n - 3), d(n - 2), T_iter(n - 2)
ReDim T_deltaind(m), T_delta(m)
ReDim x(m), y(n)
'Construct x and y arrays
x(1) = xi
For i = 2 To m
x(i) = x(i - 1) + dx
Next i
y(1) = 0
For j = 2 To n

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

c(j - 1) = v(j, i) / (2 * dy) - alpha / dy ^ 2


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

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