%
% Checcks the convergence for the parabolic pde with Dirichlet b.c.
%

a = 0;
b = 1;
tfin = 0.1;

%
% Order in At
%
% Number of subintervals
m=10;
Ax = 1/m;
x=[a:Ax:b];
f=sin(x*pi);
%f=1-2*abs(x-0.5) % Example 1
%f = x.*(1-x) % Example 2 
%f = 1 % Example 3
%f = x.*(3-2.*x) % Example 4
%f = 1-2*abs(x-0.5) % Example 5
g=0;
h=0;
% Number of steps for the first computation
npast = 10;
At = tfin/npast;
t=[0:At:npast*At];

% Reference solution (it is considered as exact)
U   = parabolic_im(a,b,m,At/(2^6),npast*(2^6),f,g,h);
%sol = U(:,npast*(2^6)+1);
test_sol=npast*(2^6)/2;
if test_sol==floor(test_sol)
    sol = U(:,test_sol);
else
    disp('Halving the number of steps must yield an integer, please revise "npast"');
end

% npast0=npast;
npast1=[24 20 18 6];
% At0=At;
At1=tfin./npast1;

% Implicit method
% Computation with different values of At
Ats_im = [];
errores = [];
tic,
for i=1:4
    Ats_im = [Ats_im,At1(i)];
    U = parabolic_im(a,b,m,At1(i),npast1(i),f,g,h);
    %aprox = U(:,npast1(i)+1);
    test_aprox=npast1(i)/2;
    if test_aprox==floor(test_aprox)
        aprox = U(:,test_aprox);
    else
        disp('Halving the number of steps must yield an integer, please revise "npast"');
    end
    error = norm(sol-aprox);
    errores = [errores,error];
    
   % U = parabolic_im(a,b,m,At,npast,f,g,h)
   % aprox = U(:,npast+1);
   % return
   % error = norm(sol-aprox)
   % errores = [errores,error];
   % Ats = [Ats,At];
   % At = At/2;
   % npast = npast*2;
end
error_im = errores;
toc
Ats_cn = [];
errores = [];
tic,
for i=1:4
    Ats_cn = [Ats_cn,At1(i)];
    U = parabolic_cn(a,b,m,At1(i),npast1(i),f,g,h);
    test_aprox=npast1(i)/2;
    if test_aprox==floor(test_aprox)
        aprox = U(:,test_aprox);
    else
        disp('Halving the number of steps must yield an integer, please revise "npast"');
    end
    error = norm(sol-aprox);
    errores = [errores,error];

end
error_cn = errores;
toc

Ats_ex = [];
errores = [];
tic,
for i=1:4
    Ats_ex = [Ats_ex,At1(i)];
    U = parabolic_ex(a,b,m,At1(i),npast1(i),f,g,h);
    test_aprox=npast1(i)/2;
    if test_aprox==floor(test_aprox)
        aprox = U(:,test_aprox);
    else
        disp('Halving the number of steps must yield an integer, please revise "npast"');
    end
    error = norm(sol-aprox);
    errores = [errores,error];

end
error_ex = errores;
toc

% Graphical representation
figure(2),clf
% plot(log(Ats),log(error_im),'-o',log(Ats),log(error_cn),'-x')
plot(log(Ats_im),log(error_im),'b-o')
hold on
plot(log(Ats_cn),log(error_cn),'r-x')
hold on
plot(log(Ats_ex),log(error_ex),'m-+')
xlabel('log(delta t)')
ylabel('log(Error)')
title('Convergence with constant delta x and delta t->0')
legend('Implicit','Crank-Nicolson','Explicit')

% Least squares approximation - Implicit
p=polyfit(log(Ats_im),log(error_im),1);
x=log(Ats_im(3))+0.125;
y=log(error_im(3))-0.125;
text(x,y,num2str(p(1),2))

% Least squares approximation - Crank-Nicolson
p=polyfit(log(Ats_cn),log(error_cn),1);
x=log(Ats_cn(3))+0.125;
y=log(error_cn(3))-0.125;
text(x,y,num2str(p(1),2))

% Least squares approximation - Explicit
p=polyfit(log(Ats_ex),log(error_ex),1);
x=log(Ats_ex(3))+0.125;
y=log(error_ex(3))-0.125;
text(x,y,num2str(p(1),2))
