% This program solves a convection-diffusion-reaction problem in a square domain [0,2]x[0,3] 
clear all;
close all;
clc;

disp(' ')
disp('This program solves a convection-diffusion-reaction equation on [0,2]x[0,3]')

% PDE coefficients
ax    = cinput('Enter x component of velocity',1);
ay    = cinput('Enter y component of velocity',0);
velo  = [ax,ay];
nu    = cinput('Enter diffusion parameter',0.001);
sigma = cinput('Enter reaction parameter',0.1); % reaction term added
s     = cinput('Enter source term',1); % source term introduced
a = sqrt(ax^2+ay^2); % average velocity

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

example.dom = dom; 
example.velo = velo; 
example.a = a; 
example.nu = nu; 
example.sigma = sigma;
example.s = s;

% Element type 
disp(' ')
disp ('The following type of element can be used:');
disp ('     [0] quadrilateral');
disp ('     [1] triangles'); % triangular elements added        
elem = cinput ('Select the type of element for solving the problem',0);

disp(' ')
disp ('The following order of interpolation can be used:');
disp ('     [1] Linear');
disp ('     [2] Quadratic');  % qaudratic interpolation introduced
p = cinput ('Choose the order of interpolation for solving the problem',1);
referenceElement = SetReferenceElement(elem,p); 


nx = cinput('Number of elements in each direction (multiple of 5)',20);
ny = nx; 
[X,T] = CreateMesh(dom,nx,ny,referenceElement);
PlotMesh(T,X,'b-');

npx = p*nx+1;
npy = p*ny+1;

Te = T(1,:); Xe = X(Te,:); 
hx = max(Xe(:,1)) - min(Xe(:,1)); 
hy = max(Xe(:,2)) - min(Xe(:,2)); 
h = (hx+hy)/2; 
Pe = a*h/(2*nu);
disp(' ')
disp(strcat('Peclet number: ',num2str(Pe)))
example.h=h;

disp(' ')
disp ('The following methods can be used:');
disp ('     [0] Galarkin');
disp ('     [1] SUPG');   
disp ('     [2] GLS');
method = cinput ('Choose a method for solving the problem',2);
example.method = method; 

% SYSTEM RESULTING OF DISCRETIZING THE WEAK FORM
[K,f] = FEM_system(X,T,referenceElement,example);


% BOUNDARY CONDITIONS (modified as per problem statement)
% Boundary conditions are imposed using Lagrange multipliers
nodes_y0 = [1:nx+1]';                           % Nodes on the boundary y=0
nodes_x1 = [2*(nx+1):nx+1:(ny+1)*(nx+1)]' ;     % Nodes on the boundary x=2
nodes_y1 = [ny*(nx+1)+nx:-1:ny*(nx+1)+1]' ;     % Nodes on the boundary y=3
nodes_x0 = [(ny-1)*(nx+1)+1:-(nx+1):nx+2]';     % Nodes on the boundary x=0
nodes = 1:max(max(T));
%%(NEUMANN and DIRECHLIT BC)%%
% nodes on which solution is u=1
nodesDir1 = nodes(X(:,2) > dom(4)/2 & (X(:,1) == dom(1) ))'; 
% nodes on which solution is u=0
nodesDir0 = nodes(X(:,1) == dom(2))';

%Boundary condition matrix (Neumann Boundary is assumed to be zero)
C = [nodesDir1, ones(length(nodesDir1),1);
     nodesDir0, zeros(length(nodesDir0),1)];
nDir = size(C,1);
neq  = size(f,1);
A = zeros(nDir,neq);
A(:,C(:,1)) = eye(nDir);
b = C(:,2);


% SOLUTION OF THE LINEAR SYSTEM
% Entire matrix
Ktot = [K A';A zeros(nDir,nDir)];
ftot = [f;b];

sol = Ktot\ftot;
Temp = sol(1:neq);
multip = sol(neq+1:end);


% % POSTPROCESS
% figure(2), clf
% xx  = reshape(X(:,1), npy, npx)'; 
% yy  = reshape(X(:,2), npy, npx)'; 
% sol = reshape(Temp, npy, npx)';  
% surface(xx,yy,sol,'FaceColor','interp');
% set(gca, 'xTick',0:0.25:2, 'yTick',0:0.25:3, 'FontSize',12)
% xlabel('x','FontSize',14); 
% ylabel('y','FontSize',14); 
% zlabel('u','FontSize',14);
% grid on; view(3)

figure
if elem == 0
 patch('faces',T(:,1:4),'vertices',[X(:,1) X(:,2) Temp],'facevertexcdata',Temp,...
      'FaceColor','interp','EdgeColor',[0.5,0.5,0.5]);
 colormap(jet(100));
 set(gca, 'xTick',0:0.25:2, 'yTick',0:0.25:3, 'FontSize',12)
 zlim([min(Temp) max(Temp)])
 xlabel('x','FontSize',14); 
 ylabel('y','FontSize',14); 
 zlabel('\rho','FontSize',14);
 grid on; view(3)

elseif elem == 1
  patch('faces',T(:,1:3),'vertices',[X(:,1) X(:,2) Temp],'facevertexcdata',Temp,...
      'FaceColor','interp','EdgeColor',[0.5,0.5,0.5]);
 colormap(jet(100));
 set(gca, 'xTick',0:0.25:2, 'yTick',0:0.25:3, 'FontSize',12)
 zlim([min(Temp) max(Temp)])
 xlabel('x','FontSize',14); 
 ylabel('y','FontSize',14); 
 zlabel('\rho','FontSize',14);
 grid on; view(3)
end
    


