Files
create/src/Mod/Ship/simRun/clSim/initialization.py
2012-07-31 18:37:10 +02:00

114 lines
5.2 KiB
Python

#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
# Simulation stuff
from Utils import *
# pyOpenCL
import pyopencl as cl
import numpy as np
class perform:
def __init__(self, FSmesh, waves, context, queue):
""" Constructor, includes program loading.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply.
@param queue OpenCL command queue.
"""
self.context = context
self.queue = queue
self.program = loadProgram(context, clPath() + "/simInit.cl")
self.loadData(FSmesh, waves)
self.execute()
def loadData(self, FSmesh, waves):
""" Convert data to numpy format, and create OpenCL
buffers.
@param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading).
"""
mf = cl.mem_flags
nx = len(FSmesh)
ny = len(FSmesh[0])
nW = len(waves)
# Mesh data
p = np.ndarray((nx*ny, 4), dtype=np.float32)
n = np.ndarray((nx*ny, 4), dtype=np.float32)
a = np.ndarray((nx*ny, 1), dtype=np.float32)
for i in range(0, nx):
for j in range(0, ny):
id = i*ny + j
pos = FSmesh[i][j].pos
normal = FSmesh[i][j].normal
area = FSmesh[i][j].area
p[id,0] = pos.x
p[id,1] = pos.y
p[id,2] = pos.z
p[id,3] = 1.
n[id,0] = normal.x
n[id,1] = normal.y
n[id,2] = normal.z
n[id,3] = 0.
a[id,0] = area
p_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=p)
n_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=n)
a_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=a)
v_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize)
f_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize)
phi = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny * np.dtype('float32').itemsize)
Phi = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny * np.dtype('float32').itemsize)
self.fs = {'Nx':nx, 'Ny':ny, 'pos':p_cl, 'vel':v_cl, 'acc':f_cl, \
'normal':n_cl, 'area':a_cl, 'velPot':phi, 'accPot':Phi}
# Waves data
w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW):
w[i,0] = waves[i][0]
w[i,1] = waves[i][1]
w[i,2] = waves[i][2]
w[i,3] = waves[i][3]
w_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=w)
self.waves = {'N':nW, 'data':w_cl}
# Ensure that all data has been written
self.queue.finish()
def execute(self):
""" Compute initial conditions. """
# Global size computation
N = np.ndarray((2, 1), dtype=np.uint32)
N[0] = self.fs['Nx']
N[1] = self.fs['Ny']
n = np.uint32(self.waves['N'])
gSize = (globalSize(N[0]),globalSize(N[1]),)
# Kernel arguments
kernelargs = (self.fs['pos'],
self.fs['vel'],
self.fs['acc'],
self.waves['data'],
self.fs['velPot'],
self.fs['accPot'],
N, n)
# Kernel launch
self.program.FS(self.queue, gSize, None, *(kernelargs))
self.queue.finish()