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

python codes cfd

The document discusses a unified Python framework for Computational Fluid Dynamics (CFD) focusing on algorithms like SIMPLE, SIMPLER, SIMPLEC, and PISO for various flow scenarios. It details the implementation of these algorithms for steady, incompressible flows over an airfoil, including code snippets and flow equations. Each algorithm is evaluated for its pros and cons, highlighting their suitability for different types of fluid flow problems.

Uploaded by

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

python codes cfd

The document discusses a unified Python framework for Computational Fluid Dynamics (CFD) focusing on algorithms like SIMPLE, SIMPLER, SIMPLEC, and PISO for various flow scenarios. It details the implementation of these algorithms for steady, incompressible flows over an airfoil, including code snippets and flow equations. Each algorithm is evaluated for its pros and cons, highlighting their suitability for different types of fluid flow problems.

Uploaded by

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

A UNIFIED PYTHON

FRAMEWORK FOR CFD:


SIMPLE, SIMPLER, SIMPLEC,
PISO
www.reallygreatsite.com
SIMPLE Python Algorithms-
Flow over an airfoil

(Semi-Implicit Method for Pressure-Linked


Equations)
Type: Iterative
Best for: Steady, incompressible flows

Pros:
• Simple and robust
• Works well for steady problems
Cons:
• Slow convergence
• Not suitable for transient or compressible
flows
Hyperbolic
Equation
Algorithm
:
• Initialize velocity (u, v) and pressure (p)
• Loop over time:
1.Solve momentum equations with guessed pressure
2.Solve pressure correction (Poisson-type) from continuity
3.Correct velocity and pressure
4.Apply boundary conditions
• Repeat until time reaches desired value
Code
clc; clear; % --- Boundary conditions ---
: u(1,:) = 1.0; % inlet
% Grid setup u(end,:) = u(end-1,:); % outlet
nx = 100; ny = 50; u(:,[1 end]) = 0;
Lx = 2; Ly = 1; v(:,[1 end]) = 0;
dx = Lx / nx; dy = Ly / ny; v(1,:) = 0; v(end,:) = 0;
x = linspace(0, Lx, nx+2);
y = linspace(0, Ly, ny+2); % No-slip on airfoil
[X, Y] = meshgrid(x, y); for i = 2:nx+1
for j = 2:ny+1
% Physical parameters if airfoil(j,i)
rho = 1.0; u(i,j) = 0;
dt = 0.001; t_end = 0.5; nt = round(t_end/dt); v(i,j) = 0;
end
% Initialize fields end
u = zeros(nx+1, ny+2); end
v = zeros(nx+2, ny+1);
p = zeros(nx+2, ny+2); % --- Momentum equations (inviscid hyperbolic
form) ---
% Elliptic airfoil mask for i = 2:nx
cx = Lx/2; cy = Ly/2; rx = 0.1; ry = 0.05; for j = 2:ny+1
airfoil = ((X - cx).^2 / rx^2 + (Y - cy).^2 / ry^2) if airfoil(j,i), continue; end
<= 1; u_adv = -u(i,j) * (u(i+1,j) - u(i-1,j)) /
(2*dx) ...
% SIMPLE loop for hyperbolic flow - v(i,j) * (u(i,j+1) - u(i,j-1)) / (2*dy);
for t = 1:nt u_pres = -(p(i+1,j) - p(i,j)) / dx / rho;
u_old = u; v_old = v; p_old = p; u(i,j) = u(i,j) + dt * (u_adv + u_pres);
end
for i = 2:nx+1 for i = 2:nx+1
for j = 2:ny for j = 2:ny
if airfoil(j,i), continue; end v(i,j) = v(i,j) - dt * (p(i,j+1) - p(i,j)) / dy / rho;
v_adv = -u(i,j) * (v(i+1,j) - v(i-1,j)) / end
(2*dx) ... end
- v(i,j) * (v(i,j+1) - v(i,j-1)) / (2*dy);
v_pres = -(p(i,j+1) - p(i,j)) / dy / rho; % --- Print progress ---
v(i,j) = v(i,j) + dt * (v_adv + v_pres); if mod(t, 50) == 0
end fprintf("Time step %d/%d complete\n", t,
end nt);
end
% --- Pressure correction (Poisson-type from end
continuity) ---
div_uv = zeros(nx+2, ny+2); % --- Plot results ---
for i = 2:nx+1 u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));
for j = 2:ny+1 v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));
div_uv(i,j) = (u(i-1,j)-u(i,j))/dx + (v(i,j-1)- u_c(airfoil) = NaN;
v(i,j))/dy; v_c(airfoil) = NaN;
end
end figure;
p = p + 0.3 * rho * div_uv; % relaxation quiver(X', Y', u_c, v_c, 'k');
factor hold on;
% --- Correct velocity (SIMPLE) --- contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);
for i = 2:nx xlabel('X'); ylabel('Y');
for j = 2:ny+1 title('SIMPLE - Hyperbolic (Unsteady Inviscid
u(i,j) = u(i,j) - dt * (p(i+1,j) - p(i,j)) / dx / Flow)');
rho; axis equal tight;
end
end continued..
Parabolic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
% Apply wall and farfield BCs
Code u(1,i) = 0; % wall (no-slip)
% Domain
: nx = 200; ny = 100;
v(1,i) = 0;
u(end,i) = U_inlet; % free-stream
Lx = 1.0; Ly = 0.5;
v(end,i) = 0;
dx = Lx / nx; dy = Ly / ny;
x = linspace(0, Lx, nx+1);
% Iterative SIMPLE loop at each x-location
y = linspace(0, Ly, ny+1);
for iter = 1:max_iter
u_star = u(:,i);
% Parameters
p_corr = zeros(ny+1,1);
rho = 1.0;
nu = 1.5e-5;
% Solve x-momentum (only y-derivatives
U_inlet = 1.0;
matter in boundary layer)
for j = 2:ny
% Initialize
dudy = (u(j+1,i) - 2*u(j,i) + u(j-1,i)) /
u = zeros(ny+1, nx+1); % velocity in x-
dy^2;
direction
conv = u(j,i-1)*(u(j,i-1) - u(j-1,i-1))/dy;
v = zeros(ny+1, nx+1); % velocity in y-
% upstream conv
direction
u_star(j) = u(j,i-1) + dx * (nu * dudy -
p = zeros(ny+1, nx+1); % pressure
conv);
u(:,1) = U_inlet; % inlet condition
end
% Solve pressure correction using continuity
% SIMPLE parameters
for j = 2:ny
alpha_u = 0.7;
div = (u_star(j) - u_star(j-1))/dy;
alpha_p = 0.3;
p_corr(j) = p_corr(j) - alpha_p * rho * div;
max_iter = 500;
end
tol = 1e-5;

% Correct u
% Marching in x (parabolic treatment)
for j = 2:ny
for i = 2:nx+1
u(j,i) = u_star(j) - dx/rho * (p_corr(j+1) -
% 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
Equation
Algorithm

:
Guess velocity and pressure fields.
• Solve momentum equations using current pressure.
• Solve pressure correction equation (from continuity).
• Correct velocities and pressure.
• Iterate until convergence.
% Boundary conditions
Code for i = 2:nx+1 u(:,1) = U_inlet; % Inlet
for j = 2:ny
: if airfoil(j,i), continue; end
u(:,end) = u(:,end-1);
(Neumann)
% Outlet

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


- v(i,j) * (v(i,j+1) - v(i,j-1)) / (2*dy); u([1 end],:) = 0; v([1 end],:) = 0; %
v_pres = -(p(i,j+1) - p(i,j)) / dy / rho; top/bottom wall
v(i,j) = v(i,j) + dt * (v_adv + v_pres);
end % No-slip at airfoil
end for i = 2:nx+1
% --- Pressure correction (Poisson-type from for j = 2:ny+1
continuity) --- if airfoil(j,i)
div_uv = zeros(nx+2, ny+2); u(j,i) = 0; v(j,i) = 0;
for i = 2:nx+1 end
for j = 2:ny+1 end
div_uv(i,j) = (u(i-1,j)-u(i,j))/dx + end
(v(i,j-1)-v(i,j))/dy;
end % --- Solve momentum equations ---
end % Internal nodes only
p = p + 0.3 * rho * div_uv; % relaxation factor for i = 2:nx+1
% --- Correct velocity (SIMPLE) --- for j = 2:ny+1
for i = 2:nx if airfoil(j,i), continue; end
for j = 2:ny+1 ue = u(j,i+1); uw = u(j,i-1);
u(i,j) = u(i,j) - dt * (p(i+1,j) - p(i,j)) / dx / rho; un = u(j+1,i); us = u(j-1,i);
end ve = v(j,i+1); vw = v(j,i);
end du2dx = (ue^2 - uw^2) / (2*dx);
duvdy = ((v(j+1,i)*u(j+1,i) - v(j-1,i)*u(j-
% SIMPLE loop 1,i)) / (2*dy));
for iter = 1:max_iter dpdx = (p(j,i+1) - p(j,i)) / dx;
u_old = u; v_old = v; p_old = p;
u(j,i) = u(j,i) + 0.1 * ( ...
-du2dx - duvdy - dpdx/rho + end
nu*(d2udx2 + d2udy2) ); end
end p = p - alpha_p * rho * div;
end
% --- Velocity correction ---
for i = 2:nx+1 for i = 2:nx+1
for j = 2:ny+1 for j = 2:ny+1
if airfoil(j,i), continue; end u(j,i) = u(j,i) - dx/rho * (p(j,i) - p(j,i-1));
vn = v(j+1,i); vs = v(j-1,i); v(j,i) = v(j,i) - dy/rho * (p(j,i) - p(j-1,i));
ve = v(j,i+1); vw = v(j,i-1); end
ue = u(j,i+1); uw = u(j,i); end
dv2dy = (vn^2 - vs^2) / (2*dy);
duvdx = ((u(j,i+1)*v(j,i+1) - u(j,i-1)*v(j,i- % Convergence check
1)) / (2*dx)); err_u = max(max(abs(u - u_old)));
dpdy = (p(j+1,i) - p(j,i)) / dy; err_v = max(max(abs(v - v_old)));
d2vdx2 = (ve - 2*v(j,i) + vw) / dx^2; err_p = max(max(abs(p - p_old)));
d2vdy2 = (vn - 2*v(j,i) + vs) / dy^2; if max([err_u, err_v, err_p]) < tol
v(j,i) = v(j,i) + 0.1 * ( ... fprintf("Converged in %d iterations\n",
-duvdx - dv2dy - dpdy/rho + iter);
nu*(d2vdx2 + d2vdy2) ); break;
end end
end end
% --- Pressure correction from continuity --- % Plot velocity magnitude
div = zeros(size(p)); u_c = 0.5*(u(:,1:end-1) + u(:,2:end));
for i = 2:nx+1 v_c = 0.5*(v(1:end-1,:) + v(2:end,:));
for j = 2:ny+1 vel_mag = sqrt(u_c.^2 + v_c.^2);
div(j,i) = ((u(j,i) - u(j,i-1))/dx + (v(j,i) - vel_mag(airfoil) = NaN;
v(j-1,i))/dy);
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;
SIMPLER Python Algorithms-
Flow over an airfoil

(SIMPLE Revised)
Type: Iterative with pre-correction
Best for: Complex steady flows

Pros:
• More stable
• Faster convergence for some problems
Cons:
• Slightly more complex than SIMPLE
Hyperbolic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
% Boundary Conditions
Code u(j,i) = u(j,i) + 0.1 * ( ...
u(1,:) = 1.0; % Inlet
-du2dx - duvdy - dpdx/rho + nu*(d2udx2 +
u(end,:) = u(end-1,:); % Outlet (Neumann)
: d2udy2) );
u(:,[1 end]) = 0; v(:,[1 end]) = 0;
end
end
% Apply mask (airfoil no-penetration)
for i = 2:nx+1
for i = 2:nx+1
for j = 2:ny+1
for j = 2:ny+1
if airfoil(j,i)
if airfoil(j,i), continue; end
u(i,j) = 0; v(i,j) = 0;
vn = v(j+1,i); vs = v(j-1,i);
end
ve = v(j,i+1); vw = v(j,i-1);
end
ue = u(j,i+1); uw = u(j,i);
end
dv2dy = (vn^2 - vs^2) / (2*dy);
duvdx = ((u(j,i+1)*v(j,i+1) - u(j,i-1)*v(j,i-
% --- Momentum update (Euler equations) ---
1)) / (2*dx));
for i = 2:nx
dpdy = (p(j+1,i) - p(j,i)) / dy;
for j = 2:ny+1
d2vdx2 = (ve - 2*v(j,i) + vw) / dx^2;
if airfoil(j,i), continue; end
d2vdy2 = (vn - 2*v(j,i) + vs) / dy^2;
dpdx = (p(i+1,j) - p(i-1,j)) / (2*dx);
v(j,i) = v(j,i) + 0.1 * ( ...
u(i,j) = u(i,j) - alpha_u * dpdx / rho(i,j);
-duvdx - dv2dy - dpdy/rho +
end
nu*(d2vdx2 + d2vdy2) );
end
end
end
for i = 2:nx+1
% --- Pressure correction from continuity ---
for j = 2:ny
div = zeros(size(p));
if airfoil(j,i), continue; end
for i = 2:nx+1
dpdy = (p(i,j+1) - p(i,j-1)) / (2*dy);
for j = 2:ny+1
v(i,j) = v(i,j) - alpha_u * dpdy / rho(i,j);
div(j,i) = ((u(j,i) - u(j,i-1))/dx + (v(j,i) -
end
v(j-1,i))/dy);
end
% --- Pressure correction (SIMPLER style) ---
for i = 2:nx+1
for j = 2:ny+1
if airfoil(j,i), continue; end
title('SIMPLER - Euler-like Compressible Flow
div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) -
(Hyperbolic)');
v(i,j))/dy);
axis equal;
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);
Parabolic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
% Time-stepping loop (parabolic)
Code u(j,i) = u(j,i) + 0.1 * ( ...
for time = 1:nt
-du2dx - duvdy - dpdx/rho + nu*(d2udx2 +
: d2udy2) ); u_old = u; v_old = v; p_old = p;
end
end % --- Boundary conditions ---
u(1,:) = 1.0; % Inlet
for i = 2:nx+1 u(end,:) = u(end-1,:); % Outlet
for j = 2:ny+1 u(:,[1 end]) = 0;
if airfoil(j,i), continue; end v(:,[1 end]) = 0;
vn = v(j+1,i); vs = v(j-1,i); v(1,:) = 0; v(end,:) = 0;
ve = v(j,i+1); vw = v(j,i-1);
ue = u(j,i+1); uw = u(j,i); % --- Apply airfoil mask (no-slip) ---
dv2dy = (vn^2 - vs^2) / (2*dy); for i = 2:nx+1
duvdx = ((u(j,i+1)*v(j,i+1) - u(j,i-1)*v(j,i-1)) / for j = 2:ny+1
(2*dx)); if airfoil(j,i)
dpdy = (p(j+1,i) - p(j,i)) / dy; u(i,j) = 0;
d2vdx2 = (ve - 2*v(j,i) + vw) / dx^2; v(i,j) = 0;
d2vdy2 = (vn - 2*v(j,i) + vs) / dy^2; end
v(j,i) = v(j,i) + 0.1 * ( ... end
-duvdx - dv2dy - dpdy/rho + nu*(d2vdx2 + end
d2vdy2) );
end % --- Pressure prediction (from continuity) ---
end div_uv = zeros(nx+2, ny+2);
% --- Pressure correction from continuity --- for i = 2:nx+1
div = zeros(size(p)); for j = 2:ny+1
for i = 2:nx+1 div_uv(i,j) = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) -
for j = 2:ny+1 v(i,j))/dy);
div(j,i) = ((u(j,i) - u(j,i-1))/dx + (v(j,i) - end
v(j-1,i))/dy); end
% --- Momentum equations (explicit time v(i,j) = v(i,j) + dt * ( ...
update) --- - duvdx - dv2dy ...
for i = 2:nx - dpdy / rho ...
for j = 2:ny+1 + mu * (d2vdx2 + d2vdy2) );
if airfoil(j,i), continue; end end
du2dx = (u(i+1,j)^2 - u(i-1,j)^2)/(2*dx); end
duvdy =
((u(i,j+1)+u(i,j))*(v(i,j+1)+v(i+1,j+1)) - (u(i,j) % --- Convergence check ---
+u(i,j-1))*(v(i,j-1)+v(i+1,j-1))) / (4*dy); err_u = max(max(abs(u - u_old)));
dpdx = (p(i+1,j) - p(i,j))/dx; err_v = max(max(abs(v - v_old)));
d2udx2 = (u(i+1,j) - 2*u(i,j) + u(i-1,j)) / err_p = max(max(abs(p - p_old)));
dx^2; if mod(time, 100) == 0
d2udy2 = (u(i,j+1) - 2*u(i,j) + u(i,j-1)) / fprintf("Time step %d: max error = %.6f\n",
dy^2; time, max([err_u err_v err_p]));
end
u(i,j) = u(i,j) + dt * ( ... end
- du2dx - duvdy ...
- dpdx / rho ... % --- Plot result ---
+ mu * (d2udx2 + d2udy2) ); u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));
end v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));
end u_c(airfoil) = NaN; v_c(airfoil) = NaN;
figure;
for i = 2:nx+1 quiver(X', Y', u_c, v_c, 'k');
for j = 2:ny hold on;
if airfoil(j,i), continue; end contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);
dv2dy = (v(i,j+1)^2 - v(i,j-1)^2)/(2*dy); xlabel('X'); ylabel('Y');
duvdx = ((v(i+1,j)+v(i,j))*(u(i+1,j) title('SIMPLER - Parabolic (Unsteady
+u(i+1,j+1)) - (v(i,j)+v(i-1,j))*(u(i-1,j)+u(i- Incompressible Flow)');
1,j+1))) / (4*dx); axis equal tight;
Elliptic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
Code % --- Pressure correction (SIMPLER style) ---
for i = 2:nx+1
for iter = 1:maxIter
u_old = u;
: for j = 2:ny+1 v_old = v;
if airfoil(j,i), continue; end p_old = p;
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; % --- Boundary conditions ---
end u(1,:) = 1.0; % Inlet
end u(end,:) = u(end-1,:); % Outlet
% --- Convergence check --- u(:,[1 end]) = 0;
err = max([max(max(abs(u - u_old))), v(:,[1 end]) = 0;
max(max(abs(p - p_old)))]); v(1,:) = 0; v(end,:) = 0;
if err < tolerance
disp(['Converged in ', num2str(iter), ' % Apply no-slip on airfoil
iterations']); for i = 2:nx+1
break; for j = 2:ny+1
end if airfoil(j,i)
end u(i,j) = 0; v(i,j) = 0;
% --- Plot velocity field --- end
u_plot = 0.5 * (u(1:end-1,:) + u(2:end,:)); end
v_plot = 0.5 * (v(:,1:end-1) + v(:,2:end)); end
u_plot(airfoil) = NaN;
v_plot(airfoil) = NaN; % --- Pressure correction from continuity
figure; (SIMPLER) ---
quiver(X', Y', u_plot, v_plot, 'k'); div_uv = zeros(nx+2, ny+2);
hold on; for i = 2:nx+1
contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2); for j = 2:ny+1
xlabel('X'); ylabel('Y'); div_uv(i,j) = (u(i-1,j)-u(i,j))/dx +
(v(i,j-1)-v(i,j))/dy;
maxIter = 1000; end
p = p + alpha_p * rho * div_uv; v(i,j) = v(i,j) + alpha_u * ...
(-duvdx - dv2dy - dpdy/rho + mu*(d2vdx2 +
% --- Momentum Equations (Steady) --- d2vdy2));
for i = 2:nx end
for j = 2:ny+1 end
if airfoil(j,i), continue; end % --- Convergence check ---
du2dx = (u(i+1,j)^2 - u(i-1,j)^2)/(2*dx); err = max([max(max(abs(u - u_old))),
duvdy = max(max(abs(v - v_old))), max(max(abs(p -
((u(i,j+1)+u(i,j))*(v(i,j+1)+v(i+1,j+1)) - (u(i,j) p_old)))]);
+u(i,j-1))*(v(i,j-1)+v(i+1,j-1))) / (4*dy); if mod(iter, 50) == 0
dpdx = (p(i+1,j) - p(i,j)) / dx; fprintf("Iter %d: Max Error = %.6f\n", iter, err);
d2udx2 = (u(i+1,j) - 2*u(i,j) + u(i-1,j)) / end
dx^2; if err < tolerance
d2udy2 = (u(i,j+1) - 2*u(i,j) + u(i,j-1)) / fprintf("Converged in %d iterations\n", iter);
dy^2; break;
end
u(i,j) = u(i,j) + alpha_u * ... end
(-du2dx - duvdy - dpdx/rho + mu*(d2udx2 + % --- Plot velocity field ---
d2udy2)); u_c = 0.5 * (u(1:end-1,:) + u(2:end,:));
end v_c = 0.5 * (v(:,1:end-1) + v(:,2:end));
end u_c(airfoil) = NaN;
v_c(airfoil) = NaN;
for i = 2:nx+1 figure;
for j = 2:ny quiver(X', Y', u_c, v_c, 'k');
if airfoil(j,i), continue; end hold on;
dv2dy = (v(i,j+1)^2 - v(i,j-1)^2)/(2*dy); contour(X, Y, airfoil, [1 1], 'r', 'LineWidth', 2);
duvdx = ((v(i+1,j)+v(i,j))*(u(i+1,j) xlabel('X'); ylabel('Y');
+u(i+1,j+1)) - (v(i,j)+v(i-1,j))*(u(i-1,j)+u(i- title('SIMPLER - Steady Incompressible Flow
1,j+1))) / (4*dx); (Elliptic)');
SIMPLEC Python Algorithms-
Flow over an airfoil

(SIMPLE-Consistent)
Type: Enhanced SIMPLE
Best for: Steady flows, faster
convergence

Pros:
• Faster convergence than SIMPLE
• More accurate velocity correction
Cons:
• Still not ideal for highly transient
problems
Hyperbolic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
import numpy as np def apply_boundary_conditions():
Code import matplotlib.pyplot as plt u[0, :] = u_inlet # Inlet
: # Grid parameters
u[-1, :] = u[-2, :] # Outlet
u[:, 0] = 0 # Bottom wall (no-
nx, ny = 50, 50 slip)
Lx, Ly = 1.0, 1.0 u[:, -1] = 0 # Top wall (no-slip)
dx, dy = Lx/nx, Ly/ny v[0, :] = 0
v[-1, :] = 0
# Flow properties v[:, 0] = 0
rho = 1.0 # Density (kg/m^3) v[:, -1] = 0
mu = 0.01 # Dynamic viscosity
(Pa.s) def solve_momentum_equations():
u_inlet = 1.0 # Inlet velocity (m/s) for i in range(1, nx+1):
max_iter = 1000 for j in range(1, ny+1):
tol = 1e-4 u[i,j] = ((mu*(u[i+1,j] + u[i-1,j]) /
dx**2 +
# Initialize fields mu*(u[i,j+1] + u[i,j-1]) /
u = np.zeros((nx+2, ny+2)) # x- dy**2 -
velocity (p[i+1,j] - p[i-1,j]) /
v = np.zeros((nx+2, ny+2)) # y- (2*dx)) /
velocity (2*mu*(1/dx*2 + 1/dy*2)))
p = np.zeros((nx+2, ny+2)) # v[i,j] = ((mu*(v[i+1,j] + v[i-1,j]) /
pressure dx**2 +
pc = np.zeros_like(p) mu*(v[i,j+1] + v[i,j-1]) /
dy**2 -
# Coefficients (p[i,j+1] - p[i,j-1]) /
aE = np.zeros_like(p) (2*dy)) /
aW = np.zeros_like(p) (2*mu*(1/dx*2 + 1/dy*2)))
aN = np.zeros_like(p)
def correct_velocity_pressure():
for i in range(1, nx+1):
for j in range(1, ny+1): # Plotting velocity contours
p[i,j] += 1.8 * pc[i,j] # Over- X, Y = np.meshgrid(np.linspace(0, Lx, nx+2),
relaxation np.linspace(0, Ly, ny+2))
u[i,j] += -(dx/rho) * (pc[i+1,j] - velocity = np.sqrt(u.T*2 + v.T*2)
pc[i,j])
v[i,j] += -(dy/rho) * (pc[i,j+1] - plt.figure(figsize=(8, 6))
pc[i,j]) cp = plt.contourf(X, Y, velocity, levels=20, cmap='jet')
plt.colorbar(cp, label="Velocity magnitude (m/s)")
def check_convergence(u_old, v_old): plt.title("Velocity Contours Over Airfoil-like Surface")
diff_u = np.linalg.norm(u - u_old) plt.xlabel("X")
diff_v = np.linalg.norm(v - v_old) plt.ylabel("Y")
return diff_u < tol and diff_v < tol plt.tight_layout()
plt.show()
# Main SIMPLEC loop
for it in range(max_iter):
u_old = u.copy()
v_old = v.copy()

apply_boundary_conditions()
solve_momentum_equations()
solve_pressure_correction()
correct_velocity_pressure()

if check_convergence(u_old, v_old):
print(f"Converged in {it}
iterations.")
break
Elliptic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
% Create airfoil mask (elliptical obstacle in
Code clc; clear; center)
: % Domain and grid
cx = Lx/2; cy = Ly/2;
rx = 0.1; ry = 0.05;
nx = 100; ny = 50; airfoil_mask = ((X - cx).^2 / rx^2 + (Y - cy).^2 /
Lx = 2; Ly = 1; ry^2) <= 1;
dx = Lx / nx; dy = Ly / ny;
% Main loop
% Grid for iter = 1:max_iter
x = linspace(0, Lx, nx+2); u_old = u; v_old = v; p_old = p;
y = linspace(0, Ly, ny+2);
[X, Y] = meshgrid(x, y); % --- Apply boundary conditions ---
u(1,:) = U_in; % inlet
% Flow properties u(end,:) = u(end-1,:); % outlet (Neumann)
rho = 1.0; u(:,[1 end]) = 0; % top/bottom wall
mu = 1.5e-5; v(1,:) = 0; v(end,:) = 0;
U_in = 1.0; v(:,[1 end]) = 0;

% Initialize fields % --- Momentum equations ---


u = zeros(nx+1, ny+2); % staggered in x for i = 2:nx
v = zeros(nx+2, ny+1); % staggered in y for j = 2:ny+1
p = zeros(nx+2, ny+2); % pressure if airfoil_mask(j,i), u(i,j) = 0; continue;
end
% SIMPLEC parameters ue = u(i+1,j); uw = u(i-1,j);
alpha_u = 0.7; un = u(i,j+1); us = u(i,j-1);
alpha_p = 0.3; dpdx = (p(i,j) - p(i+1,j)) / dx;
max_iter = 1000;
tolerance = 1e-5; Ap = rho * (2/dx^2 + 2/dy^2);
u(i,j) = ((rho/dx^2)*(ue + uw) +
for i = 2:nx+1
for i = 2:nx+1
for j = 2:ny
for j = 2:ny
if airfoil_mask(j,i), v(i,j) = 0; continue;
v(i,j) = v(i,j) + alpha_u * (p_corr(i,j) -
end
p_corr(i,j+1)) * dy;
ve = v(i+1,j); vw = v(i-1,j);
end
vn = v(i,j+1); vs = v(i,j-1);
end
dpdy = (p(i,j) - p(i,j+1)) / dy;
% --- Convergence check ---
err = max([max(max(abs(u - u_old))),
Ap = rho * (2/dx^2 + 2/dy^2);
max(max(abs(v - v_old))), max(max(abs(p -
v(i,j) = ((rho/dx^2)*(ve + vw) +
p_old)))]);
(rho/dy^2)*(vn + vs) - dpdy) / Ap;
if err < tolerance
end
disp(['Converged in ', num2str(iter), '
end
iterations']);
% --- Pressure correction ---
break;
p_corr = zeros(nx+2, ny+2);
end
for i = 2:nx+1
end
for j = 2:ny+1
% --- Postprocessing: Plot velocity field ---
if airfoil_mask(j,i), continue; end
u_center = 0.5 * (u(1:end-1,:) + u(2:end,:));
div = ((u(i-1,j) - u(i,j))/dx + (v(i,j-1) -
v_center = 0.5 * (v(:,1:end-1) + v(:,2:end));
v(i,j))/dy);
u_center(airfoil_mask) = NaN;
p_corr(i,j) = alpha_p * div;
v_center(airfoil_mask) = NaN;
end
figure;
end
quiver(X', Y', u_center, v_center);
% --- Correct pressure and velocities ---
hold on;
p = p + p_corr;
contour(X, Y, airfoil_mask, [1 1], 'k', 'LineWidth',
for i = 2:nx
2);
for j = 2:ny+1
title('Flow Field using SIMPLEC (Elliptic Navier-
u(i,j) = u(i,j) + alpha_u * (p_corr(i,j) -
Stokes)');
p_corr(i+1,j)) * dx;
PISO MATLAB Algorithms-
Flow over a Blunt body

(Pressure Implicit with Splitting of


Operators)
Type: Time-marching algorithm
Best for: Unsteady (transient)
incompressible flows

Pros:
• Fast convergence per time step
• No need for under-relaxation
• Accurate for unsteady problems
Cons:
• Higher memory cost
• Less efficient for purely steady flows
Hyperbolic
Equation
Algorithm
:
• Predict velocity from momentum (ignore pressure gradient).
• Solve pressure correction using continuity (mass conservation).
• Correct velocity.
• Repeat pressure-velocity coupling for second corrector step
(PISO-specific).
• March forward in time.
% Compute fluxes in x and y directions
Code clc; clear;
Fx = [rhou; rhou.^2 ./ rho + p; rhou.*rhov ./ rho; (E + p).*u];
: % Domain
Fy = [rhov; rhou.*rhov ./ rho; rhov.^2 ./ rho + p; (E + p).*v];

nx = 100; ny = 50;
% Update using finite volume
Lx = 4; Ly = 2;
for i = 2:nx-1
dx = Lx / nx; dy = Ly / ny;
for j = 2:ny-1
x = linspace(0, Lx, nx);
if blunt(j,i), continue; end
y = linspace(0, Ly, ny);
rho(j,i) = rho(j,i) - dt/dx * (rhou(j,i+1) - rhou(j,i));
[X, Y] = meshgrid(x, y);
u(j,i) = u(j,i) - dt/dx * ((u(j,i+1)^2 + p(j,i+1)/rho(j,i+1))
- ...
% Flow parameters
(u(j,i)^2 + p(j,i)/rho(j,i)));
gamma = 1.4;
v(j,i) = v(j,i) - dt/dy * ((v(j+1,i)^2 + p(j+1,i)/rho(j+1,i))
rho = ones(ny, nx);
- ...
u = ones(ny, nx) * 2;% Mach 2 inflow
(v(j,i)^2 + p(j,i)/rho(j,i)));
v = zeros(ny, nx);
p(j,i) = p(j,i) - gamma * p(j,i) * ( ...
p = ones(ny, nx);
(u(j,i+1) - u(j,i))/dx + (v(j+1,i) - v(j,i))/dy ) * dt;
dt = 0.001;
end
time_steps = 500;
end
% PISO Correction Step 1
% Blunt body (circular)
% Recalculate pressure correction from continuity
cx = Lx/3; cy = Ly/2; r = 0.3;
% Correct u, v accordingly (basic form shown)
blunt = ((X - cx).^2 + (Y - cy).^2) <= r^2;

for i = 2:nx-1
% Main time loop
for j = 2:ny-1
for t = 1:time_steps
if blunt(j,i), continue; end
% Step 1: Predictor - compute momentum
div_uv = (u(j,i+1) - u(j,i-1))/(2*dx) + (v(j+1,i) -
fluxes
v(j-1,i))/(2*dy);
rhou = rho .* u;
p(j,i) = p(j,i) - gamma * p(j,i) * div_uv * dt;
rhov = rho .* v;
Parabolic
Equation
Algorithm
:
• Predict velocity field using previous pressure.
• Correct pressure by solving pressure Poisson equation from
continuity.
• Correct velocities using pressure corrections.
• Optional: apply a second pressure correction (PISO's edge).
• Advance to the next time step.
clc; clear; % Apply inlet and wall BCs
Code u(:,1) = 1; % Inlet
: % Domain setup
nx = 100; ny = 100;
u(:,end) = u(:,end-1);
v(:,1) = 0; v(:,end) = 0;
% Outlet (Neumann)

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


dx = Lx/nx; dy = Ly/ny;
x = linspace(0, Lx, nx); % Predictor: solve u*, v* without updated pressure
y = linspace(0, Ly, ny); for i = 2:nx
[X, Y] = meshgrid(x, y); for j = 2:ny-1
if blunt(j,i), continue; end
% Time and physical parameters
dt = 0.002; % Time step % u-momentum
nt = 1000; % Number of time steps dudt = -((u(j,i+1)^2 - u(j,i-1)^2)/(2*dx)) ...
Re = 100; % Reynolds number - ((v(j+1,i)*u(j+1,i) - v(j-1,i)*u(j-1,i))/(2*dy)) ...
nu = 1/Re; % Kinematic viscosity + nu * ((u(j,i+1) - 2*u(j,i) + u(j,i-1))/dx^2 + ...
rho = 1; % Density (u(j+1,i) - 2*u(j,i) + u(j-1,i))/dy^2) ...
- (p(j,i) - p(j,i-1))/dx / rho;
% Velocity and pressure fields u_star(j,i) = u(j,i) + dt * dudt;
u = zeros(ny, nx+1);% staggered in x
v = zeros(ny+1, nx);% staggered in y % v-momentum
p = zeros(ny, nx);% cell-centered 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)) ...
% Define blunt body mask (cylinder) + nu * ((v(j,i+1) - 2*v(j,i) + v(j,i-1))/dx^2 + ...
cx = Lx/2; cy = Ly/2; R = 0.2; (v(j+1,i) - 2*v(j,i) + v(j-1,i))/dy^2) ...
blunt = ((X - cx).^2 + (Y - cy).^2) < R^2; - (p(j,i) - p(j-1,i))/dy / rho;
v_star(j,i) = v(j,i) + dt * dvdt;
% Main PISO loop over time end
for t = 1:nt end
u_star = u;
% 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;
Elliptic
Equation
Algorithm
:
• Discretize domain in x and y.
• Apply inlet profile (e.g., uniform u, v = 0).
• For each marching step in x:
1.Guess pressure.
2.Solve momentum equation (only in x-
direction) for u.
3.Solve pressure correction equation from
continuity.
4.Correct u and compute v from continuity.
• Apply boundary conditions and iterate
clc; clear; u_star = u;
Code v_star = v;
: % Grid parameters
nx = 100; ny = 100; % Predictor step: update velocities (pseudo-unsteady)
Lx = 2.0; Ly = 2.0; for i = 2:nx-1
dx = Lx/nx; dy = Ly/ny; for j = 2:ny-1
x = linspace(0, Lx, nx); if blunt(j,i), continue; end
y = linspace(0, Ly, ny);
[X, Y] = meshgrid(x, y); % Convective and diffusive terms for u
du = -u(j,i)*(u(j,i+1)-u(j,i-1))/(2*dx) ...
% Physical properties - v(j,i)*(u(j+1,i)-u(j-1,i))/(2*dy) ...
rho = 1;% Density + nu*((u(j,i+1) - 2*u(j,i) + u(j,i-1))/dx^2 + ...
Re = 100;% Reynolds number (u(j+1,i) - 2*u(j,i) + u(j-1,i))/dy^2);
nu = 1/Re;% Kinematic viscosity % Convective and diffusive terms for v
dv = -u(j,i)*(v(j,i+1)-v(j,i-1))/(2*dx) ...
% Fields - v(j,i)*(v(j+1,i)-v(j-1,i))/(2*dy) ...
u = ones(ny, nx);% x-velocity initialized to + nu*((v(j,i+1) - 2*v(j,i) + v(j,i-1))/dx^2 + ...
inflow (v(j+1,i) - 2*v(j,i) + v(j-1,i))/dy^2);
v = zeros(ny, nx);% y-velocity
p = zeros(ny, nx);% Pressure 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);
% Blunt body mask (circular cylinder) end
cx = Lx/2; cy = Ly/2; R = 0.2; end
blunt = ((X - cx).^2 + (Y - cy).^2) < R^2;
% Pressure correction from continuity
% Iteration parameters div = zeros(ny, nx);
max_iter = 1000; for i = 2:nx-1
tol = 1e-5; for j = 2:ny-1
dt = 0.01; % pseudo-time step for PISO-like div(j,i) = ((u_star(j,i) - u_star(j,i-1))/dx + ...
end
v(:,[1 end]) = 0;
end
v([1 end],:) = 0;
u(blunt) = 0; v(blunt) = 0;
% Pressure Poisson equation
for it_p = 1:100
% Convergence check
p_old = p;
res = max(max(abs(div)));
for i = 2:nx-1
if res < tol
for j = 2:ny-1
fprintf('Converged at iteration %d\n', iter);
if blunt(j,i), continue; end
break;
p(j,i) = 0.25*(p(j+1,i) + p(j-1,i) + p(j,i+1) + p(j,i-1) - ...
end
rho/dt * div(j,i) * dx^2);
end
% Plot every 100 iterations
end
if mod(iter,100) == 0
if max(max(abs(p - p_old))) < 1e-4
u_center = u;
break;
v_center = v;
end
vel = sqrt(u_center.^2 + v_center.^2);
end
vel(blunt) = NaN;
contourf(X, Y, vel, 20, 'LineColor','none');
% Correct velocities
axis equal tight;
for i = 2:nx-1
title(['Steady Flow Velocity Magnitude – Iteration: ' num2str(iter)]);
for j = 2:ny-1
colorbar;
if blunt(j,i), continue; end
drawnow;
u(j,i) = u_star(j,i) - dt/dx * (p(j,i) - p(j,i-1))/rho;
end
v(j,i) = v_star(j,i) - dt/dy * (p(j,i) - p(j-1,i))/rho;
end
end
end
% Boundary conditions
u(:,1) = 1; % Inlet
u(:,end) = u(:,end-1); % Outlet
u([1 end],:) = 0; % Top/bottom walls

You might also like