Showing posts with label lid driven cavity. Show all posts
Showing posts with label lid driven cavity. Show all posts

Wednesday, 3 April 2024

Airflow Simulation in Empty / Occupied Rooms and Environments

     One fine morning, I decided to code the Navier–Stokes equations [read if you are bored πŸ€£] . This post has the results of  flow simulation inside close environments of various aspect ratios. As is customary with all my CFD work using commercial and 🏑made CFD codes, this too is inspired by the free lectures of Dr. Lorena Barba.

The first case has an aspect ratio of 1:1 while for the second case, the aspect ratio is at 3:1. The airflow is at 0.4555 m/s for both cases. Both cases are isothermal at 293 K. There is no turbulence 🌬model [free code ] πŸ€‘.

The smallest resolved scale (~4x smallest mesh size) for 1:1 case is ~ 0.0045 m and for the 3:1 case is at 0.0112 m. Time scales (~4x time-step size) are at 0.0004 s and 0.0004 s, respectively. Fig. 1 shows results for 1:1 aspect ratio while the results for 3:1 case are shown in Fig. 2. For both cases, flow enters from top-left and exists at bottom-right of the rooms. The boundary conditions are taken from [1]. I compared the results with Fluent simulations I ran at same boundary conditions and stopped my simulations when eye-balling didn't revealed any difference πŸ˜†. What you expect? This is a blog not a journal 😝.


Fig. 1, 1:1 aspect ratio


Fig. 2, 3:1 aspect ratio

 
Fig. 3, 3:1 aspect ratio with partition


Fig. 4, Flow inside ducts


     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.

References

     [1] Horikiri, Kana & Yao, Yufeng. Validation Study of Convective Airflow in an Empty Room, "Recent Researches in Energy, Environment, Devices, Systems, Communications and Computers", ISBN: 978-960-474-284-4

Thursday, 21 September 2023

Lid-Driven Cavity MATLAB Code

     MATLAB code for 2D Lid-Driven Cavity. Includes labeled commands, plotting and is less than 100 lines of code. Resume possible, to resume comment close all, clear, clc, u, v, p and then run the code. Results are available here:


%% clear and close

close all

clear

clc


%% define spatial and temporal grids

h = 1/10; % grid spacing

cfl = h; % cfl number

L = 1; % cavity length

D = 1; % cavity depth

Nx = round((L/h)+1); % grid points in x-axis

Ny = round((D/h)+1); % grid points in y-axis

nu = 0.000015111; % kinematic viscosity

Uinf = 0.0015111; % free stream velocity / lid velocity

dt = h * cfl / Uinf; % time step

travel = 2; % times the disturbance travels entire length of computational domain

TT = travel * L / Uinf; % total time

ns = TT / dt; % number of time steps

l_square = 1; % length of square

Re = l_square * Uinf / nu; % Reynolds number

rho = 1.2047; % fluid density


%% initialize flowfield

u = zeros(Nx,Ny); % x-velocity

v = zeros(Nx,Ny); % y-velocity

p = zeros(Nx,Ny); % pressure

i = 2:Nx-1; % spatial interior nodes in x-axis

j = 2:Ny-1; % spatial interior nodes in y-axis

[X, Y] = meshgrid(0:h:L, 0:h:D); % spatial grid

maxNumCompThreads('automatic'); % select CPU cores


%% solve 2D Navier-Stokes equations

for nt = 1:ns

    pn = p;

    p(i, j) = ((pn(i+1, j) + pn(i-1, j)) * h^2 + (pn(i, j+1) + pn(i, j-1)) * h^2) ./ (2 * (h^2 + h^2)) ...

        - h^2 * h^2 / (2 * (h^2 + h^2)) * (rho * (1 / dt * ((u(i+1, j) - u(i-1, j)) / (2 * h) + (v(i, j+1) - v(i, j-1)) / (2 * h)))); % pressure poisson

    p(1, :) = p(2, :); % dp/dx = 0 at x = 0

    p(Nx, :) = p(Nx-1, :); % dp/dx = 0 at x = L

    p(:, 1) = p(:, 2); % dp/dy = 0 at y = 0

    p(:, Ny) = 0; % p = 0 at y = D 

    un = u;

    vn = v;

    u(i, j) = un(i, j) - un(i, j) * dt / (2 * h) .* (un(i+1, j) - un(i-1, j)) ...

        - vn(i, j) * dt / (2 * h) .* (un(i, j+1) - un(i, j-1)) - dt / (2 * rho * h) * (p(i+1, j) - p(i-1, j)) ...

        + nu * (dt / h^2 * (un(i+1, j) - 2 * un(i, j) + un(i-1, j)) + dt / h^2 * (un(i, j+1) - 2 * un(i, j) + un(i, j-1))); % x-momentum

    u(1, :) = 0; % u = 0 at x = 0

    u(Nx, :) = 0; % u = 0 at x = L

    u(:, 1) = 0; % u = 0 at y = 0

    u(:, Ny) = Uinf; % u = Uinf at y = D

    v(i, j) = vn(i, j) - un(i, j) * dt / (2 * h) .* (vn(i+1, j) - vn(i-1, j)) ...

        - vn(i, j) * dt / (2 * h) .* (vn(i, j+1) - vn(i, j-1)) - dt / (2  * rho * h) * (p(i, j+1) - p(i, j-1)) ...

        + nu * (dt / h^2 * (vn(i+1, j) - 2 * vn(i, j) + vn(i-1, j)) + dt / h^2 * (vn(i, j+1) - 2 * vn(i, j) + vn(i, j-1))); % y-momentum

    v(1, :) = 0; % v = 0 at x = 0

    v(Nx, :) = 0; % v = 0 at x = L

    v(:, 1) = 0; % v = 0 at y = 0

    v(:, Ny) = 0; % v = 0 at y = D

end


%% post-processing

velocity_magnitude = sqrt(u.^2 + v.^2); % velocity magnitude


% Visualize velocity vectors and pressure contours

hold on

contourf(X, Y, velocity_magnitude', 64, 'LineColor', 'none'); % contour plot

set(gca,'FontSize',40)

% skip = 20;

% quiver(X(1:skip:end, 1:skip:end), Y(1:skip:end, 1:skip:end),... % Velocity vectors

%     u1(1:skip:end, 1:skip:end)', v1(1:skip:end, 1:skip:end)', 1, 'k','LineWidth', 0.1);

hh = streamslice(X, Y, u', v', 5); % Streamlines

set(hh, 'Color', 'k','LineWidth', 0.1);

colorbar; % Add color bar

colormap hsv % Set color map

axis equal % Set true scale

xlim([0 L]); % Set axis limits

ylim([0 D]);

xticks([0 L]) % Set ticks

yticks([0 D]) % Set ticks

clim([0 0.95*max(velocity_magnitude(:))]) % Legend limits

title('Velocity [m/s]');

xlabel('x [m]');

ylabel('y [m]');


Cite as: Fahad Butt (2023). Lid-Driven Cavity (https://fluiddynamicscomputer.blogspot.com/2023/09/lid-driven-cavity-matlab-code.html), Blogger. Retrieved Month Date, Year

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, 14 August 2023

Heaving Flat Plate Computational Fluid Dynamics (CFD) Simulation (In-House CFD Code)

     The adventure πŸ• 🚡 I started a while ago to make my own CFD 🌬 code / software πŸ’» for my digital CV and to make a shiny new turbulence mode (one-day perhaps) is going along nicely. This post is about a 2D 10% flat plate undergoing forced heaving motion. Heaving motion is achieved by Eqn. 1.


hy = Ho*sin(2*Ο€*fh*t)                                              Eqn. 1

     w.r.t. Eqn. 1 reduced frequency is defined as (fh*Ho/U∞)), fh is the frequency of oscillations, while t is the instantaneous time. Ho is the heaving amplitude and U∞ is the free stream velocity. hy is the position of the flat plate. The animation is shown in Fig. 1.

     The Strouhal number is 0.228 and Reynolds number is at 500. As we can see, the in-house CFD code works very well for this complex CFD simulation. Validation of this work will never be completed πŸ˜†. As soon, I will move on to the next project without completing this one. Anyway, discretized Navier-Stokes equations are available here, in both C++ and MATLAB formats if you want to validate this non sense yourself! Good Luck!

The animation from in-house CFD simulation

     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.

Saturday, 22 July 2023

Home-Made Computational Fluid Dynamics (CFD), (Includes CFD code)

     One fine morning, I decided to code the Navier–Stokes equations using the finite-difference method. This post has the results of this adventure πŸž️ (so-far). As is customary with all my CFD work using commercial and home-made CFD codes, this too is inspired by the free lectures of Dr. Lorena Barba.

Internal / External Fluid Dynamics - Lid-Driven Cavity

     I started using Lid-Driven Cavity example. Just because everyone else uses it to validate the code they write. The lid-driven cavity case is giving correct results up to ~Re 1,000 without any turbulence models or wall functions.

     The results shown in Fig. 1 correspond to at Re 1,000. It can be seen that the present code which is just vanilla Navier–Stokes; captures the vortices at both bottom edges well as compared to published data. But why would you want to use a vanilla CFD code which solved only ~Re 1,000?, anyways... Some validation... u-velocity at (0.5, 0.1719) is at -0.3869 m/s as compared to -0.38289 m/s [1]. Meanwhile, v-velocity at (0.2266, 0.5) is 0.3252 as compared to 0.30203. Furthermore, v-velocity at (0.8594, 0.5) is at -0.4128 m/s as compared to -0.44993 m/s. All in all, a good agreement with published data. An animation is uploaded here.  Fig. 1a shows a different variation of lid driven cavity.


Fig. 1, Lid driven cavity post-processing


Fig. 1a, Heated lid driven cavity post-processing

Internal / External Aerodynamics - Backward-Facing Step (BFS)

     The next example is the case of Backward Facing Step (BFS). This case is analogues to flow around a building or a pipe with different diameter or anything with sharp edge along the flow. Let's be honest, flow around a building πŸ’ is at much higher Re than the measly ~1,000 this code solves. But for validation, here we are.
 
     The cases are self validating as the re-attachment length of the vortex just after the step is very well documented [4]. Fig. 2 compares the results from the vanilla code with published data. It can be seen that the results are in good agreement.

Fig. 2, Backward Facing Step (BFS) post processing at Re 200


Internal Fluid Dynamics - Aero-Thermal Pipe Flow

     This is the first case I ran as it is self validating. The product of area and velocity should be same at  the outlet as given at the inlet as a boundary condition, which it is! Furthermore, density calculated should be proportional to the temperature calculated, which it is! The results at Re ~3300 are shown in Fig. 3. This case is relevant to bio medical field as Reynolds number in human blood πŸ©Έflow is around same flow regime. Moreover, flow through heated pipes etc. is also relevant.

Fig. 3, Flow through heated pipe / between flat plates

Clot Flow

     Fig. 4 shows an example of flow where a clot appears in a blood 🩸 vessel. Done on this same 🏑made CFD 🌬️ code used throughout this blog. Or in a pipe where oil πŸ›’️ flows. It can be seen how smooth /less chaotic the flow is without clot (less work for heart ❤️ ). Eat 🦐 πŸ₯‘ πŸ₯™ πŸ₯• πŸ₯’ 🍲 healthy! Mechanical properties of fluid are taken as follows. 5 ltr/min flowrate. Blood vessel diameter 40 mm. Fluid density at 1,070 Kg/m3 and dynamic viscosity at 4.5 cP.

Fig. 4, Flow inside a blood vessel with and without clot


External Aerodynamics - Flow around a Square Cylinder

     Why not circular cylinder you ask? I am very lazy πŸ˜‚. It is hard work to draw a circle using code. I am used to CAD. πŸ˜‡. Again, low Reynolds number are very rare in practical applications but for the sake of completeness, I added this case as well. Fig. 5 shows flow around the cylinder at Re 100. Vorticity is shown in Fig. 5. The results are compared with experimental data. The Strouhal number from the home-made CFD code is at 0.158 as compared to a value of 0.148. The results are within 7%  of published literature [2-3].


Fig. 5, Post-processing

Thank you for reading! If you want to hire me as your most awesome PhD student, please reach out!

Code:

     I present to you the code-able discretized equations for solving fluid flow problems. At first, C++ version is presented followed by the MATLAB version. Equation 1-2 are Poisson equations for pressure. Equation 3 and 4 are x-momentum equations (without source). Equations 5 and 6 are y-momentum equations.

double p_ij = ((pn(i + 1, j) + pn(i - 1, j)) * dy * dy + (pn(i, j + 1) + pn(i, j - 1)) * dx * dx) / (2 * (dx * dx + dy * dy)) - dx * dx * dy * dy / (2 * (dx * dx + dy * dy)) * (rho * (1 / dt * ((u(i + 1, j) - u(i - 1, j)) / (2 * dx) + (v(i, j + 1) - v(i, j - 1)) / (2 * dy)) - ((u(i + 1, j) - u(i - 1, j)) / (2 * dx)) * ((u(i + 1, j) - u(i - 1, j)) / (2 * dx)) - 2 * ((u(i, j + 1) - u(i, j - 1)) / (2 * dy) * (v(i + 1, j) - v(i - 1, j)) / (2 * dx)) - ((v(i, j + 1) - v(i, j - 1)) / (2 * dy)) * ((v(i, j + 1) - v(i, j - 1)) / (2 * dy))));                (1)

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

double u_ij = un(i, j) - un(i, j) * dt / dx * (un(i, j) - un(i - 1, j)) - vn(i, j) * dt / dy * (un(i, j) - un(i, j - 1)) - dt / (2 * rho * dx) * (p(i + 1, j) - p(i - 1, j)) + nu * (dt / (dx * dx) * (un(i + 1, j) - 2 * un(i, j) + un(i - 1, j)) + dt / (dy * dy) * (un(i, j + 1) - 2 * un(i, j) + un(i, j - 1)));                (3)


u(i, j) = un(i, j) - un(i, j) * dt/dx .* (un(i, j) - un(i-1, j)) - vn(i, j) * dt/dy .* (un(i, j) - un(i, j-1)) - dt / (2 * rho * dx) * (p(i+1, j) - p(i-1, j)) + nu * (dt/dx^2 * (un(i+1, j) - 2 * un(i, j) + un(i-1, j)) + (dt/dy^2 * (un(i, j+1) - 2 * un(i, j) + un(i, j-1))));                (4)


double v_ij = vn(i, j) - un(i, j) * dt / dx * (vn(i, j) - vn(i - 1, j)) - vn(i, j) * dt / dy * (vn(i, j) - vn(i, j - 1)) - dt / (2 * rho * dy) * (p(i, j + 1) - p(i, j - 1)) + nu * (dt / (dx * dx) * (vn(i + 1, j) - 2 * vn(i, j) + vn(i - 1, j)) + dt / (dy * dy) * (vn(i, j + 1) - 2 * vn(i, j) + vn(i, j - 1)));                (5)

v(i, j) = vn(i, j) - un(i, j) * dt/dx .* (vn(i, j) - vn(i-1, j)) - vn(i, j) * dt/dy .* (vn(i, j) - vn(i, j-1)) - dt / (2 * rho * dy) * (p(i, j+1) - p(i, j-1)) + nu * (dt/dx^2 * (vn(i+1, j) - 2 * vn(i, j) + vn(i-1, j)) + (dt/dy^2 * (vn(i, j+1) - 2 * vn(i, j) + vn(i, j-1))));                (6)
    

     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 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.


References

[1] U Ghia, K.N Ghia, C.T Shin, "High-Re solutions for incompressible flow using the Navier-Stokes equations and a multigrid method", Journal of Computational Physics, Volume 48, Issue 3, 1982, Pages 387-411, ISSN 0021-9991, https://doi.org/10.1016/0021-9991(82)90058-4
[2] Khademinejad, Taha & Talebizadeh Sardari, Pouyan & Rahimzadeh, Hassan. (2015). Numerical Study of Unsteady Flow around a Square Cylinder in Compare with Circular Cylinder
[3] Ávila, Ítalo & Santos, Gabriel & Ribeiro Neto, Hélio & Neto, Aristeu. (2019). Physical Mathematical and Computational Modeling of the Two-Dimensional Flow Over a Heated Porous Square Cylinder. 10.26678/ABCM.COBEM2019.COB2019-0854
[4] Irisarri, Diego & Hauke, Guillermo. (2019). Stabilized virtual element methods for the unsteady incompressible Navier–Stokes equations. Calcolo. 56. 10.1007/s10092-019-0332-5.