% Domain Definition
N = 128;
PhysicalDomain = [0, 2*pi];                     % Physical Domain scaled to a 2*pi interval
h = (PhysicalDomain(2) - PhysicalDomain(1))/N;

x = linspace(h,2*pi,N);
k = [0:N/2-1 0 -N/2+1:-1];

dt = 0.001;
tf = 5;
t = 0:dt:tf;

% System Definition
% int the form u_t = G(u)
nu = 0.2;
uinicial = exp(-0.5*(x-pi).^2); 
u = zeros(length(t),length(x));
u(1,:) = uinicial;

% Fator integrante
v = @(t) exp(nu.*(k.^2).*t);
U = u;
U(1,:) = v(0).*fft(u(1,:));

G = @(t,U) -0.5i.*k.*exp(nu.*(k.^2).*t).*fft(real(ifft(exp(-nu.*t.*(k.^2).*U)).^2));


for i = 1:N-1
    
    k1 = G(t(i),U(i,:));
    k2 = G(t(i) + dt/2, U(i,:) + 0.5.*dt.*k1);
    k3 = G(t(i) + dt/2, U(i,:) + 0.5.*dt.*k2);
    k4 = G(t(i) + dt, U(i,:) + dt.*k3);

    U(i+1,:) = U(i,:) + (dt/6).*(k1 + 2.*k2 + 2.*k3 + k4);
    u(i+1,:) = real(ifft(v(t(i+1)).*U(i+1,:)));
    
end

waterfall(x,t,u)
xlabel('x')
ylabel('t')
zlabel('u')