diff --git a/Driven_Cavity_Solver.m b/Driven_Cavity_Solver.m
new file mode 100644
index 0000000000000000000000000000000000000000..6c17e5e9d0e6ef83517a07eff2cbe3c7595dda13
--- /dev/null
+++ b/Driven_Cavity_Solver.m
@@ -0,0 +1,283 @@
+function Driven_Cavity_Solver()
+    %% Driven Cavity, Finite Volume Method
+    % Paul Bataillie - paul.bataillie@student.isae-supaero.fr
+    % ---------------------------------------------------------------------
+    
+    close all
+    clc
+    clear
+    
+    %% Constants and parameters
+    Lx = 1;
+    Ly = 1;
+    rho = 1000;
+    mu = 1e-3;
+    
+    % Underrelaxation factors
+    e  = 0.5;
+    ep = 0.2;
+     
+    % Max iterations
+    numItr = 10000;
+    numItrP = 800;
+    dispResiduals = 20;
+    
+    % Number of cells 
+    Npx = 20;
+    
+    disp(append("INFO: Initializing Case ",num2str(Npx),"x",num2str(Npx),"."))
+    disp(append("INFO: Under-Relaxation Factors | e = ",num2str(e)," | ep = ",num2str(ep)))
+    
+    Npy = Npx;  % The pressure matrix (grid) is a square
+    
+    Nvx = Npx+2;  % The v-matrix contains two more columns and one more row
+    Nvy = Npx+1;  % than the pressure matrix (including dummy cells) 
+    
+    Nux = Npx+1;  % The u-matrix contains one more column and two more rows
+    Nuy = Npy+2;  % than the pressure matrix (including dummy cells) 
+    
+    % Cell size
+    dx = Lx/(Npx);
+    dy = Ly/(Npy);
+    
+    % Residual tolerances
+    RCE = 1e-5;
+    RME = 1e-7;
+    
+    %Reynolds number
+    Re = 1000;
+    Re1 = 1/Re;
+    
+    % Some variables
+    Dew = Re1*dy/dx;
+    Dns = Re1*dx/dy;
+    
+    % Initialization
+    u = zeros(Nuy,Nux);    
+    unew = zeros(Nuy,Nux); 
+    
+    v = zeros(Nvy,Nvx);
+    vnew = zeros(Nvy,Nvx);
+    
+    p  = zeros(Npy,Npx);
+    pp = zeros(Npy+2,Npx+2);
+    pp1 = zeros(Npy+2,Npx+2);
+    
+    auP = 0*ones(Nuy,Nux);
+    avP = 0*ones(Nvy,Nvx);
+    
+    uo = u;
+    vo = v;
+    
+    scrsz = get(0,'ScreenSize');
+    
+    %Boundray Conditions
+    unew(end,:) = 2 - unew(end-1,:);
+    u(end,:) = 2 - u(end-1,:);
+    
+    %Residuals Variables
+    continuity_res_scale_value = 0;
+    u_residual_vector = zeros(numItr,1);
+    v_residual_vector = zeros(numItr,1);
+    c_residual_vector = zeros(numItr,1);
+    
+    %% Start of the solution process
+    format long
+    
+    disp("INFO: Solving...")
+    
+    for i=1:numItr
+        %% Solve momentum equations
+        %% ------
+        % Mex
+        % Average velocities for the flux terms
+        uue = 0.5*(u(2:end-1,3:end) + u(2:end-1,2:end-1));
+        uuw = 0.5*(u(2:end-1,1:end-2) + u(2:end-1,2:end-1));
+        vun = 0.5*(v(2:end,2:end-2) + v(2:end,3:end-1));
+        vus = 0.5*(v(1:end-1,2:end-2) + v(1:end-1,3:end-1));
+        
+        %Flux terms
+        Fue = dy*uue;
+        Fuw = dy*uuw;
+        Fun = dx*vun;
+        Fus = dx*vus;
+        
+        % Coefficients
+        auE = Dew + max(0,-Fue);
+        auW = Dew + max(0,Fuw);
+        auN = Dns + max(0,-Fun);
+        auS = Dns + max(0,Fus);
+        auP = auE + auW + auN + auS + Fue + Fun - Fuw - Fus;
+    
+        % Solve MEx
+        unew(2:end-1,2:end-1) = (auE.*u(2:end-1,3:end) + auW.*u(2:end-1,1:end-2) + auN.*u(3:end,2:end-1) + auS.*u(1:end-2,2:end-1) - (p(1:end,2:end) - p(1:end,1:end-1))*dy) ./ (auP);
+        
+        % Update boundary conditions
+        unew(end,:) = 2 - unew(end-1,:);
+        unew(:,1) = 0;
+        unew(:,end) = 0;
+        unew(1,:) = - unew(2,:);
+        
+        %% ------
+        % Mey
+        % Average velocities for the flux terms
+        uve = 0.5*(u(2:end-2,2:end) + u(3:end-1,2:end));
+        uvw = 0.5*(u(2:end-2,1:end-1) + u(3:end-1,1:end-1));
+        vvn = 0.5*(v(2:end-1,2:end-1) + v(3:end,2:end-1));
+        vvs = 0.5*(v(1:end-2,2:end-1) + v(2:end-1,2:end-1));
+    
+        %Flux terms
+        Fve = dy*uve;
+        Fvw = dy*uvw;
+        Fvn = dx*vvn;
+        Fvs = dx*vvs;
+        
+        % Coefficients
+        avE = Dew + max(0,-Fve);
+        avW = Dew + max(0,Fvw);
+        avN = Dns + max(0,-Fvn);
+        avS = Dns + max(0,Fvs);
+        avP = avE + avW + avN + avS + Fve + Fvn - Fvw - Fvs;
+        
+        % Solve MEy
+        vnew(2:end-1,2:end-1) = (avE.*v(2:end-1,3:end) + avW.*v(2:end-1,1:end-2) + avN.*v(3:end,2:end-1) + avS.*v(1:end-2,2:end-1) - (p(2:end,1:end) - p(1:end-1,1:end))*dx) ./ (avP);
+        
+        % Update boundary conditions
+        vnew(1,:) = 0;
+        vnew(end,:) = 0;
+        vnew(:,1) = - vnew(:,2);
+        vnew(:,end) = - vnew(:,end-1);
+        
+        %% ------
+        % Pressure correction 
+        pp1 = zeros(Npy+2,Npx+2);
+    
+        apE = zeros(Npy,Npx); 
+        apN = zeros(Npy,Npx);
+        apW = zeros(Npy,Npx);
+        apS = zeros(Npy,Npx);
+        
+        apE(:,1:end-1) = dy^2./auP;
+        apE(:,end) = 0;
+    
+        apN(1:end-1,:) = dx^2./avP;
+        apN(end,:) = 0;
+    
+        apW(:,2:end) = dy^2./auP;
+        apW(:,1) = 0;
+    
+        apS(2:end,:) = dx^2./avP;
+        apS(1,:) = 0;
+    
+        ap = apE + apW + apN + apS;
+        bp = (-unew(2:end-1,2:end)+unew(2:end-1,1:end-1))*dy + (-vnew(2:end,2:end-1)+vnew(1:end-1,2:end-1))*dx;
+        
+        % Loop for p'
+        for j=1:numItrP
+            pp1(2:end-1,2:end-1) = ( apE.*pp(2:end-1,3:end) + apW.*pp(2:end-1,1:end-2) + apN.*pp(3:end,2:end-1) + apS.*pp(1:end-2,2:end-1) + bp ) ./ ap;
+            
+            % Underrelaxation
+            pp = ep*pp1 + (1-ep)*pp;
+    
+        end %...of p' loop  
+         
+        % Update p
+        p = p + pp(2:end-1,2:end-1);
+        
+        % Update u and v in internal points
+        u(2:end-1,2:end-1) = e * ( unew(2:end-1,2:end-1) + ( (dy) * (-pp(2:end-1,3:end-1) + pp(2:end-1,2:end-2)) )./(auP) ) + (1-e)*u(2:end-1,2:end-1);
+        v(2:end-1,2:end-1) = e * ( vnew(2:end-1,2:end-1) + ( (dx) * (-pp(3:end-1,2:end-1) + pp(2:end-2,2:end-1)) )./(avP) ) + (1-e)*v(2:end-1,2:end-1);
+       
+        % Update boundary conditions
+        u(end,:) = 2 - unew(end-1,:);
+        u(:,1) = 0;
+        u(:,end) = 0;
+        u(1,:) = - unew(2,:);
+        
+        v(1,:) = 0;
+        v(end,:) = 0;
+        v(:,1) = - vnew(:,2);
+        v(:,end) = - vnew(:,end-1);
+        
+        if (mod(i,dispResiduals)==0)||(i < 6)
+            %% Residuals
+            % U Momentum Sclaed Residual
+            num = abs(unew(2:end-1,2:end-1).*(auP) - ( (auE.*u(2:end-1,3:end) + auW.*u(2:end-1,1:end-2) + auN.*u(3:end,2:end-1) + auS.*u(1:end-2,2:end-1) - (p(1:end,2:end) - p(1:end,1:end-1))*dy) ));
+            den = abs(unew(2:end-1,2:end-1).*(auP));
+            r_u = sum(num,"all")/sum(den,"all");
+        
+            % V Momentum Scaled Residual
+            num = abs(vnew(2:end-1,2:end-1).*(avP) - ( (avE.*v(2:end-1,3:end) + avW.*v(2:end-1,1:end-2) + avN.*v(3:end,2:end-1) + avS.*v(1:end-2,2:end-1) - (p(2:end,1:end) - p(1:end-1,1:end))*dx) ));
+            den = abs(vnew(2:end-1,2:end-1).*(avP));
+            r_v = sum(num,"all")/sum(den,"all");
+    
+            % Continuity Scaled Residual (scaled as in Fluent, the scaled value is the largest absolute value of the continuity residual in the first five iterations)    
+            num = sum( abs( (u(2:end-1,2:end)-u(2:end-1,1:end-1))*dy + (v(2:end,2:end-1)-v(1:end-1,2:end-1))*dx ), "all");
+            if i < 6
+                continuity_res_scale_value = max(continuity_res_scale_value,num);
+            end
+            den = continuity_res_scale_value;        
+            r_c = num/den;
+            
+            % Monitor points
+            disp('----')
+            disp(append("numItr = ",num2str(i)," | U Residual = ",num2str(r_u)," | V Residual = ",num2str(r_v)," | C Residual = ",num2str(r_c)))
+            disp(append("Monitor Point | u = ",num2str(u(floor(Nux/4),floor(Nuy/4)))," | v = ",num2str(v(floor(Nux/4),floor(Nuy/4)))))
+    
+            u_residual_vector(i)=r_u;
+            v_residual_vector(i)=r_v;
+            c_residual_vector(i)=r_c;
+    
+            if (r_u<RME) && (r_v<RME) && (r_c<RCE)
+                break
+            end
+    
+        end    
+    
+    end
+    
+    %% Plotting 
+    
+    % Useful commands: meshgrid, streamslice, quiver, contour
+    
+    u_plot = zeros(Npy+2,Npx+2);
+    v_plot = zeros(Npy+2,Npx+2);
+    u_plot(2:end-1,2:end-1) = 0.5*(u(2:end-1,1:end-1) + u(2:end-1,2:end));
+    v_plot(2:end-1,2:end-1) = 0.5*(v(1:end-1,2:end-1) + v(2:end,2:end-1));
+    
+    u_plot(1,:) = 0;
+    u_plot(end,:) = 1;
+    u_plot(:,1) = 0;
+    u_plot(:,end) = 0;
+    
+    v_plot(1,:) = 0;
+    v_plot(end,:) = 0;
+    v_plot(:,1) = 0;
+    v_plot(:,end) = 0;
+    
+    x = zeros(1,Npx+2);
+    y = zeros(1,Npy+2);
+    
+    indx = (0:1/Npx:1) + 1/(Npx*2);
+    indy = (0:1/Npy:1) + 1/(Npy*2);
+    
+    x(1,2:end-1) = indx(1,1:end-1);
+    y(1,2:end-1) = indy(1,1:end-1);
+    x(1,end) = 1;
+    y(1,end) = 1;
+    
+    [X,Y] = meshgrid(x,y);
+    
+    figure
+    streamslice(X,Y,u_plot,v_plot,5);
+    title('Velocity Streamlines')
+    ylabel('$\frac{y}{L}$','interpreter','latex')
+    xlabel('$\frac{x}{L}$','interpreter','latex')
+    set(gca,'ylim',[0 1]);
+    axis tight
+    
+    u_y_line = u_plot(:,ceil((Npx+2)/2));
+    v_x_line = v_plot(ceil((Npx+2)/2),:);
+    
+    format short
+end