diff options
Diffstat (limited to 'simulation.py')
-rw-r--r-- | simulation.py | 131 |
1 files changed, 70 insertions, 61 deletions
diff --git a/simulation.py b/simulation.py index 7ddeb45..e2174ee 100644 --- a/simulation.py +++ b/simulation.py @@ -7,11 +7,11 @@ from utility.ndindex import ndindex import sympy from mako.template import Template +from mako.lookup import TemplateLookup + from pathlib import Path from pyopencl.tools import get_gl_sharing_context_properties -import OpenGL.GL as gl -from OpenGL.arrays import vbo class Geometry: def __init__(self, size_x, size_y, size_z = 1): @@ -37,21 +37,32 @@ class Geometry: return (self.size_x-2, self.size_y-2, self.size_z-2) def wireframe(self): - return ([ - [0 , 0 , 0 ], - [self.size_x, 0 , 0 ], - [self.size_x, self.size_y, 0 ], - [0 , self.size_y, 0 ], - [0 , 0 , self.size_z], - [self.size_x, 0 , self.size_z], - [self.size_x, self.size_y, self.size_z], - [0 , self.size_y, self.size_z] - ], - [ - (0,1), (1,2), (2,3), (3,0), - (4,5), (5,6), (6,7), (7,4), - (0,4), (1,5), (2,6), (3,7) - ]) + if self.size_z > 1: + return ([ + [0 , 0 , 0 ], + [self.size_x, 0 , 0 ], + [self.size_x, self.size_y, 0 ], + [0 , self.size_y, 0 ], + [0 , 0 , self.size_z], + [self.size_x, 0 , self.size_z], + [self.size_x, self.size_y, self.size_z], + [0 , self.size_y, self.size_z] + ], + [ + (0,1), (1,2), (2,3), (3,0), + (4,5), (5,6), (6,7), (7,4), + (0,4), (1,5), (2,6), (3,7) + ]) + else: + return ([ + [0 , 0 ], + [self.size_x, 0 ], + [self.size_x, self.size_y], + [0 , self.size_y], + ], + [ + (0,1), (1,2), (2,3), (3,0) + ]) def pad(n, m): return (n // m + min(1,n % m)) * m @@ -103,15 +114,8 @@ class Memory: self.cl_pop_a = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) self.cl_pop_b = cl.Buffer(self.context, mf.READ_WRITE, size=self.pop_size) - if opengl: - self.np_moments = numpy.ndarray(shape=(self.volume, 4), dtype=self.float_type) - self.gl_moments = vbo.VBO(data=self.np_moments, usage=gl.GL_DYNAMIC_DRAW, target=gl.GL_ARRAY_BUFFER) - self.gl_moments.bind() - self.cl_gl_moments = cl.GLBuffer(self.context, mf.READ_WRITE, int(self.gl_moments)) - else: - self.cl_moments = cl.Buffer(self.context, mf.WRITE_ONLY, size=self.moments_size) - - self.cl_material = cl.Buffer(self.context, mf.READ_ONLY, size=self.volume * numpy.int32(0).nbytes) + self.cl_moments = cl.Buffer(self.context, mf.WRITE_ONLY, size=self.moments_size) + self.cl_material = cl.Buffer(self.context, mf.READ_WRITE, size=self.volume * numpy.int32(0).nbytes) def gid(self, x, y, z = 0): return z * (self.size_x*self.size_y) + y * self.size_x + x; @@ -129,7 +133,7 @@ class Lattice: def __init__(self, descriptor, geometry, moments, collide, pop_eq_src = '', boundary_src = '', - platform = 0, precision = 'single', layout = None, padding = None, align = True, opengl = False + platform = 0, precision = 'single', layout = None, padding = None, align = False, opengl = False ): self.descriptor = descriptor self.geometry = geometry @@ -142,11 +146,24 @@ class Lattice: 'double': (numpy.float64, 'double'), }.get(precision, None) + self.mako_lookup = TemplateLookup(directories = [ + Path(__file__).parent + ]) + self.platform = cl.get_platforms()[platform] if opengl: - self.context = cl.Context( - properties=[(cl.context_properties.PLATFORM, self.platform)] + get_gl_sharing_context_properties()) + try: + self.context = cl.Context( + properties = [ + (cl.context_properties.PLATFORM, self.platform) + ] + get_gl_sharing_context_properties()) + except: + self.context = cl.Context( + properties = [ + (cl.context_properties.PLATFORM, self.platform) + ] + get_gl_sharing_context_properties(), + devices = [ self.platform.get_devices()[0] ]) else: self.context = cl.Context( properties=[(cl.context_properties.PLATFORM, self.platform)]) @@ -177,11 +194,28 @@ class Lattice: self.material = numpy.ndarray(shape=(self.memory.volume, 1), dtype=numpy.int32) def apply_material_map(self, material_map): - for indicator, material in material_map: - self.material[[indicator(*idx) for idx in self.memory.cells()]] = material + for primitive, material in material_map: + if callable(primitive): + self.material[[primitive(*idx) for idx in self.memory.cells()]] = material + else: + indicator = primitive.indicator() + self.material[[indicator(*idx) for idx in self.memory.cells()]] = material + + def setup_channel_with_sdf_obstacle(self, sdf_src): + sdf_kernel_src = Template( + filename = 'template/sdf.cl.mako', + lookup = self.mako_lookup + ).render( + geometry = self.memory, + sdf_src = sdf_src + ) + + sdf_program = cl.Program(self.context, sdf_kernel_src).build(self.compiler_args) + sdf_program.setup_channel_with_sdf_obstacle(self.queue, self.memory.size(), None, self.memory.cl_material) + cl.enqueue_copy(self.queue, self.material, self.memory.cl_material).wait() def sync_material(self): - cl.enqueue_copy(self.queue, self.memory.cl_material, self.material).wait(); + cl.enqueue_copy(self.queue, self.memory.cl_material, self.material).wait() def build_kernel(self): program_src = Template(filename = str(Path(__file__).parent/'template/kernel.mako')).render( @@ -227,9 +261,7 @@ class Lattice: def sync(self): self.queue.finish() - def get_moments(self): - moments = numpy.ndarray(shape=(self.descriptor.d+1, self.memory.volume), dtype=self.float_type[0]) - + def update_moments(self): if self.tick: self.program.collect_moments( self.queue, self.grid.size(), self.layout, self.memory.cl_pop_b, self.memory.cl_moments) @@ -237,31 +269,8 @@ class Lattice: self.program.collect_moments( self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_moments) + def get_moments(self): + moments = numpy.ndarray(shape=(self.descriptor.d+1, self.memory.volume), dtype=self.float_type[0]) + self.update_moments() cl.enqueue_copy(self.queue, moments, self.memory.cl_moments).wait(); - return moments - - def collect_gl_moments(self): - cl.enqueue_acquire_gl_objects(self.queue, [self.memory.cl_gl_moments]) - - if self.tick: - self.program.collect_gl_moments( - self.queue, self.grid.size(), self.layout, self.memory.cl_pop_b, self.memory.cl_material, self.memory.cl_gl_moments) - else: - self.program.collect_gl_moments( - self.queue, self.grid.size(), self.layout, self.memory.cl_pop_a, self.memory.cl_material, self.memory.cl_gl_moments) - - def update_gl_particles(self, particles, aging = False): - cl.enqueue_acquire_gl_objects(self.queue, [particles.cl_gl_particles]) - - if aging: - age = numpy.float32(0.000006) - else: - age = numpy.float32(0.0) - - self.program.update_particles( - self.queue, (particles.count,1), None, - self.memory.cl_gl_moments, - self.memory.cl_material, - particles.cl_gl_particles, particles.cl_init_particles, - age) |