aboutsummaryrefslogtreecommitdiff
path: root/utility
diff options
context:
space:
mode:
Diffstat (limited to 'utility')
-rw-r--r--utility/mouse.py34
-rw-r--r--utility/opengl.py87
-rw-r--r--utility/particles.py49
-rw-r--r--utility/projection.py67
-rw-r--r--utility/streamline.py71
5 files changed, 302 insertions, 6 deletions
diff --git a/utility/mouse.py b/utility/mouse.py
new file mode 100644
index 0000000..5d7dd5d
--- /dev/null
+++ b/utility/mouse.py
@@ -0,0 +1,34 @@
+from OpenGL.GLUT import *
+
+class MouseDragMonitor:
+ def __init__(self, button, callback):
+ self.button = button
+ self.active = False
+ self.callback = callback
+
+ def on_mouse(self, button, state, x, y):
+ if button == self.button:
+ self.active = (state == GLUT_DOWN)
+ self.last_x = x
+ self.last_y = y
+
+ def on_mouse_move(self, x, y):
+ if self.active:
+ delta_x = self.last_x - x
+ delta_y = y - self.last_y
+ self.last_x = x
+ self.last_y = y
+ self.callback(delta_x, delta_y)
+
+class MouseScrollMonitor:
+ def __init__(self, callback):
+ self.callback = callback
+
+ def on_mouse(self, button, state, x, y):
+ if button == 3:
+ self.callback(-1.0)
+ elif button == 4:
+ self.callback(1.0)
+
+ def on_mouse_move(self, x, y):
+ pass
diff --git a/utility/opengl.py b/utility/opengl.py
new file mode 100644
index 0000000..456259b
--- /dev/null
+++ b/utility/opengl.py
@@ -0,0 +1,87 @@
+import pyopencl as cl
+mf = cl.mem_flags
+
+import numpy
+import sympy
+
+from mako.template import Template
+from pathlib import Path
+
+from OpenGL.GL import *
+
+
+class MomentsTexture:
+ def __init__(self, lattice, include_materials = True):
+ self.lattice = lattice
+ self.include_materials = include_materials
+ self.gl_texture_buffer = numpy.ndarray(shape=(self.lattice.memory.volume, 4), dtype=self.lattice.memory.float_type)
+ self.gl_texture_buffer[:,:] = 0.0
+
+ self.gl_moments = glGenTextures(1)
+ self.gl_texture_type = {2: GL_TEXTURE_2D, 3: GL_TEXTURE_3D}.get(self.lattice.descriptor.d)
+ glBindTexture(self.gl_texture_type, self.gl_moments)
+
+ if self.gl_texture_type == GL_TEXTURE_3D:
+ glTexImage3D(self.gl_texture_type, 0, GL_RGBA32F, self.lattice.memory.size_x, self.lattice.memory.size_y, self.lattice.memory.size_z, 0, GL_RGBA, GL_FLOAT, self.gl_texture_buffer)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE)
+ self.cl_gl_moments = cl.GLTexture(self.lattice.context, mf.READ_WRITE, self.gl_texture_type, 0, self.gl_moments, 3)
+ elif self.gl_texture_type == GL_TEXTURE_2D:
+ glTexImage2D(self.gl_texture_type, 0, GL_RGBA32F, self.lattice.memory.size_x, self.lattice.memory.size_y, 0, GL_RGBA, GL_FLOAT, self.gl_texture_buffer)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
+ self.cl_gl_moments = cl.GLTexture(self.lattice.context, mf.READ_WRITE, self.gl_texture_type, 0, self.gl_moments, 2)
+
+ self.build_kernel()
+
+ def build_kernel(self):
+ program_src = Template(filename = str(Path(__file__).parent/'../template/opengl.mako')).render(
+ descriptor = self.lattice.descriptor,
+ geometry = self.lattice.geometry,
+ memory = self.lattice.memory,
+
+ moments_subexpr = self.lattice.moments[0],
+ moments_assignment = self.lattice.moments[1],
+ collide_subexpr = self.lattice.collide[0],
+ collide_assignment = self.lattice.collide[1],
+
+ float_type = self.lattice.float_type[1],
+
+ ccode = sympy.ccode
+ )
+ self.program = cl.Program(self.lattice.context, program_src).build(self.lattice.compiler_args)
+
+ def bind(self, location = GL_TEXTURE0):
+ glEnable(self.gl_texture_type)
+ glActiveTexture(location);
+ glBindTexture(self.gl_texture_type, self.gl_moments)
+
+ def collect_moments_from_pop_to_texture(self, population):
+ if self.include_materials:
+ self.program.collect_gl_moments_and_materials_to_texture(
+ self.lattice.queue,
+ self.lattice.grid.size(),
+ self.lattice.layout,
+ population,
+ self.lattice.memory.cl_material,
+ self.cl_gl_moments)
+ else:
+ self.program.collect_gl_moments_to_texture(
+ self.lattice.queue,
+ self.lattice.grid.size(),
+ self.lattice.layout,
+ population,
+ self.cl_gl_moments)
+
+ def collect(self):
+ cl.enqueue_acquire_gl_objects(self.lattice.queue, [self.cl_gl_moments])
+
+ if self.lattice.tick:
+ self.collect_moments_from_pop_to_texture(self.lattice.memory.cl_pop_b)
+ else:
+ self.collect_moments_from_pop_to_texture(self.lattice.memory.cl_pop_a)
diff --git a/utility/particles.py b/utility/particles.py
index a7ef777..75d2245 100644
--- a/utility/particles.py
+++ b/utility/particles.py
@@ -3,16 +3,22 @@ mf = cl.mem_flags
import numpy
+from mako.template import Template
+from pathlib import Path
+
import OpenGL.GL as gl
from OpenGL.arrays import vbo
class Particles:
- def __init__(self, context, queue, float_type, grid):
- self.context = context
+ def __init__(self, lattice, grid):
+ self.lattice = lattice
+ self.context = self.lattice.context
+ self.queue = self.lattice.queue
+ self.float_type = self.lattice.memory.float_type
self.count = len(grid)
- self.np_particles = numpy.ndarray(shape=(self.count, 4), dtype=float_type)
- self.np_init_particles = numpy.ndarray(shape=(self.count, 4), dtype=float_type)
+ self.np_particles = numpy.ndarray(shape=(self.count, 4), dtype=self.float_type)
+ self.np_init_particles = numpy.ndarray(shape=(self.count, 4), dtype=self.float_type)
if len(grid[0,:]) == 2:
self.np_particles[:,0:2] = grid
@@ -28,5 +34,36 @@ class Particles:
self.gl_particles.bind()
self.cl_gl_particles = cl.GLBuffer(self.context, mf.READ_WRITE, int(self.gl_particles))
- self.cl_init_particles = cl.Buffer(context, mf.READ_ONLY, size=self.count * 4*numpy.float32(0).nbytes)
- cl.enqueue_copy(queue, self.cl_init_particles, self.np_init_particles).wait();
+ self.cl_init_particles = cl.Buffer(self.context, mf.READ_ONLY, size=self.count * 4*numpy.float32(0).nbytes)
+ cl.enqueue_copy(self.queue, self.cl_init_particles, self.np_init_particles).wait();
+
+ self.build_kernel()
+
+ def build_kernel(self):
+ program_src = Template(filename = str(Path(__file__).parent/'../template/particles.mako')).render(
+ descriptor = self.lattice.descriptor,
+ geometry = self.lattice.geometry,
+ memory = self.lattice.memory,
+ float_type = self.float_type,
+ )
+ self.program = cl.Program(self.lattice.context, program_src).build(self.lattice.compiler_args)
+
+ def bind(self):
+ gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
+ self.gl_particles.bind()
+ gl.glVertexPointer(4, gl.GL_FLOAT, 0, self.gl_particles)
+
+ def update(self, aging = False):
+ cl.enqueue_acquire_gl_objects(self.queue, [self.cl_gl_particles])
+
+ if aging:
+ age = numpy.float32(0.000006)
+ else:
+ age = numpy.float32(0.0)
+
+ self.program.update_particles(
+ self.queue, (self.count,1), None,
+ self.lattice.memory.cl_moments,
+ self.lattice.memory.cl_material,
+ self.cl_gl_particles, self.cl_init_particles,
+ age)
diff --git a/utility/projection.py b/utility/projection.py
new file mode 100644
index 0000000..76791d9
--- /dev/null
+++ b/utility/projection.py
@@ -0,0 +1,67 @@
+import numpy
+
+from OpenGL.GL import glViewport
+
+from pyrr import matrix44, quaternion
+
+class Projection:
+ def __init__(self, distance):
+ self.distance = distance
+ self.ratio = 4./3.
+ self.update()
+
+ def update(self):
+ projection = matrix44.create_perspective_projection(20.0, self.ratio, 0.1, 5000.0)
+ look = matrix44.create_look_at(
+ eye = [0, -self.distance, 0],
+ target = [0, 0, 0],
+ up = [0, 0, -1])
+
+ self.matrix = numpy.matmul(look, projection)
+
+ def update_ratio(self, width, height, update_viewport = True):
+ if update_viewport:
+ glViewport(0,0,width,height)
+
+ self.ratio = width/height
+ self.update()
+
+ def update_distance(self, change):
+ self.distance += change
+ self.update()
+
+ def get(self):
+ return self.matrix
+
+class Rotation:
+ def __init__(self, shift, x = numpy.pi, z = numpy.pi):
+ self.matrix = matrix44.create_from_translation(shift),
+ self.rotation_x = quaternion.Quaternion()
+ self.update(x,z)
+
+ def shift(self, x, z):
+ self.matrix = numpy.matmul(
+ self.matrix,
+ matrix44.create_from_translation([x,0,z])
+ )
+ self.inverse_matrix = numpy.linalg.inv(self.matrix)
+
+ def update(self, x, z):
+ rotation_x = quaternion.Quaternion(quaternion.create_from_eulers([x,0,0]))
+ rotation_z = self.rotation_x.conjugate.cross(
+ quaternion.Quaternion(quaternion.create_from_eulers([0,0,z])))
+ self.rotation_x = self.rotation_x.cross(rotation_x)
+
+ self.matrix = numpy.matmul(
+ self.matrix,
+ matrix44.create_from_quaternion(rotation_z.cross(self.rotation_x))
+ )
+ self.inverse_matrix = numpy.linalg.inv(self.matrix)
+
+ def get(self):
+ return self.matrix
+
+ def get_inverse(self):
+ return self.inverse_matrix
+
+
diff --git a/utility/streamline.py b/utility/streamline.py
new file mode 100644
index 0000000..9f0fb55
--- /dev/null
+++ b/utility/streamline.py
@@ -0,0 +1,71 @@
+import pyopencl as cl
+mf = cl.mem_flags
+
+import numpy
+
+from mako.template import Template
+from pathlib import Path
+
+from OpenGL.GL import *
+from OpenGL.arrays import vbo
+
+class Streamlines:
+ def __init__(self, lattice, origins):
+ self.lattice = lattice
+ self.context = self.lattice.context
+ self.queue = self.lattice.queue
+ self.float_type = self.lattice.memory.float_type
+
+ self.count = len(origins)
+ self.np_origins = numpy.ndarray(shape=(self.count, 2), dtype=self.float_type)
+
+ for i, pos in enumerate(origins):
+ self.np_origins[i,:] = pos
+
+ self.cl_origins = cl.Buffer(self.context, mf.READ_ONLY, size=self.count * 2*numpy.float32(0).nbytes)
+ cl.enqueue_copy(self.queue, self.cl_origins, self.np_origins).wait();
+
+ self.gl_texture_buffer = numpy.ndarray(shape=(self.lattice.memory.volume, 4), dtype=self.lattice.memory.float_type)
+ self.gl_texture_buffer[:,:] = 0.0
+
+ self.gl_streamlines = glGenTextures(1)
+ self.gl_texture_type = GL_TEXTURE_2D
+ glBindTexture(self.gl_texture_type, self.gl_streamlines)
+
+ glTexImage2D(self.gl_texture_type, 0, GL_RGBA32F, self.lattice.memory.size_x, self.lattice.memory.size_y, 0, GL_RGBA, GL_FLOAT, self.gl_texture_buffer)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
+ glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
+ self.cl_gl_streamlines = cl.GLTexture(self.lattice.context, mf.READ_WRITE, self.gl_texture_type, 0, self.gl_streamlines, 2)
+
+ self.build_kernel()
+
+ def build_kernel(self):
+ program_src = Template(filename = str(Path(__file__).parent/'../template/streamline.mako')).render(
+ descriptor = self.lattice.descriptor,
+ geometry = self.lattice.geometry,
+ memory = self.lattice.memory,
+ float_type = self.float_type,
+ )
+ self.program = cl.Program(self.lattice.context, program_src).build(self.lattice.compiler_args)
+
+ def bind(self, location = GL_TEXTURE0):
+ glEnable(self.gl_texture_type)
+ glActiveTexture(location);
+ glBindTexture(self.gl_texture_type, self.gl_streamlines)
+
+ def update(self):
+ cl.enqueue_acquire_gl_objects(self.queue, [self.cl_gl_streamlines])
+
+ self.program.dillute(
+ self.queue, (self.lattice.memory.size_x,self.lattice.memory.size_y), None,
+ self.lattice.memory.cl_material,
+ self.cl_gl_streamlines)
+
+ self.program.draw_streamline(
+ self.queue, (self.count,1), None,
+ self.lattice.memory.cl_moments,
+ self.lattice.memory.cl_material,
+ self.cl_origins,
+ self.cl_gl_streamlines)