1

I'm trying to implement a RK implicit 2-order to convection-diffusion equation (1D) with fdm_2nd and gauss butcher coefficients: 'u_t = -uu_x + nu .u_xx' .

My goal is to compare the explit versus implcit scheme. The explicit rk which works well with a little number of viscosity. The curve of explicit schem show us a very nice shock wave.

I need your help to implement correctly the solver of the k(i) coefficient. I don't see how implement the newton method for all k(i). do I need to implement it for all time-space steps ? or just in time ? The jacobian is maybe wrong but i don't see where. Or maybe i use the jacobian in wrong direction...

Actualy, my code works, but i think it's was wrong somewhere ... also the implicit curve does not move from the initial values.

here my function :

function [t,u] = burgers(t0,U,N,dx) 
nu=0.01; %coefficient de viscosité
A=(diag(zeros(1,N))-diag(ones(1,N-1),1)+diag(ones(1,N-1),-1)) / (2*dx);
B=(-2*diag(ones(1,N))+diag(ones(1,N-1),1)+diag(ones(1,N-1),-1)) / (dx).^2;
t=t0;
u = - A * U.^2 + nu .* B * U;

the jacobian :

function Jb = burJK(U,dx,i)
%Opérateurs
    a(1,1) = 1/4;
    a(1,2) = 1/4 - (3).^(1/2) / 6;
    a(2,1) = 1/4 + (3).^(1/2) / 6;
    a(2,2) = 1/4;

Jb(1,1) = a(1,1) .* (U(i+1,1) - U(i-1,1))/ (2*dx) - 1; 
Jb(1,2) = a(1,2) .* (U(i+1,1) - U(i-1,1))/ (2*dx);
Jb(2,1) = a(2,1) .* (U(i+1,2) - U(i-1,2))/ (2*dx);
Jb(2,2) = a(2,2) .* (U(i+1,2) - U(i-1,2))/ (2*dx) - 1;

Here my newton-code:

iter = 1;
iter_max = 100;
k=zeros(2,N);
k(:,1)=[0.4;0.6];
[w_1,f1] =burgers(n + c(1) * dt,uu + dt * (a(1,:) * k(:,iter)),iter,dx);
[w_2,f2] =burgers(n + c(2) * dt,uu + dt * (a(2,:) * k(:,iter)),iter,dx);
f1 = -k(1,iter) + f1;
f2 = -k(1,iter) + f2;
f(:,1)=f1;
f(:,2)=f2;

df = burJK(f,dx,iter+1);

while iter<iter_max-1 % K_newton 

    delta = df\f(iter,:)';
    k(:,iter+1) = k(:,iter) - delta;
    iter = iter+1;

    [w_1,f1] =burgers(n + c(1) * dt,uu + dt * (a(1,:) * k(:,iter+1)),N,dx);
    [w_2,f2] =burgers(n + c(2) * dt,uu + dt * (a(2,:) * k(:,iter+1)),N,dx);
    f1 = -k(1,iter+1) + f1;
    f2 = -k(1,iter+1) + f2;
    f(:,1)=f1;
    f(:,2)=f2;
    df = burJK(f,dx,iter);

    if iter>iter_max
        disp('#');
    else
        disp('ok');
    end

end
Yee
  • 11
  • 4

1 Answers1

0

I'm a little rusty on exactly how to implement this in matlab, but I can walk your through the general steps and hopefully that will help. First we can consider the equation you are solving to fit the general class of problems that can be posed as

du/dt = F(u), where F is a linear or nonlinear function 

For a Runge Kutta scheme you typically recast the problem something like this

k(i) = F(u+dt*a(i,i)*k(i)+ a(i,j)*k(j))

for a given stage. Now comes the tricky part, you you need to make 1-D vector constructed by stacking k(1) onto k(2). So the first half of the elements of the vector are k(1) and the second half are k(2). With this new combined vector you can then change F So that it operates on the two k's separately. This results in

K = FF(u+dt*a*K) where FF is F for the new double k vector, K

Ok, now we can implement the Newton's method. You will do this for each time step and until you have converged on the right answer and use it across all spatial points at the same time. What you do is you guess a K and compute the jacobian of G(K,U) = K-FF(FF(u+dt*a*K). G(K,U) should be only valued at zero when K is at the right solution. So in other words, do you Newton's method on K and when looking for convergence you need to see that it is converging at all spots. I would run the newton's method until max(abs(G(K,U)))< SolverTolerance.

Sorry I can't be more help on the matlab implementation, but hopefully I helped with explaining how to implement the newton's method.

James Urban
  • 320
  • 1
  • 4
  • 12