%
%<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
%<><> Codigo complementar do livro "Equacoes Diferenciais Ordinarias"  <><>
%<><> dos professores Marcelo Viana e Jose Espinar                     <><>
%<><>                                                                  <><>
%<><> Codigo escrito por Guilherme Tegoni Goedert                      <><>
%<><> https://git.impa.br/ggoedert/EDO/tree/master                     <><>
%<><> v 1.0 - 25/09/2016                                               <><>
%<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

%<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
%<><> Capitulo 12                                                      <><>
%<><> Experimento: ciclo oxigenio-ozonio                               <><>
%<><> Objetivo 1                                                       <><>
%<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

% Escolha de Metodo:
% 1- Euler Implicito; 2- Cranck-Nicolson; 3- RK4; 4- RKF45; 5- ode23s
Metodo = 5;

% Definicao do dominio e parametros do modelo
h = 0.01;
tf = 5;
t = 0:h:tf;
Tol = 1e-3;

k1 = 3e-12;
k2 = 1.22e-33;
k3 = 5.5e-4;
k4 = 6.86e-16;
m = 9e17;

dim = 3;
x = zeros(length(t),dim);
%x(1,:) = 1e16.*abs(rand(1,3));
x(1,:) = 1e16.*[1,2,3];

% Definicao do modelo
F = @(t,x) CicloChapman(t,x,m,k1,k2,k3,k4);
DF = @(t,x) CicloChapman_Jacobiano(t,x,m,k1,k2,k3,k4);


%>> Resolucao do problema
% Metodo de Euler Implicito
if Metodo == 1
    tic
    for i = 2:length(t)
        x(i,:) = EulerImplicito(F,DF,t(i),h,x(i-1,:)',dim,Tol)';
    end
    TempoEulerImp = toc;
    fprintf('Tempo de computacao: %g seg. - Metodo de Euler Implicito \n',TempoEulerImp)
    
    % Representacao Grafica dos resultados
    figure; hold on
    plot(t,x(:,1),'k'); Legenda1 = '[O]';
    plot(t,x(:,2),'b'); Legenda2 = '[O2]';
    plot(t,x(:,3),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Metodo de Euler Implicito')
    xlabel('t'); ylabel('Concentracao de Gas')
    
    figure; hold on
    plot(t,log(x(:,1)),'k'); Legenda1 = '[O]';
    plot(t,log(x(:,2)),'b'); Legenda2 = '[O2]';
    plot(t,log(x(:,3)),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Metodo de Euler Implicito')
    xlabel('t'); ylabel('Concentracao de Gas (escala log)')
    
    
% Metodo de Cranck-Nicolson
elseif Metodo == 2
    tic
    for i = 2:length(t)
        x(i,:) = CrankNicolson(F,DF,x(i-1,:)',t(i-1),h,t(i),dim,Tol)';
    end
    TempoCranckNic = toc;
    fprintf('Tempo de computacao: %g seg. - Metodo de Cranck-Nicolson \n',TempoCranckNic)
        
    % Representacao Grafica dos resultados
    figure; hold on
    plot(t,x(:,1),'k'); Legenda1 = '[O]';
    plot(t,x(:,2),'b'); Legenda2 = '[O2]';
    plot(t,x(:,3),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Metodo de Cranck-Nicolson')
    xlabel('t'); ylabel('Concentracao de Gas')
    
    figure; hold on
    plot(t,log(x(:,1)),'k'); Legenda1 = '[O]';
    plot(t,log(x(:,2)),'b'); Legenda2 = '[O2]';
    plot(t,log(x(:,3)),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Metodo de Cranck-Nicolson')
    xlabel('t'); ylabel('Concentracao de Gas (escala log)')
    
    
% Metodo RK4
elseif Metodo == 3
    tic
    for i = 2:length(t)
        x(i,:) = RK4(F,t(i-1),x(i-1,:)',h)';
    end
    TempoRK4 = toc;
    fprintf('Tempo de computacao: %g seg. - Metodo RK4 \n',TempoRK4)
        
    % Representacao Grafica dos resultados
    figure; hold on
    plot(t,x(:,1),'k'); Legenda1 = '[O]';
    plot(t,x(:,2),'b'); Legenda2 = '[O2]';
    plot(t,x(:,3),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title(sprintf('Metodo RK4 - h = %g',h))
    xlabel('t'); ylabel('Concentracao de Gas')
    
    figure; hold on
    plot(t,log(x(:,1)),'k'); Legenda1 = '[O]';
    plot(t,log(x(:,2)),'b'); Legenda2 = '[O2]';
    plot(t,log(x(:,3)),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title(sprintf('Metodo RK4 - h = %g',h))
    xlabel('t'); ylabel('Concentracao de Gas (escala log)')
    
    
% Solver ODE45 (metodo RKF45)
elseif Metodo == 4
    tic
    [t ,x] = ode45(F, [0 tf], x(1,:)' );
    TempoODE45 = toc;
    fprintf('Tempo de computacao: %g seg. - Solver ODE45 \n',TempoODE45)
        
    % Representacao Grafica dos resultados
    figure; hold on
    plot(t,x(:,1),'k'); Legenda1 = '[O]';
    plot(t,x(:,2),'b'); Legenda2 = '[O2]';
    plot(t,x(:,3),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Solver ODE45')
    xlabel('t'); ylabel('Concentracao de Gas')
    
    figure; hold on
    plot(t,log(x(:,1)),'k'); Legenda1 = '[O]';
    plot(t,log(x(:,2)),'b'); Legenda2 = '[O2]';
    plot(t,log(x(:,3)),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Solver ODE45')
    xlabel('t'); ylabel('Concentracao de Gas (escala log)')
    
    
% Solver ODE23S     
elseif Metodo == 5
    tic
    [t ,x] = ode23s(F, [0 tf], x(1,:)' );
    TempoODE23S = toc;
    fprintf('Tempo de computacao: %g seg. - Solver ODE23S \n',TempoODE23S)
        
    % Representacao Grafica dos resultados
    figure; hold on
    plot(t,x(:,1),'k'); Legenda1 = '[O]';
    plot(t,x(:,2),'b'); Legenda2 = '[O2]';
    plot(t,x(:,3),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Solver ODE23S')
    xlabel('t'); ylabel('Concentracao de Gas')
    
    figure; hold on
    plot(t,log(x(:,1)),'k'); Legenda1 = '[O]';
    plot(t,log(x(:,2)),'b'); Legenda2 = '[O2]';
    plot(t,log(x(:,3)),'r'); Legenda3 = '[O3]';
    legend({Legenda1,Legenda2,Legenda3},'location','best')
    title('Solver ODE23S')
    xlabel('t'); ylabel('Concentracao de Gas (escala log)')
    
end

