% This program solves Stokes problem in a square domain


clear; close all; clc

addpath('Func_ReferenceElement')

dom = [0,2,0,3]; 

% Element type and interpolation degree
% (0: quadrilaterals, 1: triangles, 11: triangles with bubble function)
% elemV =0; degreeV = 1; degreeP =1 ;
% elemV =0; degreeV = 2; degreeP =1 ;
% elemV =0; degreeV = 1; degreeP =2 ;
% elemV =0; degreeV = 2; degreeP =2 ;
% elemV = 1; degreeV = 1; degreeP = 1;
elemV = 1; degreeV = 2; degreeP = 1;
% elemV = 11; degreeV = 1;  degreeP = 1;
% elemV = 11; degreeV = 2;  degreeP = 1;
if elemV == 11
    elemP = 1; 
else
    elemP = elemV; 
end
referenceElement = SetReferenceElementStokes(elemV,degreeV,elemP,degreeP); 

nx = cinput('Number of elements in X direction',10);
ny = cinput('Number of elements in Y direction',15); 
tic;
adapted = 0; 
[X,T,XP,TP] = CreateMeshes(dom,nx,ny,referenceElement,adapted);

figure(1); PlotMesh(T,X,elemV,'b-');
title('Mesh for the velocity')
figure(2); PlotMesh(TP,XP,elemP,'r-');
title('Mesh for the pressure')

% Matrices arising from the discretization
[K,G,f] = Stokes_system(X,T,XP,TP,referenceElement);
[ndofP,ndofV] = size(G); 

% Matrix and r.h.s vector to impose Dirichlet boundary conditions using
% Lagrange multipliers
[A_DirBC, b_DirBC, nDir, confined] = BC(X,dom,ndofV);

% Total system of equations
if confined
   nunkP = ndofP-1;
   disp(' ')
   disp('Confined flow. Pressure on lower left corner is set to zero');
   G(1,:) = [];
else
   nunkP = ndofP;
end
Atot = [K          A_DirBC'             G'
        A_DirBC    zeros(nDir,nDir)     zeros(nDir,nunkP)
        G          zeros(nunkP,nDir)    zeros(nunkP,nunkP)];
btot = [f ; b_DirBC ; zeros(nunkP,1)];

sol = Atot\btot; 

% Postprocess
velo = reshape(sol(1:ndofV), 2, [])'; 
if confined
    pres = [0; sol(ndofV+nDir+1:ndofV+nDir+nunkP)]; 
else
	pres = sol(ndofV+nDir+1:ndofV+nDir+nunkP); 
end

nPt = size(X,1); 
figure(3); 
quiver(X(1:nPt,1),X(1:nPt,2),velo(1:nPt,1),velo(1:nPt,2));
hold on 
plot(dom([1,2,2,1,1]),dom([3,3,4,4,3]),'k')
axis equal; axis tight
title('Velocity distribution')
PlotStreamlines(X,velo,dom); 


PlotResults(X,T,velo(:,1),referenceElement.elemV,referenceElement.degreeV)
title('Velocity distribution in x')
zlabel('Velocity')

PlotResults(X,T,velo(:,2),referenceElement.elemV,referenceElement.degreeV)
title('Velocity distribution in y')
zlabel('Velocity')

if degreeP == 0
    PlotResults(X,T,pres,referenceElement.elemP,referenceElement.degreeP)
    title('Pressure distribution')
    zlabel('Pressure')
else
    PlotResults(XP,TP,pres,referenceElement.elemP,referenceElement.degreeP)
    title('Pressure distribution')
    zlabel('Pressure')
end
toc