0% found this document useful (0 votes)
2 views

Matlab Codes

The document outlines the implementation of various computational fluid dynamics (CFD) methods, including SIMPLER and SIMPLEC algorithms for simulating compressible and incompressible flows over an airfoil shape. It details the setup of the computational grid, boundary conditions, and the iterative solution process for velocity and pressure fields. The results are visualized using quiver plots to illustrate the flow patterns around the airfoil in different flow regimes.

Uploaded by

uzmaanistakkalki
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Matlab Codes

The document outlines the implementation of various computational fluid dynamics (CFD) methods, including SIMPLER and SIMPLEC algorithms for simulating compressible and incompressible flows over an airfoil shape. It details the setup of the computational grid, boundary conditions, and the iterative solution process for velocity and pressure fields. The results are visualized using quiver plots to illustrate the flow patterns around the airfoil in different flow regimes.

Uploaded by

uzmaanistakkalki
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 47

SIMPLER for Compressible Hyperbolic Flow (Euler-like)

clc; clear;

% Grid setup

nx = 100; ny = 50;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Flow properties

gamma = 1.4;

rho = ones(nx+2, ny+2);

u = ones(nx+1, ny+2); % staggered u

v = zeros(nx+2, ny+1); % staggered v

p = ones(nx+2, ny+2); % pressure

E = p./((gamma - 1) * rho); % total energy

% Airfoil mask (simple ellipse)

cx = Lx/2; cy = Ly/2; rx = 0.1; ry = 0.05;

airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;

% Solver parameters

maxIter = 1000;

tolerance = 1e-5;

alpha_p = 0.3;

alpha_u = 0.7;

for iter = 1:maxIter

u_old = u; v_old = v; p_old = p;


% Boundary Conditions

u(1,:) = 1.0; % Inlet

u(end,:) = u(end-1,:); % Outlet (Neumann)

u(:,[1 end]) = 0; v(:,[1 end]) = 0;

% Apply mask (airfoil no-penetration)

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i)

u(i,j) = 0; v(i,j) = 0;

end

end

end

% --- Momentum update (Euler equations) ---

for i = 2:nx

for j = 2:ny+1

if airfoil(j,i), continue; end

dpdx = (p(i+1,j) - p(i-1,j)) / (2*dx);

u(i,j) = u(i,j) - alpha_u * dpdx / rho(i,j);

end

end

for i = 2:nx+1

for j = 2:ny

if airfoil(j,i), continue; end

dpdy = (p(i,j+1) - p(i,j-1)) / (2*dy);

v(i,j) = v(i,j) - alpha_u * dpdy / rho(i,j);

end

end
% --- Pressure correction (SIMPLER style) ---

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i), continue; end

div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) - v(i,j))/dy);

p(i,j) = p(i,j) + alpha_p * rho(i,j) * div;

end

end

% --- Convergence check ---

err = max([max(max(abs(u - u_old))), max(max(abs(p - p_old)))]);

if err < tolerance

disp(['Converged in ', num2str(iter), ' iterations']);

break;

end

end

% --- Plot velocity field ---

u_plot = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_plot = 0.5 * (v(:,1:end-1) + v(:,2:end));

u_plot(airfoil) = NaN;

v_plot(airfoil) = NaN;

figure;

quiver(X', Y', u_plot, v_plot, 'k');

hold on;

contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);

xlabel('X'); ylabel('Y');

title('SIMPLER - Euler-like Compressible Flow (Hyperbolic)');

axis equal;
Parabolic

clc; clear;

% Domain and grid

nx = 100; ny = 50;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Physical parameters

rho = 1.0; mu = 1.5e-5;

dt = 0.001; t_end = 1; nt = round(t_end/dt);

Re = 1000;

% Initialize variables

u = zeros(nx+1, ny+2); % u-velocity

v = zeros(nx+2, ny+1); % v-velocity

p = zeros(nx+2, ny+2); % pressure

% Airfoil-like ellipse mask

cx = Lx/2; cy = Ly/2; rx = 0.1; ry = 0.05;

airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;

% Relaxation factors

alpha_p = 0.3;

alpha_u = 0.7;
% Time-stepping loop (parabolic)

for time = 1:nt

u_old = u; v_old = v; p_old = p;

% --- Boundary conditions ---

u(1,:) = 1.0; % Inlet

u(end,:) = u(end-1,:); % Outlet

u(:,[1 end]) = 0;

v(:,[1 end]) = 0;

v(1,:) = 0; v(end,:) = 0;

% --- Apply airfoil mask (no-slip) ---

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i)

u(i,j) = 0;

v(i,j) = 0;

end

end

end

% --- Pressure prediction (from continuity) ---

div_uv = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

div_uv(i,j) = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) - v(i,j))/dy);

end

end

p = p + alpha_p * rho * div_uv;


% --- Momentum equations (explicit time update) ---

for i = 2:nx

for j = 2:ny+1

if airfoil(j,i), continue; end

du2dx = (u(i+1,j)^2 - u(i-1,j)^2)/(2*dx);

duvdy = ((u(i,j+1)+u(i,j))*(v(i,j+1)+v(i+1,j+1)) - (u(i,j)+u(i,j-1))*(v(i,j-1)+v(i+1,j-1))) / (4*dy);

dpdx = (p(i+1,j) - p(i,j))/dx;

d2udx2 = (u(i+1,j) - 2*u(i,j) + u(i-1,j)) / dx^2;

d2udy2 = (u(i,j+1) - 2*u(i,j) + u(i,j-1)) / dy^2;

u(i,j) = u(i,j) + dt * ( ...

- du2dx - duvdy ...

- dpdx / rho ...

+ mu * (d2udx2 + d2udy2) );

end

end

for i = 2:nx+1

for j = 2:ny

if airfoil(j,i), continue; end

dv2dy = (v(i,j+1)^2 - v(i,j-1)^2)/(2*dy);

duvdx = ((v(i+1,j)+v(i,j))*(u(i+1,j)+u(i+1,j+1)) - (v(i,j)+v(i-1,j))*(u(i-1,j)+u(i-1,j+1))) / (4*dx);

dpdy = (p(i,j+1) - p(i,j))/dy;

d2vdx2 = (v(i+1,j) - 2*v(i,j) + v(i-1,j)) / dx^2;

d2vdy2 = (v(i,j+1) - 2*v(i,j) + v(i,j-1)) / dy^2;

v(i,j) = v(i,j) + dt * ( ...

- duvdx - dv2dy ...

- dpdy / rho ...

+ mu * (d2vdx2 + d2vdy2) );

end
end

% --- Convergence check ---

err_u = max(max(abs(u - u_old)));

err_v = max(max(abs(v - v_old)));

err_p = max(max(abs(p - p_old)));

if mod(time, 100) == 0

fprintf("Time step %d: max error = %.6f\n", time, max([err_u err_v err_p]));

end

end

% --- Plot result ---

u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));

u_c(airfoil) = NaN; v_c(airfoil) = NaN;

figure;

quiver(X', Y', u_c, v_c, 'k');

hold on;

contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);

xlabel('X'); ylabel('Y');

title('SIMPLER - Parabolic (Unsteady Incompressible Flow)');

axis equal tight;


Elliptic

clc; clear;

% Domain

nx = 100; ny = 50;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Physical properties

rho = 1.0;

mu = 1.5e-3; % viscosity

Re = 1000;

u = zeros(nx+1, ny+2);

v = zeros(nx+2, ny+1);

p = zeros(nx+2, ny+2);

% Airfoil shape (ellipse mask)

cx = Lx/2; cy = Ly/2; rx = 0.1; ry = 0.05;

airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;

% Relaxation factors

alpha_p = 0.3;

alpha_u = 0.7;
maxIter = 1000;

tolerance = 1e-5;

for iter = 1:maxIter

u_old = u;

v_old = v;

p_old = p;

% --- Boundary conditions ---

u(1,:) = 1.0; % Inlet

u(end,:) = u(end-1,:); % Outlet

u(:,[1 end]) = 0;

v(:,[1 end]) = 0;

v(1,:) = 0; v(end,:) = 0;

% Apply no-slip on airfoil

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i)

u(i,j) = 0; v(i,j) = 0;

end

end

end

% --- Pressure correction from continuity (SIMPLER) ---

div_uv = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

div_uv(i,j) = (u(i-1,j)-u(i,j))/dx + (v(i,j-1)-v(i,j))/dy;

end
end

p = p + alpha_p * rho * div_uv;

% --- Momentum Equations (Steady) ---

for i = 2:nx

for j = 2:ny+1

if airfoil(j,i), continue; end

du2dx = (u(i+1,j)^2 - u(i-1,j)^2)/(2*dx);

duvdy = ((u(i,j+1)+u(i,j))*(v(i,j+1)+v(i+1,j+1)) - (u(i,j)+u(i,j-1))*(v(i,j-1)+v(i+1,j-1))) / (4*dy);

dpdx = (p(i+1,j) - p(i,j)) / dx;

d2udx2 = (u(i+1,j) - 2*u(i,j) + u(i-1,j)) / dx^2;

d2udy2 = (u(i,j+1) - 2*u(i,j) + u(i,j-1)) / dy^2;

u(i,j) = u(i,j) + alpha_u * ...

(-du2dx - duvdy - dpdx/rho + mu*(d2udx2 + d2udy2));

end

end

for i = 2:nx+1

for j = 2:ny

if airfoil(j,i), continue; end

dv2dy = (v(i,j+1)^2 - v(i,j-1)^2)/(2*dy);

duvdx = ((v(i+1,j)+v(i,j))*(u(i+1,j)+u(i+1,j+1)) - (v(i,j)+v(i-1,j))*(u(i-1,j)+u(i-1,j+1))) / (4*dx);

dpdy = (p(i,j+1) - p(i,j)) / dy;

d2vdx2 = (v(i+1,j) - 2*v(i,j) + v(i-1,j)) / dx^2;

d2vdy2 = (v(i,j+1) - 2*v(i,j) + v(i,j-1)) / dy^2;

v(i,j) = v(i,j) + alpha_u * ...

(-duvdx - dv2dy - dpdy/rho + mu*(d2vdx2 + d2vdy2));

end

end
% --- Convergence check ---

err = max([max(max(abs(u - u_old))), max(max(abs(v - v_old))), max(max(abs(p - p_old)))]);

if mod(iter, 50) == 0

fprintf("Iter %d: Max Error = %.6f\n", iter, err);

end

if err < tolerance

fprintf("Converged in %d iterations\n", iter);

break;

end

end

% --- Plot velocity field ---

u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));

u_c(airfoil) = NaN;

v_c(airfoil) = NaN;

figure;

quiver(X', Y', u_c, v_c, 'k');

hold on;

contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);

xlabel('X'); ylabel('Y');

title('SIMPLER - Steady Incompressible Flow (Elliptic)');

axis equal tight;


SIMPLEC HYPERBOLA

% SIMPLEC algorithm for 2D incompressible flow (e.g., lid-driven cavity)

clear; clc;

% Grid

nx = 50; ny = 50;

Lx = 1; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

% Physical parameters

rho = 1.0;

mu = 0.01;

U_lid = 1.0;

maxIter = 500;

tolerance = 1e-4;

% Initialize fields

u = zeros(nx+1, ny+2); % staggered in x

v = zeros(nx+2, ny+1); % staggered in y

p = zeros(nx+2, ny+2); % pressure

% Under-relaxation

alpha_u = 0.7;

alpha_p = 0.3;
for iter = 1:maxIter

u_old = u; v_old = v; p_old = p;

% --- Boundary Conditions ---

u(:,end) = U_lid; % lid velocity

u(:,1) = 0; u(:,end) = U_lid;

v(1,:) = 0; v(end,:) = 0;

% --- Momentum Equations (Discretized) ---

for i = 2:nx

for j = 2:ny+1

Ae = mu/dx; Aw = mu/dx; An = mu/dy; As = mu/dy;

Ap_u = Ae + Aw + An + As;

u(i,j) = (Ae*u(i+1,j) + Aw*u(i-1,j) + ...

An*u(i,j+1) + As*u(i,j-1) + ...

dx*(p(i,j) - p(i+1,j))) / Ap_u;

end

end

for i = 2:nx+1

for j = 2:ny

Ae = mu/dx; Aw = mu/dx; An = mu/dy; As = mu/dy;

Ap_v = Ae + Aw + An + As;

v(i,j) = (Ae*v(i+1,j) + Aw*v(i-1,j) + ...

An*v(i,j+1) + As*v(i,j-1) + ...

dy*(p(i,j) - p(i,j+1))) / Ap_v;

end

end
% --- Pressure Correction (SIMPLEC) ---

p_corr = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) - v(i,j))/dy);

p_corr(i,j) = p_corr(i,j) - alpha_p * div;

end

end

% --- Pressure and Velocity Correction ---

p = p + p_corr;

for i = 2:nx

for j = 2:ny+1

u(i,j) = u(i,j) + (p_corr(i,j) - p_corr(i+1,j)) * dx;

end

end

for i = 2:nx+1

for j = 2:ny

v(i,j) = v(i,j) + (p_corr(i,j) - p_corr(i,j+1)) * dy;

end

end

% --- Convergence Check ---

err_u = max(max(abs(u - u_old)));

err_v = max(max(abs(v - v_old)));

err_p = max(max(abs(p - p_old)));

if err_u < tolerance && err_v < tolerance && err_p < tolerance
disp(['Converged in ', num2str(iter), ' iterations']);

break;

end

end

% --- Post-processing ---

[X, Y] = meshgrid(linspace(0,Lx,nx+2), linspace(0,Ly,ny+2));

u_center = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_center = 0.5 * (v(:,1:end-1) + v(:,2:end));

quiver(X', Y', u_center, v_center);

title('Velocity Field');

xlabel('X'); ylabel('Y');
Parbola

% SIMPLEC Algorithm - 2D Parabolic Flow (Incompressible)

clc; clear;

% Grid setup

nx = 50; ny = 25;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2); y = linspace(0, Ly, ny+2);

% Physical properties

rho = 1; mu = 1.5e-5;

U_in = 1; % inlet velocity

% Initialize fields

u = zeros(nx+1, ny+2); % u-velocity (x-dir)

v = zeros(nx+2, ny+1); % v-velocity (y-dir)

p = zeros(nx+2, ny+2); % pressure

% SIMPLEC relaxation factors


alpha_u = 0.7;

alpha_p = 0.3;

max_iter = 500;

tolerance = 1e-5;

% Time stepping (parabolic in time)

for iter = 1:max_iter

u_old = u; v_old = v; p_old = p;

% --- Boundary Conditions ---

u(1,:) = U_in; % Inlet

u(end,:) = u(end-1,:); % Outlet (Neumann)

v(1,:) = 0; v(end,:) = 0;

u(:,1) = 0; u(:,end) = 0; % Bottom/top wall

v(:,1) = 0; v(:,end) = 0;

% --- Solve u-momentum ---

for i = 2:nx

for j = 2:ny+1

ue = u(i+1,j); uw = u(i-1,j);

un = u(i,j+1); us = u(i,j-1);

dpdx = (p(i,j) - p(i+1,j)) / dx;

Ap = rho * (2/dx^2 + 2/dy^2);

u(i,j) = ((rho/dx^2)*(ue + uw) + (rho/dy^2)*(un + us) - dpdx) / Ap;

end

end

% --- Solve v-momentum ---


for i = 2:nx+1

for j = 2:ny

ve = v(i+1,j); vw = v(i-1,j);

vn = v(i,j+1); vs = v(i,j-1);

dpdy = (p(i,j) - p(i,j+1)) / dy;

Ap = rho * (2/dx^2 + 2/dy^2);

v(i,j) = ((rho/dx^2)*(ve + vw) + (rho/dy^2)*(vn + vs) - dpdy) / Ap;

end

end

% --- Pressure Correction using continuity ---

p_corr = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) - v(i,j))/dy);

p_corr(i,j) = alpha_p * div;

end

end

% --- Correct Pressure and Velocities ---

p = p + p_corr;

for i = 2:nx

for j = 2:ny+1

u(i,j) = u(i,j) + alpha_u * (p_corr(i,j) - p_corr(i+1,j)) * dx;

end

end

for i = 2:nx+1

for j = 2:ny

v(i,j) = v(i,j) + alpha_u * (p_corr(i,j) - p_corr(i,j+1)) * dy;

end
end

% --- Convergence Check ---

err_u = max(max(abs(u - u_old)));

err_v = max(max(abs(v - v_old)));

err_p = max(max(abs(p - p_old)));

if max([err_u, err_v, err_p]) < tolerance

disp(['Converged in ', num2str(iter), ' iterations']);

break;

end

end

% --- Post-Processing ---

[X, Y] = meshgrid(x, y);

u_center = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_center = 0.5 * (v(:,1:end-1) + v(:,2:end));

quiver(X', Y', u_center, v_center);

xlabel('X'); ylabel('Y'); title('Velocity Field (SIMPLEC)');


Elliptic

clc; clear;

% Domain and grid

nx = 100; ny = 50;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

% Grid

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Flow properties

rho = 1.0;

mu = 1.5e-5;
U_in = 1.0;

% Initialize fields

u = zeros(nx+1, ny+2); % staggered in x

v = zeros(nx+2, ny+1); % staggered in y

p = zeros(nx+2, ny+2); % pressure

% SIMPLEC parameters

alpha_u = 0.7;

alpha_p = 0.3;

max_iter = 1000;

tolerance = 1e-5;

% Create airfoil mask (elliptical obstacle in center)

cx = Lx/2; cy = Ly/2;

rx = 0.1; ry = 0.05;

airfoil_mask = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;

% Main loop

for iter = 1:max_iter

u_old = u; v_old = v; p_old = p;

% --- Apply boundary conditions ---

u(1,:) = U_in; % inlet

u(end,:) = u(end-1,:); % outlet (Neumann)

u(:,[1 end]) = 0; % top/bottom wall

v(1,:) = 0; v(end,:) = 0;

v(:,[1 end]) = 0;

% --- Momentum equations ---

for i = 2:nx
for j = 2:ny+1

if airfoil_mask(j,i), u(i,j) = 0; continue; end

ue = u(i+1,j); uw = u(i-1,j);

un = u(i,j+1); us = u(i,j-1);

dpdx = (p(i,j) - p(i+1,j)) / dx;

Ap = rho * (2/dx^2 + 2/dy^2);

u(i,j) = ((rho/dx^2)*(ue + uw) + (rho/dy^2)*(un + us) - dpdx) / Ap;

end

end

for i = 2:nx+1

for j = 2:ny

if airfoil_mask(j,i), v(i,j) = 0; continue; end

ve = v(i+1,j); vw = v(i-1,j);

vn = v(i,j+1); vs = v(i,j-1);

dpdy = (p(i,j) - p(i,j+1)) / dy;

Ap = rho * (2/dx^2 + 2/dy^2);

v(i,j) = ((rho/dx^2)*(ve + vw) + (rho/dy^2)*(vn + vs) - dpdy) / Ap;

end

end

% --- Pressure correction ---

p_corr = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

if airfoil_mask(j,i), continue; end

div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) - v(i,j))/dy);

p_corr(i,j) = alpha_p * div;

end
end

% --- Correct pressure and velocities ---

p = p + p_corr;

for i = 2:nx

for j = 2:ny+1

u(i,j) = u(i,j) + alpha_u * (p_corr(i,j) - p_corr(i+1,j)) * dx;

end

end

for i = 2:nx+1

for j = 2:ny

v(i,j) = v(i,j) + alpha_u * (p_corr(i,j) - p_corr(i,j+1)) * dy;

end

end

% --- Convergence check ---

err = max([max(max(abs(u - u_old))), max(max(abs(v - v_old))), max(max(abs(p - p_old)))]);

if err < tolerance

disp(['Converged in ', num2str(iter), ' iterations']);

break;

end

end

% --- Postprocessing: Plot velocity field ---

u_center = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_center = 0.5 * (v(:,1:end-1) + v(:,2:end));

u_center(airfoil_mask) = NaN;

v_center(airfoil_mask) = NaN;

figure;
quiver(X', Y', u_center, v_center);

hold on;

contour(X, Y, airfoil_mask, [1 1], 'k', 'LineWidth', 2);

title('Flow Field using SIMPLEC (Elliptic Navier-Stokes)');

xlabel('X'); ylabel('Y'); axis equal;

PISO hyperbola

clc; clear;

% Domain

nx = 100; ny = 50;

Lx = 4; Ly = 2;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx);

y = linspace(0, Ly, ny);

[X, Y] = meshgrid(x, y);

% Flow parameters

gamma = 1.4;

rho = ones(ny, nx);


u = ones(ny, nx) * 2; % Mach 2 inflow

v = zeros(ny, nx);

p = ones(ny, nx);

dt = 0.001;

time_steps = 500;

% Blunt body (circular)

cx = Lx/3; cy = Ly/2; r = 0.3;

blunt = ((X - cx).^2 + (Y - cy).^2) <= r^2;

% Main time loop

for t = 1:time_steps

% Step 1: Predictor - compute momentum fluxes

rhou = rho .* u;

rhov = rho .* v;

E = p/(gamma - 1) + 0.5*rho.*(u.^2 + v.^2);

% Compute fluxes in x and y directions

Fx = [rhou; rhou.^2 ./ rho + p; rhou.*rhov ./ rho; (E + p).*u];

Fy = [rhov; rhou.*rhov ./ rho; rhov.^2 ./ rho + p; (E + p).*v];

% Update using finite volume

for i = 2:nx-1

for j = 2:ny-1

if blunt(j,i), continue; end

rho(j,i) = rho(j,i) - dt/dx * (rhou(j,i+1) - rhou(j,i));

u(j,i) = u(j,i) - dt/dx * ((u(j,i+1)^2 + p(j,i+1)/rho(j,i+1)) - ...

(u(j,i)^2 + p(j,i)/rho(j,i)));

v(j,i) = v(j,i) - dt/dy * ((v(j+1,i)^2 + p(j+1,i)/rho(j+1,i)) - ...

(v(j,i)^2 + p(j,i)/rho(j,i)));

p(j,i) = p(j,i) - gamma * p(j,i) * ( ...


(u(j,i+1) - u(j,i))/dx + (v(j+1,i) - v(j,i))/dy ) * dt;

end

end

% PISO Correction Step 1

% Recalculate pressure correction from continuity

% Correct u, v accordingly (basic form shown)

for i = 2:nx-1

for j = 2:ny-1

if blunt(j,i), continue; end

div_uv = (u(j,i+1) - u(j,i-1))/(2*dx) + (v(j+1,i) - v(j-1,i))/(2*dy);

p(j,i) = p(j,i) - gamma * p(j,i) * div_uv * dt;

u(j,i) = u(j,i) - dt * (p(j,i+1) - p(j,i-1))/(2*dx) / rho(j,i);

v(j,i) = v(j,i) - dt * (p(j+1,i) - p(j-1,i))/(2*dy) / rho(j,i);

end

end

% PISO Correction Step 2 (optional second corrector)

% Boundary conditions

rho(:,1) = 1; u(:,1) = 2; v(:,1) = 0; p(:,1) = 1; % inlet

rho(:,end) = rho(:,end-1); p(:,end) = p(:,end-1); % outlet

u(blunt) = 0; v(blunt) = 0; % blunt body

% Visualization every N steps

if mod(t,50) == 0

contourf(X, Y, sqrt(u.^2 + v.^2), 20, 'LineColor','none');

colorbar; axis equal tight;

title(['Velocity Magnitude at t = ' num2str(t*dt)]);

drawnow;
end

end

Parabola

clc; clear;

% Domain setup

nx = 100; ny = 100;

Lx = 2.0; Ly = 2.0;

dx = Lx/nx; dy = Ly/ny;

x = linspace(0, Lx, nx);

y = linspace(0, Ly, ny);

[X, Y] = meshgrid(x, y);


% Time and physical parameters

dt = 0.002; % Time step

nt = 1000; % Number of time steps

Re = 100; % Reynolds number

nu = 1/Re; % Kinematic viscosity

rho = 1; % Density

% Velocity and pressure fields

u = zeros(ny, nx+1); % staggered in x

v = zeros(ny+1, nx); % staggered in y

p = zeros(ny, nx); % cell-centered

% Define blunt body mask (cylinder)

cx = Lx/2; cy = Ly/2; R = 0.2;

blunt = ((X - cx).^2 + (Y - cy).^2) < R^2;

% Main PISO loop over time

for t = 1:nt

u_star = u;

v_star = v;

% Apply inlet and wall BCs

u(:,1) = 1; % Inlet

u(:,end) = u(:,end-1); % Outlet (Neumann)

v(:,1) = 0; v(:,end) = 0;

u([1 end],:) = 0; v([1 end],:) = 0;

% Predictor: solve u*, v* without updated pressure

for i = 2:nx

for j = 2:ny-1

if blunt(j,i), continue; end


% u-momentum

dudt = -((u(j,i+1)^2 - u(j,i-1)^2)/(2*dx)) ...

- ((v(j+1,i)*u(j+1,i) - v(j-1,i)*u(j-1,i))/(2*dy)) ...

+ nu * ((u(j,i+1) - 2*u(j,i) + u(j,i-1))/dx^2 + ...

(u(j+1,i) - 2*u(j,i) + u(j-1,i))/dy^2) ...

- (p(j,i) - p(j,i-1))/dx / rho;

u_star(j,i) = u(j,i) + dt * dudt;

% v-momentum

dvdt = -((u(j,i+1)*v(j,i+1) - u(j,i-1)*v(j,i-1))/(2*dx)) ...

- ((v(j+1,i)^2 - v(j-1,i)^2)/(2*dy)) ...

+ nu * ((v(j,i+1) - 2*v(j,i) + v(j,i-1))/dx^2 + ...

(v(j+1,i) - 2*v(j,i) + v(j-1,i))/dy^2) ...

- (p(j,i) - p(j-1,i))/dy / rho;

v_star(j,i) = v(j,i) + dt * dvdt;

end

end

% Pressure correction (from continuity)

div = zeros(ny, nx);

for i = 2:nx-1

for j = 2:ny-1

div(j,i) = ((u_star(j,i+1) - u_star(j,i))/dx + ...

(v_star(j+1,i) - v_star(j,i))/dy);

end

end

% Solve pressure Poisson equation

for it = 1:100

p_old = p;
for i = 2:nx-1

for j = 2:ny-1

if blunt(j,i), continue; end

p(j,i) = 0.25*(p(j+1,i) + p(j-1,i) + p(j,i+1) + p(j,i-1) ...

- rho*(dx^2)*(div(j,i))/dt);

end

end

if max(max(abs(p - p_old))) < 1e-4

break;

end

end

% Velocity correction (PISO step)

for i = 2:nx

for j = 2:ny-1

if blunt(j,i), continue; end

u(j,i) = u_star(j,i) - dt/dx * (p(j,i) - p(j,i-1))/rho;

v(j,i) = v_star(j,i) - dt/dy * (p(j,i) - p(j-1,i))/rho;

end

end

% Optional second pressure correction (PISO enhancement)

% Skipped for simplicity

% Display results every 100 steps

if mod(t,100)==0

u_center = 0.5*(u(:,1:end-1) + u(:,2:end));

v_center = 0.5*(v(1:end-1,:) + v(2:end,:));

vel = sqrt(u_center.^2 + v_center.^2);

vel(blunt) = NaN;

contourf(X, Y, vel, 20, 'LineColor','none');


title(['Velocity Magnitude at time step: ' num2str(t)]);

axis equal tight;

colorbar;

drawnow;

end

end

Elliptic

clc; clear;

% Grid parameters

nx = 100; ny = 100;

Lx = 2.0; Ly = 2.0;

dx = Lx/nx; dy = Ly/ny;
x = linspace(0, Lx, nx);

y = linspace(0, Ly, ny);

[X, Y] = meshgrid(x, y);

% Physical properties

rho = 1; % Density

Re = 100; % Reynolds number

nu = 1/Re; % Kinematic viscosity

% Fields

u = ones(ny, nx); % x-velocity initialized to inflow

v = zeros(ny, nx); % y-velocity

p = zeros(ny, nx); % Pressure

% Blunt body mask (circular cylinder)

cx = Lx/2; cy = Ly/2; R = 0.2;

blunt = ((X - cx).^2 + (Y - cy).^2) < R^2;

% Iteration parameters

max_iter = 1000;

tol = 1e-5;

dt = 0.01; % pseudo-time step for PISO-like steady simulation

for iter = 1:max_iter

u_star = u;

v_star = v;

% Predictor step: update velocities (pseudo-unsteady)

for i = 2:nx-1

for j = 2:ny-1

if blunt(j,i), continue; end


% Convective and diffusive terms for u

du = -u(j,i)*(u(j,i+1)-u(j,i-1))/(2*dx) ...

- v(j,i)*(u(j+1,i)-u(j-1,i))/(2*dy) ...

+ nu*((u(j,i+1) - 2*u(j,i) + u(j,i-1))/dx^2 + ...

(u(j+1,i) - 2*u(j,i) + u(j-1,i))/dy^2);

% Convective and diffusive terms for v

dv = -u(j,i)*(v(j,i+1)-v(j,i-1))/(2*dx) ...

- v(j,i)*(v(j+1,i)-v(j-1,i))/(2*dy) ...

+ nu*((v(j,i+1) - 2*v(j,i) + v(j,i-1))/dx^2 + ...

(v(j+1,i) - 2*v(j,i) + v(j-1,i))/dy^2);

u_star(j,i) = u(j,i) + dt * (du - (1/rho)*(p(j,i+1) - p(j,i))/dx);

v_star(j,i) = v(j,i) + dt * (dv - (1/rho)*(p(j+1,i) - p(j,i))/dy);

end

end

% Pressure correction from continuity

div = zeros(ny, nx);

for i = 2:nx-1

for j = 2:ny-1

div(j,i) = ((u_star(j,i) - u_star(j,i-1))/dx + ...

(v_star(j,i) - v_star(j-1,i))/dy);

end

end

% Pressure Poisson equation

for it_p = 1:100

p_old = p;

for i = 2:nx-1
for j = 2:ny-1

if blunt(j,i), continue; end

p(j,i) = 0.25*(p(j+1,i) + p(j-1,i) + p(j,i+1) + p(j,i-1) - ...

rho/dt * div(j,i) * dx^2);

end

end

if max(max(abs(p - p_old))) < 1e-4

break;

end

end

% Correct velocities

for i = 2:nx-1

for j = 2:ny-1

if blunt(j,i), continue; end

u(j,i) = u_star(j,i) - dt/dx * (p(j,i) - p(j,i-1))/rho;

v(j,i) = v_star(j,i) - dt/dy * (p(j,i) - p(j-1,i))/rho;

end

end

% Boundary conditions

u(:,1) = 1; % Inlet

u(:,end) = u(:,end-1); % Outlet

u([1 end],:) = 0; % Top/bottom walls

v(:,[1 end]) = 0;

v([1 end],:) = 0;

u(blunt) = 0; v(blunt) = 0;

% Convergence check

res = max(max(abs(div)));

if res < tol


fprintf('Converged at iteration %d\n', iter);

break;

end

% Plot every 100 iterations

if mod(iter,100) == 0

u_center = u;

v_center = v;

vel = sqrt(u_center.^2 + v_center.^2);

vel(blunt) = NaN;

contourf(X, Y, vel, 20, 'LineColor','none');

axis equal tight;

title(['Steady Flow Velocity Magnitude – Iteration: ' num2str(iter)]);

colorbar;

drawnow;

end

end

SIMPLE hyperbola

clc; clear;
% Grid setup

nx = 100; ny = 50;

Lx = 2; Ly = 1;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Physical parameters

rho = 1.0;

dt = 0.001; t_end = 0.5; nt = round(t_end/dt);

% Initialize fields

u = zeros(nx+1, ny+2);

v = zeros(nx+2, ny+1);

p = zeros(nx+2, ny+2);

% Elliptic airfoil mask

cx = Lx/2; cy = Ly/2; rx = 0.1; ry = 0.05;

airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;

% SIMPLE loop for hyperbolic flow

for t = 1:nt

u_old = u; v_old = v; p_old = p;

% --- Boundary conditions ---

u(1,:) = 1.0; % inlet

u(end,:) = u(end-1,:); % outlet

u(:,[1 end]) = 0;

v(:,[1 end]) = 0;

v(1,:) = 0; v(end,:) = 0;
% No-slip on airfoil

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i)

u(i,j) = 0;

v(i,j) = 0;

end

end

end

% --- Momentum equations (inviscid hyperbolic form) ---

for i = 2:nx

for j = 2:ny+1

if airfoil(j,i), continue; end

u_adv = -u(i,j) * (u(i+1,j) - u(i-1,j)) / (2*dx) ...

- v(i,j) * (u(i,j+1) - u(i,j-1)) / (2*dy);

u_pres = -(p(i+1,j) - p(i,j)) / dx / rho;

u(i,j) = u(i,j) + dt * (u_adv + u_pres);

end

end

for i = 2:nx+1

for j = 2:ny

if airfoil(j,i), continue; end

v_adv = -u(i,j) * (v(i+1,j) - v(i-1,j)) / (2*dx) ...

- v(i,j) * (v(i,j+1) - v(i,j-1)) / (2*dy);

v_pres = -(p(i,j+1) - p(i,j)) / dy / rho;

v(i,j) = v(i,j) + dt * (v_adv + v_pres);

end

end
% --- Pressure correction (Poisson-type from continuity) ---

div_uv = zeros(nx+2, ny+2);

for i = 2:nx+1

for j = 2:ny+1

div_uv(i,j) = (u(i-1,j)-u(i,j))/dx + (v(i,j-1)-v(i,j))/dy;

end

end

p = p + 0.3 * rho * div_uv; % relaxation factor

% --- Correct velocity (SIMPLE) ---

for i = 2:nx

for j = 2:ny+1

u(i,j) = u(i,j) - dt * (p(i+1,j) - p(i,j)) / dx / rho;

end

end

for i = 2:nx+1

for j = 2:ny

v(i,j) = v(i,j) - dt * (p(i,j+1) - p(i,j)) / dy / rho;

end

end

% --- Print progress ---

if mod(t, 50) == 0

fprintf("Time step %d/%d complete\n", t, nt);

end

end

% --- Plot results ---

u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));

v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));


u_c(airfoil) = NaN;

v_c(airfoil) = NaN;

figure;

quiver(X', Y', u_c, v_c, 'k');

hold on;

contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);

xlabel('X'); ylabel('Y');

title('SIMPLE - Hyperbolic (Unsteady Inviscid Flow)');

axis equal tight;


Parabolic

clc; clear;

% Domain

nx = 200; ny = 100;

Lx = 1.0; Ly = 0.5;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+1);

y = linspace(0, Ly, ny+1);

% Parameters

rho = 1.0;

nu = 1.5e-5;

U_inlet = 1.0;

% Initialize

u = zeros(ny+1, nx+1); % velocity in x-direction

v = zeros(ny+1, nx+1); % velocity in y-direction

p = zeros(ny+1, nx+1); % pressure

u(:,1) = U_inlet; % inlet condition

% SIMPLE parameters

alpha_u = 0.7;

alpha_p = 0.3;

max_iter = 500;

tol = 1e-5;

% Marching in x (parabolic treatment)

for i = 2:nx+1

u_old = u(:,i-1); % use previous x-location


% Apply wall and farfield BCs

u(1,i) = 0; % wall (no-slip)

v(1,i) = 0;

u(end,i) = U_inlet; % free-stream

v(end,i) = 0;

% Iterative SIMPLE loop at each x-location

for iter = 1:max_iter

u_star = u(:,i);

p_corr = zeros(ny+1,1);

% Solve x-momentum (only y-derivatives matter in boundary layer)

for j = 2:ny

dudy = (u(j+1,i) - 2*u(j,i) + u(j-1,i)) / dy^2;

conv = u(j,i-1)*(u(j,i-1) - u(j-1,i-1))/dy; % upstream conv

u_star(j) = u(j,i-1) + dx * (nu * dudy - conv);

end

% Solve pressure correction using continuity

for j = 2:ny

div = (u_star(j) - u_star(j-1))/dy;

p_corr(j) = p_corr(j) - alpha_p * rho * div;

end

% Correct u

for j = 2:ny

u(j,i) = u_star(j) - dx/rho * (p_corr(j+1) - p_corr(j))/dy;

end

% Recompute v from continuity


for j = 2:ny

v(j,i) = v(j-1,i) - dy * (u(j,i) - u(j,i-1)) / dx;

end

% Check convergence

if max(abs(u(:,i) - u_star)) < tol

break;

end

end

end

% Plot results

[X, Y] = meshgrid(x, y);

figure;

contourf(X, Y, u, 20, 'LineColor', 'none');

colorbar;

xlabel('x'); ylabel('y');

title('Velocity Profile u(x,y) - SIMPLE for Parabolic Flow');

figure;

quiver(X, Y, u, v, 2);

xlabel('x'); ylabel('y');

title('Velocity Field (u, v)');


Elliptic

clc; clear;

% Domain

nx = 100; ny = 50;

Lx = 2.0; Ly = 1.0;

dx = Lx / nx; dy = Ly / ny;

x = linspace(0, Lx, nx+2);

y = linspace(0, Ly, ny+2);

[X, Y] = meshgrid(x, y);

% Parameters

rho = 1.0;

nu = 1e-3;

U_inlet = 1.0;

max_iter = 500;

tol = 1e-4;

alpha_p = 0.3;

% Field variables

u = zeros(ny+2, nx+3); % u at cell faces in x

v = zeros(ny+3, nx+2); % v at cell faces in y

p = zeros(ny+2, nx+2); % pressure at cell centers

% Airfoil mask (elliptical)

cx = Lx/2; cy = Ly/2; rx = 0.2; ry = 0.1;

airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) <= 1;


% SIMPLE loop

for iter = 1:max_iter

u_old = u; v_old = v; p_old = p;

% Boundary conditions

u(:,1) = U_inlet; % Inlet

u(:,end) = u(:,end-1); % Outlet (Neumann)

v(:,1) = 0; v(:,end) = 0;

u([1 end],:) = 0; v([1 end],:) = 0; % top/bottom wall

% No-slip at airfoil

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i)

u(j,i) = 0; v(j,i) = 0;

end

end

end

% --- Solve momentum equations ---

% Internal nodes only

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i), continue; end

ue = u(j,i+1); uw = u(j,i-1);

un = u(j+1,i); us = u(j-1,i);

ve = v(j,i+1); vw = v(j,i);

du2dx = (ue^2 - uw^2) / (2*dx);

duvdy = ((v(j+1,i)*u(j+1,i) - v(j-1,i)*u(j-1,i)) / (2*dy));


dpdx = (p(j,i+1) - p(j,i)) / dx;

d2udx2 = (ue - 2*u(j,i) + uw) / dx^2;

d2udy2 = (un - 2*u(j,i) + us) / dy^2;

u(j,i) = u(j,i) + 0.1 * ( ...

-du2dx - duvdy - dpdx/rho + nu*(d2udx2 + d2udy2) );

end

end

for i = 2:nx+1

for j = 2:ny+1

if airfoil(j,i), continue; end

vn = v(j+1,i); vs = v(j-1,i);

ve = v(j,i+1); vw = v(j,i-1);

ue = u(j,i+1); uw = u(j,i);

dv2dy = (vn^2 - vs^2) / (2*dy);

duvdx = ((u(j,i+1)*v(j,i+1) - u(j,i-1)*v(j,i-1)) / (2*dx));

dpdy = (p(j+1,i) - p(j,i)) / dy;

d2vdx2 = (ve - 2*v(j,i) + vw) / dx^2;

d2vdy2 = (vn - 2*v(j,i) + vs) / dy^2;

v(j,i) = v(j,i) + 0.1 * ( ...

-duvdx - dv2dy - dpdy/rho + nu*(d2vdx2 + d2vdy2) );

end

end

% --- Pressure correction from continuity ---

div = zeros(size(p));

for i = 2:nx+1

for j = 2:ny+1

div(j,i) = ((u(j,i) - u(j,i-1))/dx + (v(j,i) - v(j-1,i))/dy);

end

end
p = p - alpha_p * rho * div;

% --- Velocity correction ---

for i = 2:nx+1

for j = 2:ny+1

u(j,i) = u(j,i) - dx/rho * (p(j,i) - p(j,i-1));

v(j,i) = v(j,i) - dy/rho * (p(j,i) - p(j-1,i));

end

end

% Convergence check

err_u = max(max(abs(u - u_old)));

err_v = max(max(abs(v - v_old)));

err_p = max(max(abs(p - p_old)));

if max([err_u, err_v, err_p]) < tol

fprintf("Converged in %d iterations\n", iter);

break;

end

end

% Plot velocity magnitude

u_c = 0.5*(u(:,1:end-1) + u(:,2:end));

v_c = 0.5*(v(1:end-1,:) + v(2:end,:));

vel_mag = sqrt(u_c.^2 + v_c.^2);

vel_mag(airfoil) = NaN;

figure;

contourf(X, Y, vel_mag, 20, 'LineColor', 'none');

colorbar;

title('Velocity Magnitude - SIMPLE for Elliptic Flow');

xlabel('x'); ylabel('y');
axis equal tight;

figure;

quiver(X, Y, u_c, v_c, 2);

hold on;

contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);

title('Velocity Field (u, v)');

xlabel('x'); ylabel('y');

axis equal tight;

You might also like