A 2D Lattice Botlzmann flow solver demo
Vortex shedding behind a "cylinder". Top CPU (C), bottom GPU (CUDA)
The lattice Boltzmann method is a simple way of calculating fluid flow (particularly if the flow is incompressible and the problem of interest is at a low Reynolds number). More details of the method can be found at lbmethod.org.
The objective here is not to produce a sophisticated flow solver that will push the boundaries of science or engineering, but to provide an interactive demo that illustrates the power of modern GPUs. The same method is coded for the CPU (using C) and NVIDIA GPUs (using CUDA). It is found that the latter is approximately 20x quicker than a single core of the former.
The method can be thought of as a "particle" based approach. The 2D domain is divided into a uniform grid (lattice). Particles may only move from one grid node to one of the 8 surrounding nodes. We store floats to represents the number of particles moving in these 8 directions - and also particles at rest - so we need 9 floats per grid node. These float arrays are the "distribution functions" - assigned names, f0, f1 ... f8 in the code.
Each time step can be divided into 3 functions or kernels:
The f values are copied from the nodes to the adjacent nodes in the appropriate directions - e.g. f1 is the distribution function pointing "east". In the CUDA code, this is implemented using texture lookups.
- Boundary conditions
Special treatments are used at the inlet (left side), exit (right side), periodic (top and bottom) and solid boundaries. In each case, the f values entering the domain from the boundaries are unknown after the stream step and have to be set.
The f values are adjusted toward the local equilibrium values to model the collisions between particles. This is a purely local operation (only the f values at the current node are needed) so it is easy to get coallesced memory access.
Both the C and CUDA codes are available here. There are 3 files: the C version, the CUDA version, and a colourmap data file.
To compile the programs, first make sure that the CUDA SDK is installed (also make sure that the CUDA libraries are in your library path, e.g. that /usr/local/cuda/lib is in the LD_LIBRARY_PATH environment variable.)
C version (for Linux x86_64)
gcc -O2 -o 2dLB_C 2dLB_C.c -I$HOME/NVIDIA_CUDA_SDK/common/inc -L$HOME/NVIDIA_CUDA_SDK/common/lib/linux -lGLEW_x86_64 -lglut
CUDA version (for Linux x86_64)
nvcc -o 2dLB_cuda 2dLB_cuda.cu -I$HOME/NVIDIA_CUDA_SDK/common/inc -I/usr/local/cuda/include -lcuda -lcudart -L$HOME/NVIDIA_CUDA_SDK/common/lib/linux -lGLEW_x86_64 -lglut
When running, a small blue window appears. The flow is moving from left to right and is coloured by velocity magnitude. You can add a solid node using the left mouse button and remove a solid node using the right mouse button. The size of the window can be altered by changing ni and nj in the code, and the viscosity of the flow by changing tau (which may not be less than 0.5).