clear, close all, home

disp(' ')
disp('This program solves a transient convection-diffusion problem')
disp('on a square domain [0, 2] x [0, 3].')
%degree of the elements
p=1;

disp(' ')
disp('Velocity field is (-x,-y)')
%a = 1;
a=input('Enter the value of the convection (default: 1) =');
if isempty(a)
    a= 1;
end
nu = input('Enter the value of the diffusion (default: 10^-3) =  ');
if isempty(nu)
    nu = 10^-3;
end

% GEOMETRY
% Number of elements on each direction
disp(' ')
nx = input('Number of elements on both directions (default: 10)= ');
if isempty(nx)
    nx = 10;
end
ny=nx;

% Vertex coordinates
x_lo = 0; x_up = 2; y_lo = 0; y_up = 3; 
% Matrices of nodal coordinates and connectivities
[X,T] = CreateMesh(x_lo,x_up,y_lo,y_up,nx,ny,p);
numnp = size(X,1); 
h=x_up/nx;
if nu ~= 0    
    Pe = a*h/(2*nu);
    
    disp(' ')
    disp(strcat('   Péclet number: ',num2str(Pe)));  
    if Pe>1
        disp(strcat('WARNING: PECLET CAN CAUSE INESTABILITIES ',num2str(Pe))); 
    end
end

% DATA FOR THE TRANSIENT ANALYSIS
disp(' ')
C = 1;
dt = input(sprintf('Time step (default: %g) = ',C*h/a));
if (isempty(dt)), dt = C*h/a; end
endt= input('End time (default: pi) =  ');
if isempty(endt), endt = pi; end
nstep = ceil(endt/dt);

Courant = a*dt/h;
disp(' ')
disp(strcat('   Courant number: ',num2str(Courant)));  
if Courant>(1/2)^(3/2)
        disp(strcat('WARNING: COURANT CAN CAUSE INESTABILITIES ',num2str(Courant))); 
end
% CONVECTION VELOCITY
Conv = zeros(size(X));

Conv(:,1) =-X(:,2);
Conv(:,2) =-X(:,1);

dom = [0,2,0,3]; 
figure(1); hold on; 
quiver(X(:,1),X(:,2),Conv(:,1),Conv(:,2))
plot(dom([1,2,2,1,1]), dom([3,3,4,4,3]), 'k')
axis equal
% SOURCE TERM
% has been set to 0 or 1, fully zeros, ones
f = SourceTerm(X);

% INITIAL CONDITION
c = zeros(numnp,1);
for i=1:numnp;
    c(i,1)=X(i,1)*(2-X(i,1));
end


% BOUNDARY CONDITIONS  (LAGRANGE MULTIPLIERS METHOD)
[Accd, bccd] = BC(nx,ny,numnp,X,p);

% SOLUTION
disp(' ')
disp('There are three integration schemes available ')
disp('      [0] = Crank-Nicolson');
disp('      [1] = R22');
disp('      [2] = R33');
disp('and five methods to perform spatial discretization')
disp('      [0] = Galerkin');
disp('      [1] = Least-Squares');
disp('      [2] = Streamline-Upwind Petrov-Galerkin (SUPG)');
disp(' ')
d_temp = input('Choose a method to perform time integration = ');
d_esp = input('and another one for the spatial discretization  = ');  

% Matrices for the time integration
if d_temp == 0
    method = 'CN + ';
    W = 1/2;
    w = 1;    
    beta = [0,1];
elseif d_temp == 1
    method = 'R22 + ';
    W = (1/24)*[7 -1; 13 5];
    w = [1/2; 1/2];
    beta = [0,1/2,1];
elseif d_temp == 2
    method = 'R33 + ';
    r5 = sqrt(5);
    W = [49-13*r5       12*(2-r5)       r5-1
         26*r5          12*r5           -2*r5
         61-13*r5       36              11+r5]/120;
    w = [12*(5-r5); 24*r5; 12*(5-r5)]/120;
    beta = [0, (5-r5)/10, (5+r5)/10, 1];
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,' LS');
    disp(' ')
    disp(method)
elseif d_esp == 2
    method = strcat(method,' SUPG');
    disp(' ')
    disp(method)
else
    error('Unavailable spatial discretization method')
end

% Stabilization parameter
if any(d_esp ==[2:4])
    % Soulaimani and Fortin (1994), Codina (2000)
    inv_W = inv(W);
    tau = (inv_W/dt + (2*a/h + 4*nu/h^2))'\inv_W;
    disp(' ')
    disp('Stabilization matrix for multistage scheme:')
    disp(tau)
end

      
% Solution
if d_esp == 0
    Sol = Galerkin(X,T,Conv,nu,f,c,Accd,bccd,W,w,beta,dt,nstep,p);
elseif d_esp == 1
    Sol = ILS(X,T,Conv,nu,f,c,Accd,bccd,W,w,beta,dt,nstep,p);
elseif d_esp == 2
    Sol = SUPG(X,T,Conv,nu,f,c,Accd,bccd,W,w,beta,dt,nstep,tau,p);
end
    
  
% POST PROCESS
% Solution at final time
figure(1); clf;
set(gca,'FontSize',12,...
    'XTick',[0:0.25:2], 'YTick',[0:0.25:3],'ZTick',[0:0.2:2]);
if p==1
    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)';
elseif p==2
    xx = reshape(X(:,1),2*ny+1,2*nx+1)' ;
    yy = reshape(X(:,2),2*ny+1,2*nx+1)';
    sol = reshape(Sol(:,nstep+1), 2*ny+1, 2*nx+1)';
end
surface(xx,yy,sol);
view(3)
axis([x_lo,x_up,y_lo,y_up,0,2])
grid on;

figure(2); clf;
contour(xx,yy,sol,[-0.01,0.01,0.1:0.1:0.5]);
axis equal tight
axis([x_lo,x_up,y_lo,y_up])
set(gca,'FontSize',12,...
    'XTick',[0:0.25:2], 'YTick',[0:0.25:3],...
    'Box','on');

% Movie
figure(10); clf;
peli = moviein(nstep+1);
axis auto
%xlabel('fig10')
axis([x_lo,x_up,y_lo,y_up])
set(gca,'nextplot','replacechildren',...
    'FontSize',12,...
    'XTick',[0:0.25:2], 'YTick',[0:0.25:3]);
if p==1
    for n=1:nstep+1
        xx = reshape(X(:,1),ny+1,nx+1)';
        yy = reshape(X(:,2),ny+1,nx+1)';
        sol = reshape(Sol(:,n), ny+1, nx+1)';
        surf(xx,yy,sol); view(3);
        %contour(xx,yy,sol,[-0.01,0.01,0.1:0.1:0.8]);
        peli(:,n) = getframe;
        pause(0.1)
    end
elseif p==2
    for n=1:nstep+1
        xx = reshape(X(:,1),2*ny+1,2*nx+1)';
        yy = reshape(X(:,2),2*ny+1,2*nx+1)';
        sol = reshape(Sol(:,n), 2*ny+1, 2*nx+1)';
        surf(xx,yy,sol); view(3);
        %contour(xx,yy,sol,[-0.01,0.01,0.1:0.1:0.8]);
        peli(:,n) = getframe;
        pause(0.1)
    end
end
