sandbox/easystab/burgers_global.m

    Burgers equation without time marching

    Just like in advection_global.m, but here for a nonlinear system, the Burgers equation. Since the system is now nonlinear, we use the Newton iterations to converge progressively to the solution.

    We do as well the time marching for a comparison.

    clear all; clf
    
    % parameters
    Nx=61; % number of gridpoints
    Nt=100; % gridpoints in time
    Lx=10; % domain length in x
    Lt=20; % duration in time
    xpos=Lx/4; % position of the initial condition
    mu=0.1; % diffusion
    
    % differentiation 
    [d.x,d.xx,d.wx,x]=dif1D('cheb',0,Lx,Nx);
    [d.y,d.yy,d.wy,y]=dif1D('fd',0,Lt,Nt,5);
    [D,l,X,Y,Z,I,NN]=dif2D(d,x,y);
    
    % rename y to time derivative
    D.t=D.y;
    D.tt=D.yy;
    t=y;
    T=Y;
    
    l.left=[l.cbl;l.left;l.ctl];
    l.right=[l.cbr;l.right;l.ctr];
    l.start=l.bot;
    l.end=l.top;
    
    
    %initial guess
    u0=exp(-((X-xpos)/1).^2);
    sol=u0(:);
    
    % Newton iterations
    quit=0;count=0;
    while ~quit
    
    
        % the present solution and its derivatives
        u=sol; ux=D.x*u;  uxx=D.xx*u; ut=D.t*u;
    

    The function and its Jacobian

    The Burgers equation is \displaystyle u_t+uu_x=\mu u_{xx} so the function that we want to become zero is \displaystyle f=u_t+uu_x-\mu u_{xx} and the jacobian is \displaystyle A=\partial_t+u\partial_x+u_xI-\mu\partial_{xx} we should not be afraid to have time derivatives in the Jacobian, since they do not have formally any difference with the spatial derivatives.

        % nonlinear function
        f=ut+u.*ux-mu*uxx; 
    
        % analytical jacobian
        A=D.t+(spd(u)*D.x+spd(ux))-mu*D.xx;
    
        % boundary conditions
        loc=[l.start; l.left; l.right];
        C=I(loc,:); 
        f(loc)=C*(u-u0(:)); 
        A(loc,:)=C;
        
        % showing present solution
        subplot(1,2,1);
        surf(X,T,reshape(u,Nt,Nx)); view(2); 
        xlabel('x'); ylabel('t');title('Global solution');
        drawnow
          
        % convergence test
        res=norm(f); disp([num2str(count),' ' num2str(res)])
        if count>50|res>1e5; disp('no convergence'); break; end
        if res<1e-5; quit=1; disp('converged'); continue; end
    
        % Newton step
        sol=sol-A\f;
        count=count+1;
    end
    

    Time marching

    Here we compare with the solution that we get using time marching. For this we treat the diffusion term by Crank-Nicolsin, just like in vibrating_string.m, and for the nonlinear terms, we use forward Euler. Since forward Euler is explicit, this avoids to solve a nonlinear system at each time step.

    % comparison with time marching
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % system matrices
    I=eye(Nx);
    E=I;
    A=mu*d.xx; 
    
    % boundary conditions
    loc=[1;Nx];
    E(loc,:)=0;
    A(loc,:)=I(loc,:);
    

    Just like in vibrating_string.m we use the Crank-Nicolson scheme for the linear terms, this gives \displaystyle M_m u(t+dt)=M_p u(t)-uu_x dt where the integral of the nonlinear term from t to t+dt was approximated by uu_xdt like in the forward Euler scheme, and with the matrices \displaystyle M_m=(E-Adt/2), M_p=(E+Adt/2)

    % march in time matrix 
    dt=t(2)-t(1);
    Mm=(E-A*dt/2);
    M=Mm\(E+A*dt/2);
    
    % initial condition
    q=u0(1,:)';
    
    % marching loop
    for ind=1:(Nt-1)    
        nl=-q.*(d.x*q);

    Here we should not forget that we have to impose the boundary conditions. Here the nonlinear terms act like a nonhomogeneous forcing. We should remember not to put a forcing on the boundary conditions. This would be good for nonhomogeneous boundary conditions, but this is not what we want to do here. So we put some zeros in the lines of the constraints (stored in loc).

        nl(loc)=0;
        
        q=M*q+Mm\nl*dt; % one step forward
    end
        
    % plotting
    subplot(1,2,2);
    plot(x,q,'b',X(l.end),u(l.end),'r.-');    
    axis([0,Lx,0,0.5])    
    legend('march in time','global'); title('Vibrating string')
    xlabel('x'); ylabel('final time');
    
    
    set(gcf,'paperpositionmode','auto');
    print('-dpng','-r80','burgers_global.png');
    

    On the left subplot, you see the golbal solutino obtained using Newton iterations. And on the right you have the final state, comparing the two methods.

    Validation

    Validation

    Exercises/contributions

    • Please do the time marching of the Burgers equations using as well Crank_nicolson for the nonlinear term, and so solving at each time step a nonlinear equation using the Newton iterations.