Lattice Boltzmann Equation: D2Q9 Model Simulation
Lattice Boltzmann Equation: D2Q9 Model Simulation
Lattice Boltzmann Equation: D2Q9 Model Simulation
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Topic 6 Complex Systems Lecture 8<br />
<strong>Lattice</strong> <strong>Boltzmann</strong> <strong>Equation</strong>: <strong>D2Q9</strong> <strong>Model</strong> <strong>Simulation</strong><br />
The following program lbe.cpp simulates two-dimensional flow in a channel with a linear obstacle using the <strong>Lattice</strong><br />
<strong>Boltzmann</strong> <strong>Equation</strong> in the Bhatnagar-Gross-Krook approximation. The program is based on lbe.f by Dr. Sauro Succi.<br />
lbe.cpp<br />
// <strong>Lattice</strong> <strong>Boltzmann</strong> <strong>Equation</strong>: <strong>D2Q9</strong> <strong>Model</strong> <strong>Simulation</strong> 1<br />
// Flow in a channel with a linear obstacle 2<br />
#include 4<br />
#include 5<br />
#include 6<br />
using namespace std; 8<br />
#include 10<br />
int Nx = 64; // number of cells in x direction 12<br />
int Ny = 32; // number of cells in y direction 13<br />
int Nc = 9; // number of discrete velocities 15<br />
enum direction { 16<br />
East = 1, North, West, South, 17<br />
NorthEast, NorthWest, SouthWest, SouthEast 18<br />
}; 19<br />
double ***n; // number densities 21<br />
double ***neq; // equilibrium number densities 22<br />
double ***u; // fluid velocity 23<br />
PHY 411-506 Computational Physics II 1 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
void allocate() { 25<br />
static int oldNx = 0, oldNy = 0; 26<br />
if (Nx != oldNx) { 27<br />
if (n != 0) { 28<br />
for (int x = 0; x < oldNx+2; x++) { 29<br />
for (int y = 0; y < oldNy+2; y++) { 30<br />
delete [] n[x][y]; delete [] neq[x][y]; delete [] u[x][y]; 31<br />
} 32<br />
delete [] n[x]; delete [] neq[x]; delete [] u[x]; 33<br />
} 34<br />
} 35<br />
delete [] n; delete [] neq; delete [] u; 36<br />
oldNx = Nx; 37<br />
oldNy = Ny; 38<br />
n = new double** [Nx+2]; 39<br />
neq = new double** [Nx+2]; 40<br />
u = new double** [Nx+2]; 41<br />
for (int x = 0; x < Nx+2; x++) { 42<br />
n[x] = new double* [Ny+2]; 43<br />
neq[x] = new double* [Ny+2]; 44<br />
u[x] = new double* [Ny+2]; 45<br />
for (int y = 0; y < Ny+2; y++) { 46<br />
n[x][y] = new double [Nc]; 47<br />
neq[x][y] = new double [Nc]; 48<br />
u[x][y] = new double [2]; 49<br />
} 50<br />
} 51<br />
} 52<br />
} 53<br />
PHY 411-506 Computational Physics II 2 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
double rho; // fluid density 55<br />
double u0[2]; // initial fluid velocity 56<br />
double uf[2]; // final fluid velocity 57<br />
double tau; // relaxation time 58<br />
int nObstacle; // extent of obstacle in y direction 59<br />
void getInput() { 61<br />
cout > u0[0]; u0[1] = 0; 64<br />
cout > rho; 66<br />
cout > uf[0]; uf[1] = 0; 68<br />
cout > tau; 70<br />
cout > nObstacle; 72<br />
} 73<br />
const double w0 = 16 / 36.0, 75<br />
w1 = 4 / 36.0, 76<br />
w2 = 1 / 36.0; 77<br />
const double w[9] = { // directional weights 78<br />
w0, // zero 79<br />
w1, w1, w1, w1, // east, north, west, south 80<br />
w2, w2, w2, w2 // north-east, north-west, south-west, south-east 81<br />
}; 82<br />
PHY 411-506 Computational Physics II 3 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
const double c[9][2] = { // particle velocities 83<br />
{0, 0}, // zero 84<br />
{1, 0}, {0, 1}, // east, north 85<br />
{-1, 0}, {0, -1}, // west, south 86<br />
{1, 1}, {-1, 1}, // north-east, north-west 87<br />
{-1, -1}, {1, -1} // south-west, south-east 88<br />
}; 89<br />
const double csSqd = 1 / 3.0; // speed of sound squared 90<br />
void initialize_u() { 92<br />
for (int x = 0; x < Nx; x++) 93<br />
for (int y = 0; y < Ny; y++) { 94<br />
for (int d = 0; d < 2; d++) 95<br />
u[x][y][d] = u0[d]; 96<br />
} 97<br />
} 98<br />
void compute_neq() { 100<br />
for (int x = 0; x < Nx+2; x++) 101<br />
for (int y = 0; y < Ny+2; y++) { 102<br />
double uSqd = u[x][y][0] * u[x][y][0] + u[x][y][1] * u[x][y][1]; 103<br />
uSqd /= 2 * csSqd; 104<br />
for (int i = 0; i < Nc; i++) { 105<br />
double uci = u[x][y][0] * c[i][0] + u[x][y][1] * c[i][1]; 106<br />
uci /= csSqd; 107<br />
neq[x][y][i] = rho * w[i] * (1 + uci * (1 + uci / 2) - uSqd); 108<br />
} 109<br />
} 110<br />
} 111<br />
PHY 411-506 Computational Physics II 4 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
void initialize_n() { 113<br />
for (int x = 0; x < Nx + 2; x++) 114<br />
for (int y = 0; y < Ny + 2; y++) 115<br />
for (int i = 0; i < Nc; i++) 116<br />
n[x][y][i] = neq[x][y][i]; 117<br />
} 118<br />
void initialize() { 120<br />
getInput(); 121<br />
allocate(); 122<br />
initialize_u(); 123<br />
compute_neq(); 124<br />
initialize_n(); 125<br />
} 126<br />
void boundaryConditions() { 128<br />
// periodic boundary conditions for east moving particles at east/west ends 130<br />
for (int y = 1; y
Topic 6 Complex Systems Lecture 8<br />
n[Nx + 1][y][SouthWest] = n[1][y][SouthWest]; 141<br />
} 142<br />
// no-slip boundary conditions for north moving particles at the top end 144<br />
for (int x = 1; x
Topic 6 Complex Systems Lecture 8<br />
for (int y = Ny; y >= 1; y--) { 170<br />
n[x][y][East] = n[x - 1][y][East]; 171<br />
n[x][y][NorthEast] = n[x - 1][y - 1][NorthEast]; 172<br />
} 173<br />
// start at SE corner and stream south and south-east moving particles 175<br />
for (int x = Nx; x >= 1; x--) 176<br />
for (int y = 1; y
Topic 6 Complex Systems Lecture 8<br />
} 199<br />
} 200<br />
void collide() { 202<br />
for (int x = 1; x
Topic 6 Complex Systems Lecture 8<br />
int x = Nx / 4; 229<br />
int y1 = Ny / 2 - nObstacle / 2; 230<br />
int y2 = Ny / 2 + nObstacle / 2; 231<br />
for (int y = y1 + 1; y
Topic 6 Complex Systems Lecture 8<br />
obstacle(); 257<br />
glutPostRedisplay(); 259<br />
} 260<br />
const double toDegrees = 180.0 / (4 * atan(1.0)); 262<br />
void display() { 264<br />
glClear(GL_COLOR_BUFFER_BIT); 265<br />
glColor3ub(0, 0, 255); 266<br />
glRectd(0, - 0.05 * (Ny + 2), Nx + 2, 0); 267<br />
glRectd(0, Ny + 1, Nx + 2, (Ny + 1) * 1.05); 268<br />
if (nObstacle > 1) { 269<br />
glColor3ub(0, 255, 0); 270<br />
int x = Nx / 4, y1 = Ny / 2 - nObstacle / 2, 271<br />
y2 = Ny / 2 + nObstacle / 2; 272<br />
glRectd(x, y1, x + 1, y2); 273<br />
} 274<br />
double uMax = 0; 276<br />
for (int x = 0; x < Nx + 2; x++) 277<br />
for (int y = 0; y < Ny + 2; y++) { 278<br />
double uMag = sqrt(u[x][y][0] * u[x][y][0] + u[x][y][1] * u[x][y][1]); 279<br />
if (uMag > uMax) 280<br />
uMax = uMag; 281<br />
} 282<br />
if (uMax == 0) uMax = 1; 283<br />
glColor3ub(255, 0, 0); 285<br />
PHY 411-506 Computational Physics II 10 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
for (int x = 0; x < Nx + 2; x++) 286<br />
for (int y = 0; y < Ny + 2; y++) { 287<br />
glPushMatrix(); 288<br />
double uMag = sqrt(u[x][y][0] * u[x][y][0] + 289<br />
u[x][y][1] * u[x][y][1]); 290<br />
double scale = uMag / uMax; 291<br />
double angle = atan2(u[x][y][1], u[x][y][0]) * toDegrees; 292<br />
glTranslated(x, y, 0); 293<br />
glScaled(scale, scale, 1); 294<br />
glRotated(angle, 0, 0, 1); 295<br />
glBegin(GL_LINES); 296<br />
glVertex2d(0, 0); glVertex2d(1, 0); 297<br />
glVertex2d(1, 0); glVertex2d(0.8, 0.2); 298<br />
glVertex2d(1, 0); glVertex2d(0.8, -0.2); 299<br />
glEnd(); 300<br />
glPopMatrix(); 301<br />
} 302<br />
glutSwapBuffers(); 304<br />
} 305<br />
void reshape(int w, int h) { 307<br />
int x0 = 0, y0 = 0, dx = w, dy = h; 308<br />
double aspect = (w * (Ny + 2) * 1.1) / (h * (Nx + 2)); 309<br />
if (aspect > 1) { 310<br />
dx = int(dx / aspect); 311<br />
x0 = (w - dx) / 2; 312<br />
} else { 313<br />
dy = int(dy * aspect); 314<br />
PHY 411-506 Computational Physics II 11 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
y0 = (h - dy) / 2; 315<br />
} 316<br />
glViewport(x0, y0, dx, dy); 317<br />
glMatrixMode(GL_PROJECTION); 318<br />
glLoadIdentity(); 319<br />
gluOrtho2D(0, Nx + 2, - 0.05 * (Ny + 2), (Ny + 2) * 1.05); 320<br />
glMatrixMode(GL_MODELVIEW); 321<br />
glLoadIdentity(); 322<br />
} 324<br />
void mouse(int button, int state, int x, int y) { 326<br />
switch (button) { 327<br />
case GLUT_LEFT_BUTTON: 328<br />
if (state == GLUT_DOWN) 329<br />
; 330<br />
break; 331<br />
default: 332<br />
break; 333<br />
} 334<br />
} 335<br />
int main(int argc, char *argv[]) { 337<br />
glutInit(&argc, argv); 338<br />
if (argc > 1) { 339<br />
Nx = atoi(argv[1]); 340<br />
Ny = atoi(argv[2]); 341<br />
} 342<br />
initialize(); 343<br />
PHY 411-506 Computational Physics II 12 Friday, April 16, 2004
Topic 6 Complex Systems Lecture 8<br />
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 344<br />
glutInitWindowSize(600, 330); 345<br />
glutInitWindowPosition(100, 100); 346<br />
glutCreateWindow("<strong>Lattice</strong> <strong>Boltzmann</strong> <strong>Equation</strong>: <strong>D2Q9</strong> <strong>Model</strong>"); 347<br />
glClearColor(1.0, 1.0, 1.0, 0.0); 348<br />
glShade<strong>Model</strong>(GL_FLAT); 349<br />
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 350<br />
glutDisplayFunc(display); 351<br />
glutReshapeFunc(reshape); 352<br />
glutIdleFunc(takeStep); 353<br />
glutMouseFunc(mouse); 354<br />
glutMainLoop(); 355<br />
} 356<br />
PHY 411-506 Computational Physics II 13 Friday, April 16, 2004