% Unsteady convection-diffusion-reaction probem

% Compute velocity at the nodes
numnp = size(X,1); %number of rows of the node coordinates matrix
if a == 1
    Conv = [-1*ones(numnp,1), zeros(numnp,1)];
elseif a == 2 
    Conv = [-1e-3*ones(numnp,1), zeros(numnp,1)];
elseif a == 3
    Conv = [1e-3*ones(numnp,1), zeros(numnp,1)]; 
else
    error('not available velocity')
end

h = sqrt(2/nx^2); % approximate element size

Pe = norm(Conv(1,:))*h/(2*ProblemData.nu); % Peclet number
disp(' ')
disp(strcat('   Peclet number: ',num2str(Pe)));

% Time discretization
tend = cinput('End time', 2*pi);
nstep = cinput('Number of time-steps', 120);
dt = tend / nstep; 

Courant = norm(Conv(1,:))*dt/h; % Courant number
disp(' ')
disp(strcat('   Courant number: ',num2str(Courant))); 


% Boundary conditions matrix for Lagrange multipliers method
[Accd, bccd, nodesDir0, nodesDir1] = BoundaryConditionMat(X,nx,ny);

% Initial condition
%c = 0.0*ones(numnp,1); 
%c(nodesDir1) = 1;
c = InitialCondition(X);

fprintf('\n')
disp('------------- DISCRETIZATION METHODS --------------')
% Solution method
disp(' ')
disp('Time discretization schemes: ')
disp('      [0] = R11 --> Crank-Nicholson');
disp('      [1] = R22 --> 4th order Pade');
disp('      [2] = R20 --> Lax Wendroff (explicit)');
disp('Spatial discretization methods:')
disp('      [0] = Galerkin');
disp('      [1] = Least-Squares (GLS)');
disp('      [2] = Streamline-Upwind Petrov-Galerkin (SUPG)');
disp(' ')
d_temp = input('Choose a time integration scheme: ');
d_esp = input('Choose a spatial discretization method: '); 

% Matrices for the time integration
if d_temp == 0
    method = 'CN + ';
    W = 1/2;
    w = 1;    
elseif d_temp == 1
    method = 'R22 + ';
    W = (1/24)*[7 -1; 13 5];
    w = [1/2; 1/2];
elseif d_temp ==2
    method = 'Lax-Wendroff (explicit) + ' ;
    W = [0, 0 ; 1, 0];
    w = [1/2; 1/2];
else
    error('Unavailable time integration scheme')
end

if d_esp == 0
    method = strcat(method,' Galerkin');
    disp(' ')
    disp(method)
elseif d_esp == 1
    method = strcat(method,' GLS');
    disp(' ')
    disp(method)
elseif d_esp == 2
    method = strcat(method,' SUPG');
    disp(' ')
    disp(method)
else
    error('Unavailable spatial discretization method')
end

% Stabilization parameter
if d_esp == 1 || d_esp == 2
    if d_temp == 2
        tau = (1/(1/dt + 2*norm(Conv(1,:))/h + 4*ProblemData.nu/h^2 + ProblemData.sigma))*ones(2,2);
        disp(' ')
        disp('Stabilization matrix for multistage scheme: ')
        disp(tau)
    else
    inv_W = inv(W);
    % Stabilization parameter
    tau = (inv_W/dt + (2*norm(Conv(1,:))/h + 4*ProblemData.nu/h^2 + ProblemData.sigma)*eye(size(W,1)))'\inv_W;
    disp(' ')
    disp('Stabilization matrix for multistage scheme: ')
    disp(tau)
    end
end

% Solution
if d_esp == 0
    Sol = GalerkinSolution(X,T,Conv,W,w,ProblemData.s,Element,ProblemData.nu,ProblemData.sigma,Accd,bccd,c,dt,nstep, nodesDir0, nodesDir1);
elseif d_esp == 1
    Sol = GLSSOlution(X,T,Conv,W,w,ProblemData.s,Element,ProblemData.nu,ProblemData.sigma,Accd,bccd,c,dt,nstep, tau, nodesDir0, nodesDir1);
elseif d_esp == 2
    Sol = SUPGSolution(X,T,Conv,W,w,ProblemData.s,Element,ProblemData.nu,ProblemData.sigma,Accd,bccd,c,dt,nstep, tau, nodesDir0, nodesDir1);        
end

% POST PROCESS
% Solution at final time
 x_lo = 0; x_up =2 ; y_lo =0 ; y_up =3 ;
figure(1); clf;
xx = reshape(X(:,1),ny+1,nx+1)';
yy = reshape(X(:,2),ny+1,nx+1)';
sol = reshape(Sol(:,nstep+1), ny+1, nx+1)';
surface(xx,yy,sol);
view(3)
grid on;
xlabel('x');
ylabel('y');
zlabel('u');

% Movie
% figure(2); clf;
% peli = moviein(nstep+1);
% axis manual
% axis([x_lo,x_up,y_lo,y_up, -3, 1.5])
% set(gca,'nextplot','replacechildren',...
%     'FontSize',12);
%     %'XTick',[0:0.25:2], 'YTick',[0:0.25:3], 'ZTick', [-3:0.5:1.5]);
% for numnp=1:nstep+1
%     xx = reshape(X(:,1),ny+1,nx+1)';
%     yy = reshape(X(:,2),ny+1,nx+1)';
%     sol = reshape(Sol(:,numnp), ny+1, nx+1)';
%     surf(xx,yy,sol); view(3);
%     peli(:,numnp) = getframe;
%     pause(0.1)
% end

% figure(3); 
% [xx,yy,u0] = MatSol(X,nx,ny,c);
% surface(xx,yy,u0);
% view(3);
% grid on
% xlabel('x');
% ylabel('y');
% zlabel('u0');