1
$\begingroup$

I have been trying to port and understand the code used in the paper Real-Time Fluid Dynamics for Games. One function in the paper, the method to diffuse one of the vector fields is said to use the Gauss-Siedel relaxation to approximate the solutions.

Here is the function:

void diffuse ( int N, int b, float * x, float * x0, float diff, float dt ) 
{ 
    int i, j, k; 
    float a=dt*diff*N*N; 
 
    for ( k=0 ; k<20 ; k++ ) { 
        for ( i=1 ; i<=N ; i++ ) { 
            for ( j=1 ; j<=N ; j++ ) { 
                x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)]+ 
  x[IX(i,j-1)]+x[IX(i,j+1)]))/(1+4*a); 
            } 
        } 
        set_bnd ( N, b, x ); 
    } 
}

I understand what the set_bnd(N, b, x) call is doing (handling interactions with the edges of the simulation), and I know that the outermost for-loop is doing the iteration 20 times, but how does this relate to the formula for the gauss-siedel method? Also, what is the term a doing here, and why is the sum of the surrounding cells in the matrix multiplied by $\frac{a}{1+4a}$?

$\endgroup$
1
  • $\begingroup$ I am not sure , but I think it is the Gauss-Seidel-alhorithm , not Gauss-Siedel. $\endgroup$
    – Peter
    Commented Jul 2, 2023 at 11:14

1 Answer 1

-1
$\begingroup$

This is exactly diffusion process there's a change of matter between every two adjacent cells, thus each element tends towards the average of it's neighbors in the given rate $a$, which is proportional to the timestep, the diffusion rate, and inversely proportional to the cell area.

$ x_{n+1} (i,j) = a * \sum_{neighbors} ({x_n(neighbor) - x_n(i,j)})$

Summing it up gives

$ x_{n+1} (i,j) = a * (x_n(i+1, j) + x_n(i-1, j) + x_n(i, j+1) + x_n(i, j-1) -4x_n(i,j)) $

Substituting this exactly gives an unstable solution (what was called "diffuse bad" in the article), since this method is explicit. In order to make the method implicit, we will replace $4x_n(i,j)$ on the RHS by $4x_{n+1}(i,j)$, move the $4x_{n+1}(i,j)$ to the LHS obtaining $(1+4a)x_{n+1}(i,j)$, and dividing by $1+4a$ to get the formula you wrote. This implicitization procedure is common to improve stability of iterative methods.

The notation "Gauss-Seidel" here is correct, but misleading in my opinion, since the Gauss-Seidel algorithm works in an entirely different "framework" (when you're solving a system of linear equations $Ax=b$), though they are equivalent (in GS you decompose $A$ into $U+D+L$ and then replace $Dx_{n}$ by $Dx_{n+1}$, which exactly what we did). Please think of it purely as a method of making the iterative algorithm more implicit to improve stability.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .