Showing posts with label coding. Show all posts
Showing posts with label coding. Show all posts

Saturday, 26 August 2023

Open - Source coded 3D Navier–Stokes equations in C++

     Here are 3D Navier–Stokes equations configured for lid-driven cavity flow. The syntax is C++. The results from this code are shown in Fig. 1. From the pressure-Poisson equation, I removed mixed derivative terms to improve solution stability. 😆

p[i][j][k] = ((p[i+1][j][k] + p[i-1][j][k]) * h * h + (p[i][j+1][k] + p[i][j-1][k]) * h * h + (p[i][j][k+1] + p[i][j][k-1]) * h * h) / (2 * (h * h + h * h + h * h)) - h * h * h * h * h * h / (2 * (h * h + h * h + h * h)) * (rho * (1 / dt * ((u(i+1, j, k) - u(i-1, j, k)) / (2 * h) + (v(i, j+1, k) - v(i, j-1, k)) / (2 * h) + (w(i, j, k+1) - w(i, j, k-1)) / (2 * h))));

p[0][j][k] = p[1][j][k];

p[num_i - 1][j][k] = p[num_i - 2][j][k];

p[i][0][k] = p[i][1][k];

p[i][num_j - 1][k] = p[i][num_j - 2][k];

p[i][j][0] = p[i][j][1];

p[i][j][num_k - 1] = 0.0;

u[i][j][k] = u[i][j][k] - u[i][j][k] * dt / (2 * h) * (u[i+1][j][k] - u[i-1][j][k]) - v[i][j][k] * dt / (2 * h) * (u[i][j+1][k] - u[i][j-1][k]) - w[i][j][k] * dt / (2 * h) * (u[i][j][k+1] - u[i][j][k-1]) - dt / (2 * rho * h) * (p[i+1][j][k] - p[i-1][j][k]) + nu * (dt / (h * h) * (u[i+1][j][k] - 2 * u[i][j][k] + u[i-1][j][k]) + dt / (h * h) * (u[i][j+1] [k] - 2 * u[i][j][k] + u[i][j-1][k]) + dt / (h * h) * (u[i][j][k+1] - 2 * u[i][j][k] + u[i][j][k-1]));

u[0][j][k] = 0.0;

u[num_i - 1][j][k] = 0.0;

u[i][0][k] = 0.0;

u[i][num_j - 1][k] = 0.0;

u[i][j][0] = 0.0;

u[i][j][num_k - 1] = -Uinf;

v[i][j][k] = v[i][j][k] - u[i][j][k] * dt / (2 * h) * (v[i+1][j][k] - v[i-1][j][k]) - v[i][j][k] * dt / (2 * h) * (v[i][j+1][k] - v[i][j-1][k]) - w[i][j][k] * dt / (2 * h) * (v[i][j][k+1] - v[i][j][k-1]) - dt / (2 * rho * h) * (p[i][j+1][k] - p[i][j-1][k]) + nu * (dt / (h * h) * (v[i+1][j][k] - 2 * v[i][j][k] + v[i-1][j][k]) + dt / (h * h) * (v[i][j+1][k] - 2 * v[i][j][k] + v[i][j-1][k]) + dt / (h * h) * (v[i][j][k+1] - 2 * v[i][j][k] + v[i][j][k-1]));

v[0][j][k] = 0.0;

v[num_i - 1][j][k] = 0.0;

v[i][0][k] = 0.0;

v[i][num_j - 1][k] = 0.0;

v[i][j][0] = 0.0;

v[i][j][num_k - 1] = 0.0;

w[i][j][k] = w[i][j][k] - u[i][j][k] * dt / (2 * h) * (w[i+1][j][k] - w[i-1][j][k]) - v[i][j][k] * dt / (2 * h) * (w[i][j+1][k] - w[i][j-1][k]) - w[i][j][k] * dt / (2 * h) * (w[i][j][k+1] - w[i][j][k-1]) - dt / (2 * rho * h) * (p[i][j][k+1] - p[i][j][k-1]) + nu * (dt / (h * h) * (w[i+1][j][k] - 2 * w[i][j][k] + w[i-1][j][k]) + dt / (h * h) * (w[i][j+1][k] - 2 * w[i][j][k] + w[i][j-1][k]) + dt / (h * h) * (w[i][j][k+1] - 2 * w[i][j][k] + w[i][j][k-1]));

w[0][j][k] = 0.0;

w[num_i - 1][j][k] = 0.0;

w[i][0][k] = 0.0;

w[i][num_j - 1][k] = 0.0;

w[i][j][0] = 0.0;

w[i][j][num_k - 1] = 0.0;


Fig. 1, Velocity and pressure iso-surfaces


     Of course constants need to be defined, such as grid spacing in space and time, density, kinematic viscosity. These equations have been validated, as you might have read and here already! Happy coding!

     If you want to hire me as your PhD student in the research projects related to turbo-machinery, aerodynamics, renewable energy, please reach out. Thank you very much for reading.

Monday, 10 July 2023

CFD Basics: Code Vectorization

     This post is about comparing 2 codes to solve the 2D Laplace equation using finite difference method. A sample code mentioned under "Code 01" uses nested loops. We must, wherever possible avoid nested loops. The solution to the code is shown in Fig. 1. The second code uses vectorization instead of the nested loops. The vectorized version is mentioned under  "Code 02".

Code 01

clear
clc
close all
%% Parameters
Lx = 1; % Length of the domain in the x-direction
Ly = 1; % Length of the domain in the y-direction
Nx = 201; % Number of grid points in the x-direction
Ny = 201; % Number of grid points in the y-direction
dx = Lx / (Nx - 1); % Grid spacing in the x-direction
dy = Ly / (Ny - 1); % Grid spacing in the y-direction
%% Initialize temperature matrix
T = zeros(Nx, Ny);
T(:, 1) = 100;
T(:, Nx) = 0;
T(1, :) = 25;
T(Ny, :) = 50;
%% Gauss-Seidel iteration
max_iter = 50000; % Maximum number of iterations
tolerance = 1e-10; % Convergence tolerance
error = inf; % Initialize error
iter = 0; % Iteration counter
while error > tolerance && iter < max_iter
T_old = T;
% Solve Laplace equation using Gauss-Seidel iterations
for i = 2:Nx-1
for j = 2:Ny-1
T(i, j) = ((T(i+1, j) + T(i-1, j))*dy^2 + (T(i, j+1) + T(i, j-1))*dx^2) / (2*(dx^2 + dy^2));
end
end
% Compute error
error = max(abs(T(:) - T_old(:)));
% Increment iteration counter
iter = iter + 1;
end
%% plotting
[X, Y] = meshgrid(0:dx:Lx, 0:dy:Ly);
contourf(X, Y, T')
axis equal
colormap jet
colorbar
clim([0 100])
title('Temperature Distribution Non Vec')
xlabel('x')
ylabel('y')
zlabel('Temperature (T)')
colorbar

Code 02

clear
clc
close all
%% Parameters
Lx = 1; % Length of the domain in the x-direction
Ly = 1; % Length of the domain in the y-direction
Nx = 201; % Number of grid points in the x-direction
Ny = 201; % Number of grid points in the y-direction
dx = Lx / (Nx - 1); % Grid spacing in the x-direction
dy = Ly / (Ny - 1); % Grid spacing in the y-direction
i = 2:Nx-1;
j = 2:Ny-1;
%% Initialize temperature matrix
T = zeros(Nx, Ny);
T(:, 1) = 100;
T(:, Nx) = 0;
T(1, :) = 25;
T(Ny, :) = 50;
%% Gauss-Seidel iteration
max_iter = 50000; % Maximum number of iterations
tolerance = 1e-10; % Convergence tolerance
error = inf; % Initialize error
iter = 0; % Iteration counter
while error > tolerance && iter < max_iter
T_old = T;
% Solve Laplace equation using Gauss-Seidel iterations
T(i, j) = ((T(i+1, j) + T(i-1, j))*dy^2 + (T(i, j+1) + T(i, j-1))*dx^2) / (2*(dx^2 + dy^2));
% Compute error
error = max(abs(T(:) - T_old(:)));
% Increment iteration counter
iter = iter + 1;
end
%% plotting
[X, Y] = meshgrid(0:dx:Lx, 0:dy:Ly);
contourf(X, Y, T')
axis equal
colormap jet
colorbar
clim([0 100])
title('Temperature Distribution Vec')
xlabel('x')
ylabel('y')
zlabel('Temperature (T)')
colorbar

Result

Results say that vectorized code is ~1.5x faster than nested looped code for 200x200 matrix. Simulation results are now presented.

Fig. 1, Vectorized VS Nested Loops


Thank you for reading! I hope you learned something new! If you like this blog and want to hire me as your PhD student, please get in touch!