% This program solves the leaky cavity-flow Stokes problem
% using a mixed finite element formulation.
%

clear, close all, home

global nu;
nu = 1;

disp(' ' )
disp('CAVITY FLOW STOKES PROBLEM')

% MIXED ELEMENT USED FOR THE SOLUTION
disp(' ')
disp('The problem is solved using a mixed fomulation.')
disp('The following elements are available: ')
disp('Quadrilaterals')
disp('         [0]: Q1P0    [1]: Q1Q1    [2]: Q2Q1   [3]: Q2Q2')
disp('Triangles')
disp('         [4]: P1P0    [5]: P1P1    [6]: P1+P1 (MINI)    [7]: P2P1   [8]: P2P2')
imix = input('Choose the element for the solution :  ');
% Type of element (0 for quadrilaterals and 1 for triangles)
% and number of element nodes for velocity (nen) and pressure (nenP).
if imix == 0
    elem = 0;
    nen = 4; nenP = 1;
elseif imix == 1
    elem = 0;
    nen = 4; nenP = 4;
elseif imix == 2
    elem = 0;
    nen = 9; nenP = 4;
elseif imix == 3
    elem = 0;
    nen = 9; nenP = 9;
elseif imix == 4
    elem = 1;
    nen = 3; nenP = 1;
elseif imix == 5
    elem = 1;
    nen = 3; nenP = 3;
elseif imix == 6
    elem = 1;
    nen = 4; nenP = 3;
elseif imix == 7
    elem = 1;
    nen = 6; nenP = 3;
elseif imix == 8
    elem = 1;
    nen = 6; nenP = 6;
else
    error('Unavailable element')
end

% GEOMETRY
% Number of nodes on each direction
disp(' ')
npx = input('Number of nodes in X direction (default: 21)= ');
npy = input('Number of nodes in Y direction (default: npx)= ');
if isempty(npx)  npx = 21;     end
if isempty(npy)  npy = npx;    end
% Number of elements on each direction
nx = npx-1; ny = npy-1;
npt = npx*npy;

% Coordinates of domain's vertices
x_lo = 0; x_up = 2; 
y_lo = 0; y_up = 3; 
% Nodal coordinates matrix and connectivities for velocity 
disp('Problem is solved on an structured mesh.')
disp('It can be uniform ([1]) or adapted to the problem ([2]).')
meshtype = input('Choose a computational mesh (default: uniform): ');
if isempty(meshtype)
    meshtype = 1;
end
if meshtype == 1
    [X,T] = CreateUniformMesh(elem,nen,x_lo,x_up,y_lo,y_up,npx,npy);      
elseif meshtype == 2
    [X,T] = CreateMesh(elem,nen,x_lo,x_up,y_lo,y_up,npx,npy);    
else
    error('Unavailable mesh option')
end
% Nodal coordinates matrix and connectivities for pressure
[XP,TP] = CreatePresNod(elem,nenP,X,T,npx,npy);

% Total number of nodes and degrees of freedom
if elem == 1 & nen == 4     % MINI
    numnp = size(X,1) + size(T,1);
    nunk = 2*numnp;
else
    numnp = size(X,1); 
    nunk = 2*numnp;
end
ndofP = size(XP,1);

% Meshes plots
figure('Name','Mesh for velocity','NumberTitle','off'); clf;
PlotMesh(T,X,elem,'b')
figure('Name','Mesh for pressure','NumberTitle','off'); clf;
PlotMesh(TP,XP,elem,'r')
figure('Name','Meshes','NumberTitle','off'); clf;
PlotMesh(T,X,elem,'b'),     hold on
PlotMesh(TP,XP,elem,'r'),   hold off

% BOUNDARY CONDITIONS
[Accd, bccd] = BC_Cavity(nx,ny,nunk);
% confined flow (only essential conditions on the velocity are imposed)
confined = 1;     
% number of prescribed degrees of freedom
nDir = size(Accd,1);

% SOLUTION
% Computation of matrices
[K,G,f] = CreMat(X,T,XP,TP,elem);
if confined
   nunkP = ndofP-1;
   disp(' ')
   disp('Confined flow. Pressure on lower left corner is set to sero');
   G(1,:)=[];
else
   nunkP = ndofP;
end
% Entire matrix (including boundary conditions with Lagrange multipliers)
Atot = [K       Accd'                G'
        Accd    zeros(nDir,nDir)     zeros(nDir,nunkP)
        G       zeros(nunkP,nDir)    zeros(nunkP,nunkP)];
btot = [f ; bccd ; zeros(nunkP,1)];
% Free up memory space
clear K G f Accd bccd; pack
% Solution
aux = Atot\btot;

% POSTPROCESS
% Recover velocity field
velo = zeros(numnp,2); 
velo = reshape(aux(1:nunk),2,numnp)';
% Recover pressure field
pres= zeros(ndofP,1);
if confined
    % Pressure is set to zero on the first node (lower left corner)
    pres = [0; aux(nunk+nDir+1:nunk+nDir+nunkP)];
else
    pres = aux(nunk+nDir+1:nunk+nDir+nunkP);
end

clear aux; pack;


% POST PROCESS
% Velocity 
figure('Name','Velocity field','NumberTitle','off'); clf;
quiver(X(1:npt,1),X(1:npt,2),velo(1:npt,1),velo(1:npt,2),2);
box on; axis equal;
%set(gca, 'FontSize', 12,...
    %'XTick', [0:0.25:2], 'YTick', [0:0.25:3]);
axis([0,2,0,3])

% Pressure 
if elem == 0
    if (imix == 0)
        x = []; y = []; z = [];
        for e = 1:nx*ny
            x = [x, X(T(e,:),1)];
            y = [y, X(T(e,:),2)];
            z = [z, pres(e)*ones(4,1)];
        end
        figure('Name','Pressure field','NumberTitle','off'); clf;
        patch(x,y,z,z)
        view(3); grid on;
        set(gca, 'FontSize', 12,...
            'XTick', [0:0.25:2], 'YTick', [0:0.25:3]);
    elseif (imix == 1 | imix == 3)
        aux_x = ones(npy,1)*X(1:npx,1)';
        aux_y = X(1:npx:npt,2)*ones(1,npx);
        aux_p = reshape(pres,npx,npy)';
        figure('Name','Pressure field','NumberTitle','off'); clf;
        surface(aux_x, aux_y, aux_p,'FaceColor','interp')       
        view(3); grid on;
        set(gca, 'FontSize', 12,...
            'XTick', [0:0.25:2], 'YTick', [0:0.25:3]);        
    elseif (imix == 2)
        aux_x = ones(ny/2+1,1)*X(1:2:npx,1)';
        aux_y = X(1:2*npx:npt,2)*ones(1,nx/2+1);
        aux_p = reshape(pres, nx/2+1, ny/2+1)';
        figure('Name','Pressure field','NumberTitle','off'); clf;
        surface(aux_x, aux_y, aux_p,'FaceColor','interp')
        view(3); grid on;
        set(gca, 'FontSize', 12,...
            'XTick', [0:0.25:2], 'YTick', [0:0.25:3]);
    end
else
    figure('Name','Pressure field','NumberTitle','off'); clf;
    tri = delaunay(XP(:,1),XP(:,2));
    trisurf(tri,XP(:,1),XP(:,2),pres);
    view(3); grid on;
    set(gca, 'FontSize', 12,...
        'XTick', [0:0.25:2], 'YTick', [0:0.25:3]);
end
% Streamlines (computed as level sets)
phi = StreamLines_ls(X,T,elem,velo,npx,npy);

% Streamlines (using Matlab function)
sx = [0:0.1:1, 0.5*ones(1,11), 0:0.1:1, 1:-0.1:0];
sy = [0.5*ones(1,11), 0:0.1:1, 0:0.1:1, 0:0.1:1];
StreamLines(X,velo,npx,npy,sx,sy), hold on
plot([x_lo,x_up,x_up,x_lo,x_lo],[y_lo,y_lo,y_up,y_up,y_lo],'k','LineWidth',2)
axis equal; axis([0,2,0,3]); box on;
hold off

%%%%%%%%%%%%

v_max=max(sqrt(velo(:,1).^2+velo(:,2).^2))
vx_max=max(velo(:,1))
vy_max=max(velo(:,2))

h =[1 0.5 0.2 0.1 0.05 0.025];
vx = [0.1748 0.3144 0.3538 0.3716 0.3784 0.3827];
vy = [0.2327 0.2681 0.2764 0.2805 0.2821 0.2832];

figure
plot(1./h,vx)
xlabel('1/h','FontSize',14)
ylabel('V_x','FontSize',14)
figure
plot(1./h,vy)
xlabel('1/h','FontSize',14)
ylabel('V_x','FontSize',14)