clc
close all
clear all

% 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 = 50;
Ax = 1/m;
x = a:Ax:b;
f = sin(x*pi);
g = 0;
h = 0;
% Number of steps for the first computation
npast = 15;
At = tfin/npast;
t=0:At:npast*At;

% Reference solution (it is considered as exact)
Uex = parabolic_ex(a,b,m,At/(2^6),npast*(2^6),f,g,h);
Uim = parabolic_im(a,b,m,At/(2^6),npast*(2^6),f,g,h);
Ucn = parabolic_cn(a,b,m,At/(2^6),npast*(2^6),f,g,h);
solex = Uex(:,npast*(2^6)+1);
solim = Uim(:,npast*(2^6)+1);
solcn = Ucn(:,npast*(2^6)+1);

npast0 = npast;
At0 = At;

% Explicit method
% Computation with different values of At
Atsex = [];
erroresex = [];
for i=0:4
    Uex = parabolic_ex(a,b,m,At,npast,f,g,h);
    aproxex = Uex(:,npast+1);
    errorex = norm(solex-aproxex);
    erroresex = [erroresex,errorex];
    Atsex = [Atsex,At];
    At = At/2;
    npast = npast*2;
end
error_ex = erroresex;

At = At0;
npast = npast0;

% Implicit method
% Computation with different values of At
Atsim = [];
erroresim = [];
for i=0:4
    Uim = parabolic_im(a,b,m,At,npast,f,g,h);
    aproxim = Uim(:,npast+1);
    errorim = norm(solim-aproxim);
    erroresim = [erroresim,errorim];
    Atsim = [Atsim,At];
    At = At/2;
    npast = npast*2;
end
error_im = erroresim;

At = At0;
npast = npast0;

% Crank-Nicolson method
% Computation with different values of At
Atscn = [];
errorescn = [];
  for i=0:4
     U = parabolic_cn(a,b,m,At,npast,f,g,h);
     aproxcn = U(:,npast+1);
     errorcn = norm(solcn-aproxcn);
     errorescn = [errorescn,errorcn];
     Atscn = [Atscn,At];
     At = At/2;
     npast = npast*2;
  end
  error_cn = errorescn;

% Graphical representation
figure
hold on
grid on
%plot(log(Atsex),log(error_ex),'-o','DisplayName','Explicit')
plot(log(Atsim),log(error_im),'-o','DisplayName','Implicit')
plot(log(Atscn),log(error_cn),'-o','DisplayName','Crank-Nicholson')
xlabel('log(\Deltat)')
ylabel('log(Error)')
title('Convergence with constant \Deltax and \Deltat->0')
legend('toggle')

% Least squares approximation
pex=polyfit(log(Atsex),log(error_ex),1);
pim=polyfit(log(Atsim),log(error_im),1);
pcn=polyfit(log(Atscn),log(error_cn),1);
xex=log(Atsex(3))+0.125;
xim=log(Atsim(3))+0.125;
xcn=log(Atscn(3))+0.125;
yex=log(error_ex(3))-0.125;
yim=log(error_im(3))-0.125;
ycn=log(error_cn(3))-0.125;
text(xex,yex,num2str(pex(1),2))
text(xim,yim,num2str(pim(1),2))
text(xcn,ycn,num2str(pcn(1),2))