diff options
-rw-r--r-- | codegen_lbm.py | 221 | ||||
-rw-r--r-- | lbm_codegen.ipynb | 1557 | ||||
-rw-r--r-- | lid_driven_cavity.py | 14 |
3 files changed, 1041 insertions, 751 deletions
diff --git a/codegen_lbm.py b/codegen_lbm.py new file mode 100644 index 0000000..cd93649 --- /dev/null +++ b/codegen_lbm.py @@ -0,0 +1,221 @@ +import pyopencl as cl +mf = cl.mem_flags + +from string import Template + +import numpy +import matplotlib.pyplot as plt + +import time + +kernel = """ +unsigned int indexOfDirection(int i, int j) { + return (i+1) + 3*(1-j); +} + +unsigned int indexOfCell(int x, int y) +{ + return y * $nX + x; +} + +unsigned int idx(int x, int y, int i, int j) { + return indexOfDirection(i,j)*$nCells + indexOfCell(x,y); +} + +__global float f_i(__global __read_only float* f, int x, int y, int i, int j) { + return f[idx(x,y,i,j)]; +} + +__kernel void collide_and_stream(__global __write_only float* f_a, + __global __read_only float* f_b, + __global __write_only float* moments, + __global __read_only int* material) +{ + const unsigned int gid = indexOfCell(get_global_id(0), get_global_id(1)); + + const uint2 cell = (uint2)(get_global_id(0), get_global_id(1)); + + const int m = material[gid]; + + if ( m == 0 ) { + return; + } + + const float f_curr_0 = f_i(f_b, cell.x+1, cell.y-1, -1, 1); + const float f_curr_1 = f_i(f_b, cell.x , cell.y-1, 0, 1); + const float f_curr_2 = f_i(f_b, cell.x-1, cell.y-1, 1, 1); + const float f_curr_3 = f_i(f_b, cell.x+1, cell.y , -1, 0); + const float f_curr_4 = f_i(f_b, cell.x , cell.y , 0, 0); + const float f_curr_5 = f_i(f_b, cell.x-1, cell.y , 1, 0); + const float f_curr_6 = f_i(f_b, cell.x+1, cell.y+1, -1,-1); + const float f_curr_7 = f_i(f_b, cell.x , cell.y+1, 0,-1); + const float f_curr_8 = f_i(f_b, cell.x-1, cell.y+1, 1,-1); + + const float x0 = f_curr_0 + f_curr_1 + f_curr_2 + f_curr_3 + f_curr_4 + f_curr_5 + f_curr_6 + f_curr_7 + f_curr_8; + const float x1 = 2*f_curr_0; + const float x2 = 2*f_curr_8; + const float x3 = -f_curr_3 + f_curr_5; + const float x4 = pow(x0, -2); + const float x5 = 9*x4; + const float x6 = f_curr_0 - f_curr_8; + const float x7 = f_curr_1 - f_curr_7; + const float x8 = f_curr_2 - f_curr_6; + const float x9 = x6 + x7 + x8; + const float x10 = 6/x0; + const float x11 = x10*x9; + const float x12 = f_curr_3 - f_curr_5; + const float x13 = -f_curr_2 + f_curr_6 + x12 + x6; + const float x14 = pow(x13, 2); + const float x15 = 3*x4; + const float x16 = -x14*x15 + 2; + const float x17 = x11 + x16; + const float x18 = pow(x9, 2); + const float x19 = x15*x18; + const float x20 = -x19; + const float x21 = x10*x13; + const float x22 = x20 + x21; + const float x23 = 1.0/$tau; + const float x24 = (1.0/72.0)*x23; + const float x25 = 6*x4; + const float x26 = x18*x25; + const float x27 = (1.0/18.0)*x23; + const float x28 = x5*pow(2*f_curr_2 - 2*f_curr_6 + x3 + x7, 2); + const float x29 = x20 - x21; + const float x30 = x14*x25 + 2; + const float x31 = -f_curr_0 + f_curr_8 + x3 + x8; + const float x32 = x15*pow(x31, 2) - 2; + const float x33 = x19 + x32; + + f_a[0*$nCells + gid] = f_curr_0 - x24*(72*f_curr_0 - x0*(x17 + x22 + x5*pow(-f_curr_1 + f_curr_7 - x1 + x2 + x3, 2))); + f_a[1*$nCells + gid] = f_curr_1 - x27*(18*f_curr_1 - x0*(x17 + x26)); + f_a[2*$nCells + gid] = f_curr_2 - x24*(72*f_curr_2 - x0*(x17 + x28 + x29)); + f_a[3*$nCells + gid] = f_curr_3 - x27*(18*f_curr_3 - x0*(x22 + x30)); + f_a[4*$nCells + gid] = f_curr_4 - 1.0/9.0*x23*(9*f_curr_4 + 2*x0*x33); + f_a[5*$nCells + gid] = f_curr_5 - x27*(18*f_curr_5 - x0*(x29 + x30)); + f_a[6*$nCells + gid] = f_curr_6 - x24*(72*f_curr_6 + x0*(x10*x31 + x11 - x28 + x33)); + f_a[7*$nCells + gid] = f_curr_7 - x27*(18*f_curr_7 + x0*(x11 - x26 + x32)); + f_a[8*$nCells + gid] = f_curr_8 - x24*(72*f_curr_8 - x0*(-x11 + x16 + x29 + x5*pow(x1 + x12 - x2 + x7, 2))); + + moments[gid] = x0; +}""" + + +class D2Q9_BGK_Lattice: + def idx(self, x, y): + return y * self.nX + x; + + def __init__(self, nX, nY): + self.nX = nX + self.nY = nY + self.nCells = nX * nY + self.tick = True + + self.platform = cl.get_platforms()[0] + self.context = cl.Context(properties=[(cl.context_properties.PLATFORM, self.platform)]) + self.queue = cl.CommandQueue(self.context) + + self.np_pop_a = numpy.ndarray(shape=(9, self.nCells), dtype=numpy.float32) + self.np_pop_b = numpy.ndarray(shape=(9, self.nCells), dtype=numpy.float32) + + self.np_moments = numpy.ndarray(shape=(3, self.nCells), dtype=numpy.float32) + self.np_material = numpy.ndarray(shape=(self.nCells, 1), dtype=numpy.int32) + + self.setup_geometry() + + self.equilibrilize() + self.setup_anomaly() + + self.cl_pop_a = cl.Buffer(self.context, mf.READ_WRITE | mf.USE_HOST_PTR, hostbuf=self.np_pop_a) + self.cl_pop_b = cl.Buffer(self.context, mf.READ_WRITE | mf.USE_HOST_PTR, hostbuf=self.np_pop_b) + + self.cl_material = cl.Buffer(self.context, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.np_material) + self.cl_moments = cl.Buffer(self.context, mf.READ_WRITE | mf.USE_HOST_PTR, hostbuf=self.np_moments) + + self.build_kernel() + + def setup_geometry(self): + self.np_material[:] = 0 + for x in range(1,self.nX-1): + for y in range(1,self.nY-1): + if x == 1 or y == 1 or x == self.nX-2 or y == self.nY-2: + self.np_material[self.idx(x,y)] = 2 + else: + self.np_material[self.idx(x,y)] = 1 + + def equilibrilize(self): + self.np_pop_a[(0,2,6,8),:] = 1./36. + self.np_pop_a[(1,3,5,7),:] = 1./9. + self.np_pop_a[4,:] = 4./9. + + self.np_pop_b[(0,2,6,8),:] = 1./36. + self.np_pop_b[(1,3,5,7),:] = 1./9. + self.np_pop_b[4,:] = 4./9. + + def setup_anomaly(self): + bubbles = [ [ self.nX//4, self.nY//4], + [ self.nX//4,self.nY-self.nY//4], + [self.nX-self.nX//4, self.nY//4], + [self.nX-self.nX//4,self.nY-self.nY//4] ] + + for x in range(0,self.nX-1): + for y in range(0,self.nY-1): + for [a,b] in bubbles: + if numpy.sqrt((x-a)*(x-a)+(y-b)*(y-b)) < self.nX//10: + self.np_pop_a[:,self.idx(x,y)] = 1./24. + self.np_pop_b[:,self.idx(x,y)] = 1./24. + + def build_kernel(self): + self.program = cl.Program(self.context, Template(kernel).substitute({ + 'nX' : self.nX, + 'nY' : self.nY, + 'nCells': self.nCells, + 'tau': '0.8f' + })).build() #'-cl-single-precision-constant -cl-fast-relaxed-math') + + def evolve(self): + if self.tick: + self.tick = False + self.program.collide_and_stream(self.queue, (self.nX,self.nY), (64,1), self.cl_pop_a, self.cl_pop_b, self.cl_moments, self.cl_material) + else: + self.tick = True + self.program.collide_and_stream(self.queue, (self.nX,self.nY), (64,1), self.cl_pop_b, self.cl_pop_a, self.cl_moments, self.cl_material) + + def sync(self): + self.queue.finish() + + def show(self, i): + cl.enqueue_copy(LBM.queue, LBM.np_moments, LBM.cl_moments).wait(); + + density = numpy.ndarray(shape=(self.nX-2, self.nY-2)) + for y in range(1,self.nY-1): + for x in range(1,self.nX-1): + density[y-1,x-1] = self.np_moments[0,self.idx(x,y)] + + plt.imshow(density, vmin=0.2, vmax=2.0, cmap=plt.get_cmap("seismic")) + plt.savefig("result/density_" + str(i) + ".png") + + +def MLUPS(cells, steps, time): + return cells * steps / time * 1e-6 + +nUpdates = 1000 +nStat = 100 + +print("Initializing simulation...\n") + +LBM = D2Q9_BGK_Lattice(1024, 1024) + +print("Starting simulation using %d cells...\n" % LBM.nCells) + +lastStat = time.time() + +for i in range(1,nUpdates+1): + if i % nStat == 0: + LBM.sync() + #LBM.show(i) + print("i = %4d; %3.0f MLUPS" % (i, MLUPS(LBM.nCells, nStat, time.time() - lastStat))) + lastStat = time.time() + + LBM.evolve() + +LBM.show(nUpdates) diff --git a/lbm_codegen.ipynb b/lbm_codegen.ipynb index efc1200..7d13f70 100644 --- a/lbm_codegen.ipynb +++ b/lbm_codegen.ipynb @@ -14,40 +14,39 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ - "c = [Matrix((x,)) for x in [(-1, 1), ( 0, 1), ( 1, 1), (-1, 0), ( 0, 0), ( 1, 0), (-1, 0), ( 0, -1), ( 1, -1)]]" + "c = [Matrix((x,)) for x in [(-1, 1), ( 0, 1), ( 1, 1), (-1, 0), ( 0, 0), ( 1, 0), (-1,-1), ( 0, -1), ( 1, -1)]]" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 31, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAA0AAAASCAYAAACAa1QyAAAABHNCSVQICAgIfAhkiAAAAHZJREFUKJFjYKACCGFgYJjMwMBwmIGB4RMDA8N/BgaGJYQ0XYAq/MzAwHCdWE2ODAwMqgwMDIwMDAwOuDSxoPH3EzKVgYGBgYkYRaOaBlwTeuQGQDEDAwODBJS2ZGBgWABlv2FgYChBN6SBAZJ0cOEH5LiMzgAA6XoX52TB9a4AAAAASUVORK5CYII=\n", "text/latex": [ - "$$1$$" + "$$\\left [ \\left[\\begin{matrix}-1 & 1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0 & 1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}1 & 1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}-1 & 0\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0 & 0\\end{matrix}\\right], \\quad \\left[\\begin{matrix}1 & 0\\end{matrix}\\right], \\quad \\left[\\begin{matrix}-1 & -1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0 & -1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}1 & -1\\end{matrix}\\right]\\right ]$$" ], "text/plain": [ - "1" + "[[-1 1], [0 1], [1 1], [-1 0], [0 0], [1 0], [-1 -1], [0 -1], [1 -1]]" ] }, - "execution_count": 3, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "c[1][1]" + "c" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -69,7 +68,7 @@ "[1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36]" ] }, - "execution_count": 5, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -80,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -93,7 +92,7 @@ "1" ] }, - "execution_count": 6, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -104,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -119,7 +118,7 @@ "3 " ] }, - "execution_count": 8, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -131,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -140,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -150,7 +149,7 @@ " f_next_6, f_next_7, f_next_8], dtype=object)" ] }, - "execution_count": 10, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -162,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -172,7 +171,7 @@ " f_curr_6, f_curr_7, f_curr_8], dtype=object)" ] }, - "execution_count": 11, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -184,7 +183,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -198,7 +197,7 @@ "_curr_7 + f_curr_8" ] }, - "execution_count": 12, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -210,7 +209,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -229,7 +228,7 @@ "_curr_7 + f_curr_8" ] }, - "execution_count": 13, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -241,26 +240,26 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 41, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/latex": [ - "$$\\frac{f_{curr 0} + f_{curr 1} + f_{curr 2} - f_{curr 7} - f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}$$" + "$$\\frac{f_{curr 0} + f_{curr 1} + f_{curr 2} - f_{curr 6} - f_{curr 7} - f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}$$" ], "text/plain": [ - " f_curr_0 + f_curr_1 + f_curr_2 - f_curr_7 - f_curr_8 \n", + " f_curr_0 + f_curr_1 + f_curr_2 - f_curr_6 - f_curr_7 - f_curr_\n", "──────────────────────────────────────────────────────────────────────────────\n", "f_curr_0 + f_curr_1 + f_curr_2 + f_curr_3 + f_curr_4 + f_curr_5 + f_curr_6 + f\n", "\n", - " \n", + "8 \n", "──────────────────\n", "_curr_7 + f_curr_8" ] }, - "execution_count": 14, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -272,20 +271,20 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$$\\left[\\begin{matrix}\\frac{- f_{curr 0} + f_{curr 2} - f_{curr 3} + f_{curr 5} - f_{curr 6} + f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}\\\\\\frac{f_{curr 0} + f_{curr 1} + f_{curr 2} - f_{curr 7} - f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}\\end{matrix}\\right]$$" + "$$\\left[\\begin{matrix}\\frac{- f_{curr 0} + f_{curr 2} - f_{curr 3} + f_{curr 5} - f_{curr 6} + f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}\\\\\\frac{f_{curr 0} + f_{curr 1} + f_{curr 2} - f_{curr 6} - f_{curr 7} - f_{curr 8}}{f_{curr 0} + f_{curr 1} + f_{curr 2} + f_{curr 3} + f_{curr 4} + f_{curr 5} + f_{curr 6} + f_{curr 7} + f_{curr 8}}\\end{matrix}\\right]$$" ], "text/plain": [ "⎡ -f_curr_0 + f_curr_2 - f_curr_3 + f_curr_5 - f_curr_6 + f_cur\n", "⎢─────────────────────────────────────────────────────────────────────────────\n", "⎢f_curr_0 + f_curr_1 + f_curr_2 + f_curr_3 + f_curr_4 + f_curr_5 + f_curr_6 + \n", "⎢ \n", - "⎢ f_curr_0 + f_curr_1 + f_curr_2 - f_curr_7 - f_curr_8 \n", + "⎢ f_curr_0 + f_curr_1 + f_curr_2 - f_curr_6 - f_curr_7 - f_curr\n", "⎢─────────────────────────────────────────────────────────────────────────────\n", "⎣f_curr_0 + f_curr_1 + f_curr_2 + f_curr_3 + f_curr_4 + f_curr_5 + f_curr_6 + \n", "\n", @@ -293,12 +292,12 @@ "───────────────────⎥\n", "f_curr_7 + f_curr_8⎥\n", " ⎥\n", - " ⎥\n", + "_8 ⎥\n", "───────────────────⎥\n", "f_curr_7 + f_curr_8⎦" ] }, - "execution_count": 15, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -310,311 +309,311 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 43, "metadata": {}, "outputs": [ { "data": { - "image/png": "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 |