aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2018-06-19 22:03:25 +0200
committerAdrian Kummerlaender2018-06-19 22:27:01 +0200
commit369159ceb811cec067f194d75ffef7950b20e0ac (patch)
tree4c43b05664aadff981f1322a5f7e5ff9d78efb58
parente698d1593cc4407b28f324ee930d8c83a8589955 (diff)
downloadboltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar.gz
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar.bz2
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar.lz
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar.xz
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.tar.zst
boltzbub-369159ceb811cec067f194d75ffef7950b20e0ac.zip
Split collide and stream steps
Simplifies correct implementation of Zou He boundary condition (used for the lid in lid driven cavity). Fix tau using lid velocity and Reynolds number. Simulation now seems to converge for Reynolds numbers greater than 100 if lattice resolution is sufficient.
-rw-r--r--boltz.cc118
1 files changed, 67 insertions, 51 deletions
diff --git a/boltz.cc b/boltz.cc
index 3949efa..a361a58 100644
--- a/boltz.cc
+++ b/boltz.cc
@@ -92,13 +92,32 @@ class CellBuffer {
}
};
+std::pair<Vector<int>, Vector<int>> neighbors(Vector<int> v) {
+ if ( v[0] == 0 ) {
+ return {
+ { -1, v[1] },
+ { 1, v[1] }
+ };
+ } else if ( v[1] == 0 ) {
+ return {
+ { v[0], -1 },
+ { v[0], 1 }
+ };
+ } else {
+ return {
+ { 0, v[1] },
+ { v[0], 0 }
+ };
+ }
+}
+
constexpr std::size_t dimX = 256;
-constexpr std::size_t dimY = 256;
+constexpr std::size_t dimY = dimX;
-constexpr double tau = 2./3.;
-constexpr int reynolds = 1000;
-constexpr double lidVelocityX = reynolds * (2.*tau - 1.) / (6.*(dimX - 1.));
+constexpr double uLid = 0.1;
+constexpr double reynolds = 1000;
+constexpr double tau = 3 * uLid * (dimX-1) / reynolds + 0.5;
constexpr double omega = 1. / tau;
CellBuffer pop(dimX, dimY);
@@ -106,47 +125,48 @@ CellBuffer pop(dimX, dimY);
Density density [dimX][dimY];
Velocity velocity[dimX][dimY];
-void computeFluidCell(std::size_t x, std::size_t y) {
- // compute equilibrium
- Cell eq;
- eq.equilibrize(density[x][y], velocity[x][y]);
-
- // collide (BGK, relax towards equilibrium) & stream
+void streamFluidCell(std::size_t x, std::size_t y) {
if ( x != 0 && x != dimX - 1 && y != 0 && y != dimY -1 ) {
+ // stream internal cells
for ( int i = -1; i <= 1; ++i ) {
for ( int j = -1; j <= 1; ++j ) {
- pop.curr(x+i,y+j).get(i,j) = pop.prev(x,y).get(i,j) + omega * (eq.get(i,j) - pop.prev(x,y).get(i,j));
+ pop.curr(x+i,y+j).get(i,j) = pop.prev(x,y).get(i,j);
}
}
} else {
- // partial collide and stream for boundary cells,
- // remaining populations to be determined by boundary conditions
+ // stream boundary cells,
+ // missing populations to be determined by boundary conditions
for ( int i = -1; i <= 1; ++i ) {
for ( int j = -1; j <= 1; ++j ) {
if ( x+i >= 0 && x+i <= dimX - 1 && y+j >= 0 && y+j <= dimY - 1 ) {
- pop.curr(x+i,y+j).get(i,j) = pop.prev(x,y).get(i,j) + omega * (eq.get(i,j) - pop.prev(x,y).get(i,j));
+ pop.curr(x+i,y+j).get(i,j) = pop.prev(x,y).get(i,j);
}
}
}
}
}
-std::pair<Vector<int>, Vector<int>> neighbors(Vector<int> v) {
- if ( v[0] == 0 ) {
- return {
- { -1, v[1] },
- { 1, v[1] }
- };
- } else if ( v[1] == 0 ) {
- return {
- { v[0], -1 },
- { v[0], 1 }
- };
+void collideFluidCell(std::size_t x, std::size_t y) {
+ // compute equilibrium
+ Cell eq;
+ eq.equilibrize(density[x][y], velocity[x][y]);
+
+ // collide (BGK, relax towards equilibrium)
+ if ( x != 0 && x != dimX - 1 && y != 0 && y != dimY -1 ) {
+ for ( int i = -1; i <= 1; ++i ) {
+ for ( int j = -1; j <= 1; ++j ) {
+ pop.curr(x,y).get(i,j) = pop.curr(x,y).get(i,j) + omega * (eq.get(i,j) - pop.curr(x,y).get(i,j));
+ }
+ }
} else {
- return {
- { 0, v[1] },
- { v[0], 0 }
- };
+ // partial collide for boundary cells
+ for ( int i = -1; i <= 1; ++i ) {
+ for ( int j = -1; j <= 1; ++j ) {
+ if ( x+i >= 0 && x+i <= dimX - 1 && y+j >= 0 && y+j <= dimY - 1 ) {
+ pop.curr(x,y).get(i,j) = pop.curr(x,y).get(i,j) + omega * (eq.get(i,j) - pop.curr(x,y).get(i,j));
+ }
+ }
+ }
}
}
@@ -158,14 +178,6 @@ void computeWallCell(Vector<std::size_t> cell, Vector<int> normal) {
pop.curr(cell).get(neighborB) = pop.curr(cell).get(-neighborB);
}
-void computeSimpleVelocityWallCell(Vector<std::size_t> cell, Vector<int> normal, double vX) {
- const auto [neighborA, neighborB] = neighbors(normal);
-
- pop.curr(cell).get(neighborA) = pop.curr(cell).get(-neighborA) - 6 * weight.get( 1, 1) * density[cell[0]][cell[1]] * vX;
- pop.curr(cell).get(normal ) = pop.curr(cell).get(-normal );
- pop.curr(cell).get(neighborB) = pop.curr(cell).get(-neighborB) + 6 * weight.get(-1, 1) * density[cell[0]][cell[0]] * vX;
-}
-
void computeZouHeVelocityWallCell(Vector<std::size_t> cell, Vector<int> normal, double vX) {
const auto [neighborA, neighborB] = neighbors(normal);
@@ -184,17 +196,18 @@ void computeZouHeVelocityWallCell(Vector<std::size_t> cell, Vector<int> normal,
void computeLbmStep(std::size_t t) {
pop.swap();
- for ( std::size_t x = 1; x < dimX-1; ++x ) {
+ for ( std::size_t x = 0; x < dimX; ++x ) {
for ( std::size_t y = 0; y < dimY; ++y ) {
- computeFluidCell(x, y);
+ streamFluidCell(x, y);
}
}
// straight wall cell bounce back
for ( std::size_t x = 0; x < dimX; ++x ) {
+ computeZouHeVelocityWallCell({x, dimY-1}, { 0,-1}, uLid);
+ }
+ for ( std::size_t x = 1; x < dimX-1; ++x ) {
computeWallCell({x, 0}, { 0, 1});
- computeZouHeVelocityWallCell({x, dimY-1}, { 0,-1}, lidVelocityX);
- //computeSimpleVelocityWallCell({x, dimY-1}, { 0,-1}, lidVelocityX);
}
for ( std::size_t y = 1; y < dimY-1; ++y ) {
computeWallCell({0, y}, { 1, 0});
@@ -202,16 +215,15 @@ void computeLbmStep(std::size_t t) {
}
// edge wall cell bounce back
- //computeWallCell({0, dimY-1}, { 1,-1});
- //computeWallCell({dimX-1, dimY-1}, {-1,-1});
- //computeWallCell({0, 0 }, { 1, 1});
- //computeWallCell({dimX-1, 0 }, {-1, 1});
+ computeWallCell({0, 0 }, { 1, 1});
+ computeWallCell({dimX-1, 0 }, {-1, 1});
- // update density, velocity field
for ( std::size_t x = 0; x < dimX; ++x ) {
for ( std::size_t y = 0; y < dimY; ++y ) {
density[x][y] = pop.curr(x,y).sum();
velocity[x][y] = pop.curr(x,y).velocity(density[x][y]);
+
+ collideFluidCell(x, y);
}
}
}
@@ -273,15 +285,19 @@ void writeCurrentStateAsVTK(int time) {
int main() {
init();
- std::cout << "tau: " << tau << std::endl;
- std::cout << "u: " << lidVelocityX << std::endl;
+ std::cout << "Re: " << reynolds << std::endl;
+ std::cout << "uLid: " << uLid << std::endl;
+ std::cout << "tau: " << tau << std::endl;
- for ( std::size_t t = 0; t <= 40000; ++t ) {
+ for ( std::size_t t = 0; t <= 100000; ++t ) {
computeLbmStep(t);
- if ( t < 100 || t % 1000 == 0 ) {
- std::cout << "Writing " << t << "." << std::endl;
+ if ( (t < 1000 && t % 10 == 0) || t % 1000 == 0 ) {
+ std::cout << ".";
+ std::cout.flush();
writeCurrentStateAsVTK(t);
}
}
+
+ std::cout << std::endl;
}