I am an undergraduate student writing simulations using the lattice Boltzmann method for a research project. I seem to have some problem in my code that causes my simulations to deviate slightly from analytic solutions for the problem I am simulating, so my research adviser recommended that I derive analytic solutions for what he called the “free-streaming” limit, where there is no equilibrium part of the distribution, and use this to debug my code. That is, for a streaming step that assigns as follows,

fout = (1 - omega)f + omegafeq,

I am assigning omega = 0, so I have fout = f. Is this a valid assignment to make in the lattice Boltzmann method? Is there a way to think about how this affects the algorithm, and what this means physically? Being, as I understand, the opposite of the zero-viscosity limit, I would think that the initial distribution would not change at all over time, but it certainly does, just not in the way I would expect.

Any help is very much appreciated, I am lost on how to understand and execute free-streaming in lattice Boltzmann! Thanks much.

I am not really deep into the theory, but would consider your assumption correct: omega = 0 means relaxation time = infinite and thus lattice viscosity = infinite, which should result in constant populations. The assignment you wrote down, however, is the collision step - could it be that you have some errors in your streaming step?

It is very possible that I have errors in my streaming step. I have implemented circular boundary conditions, meaning that any fluid that crosses the lattice boundary comes into the other side of the lattice (for the problem we are solving the fluid isn’t constrained by boundaries, so we just try to make the lattice large enough that the mass density on the lattice boundaries is very low). This is what I have implemented:

// boundaries

int in = i-1;
int ip = i+1;
int jn = j-1;
int jp = j+1;
if (in == -1) { in = nx-1; }
if (jn == -1) { jn = ny-1; }
if (ip == nx) { ip = 0; }
if (jp == ny) { jp = 0; }
//streaming step
f[i][j][0]=fOut[i][j][0];
f[ip][j][1]=fOut[i][j][1];
f[i][jp][2]=fOut[i][j][2];
f[in][j][3]=fOut[i][j][3];
f[i][jn][4]=fOut[i][j][4];
f[ip][jp][5]=fOut[i][j][5];
f[in][jp][6]=fOut[i][j][6];
f[in][jn][7]=fOut[i][j][7];
f[ip][jn][8]=fOut[i][j][8];

This is for a D2Q9 lattice. Thanks again for your help!

In what language did you write this? If you used c/c++ I am astonished that this even compiled, you use f once as 2d array and another time as 3d array…