Merge branch 'sanguinariojoe-ship' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad into sanguinariojoe-ship

This commit is contained in:
Jose Luis Cercós Pita 2012-07-31 18:38:34 +02:00
commit 219e76f6ed
11 changed files with 284 additions and 476 deletions

View File

@ -145,9 +145,11 @@ SET(SimRun_SRCS
simRun/Simulation.py simRun/Simulation.py
simRun/TaskPanel.py simRun/TaskPanel.py
simRun/TaskPanel.ui simRun/TaskPanel.ui
simRun/clSim/__init__.py
simRun/clSim/initialization.py
simRun/clSim/Utils.py
simRun/Sim/__init__.py simRun/Sim/__init__.py
simRun/Sim/initialization.py simRun/Sim/initialization.py
simRun/Sim/Utils.py
) )
SOURCE_GROUP("simrun" FILES ${SimRun_SRCS}) SOURCE_GROUP("simrun" FILES ${SimRun_SRCS})

View File

@ -98,10 +98,11 @@ nobase_data_DATA = \
simRun/Simulation.py \ simRun/Simulation.py \
simRun/TaskPanel.py \ simRun/TaskPanel.py \
simRun/TaskPanel.ui \ simRun/TaskPanel.ui \
simRun/clSim/__init__.py \
simRun/clSim/initialization.py \
simRun/clSim/Utils.py \
simRun/Sim/__init__.py \ simRun/Sim/__init__.py \
simRun/Sim/initialization.py simRun/Sim/initialization.py
simRun/Sim/Utils.py
CLEANFILES = $(BUILT_SOURCES) CLEANFILES = $(BUILT_SOURCES)

View File

@ -1,58 +0,0 @@
#***************************************************************************
#* *
#* 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 *
#* *
#***************************************************************************
# FreeCAD
from shipUtils import Paths
# pyOpenCL
import pyopencl as cl
import numpy as np
# Standard
import math
def loadProgram(context, file):
""" Loads a file and comnpile it.
@param context OpenCL context where apply.
@param file File to load and compile.
@return Ready to use OpenCL program.
"""
f = open(file, 'r')
str = "".join(f.readlines())
print(str)
return cl.Program(context, str).build()
def clPath():
""" Gets the OpenCL kernels path
@return OpenCL kernels path
"""
path = Paths.modulePath() + "/OpenCL"
return path
def globalSize(n):
""" Compute global size from amount of data.
@param n Amount of data.
@return global size.
"""
localSize = 256.0
return int(math.ceil(n/localSize)*localSize)

View File

@ -21,4 +21,4 @@
#* * #* *
#*************************************************************************** #***************************************************************************
import initialization, Utils import initialization

View File

@ -21,65 +21,62 @@
#* * #* *
#*************************************************************************** #***************************************************************************
# Simulation stuff # numpy
from Utils import *
# pyOpenCL
import pyopencl as cl
import numpy as np import numpy as np
grav=9.81
class perform: class perform:
def __init__(self, context, queue, FSmesh, waves): def __init__(self, FSmesh, waves, context=None, queue=None):
""" Constructor, includes program loading. """ Constructor, includes program loading.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
@param FSmesh Initial free surface mesh. @param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading). @param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply. Only for compatibility,
must be None.
@param queue OpenCL command queue. Only for compatibility,
must be None.
""" """
self.context = context self.context = context
self.queue = queue self.queue = queue
self.program = loadProgram(context, clPath() + "/simInit.cl")
self.loadData(FSmesh, waves) self.loadData(FSmesh, waves)
self.execute() self.execute()
def loadData(self, FSmesh, waves): def loadData(self, FSmesh, waves):
""" Convert data to numpy format, and create OpenCL """ Convert data to numpy format.
buffers.
@param FSmesh Initial free surface mesh. @param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading). @param waves Considered simulation waves (A,T,phi,heading).
""" """
mf = cl.mem_flags
nx = len(FSmesh) nx = len(FSmesh)
ny = len(FSmesh[0]) ny = len(FSmesh[0])
nW = len(waves) nW = len(waves)
# Mesh data # Mesh data
p = np.ndarray((nx*ny, 4), dtype=np.float32) p = np.ndarray((nx,ny, 3), dtype=np.float32)
n = np.ndarray((nx*ny, 4), dtype=np.float32) v = np.ndarray((nx,ny, 3), dtype=np.float32)
a = np.ndarray((nx*ny, 1), dtype=np.float32) f = np.ndarray((nx,ny, 3), dtype=np.float32)
n = np.ndarray((nx,ny, 3), dtype=np.float32)
a = np.ndarray((nx,ny, 1), dtype=np.float32)
phi = np.ndarray((nx,ny, 1), dtype=np.float32)
Phi = np.ndarray((nx,ny, 1), dtype=np.float32)
for i in range(0, nx): for i in range(0, nx):
for j in range(0, ny): for j in range(0, ny):
id = i*ny + j
pos = FSmesh[i][j].pos pos = FSmesh[i][j].pos
normal = FSmesh[i][j].normal normal = FSmesh[i][j].normal
area = FSmesh[i][j].area area = FSmesh[i][j].area
p[id,0] = pos.x p[i,j,0] = pos.x
p[id,1] = pos.y p[i,j,1] = pos.y
p[id,2] = pos.z p[i,j,2] = pos.z
p[id,3] = 1. v[i,j,0] = 0.
n[id,0] = normal.x v[i,j,1] = 0.
n[id,1] = normal.y v[i,j,2] = 0.
n[id,2] = normal.z f[i,j,0] = 0.
n[id,3] = 0. f[i,j,1] = 0.
a[id,0] = area f[i,j,2] = 0.
p_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=p) n[i,j,0] = normal.x
n_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=n) n[i,j,1] = normal.y
a_cl = cl.Buffer(self.context, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=a) n[i,j,2] = normal.z
v_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize) a[i,j] = area
f_cl = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny*4 * np.dtype('float32').itemsize) self.fs = {'Nx':nx, 'Ny':ny, 'pos':p, 'vel':v, 'acc':f, \
phi = cl.Buffer(self.context, mf.READ_WRITE, size = nx*ny * np.dtype('float32').itemsize) 'normal':n, 'area':a, 'velPot':phi, 'accPot':Phi}
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 # Waves data
w = np.ndarray((nW, 4), dtype=np.float32) w = np.ndarray((nW, 4), dtype=np.float32)
for i in range(0,nW): for i in range(0,nW):
@ -87,27 +84,31 @@ class perform:
w[i,1] = waves[i][1] w[i,1] = waves[i][1]
w[i,2] = waves[i][2] w[i,2] = waves[i][2]
w[i,3] = waves[i][3] 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}
self.waves = {'N':nW, 'data':w_cl}
# Ensure that all data has been written
self.queue.finish()
def execute(self): def execute(self):
""" Compute initial conditions. """ """ Compute initial conditions. """
# Global size computation nx = self.fs['Nx']
N = np.ndarray((2, 1), dtype=np.uint32) ny = self.fs['Ny']
N[0] = self.fs['Nx'] for i in range(0,nx):
N[1] = self.fs['Ny'] for j in range(0,ny):
n = np.uint32(self.waves['N']) for w in self.waves['data']:
gSize = (globalSize(N[0]),globalSize(N[1]),) A = w[0]
# Kernel arguments T = w[1]
kernelargs = (self.fs['pos'], phase = w[2]
self.fs['vel'], heading = np.pi*w[3]/180.0
self.fs['acc'], wl = 0.5 * grav / np.pi * T*T
self.waves['data'], k = 2.0*np.pi/wl
self.fs['velPot'], frec = 2.0*np.pi/T
self.fs['accPot'], pos = self.fs['pos'][i,j]
N, n) l = pos[0]*np.cos(heading) + pos[1]*np.sin(heading)
# Kernel launch amp = A*np.sin(k*l + phase)
self.program.FS(self.queue, gSize, None, *(kernelargs)) self.fs['pos'][i,j][2] = self.fs['pos'][i,j][2] + amp
self.queue.finish() amp = frec*A*np.cos(k*l + phase)
self.fs['vel'][i,j][2] = self.fs['vel'][i,j][2] - amp
amp = frec*frec*A*np.sin(k*l + phase)
self.fs['acc'][i,j][2] = self.fs['acc'][i,j][2] - amp
amp = grav/frec*A*np.sin(k*l + phase)
self.fs['velPot'][i,j] = self.fs['velPot'][i,j] + amp
amp = grav*A*np.cos(k*l + phase)
self.fs['accPot'][i,j] = self.fs['accPot'][i,j] + amp

View File

@ -34,9 +34,6 @@ import FreeCAD,FreeCADGui
from FreeCAD import Base, Vector from FreeCAD import Base, Vector
import Part import Part
# Simulation stuff
from Sim import initialization
# Ship design module # Ship design module
from shipUtils import Paths, Translator, Math from shipUtils import Paths, Translator, Math
@ -65,8 +62,12 @@ class FreeCADShipSimulation(threading.Thread):
self.active = False self.active = False
# Build OpenCL context and command queue # Build OpenCL context and command queue
self.device = device self.device = device
self.context = cl.Context(devices=[self.device]) if self.device == None: # Can't use OpenCL
self.queue = cl.CommandQueue(self.context) self.context = None
self.queue = None
else:
self.context = cl.Context(devices=[self.device])
self.queue = cl.CommandQueue(self.context)
# Storage data # Storage data
self.endTime = endTime self.endTime = endTime
self.output = output self.output = output
@ -77,10 +78,14 @@ class FreeCADShipSimulation(threading.Thread):
""" Runs the simulation. """ Runs the simulation.
""" """
self.active = True self.active = True
# Perform work here # Simulation stuff
if self.device == None:
from Sim import initialization
else:
from clSim import initialization
msg = Translator.translate("\t[Sim]: Initializating OpenCL...\n") msg = Translator.translate("\t[Sim]: Initializating OpenCL...\n")
FreeCAD.Console.PrintMessage(msg) FreeCAD.Console.PrintMessage(msg)
init = initialization.perform(self.context,self.queue,self.FSmesh,self.waves) init = initialization.perform(self.FSmesh,self.waves,self.context,self.queue)
msg = Translator.translate("\t[Sim]: Iterating (outputs will be noticed)...\n") msg = Translator.translate("\t[Sim]: Iterating (outputs will be noticed)...\n")
FreeCAD.Console.PrintMessage(msg) FreeCAD.Console.PrintMessage(msg)
while self.active: while self.active:

View File

@ -1,107 +0,0 @@
#***************************************************************************
#* *
#* 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 *
#* *
#***************************************************************************
import time
from math import *
import threading
# pyOpenCL
import pyopencl as cl
import numpy as np
# FreeCAD
import FreeCAD,FreeCADGui
from FreeCAD import Base, Vector
import Part
# Simulation stuff
from Sim import initialization
# Ship design module
from shipUtils import Paths, Translator, Math
class Singleton(type):
def __init__(cls, name, bases, dct):
cls.__instance = None
type.__init__(cls, name, bases, dct)
def __call__(cls, *args, **kw):
if cls.__instance is None:
cls.__instance = type.__call__(cls, *args,**kw)
return cls.__instance
class FreeCADShipSimulation(threading.Thread):
__metaclass__ = Singleton
def __init__ (self, device, endTime, output, FSmesh, waves):
""" Thread constructor.
@param device Device to use.
@param endTime Maximum simulation time.
@param output [Rate,Type] Output rate, Type=0 if FPS, 1 if IPF.
@param FSmesh Free surface mesh faces.
@param waves Waves parameters (A,T,phi,heading)
"""
threading.Thread.__init__(self)
# Setup as stopped
self.active = False
# Build OpenCL context and command queue
self.device = device
self.context = cl.Context(devices=[self.device])
self.queue = cl.CommandQueue(self.context)
# Storage data
self.endTime = endTime
self.output = output
self.FSmesh = FSmesh
self.waves = waves
def run(self):
""" Runs the simulation.
"""
self.active = True
# Perform work here
msg = Translator.translate("\t[Sim]: Initializating OpenCL...\n")
FreeCAD.Console.PrintMessage(msg)
init = initialization.perform(self.context,self.queue,self.FSmesh,self.waves)
msg = Translator.translate("\t[Sim]: Iterating (outputs will be noticed)...\n")
FreeCAD.Console.PrintMessage(msg)
while self.active:
print("Im thread, Im running...")
time.sleep(1)
# ...
print("Im thread, step done!")
msg = Translator.translate("\t[Sim]: Output performed!\n")
FreeCAD.Console.PrintMessage(msg)
# Set thread as stopped (and prepare it to restarting)
self.active = False
threading.Event().set()
threading.Thread.__init__(self)
def stop(self):
""" Call to stop execution.
"""
self.active = False
def isRunning(self):
""" Report thread state
@return True if thread is running, False otherwise.
"""
return self.active

View File

@ -1,203 +1,204 @@
#*************************************************************************** #***************************************************************************
#* * #* *
#* Copyright (c) 2011, 2012 * #* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> * #* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* * #* *
#* This program is free software; you can redistribute it and/or modify * #* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) * #* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of * #* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. * #* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. * #* for detail see the LICENCE text file. *
#* * #* *
#* This program is distributed in the hope that it will be useful, * #* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. * #* GNU Library General Public License for more details. *
#* * #* *
#* You should have received a copy of the GNU Library General Public * #* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software * #* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA * #* USA *
#* * #* *
#*************************************************************************** #***************************************************************************
# FreeCAD modules # FreeCAD modules
import FreeCAD as App import FreeCAD as App
import FreeCADGui as Gui import FreeCADGui as Gui
# Qt library # Qt library
from PyQt4 import QtGui,QtCore from PyQt4 import QtGui,QtCore
# pyOpenCL # pyOpenCL
import pyopencl as cl import pyopencl as cl
# Module # Module
import SimInstance import SimInstance
from shipUtils import Paths, Translator from shipUtils import Paths, Translator
from Simulation import FreeCADShipSimulation as Sim from Simulation import FreeCADShipSimulation as Sim
import time import time
class TaskPanel: class TaskPanel:
def __init__(self): def __init__(self):
self.ui = Paths.modulePath() + "/simRun/TaskPanel.ui" self.ui = Paths.modulePath() + "/simRun/TaskPanel.ui"
self.sim = False self.sim = False
def accept(self): def accept(self):
msg = Translator.translate("Building data...\n") msg = Translator.translate("Building data...\n")
App.Console.PrintMessage(msg) App.Console.PrintMessage(msg)
# Get GUI data # Get GUI data
endTime = self.form.time.value() endTime = self.form.time.value()
output = [] output = []
output.append(self.form.output.value()) output.append(self.form.output.value())
output.append(self.form.outputType.currentIndex()) output.append(self.form.outputType.currentIndex())
devId = self.form.device.currentIndex() devId = self.form.device.currentIndex() - 1 # First is not OpenCL
# Get OpenCL device # Get OpenCL device
count = 0 device = None
platforms = cl.get_platforms() count = 0
for p in platforms: platforms = cl.get_platforms()
devs = p.get_devices() for p in platforms:
for d in devs: devs = p.get_devices()
if count == devId: for d in devs:
device = d if count == devId:
count = count + 1 device = d
# Get free surfaces data count = count + 1
FSMesh = SimInstance.FSMesh(self.sim) # Get free surfaces data
wData = self.sim.Waves FSMesh = SimInstance.FSMesh(self.sim)
wDir = self.sim.Waves_Dir wData = self.sim.Waves
waves = [] wDir = self.sim.Waves_Dir
for i in range(0,len(wData)): waves = []
waves.append([wData[i].x, wData[i].y, wData[i].z, wDir[i]]) for i in range(0,len(wData)):
msg = Translator.translate("Launching simulation...\n") waves.append([wData[i].x, wData[i].y, wData[i].z, wDir[i]])
App.Console.PrintMessage(msg) msg = Translator.translate("Launching simulation...\n")
# Build simulation thread App.Console.PrintMessage(msg)
simulator = Sim(device, endTime, output, FSMesh, waves) # Build simulation thread
simulator.start() simulator = Sim(device, endTime, output, FSMesh, waves)
msg = Translator.translate("Done!\n") simulator.start()
App.Console.PrintMessage(msg) msg = Translator.translate("Done!\n")
return True App.Console.PrintMessage(msg)
return True
def reject(self):
return True def reject(self):
return True
def clicked(self, index):
pass def clicked(self, index):
pass
def open(self):
pass def open(self):
pass
def needsFullSpace(self):
return True def needsFullSpace(self):
return True
def isAllowedAlterSelection(self):
return False def isAllowedAlterSelection(self):
return False
def isAllowedAlterView(self):
return True def isAllowedAlterView(self):
return True
def isAllowedAlterDocument(self):
return False def isAllowedAlterDocument(self):
return False
def helpRequested(self):
pass def helpRequested(self):
pass
def setupUi(self):
mw = self.getMainWindow() def setupUi(self):
form = mw.findChild(QtGui.QWidget, "TaskPanel") mw = self.getMainWindow()
form.time = form.findChild(QtGui.QDoubleSpinBox, "SimTime") form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.output = form.findChild(QtGui.QDoubleSpinBox, "Output") form.time = form.findChild(QtGui.QDoubleSpinBox, "SimTime")
form.outputType = form.findChild(QtGui.QComboBox, "OutputType") form.output = form.findChild(QtGui.QDoubleSpinBox, "Output")
form.device = form.findChild(QtGui.QComboBox, "Device") form.outputType = form.findChild(QtGui.QComboBox, "OutputType")
self.form = form form.device = form.findChild(QtGui.QComboBox, "Device")
# Initial values self.form = form
if self.initValues(): # Initial values
return True if self.initValues():
self.retranslateUi() return True
# Connect Signals and Slots self.retranslateUi()
# QtCore.QObject.connect(form.time, QtCore.SIGNAL("valueChanged(double)"), self.onData) # Connect Signals and Slots
# QtCore.QObject.connect(form.time, QtCore.SIGNAL("valueChanged(double)"), self.onData)
def getMainWindow(self):
"returns the main window" def getMainWindow(self):
# using QtGui.qApp.activeWindow() isn't very reliable because if another "returns the main window"
# widget than the mainwindow is active (e.g. a dialog) the wrong widget is # using QtGui.qApp.activeWindow() isn't very reliable because if another
# returned # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
toplevel = QtGui.qApp.topLevelWidgets() # returned
for i in toplevel: toplevel = QtGui.qApp.topLevelWidgets()
if i.metaObject().className() == "Gui::MainWindow": for i in toplevel:
return i if i.metaObject().className() == "Gui::MainWindow":
raise Exception("No main window found") return i
raise Exception("No main window found")
def initValues(self):
""" Set initial values for fields def initValues(self):
""" """ Set initial values for fields
# Get objects """
selObjs = Gui.Selection.getSelection() # Get objects
if not selObjs: selObjs = Gui.Selection.getSelection()
msg = Translator.translate("Ship simulation instance must be selected (no object selected)\n") if not selObjs:
App.Console.PrintError(msg) msg = Translator.translate("Ship simulation instance must be selected (no object selected)\n")
return True App.Console.PrintError(msg)
for i in range(0,len(selObjs)): return True
obj = selObjs[i] for i in range(0,len(selObjs)):
# Test if is a ship instance obj = selObjs[i]
props = obj.PropertiesList # Test if is a ship instance
try: props = obj.PropertiesList
props.index("IsShipSimulation") try:
except ValueError: props.index("IsShipSimulation")
continue except ValueError:
if obj.IsShipSimulation: continue
# Test if another ship already selected if obj.IsShipSimulation:
if self.sim: # Test if another ship already selected
msg = Translator.translate("More than one ship simulation selected (extra simulations will be neglected)\n") if self.sim:
App.Console.PrintWarning(msg) msg = Translator.translate("More than one ship simulation selected (extra simulations will be neglected)\n")
break App.Console.PrintWarning(msg)
self.sim = obj break
# Test if any valid ship was selected self.sim = obj
if not self.sim: # Test if any valid ship was selected
msg = Translator.translate("Ship simulation instance must be selected (no valid simulation found at selected objects)\n") if not self.sim:
App.Console.PrintError(msg) msg = Translator.translate("Ship simulation instance must be selected (no valid simulation found at selected objects)\n")
return True App.Console.PrintError(msg)
# Get the list of devices return True
devices = [] # Get the list of devices
platforms = cl.get_platforms() self.form.device.addItem("CPU based version (No OpenCL)")
for p in platforms: devices = []
devs = p.get_devices() platforms = cl.get_platforms()
for d in devs: for p in platforms:
devices.append([p,d]) devs = p.get_devices()
dname = d.get_info(cl.device_info.NAME) for d in devs:
pname = p.get_info(cl.platform_info.NAME) devices.append([p,d])
self.form.device.addItem(dname + " (" + pname + ")") dname = d.get_info(cl.device_info.NAME)
if not len(devices): pname = p.get_info(cl.platform_info.NAME)
msg = Translator.translate("This tool requires an active OpenCL context to work\n") self.form.device.addItem(dname + " (" + pname + ")")
App.Console.PrintError(msg) if not len(devices):
return True msg = Translator.translate("Can't find OpenCL devices\n")
msg = Translator.translate("Ready to work\n") App.Console.PrintWarning(msg)
App.Console.PrintMessage(msg) msg = Translator.translate("Ready to work\n")
return False App.Console.PrintMessage(msg)
return False
def retranslateUi(self):
""" Set user interface locale strings. def retranslateUi(self):
""" """ Set user interface locale strings.
self.form.setWindowTitle(Translator.translate("Run the simulation")) """
self.form.findChild(QtGui.QLabel, "SimTimeLabel").setText(Translator.translate("Simulation time")) self.form.setWindowTitle(Translator.translate("Run the simulation"))
self.form.findChild(QtGui.QLabel, "OutputLabel").setText(Translator.translate("Output")) self.form.findChild(QtGui.QLabel, "SimTimeLabel").setText(Translator.translate("Simulation time"))
self.form.findChild(QtGui.QLabel, "DeviceLabel").setText(Translator.translate("OpenCL device")) self.form.findChild(QtGui.QLabel, "OutputLabel").setText(Translator.translate("Output"))
self.form.findChild(QtGui.QLabel, "DeviceLabel").setText(Translator.translate("OpenCL device"))
def createTask():
panel = TaskPanel() def createTask():
Gui.Control.showDialog(panel) panel = TaskPanel()
if panel.setupUi(): Gui.Control.showDialog(panel)
Gui.Control.closeDialog(panel) if panel.setupUi():
return None Gui.Control.closeDialog(panel)
return panel return None
return panel
def stopSimulation():
try: def stopSimulation():
simulator = Sim() try:
if not simulator.isRunning(): simulator = Sim()
msg = Translator.translate("Simulation already stopped\n") if not simulator.isRunning():
App.Console.PrintWarning(msg) msg = Translator.translate("Simulation already stopped\n")
return App.Console.PrintWarning(msg)
except: return
msg = Translator.translate("Any active simulation to stop!\n") except:
App.Console.PrintError(msg) msg = Translator.translate("Any active simulation to stop!\n")
return App.Console.PrintError(msg)
simulator.stop() return
msg = Translator.translate("Simulation will stop at the end of actual iteration\n") simulator.stop()
App.Console.PrintMessage(msg) msg = Translator.translate("Simulation will stop at the end of actual iteration\n")
App.Console.PrintMessage(msg)

View File

@ -21,37 +21,4 @@
#* * #* *
#*************************************************************************** #***************************************************************************
# FreeCAD import initialization, Utils
from shipUtils import Paths
# pyOpenCL
import pyopencl as cl
import numpy as np
# Standard
import math
def loadProgram(context, file):
""" Loads a file and comnpile it.
@param context OpenCL context where apply.
@param file File to load and compile.
@return Ready to use OpenCL program.
"""
f = open(file, 'r')
str = "".join(f.readlines())
return cl.Program(context, str).build()
def clPath():
""" Gets the OpenCL kernels path
@return OpenCL kernels path
"""
path = Paths.modulePath() + "/OpenCL"
return path
def globalSize(n):
""" Compute global size from amount of data.
@param n Amount of data.
@return global size.
"""
localSize = 256
return int(math.ceil(n/localSize))

View File

@ -29,12 +29,12 @@ import pyopencl as cl
import numpy as np import numpy as np
class perform: class perform:
def __init__(self, context, queue, FSmesh, waves): def __init__(self, FSmesh, waves, context, queue):
""" Constructor, includes program loading. """ Constructor, includes program loading.
@param context OpenCL context where apply.
@param queue OpenCL command queue.
@param FSmesh Initial free surface mesh. @param FSmesh Initial free surface mesh.
@param waves Considered simulation waves (A,T,phi,heading). @param waves Considered simulation waves (A,T,phi,heading).
@param context OpenCL context where apply.
@param queue OpenCL command queue.
""" """
self.context = context self.context = context
self.queue = queue self.queue = queue
@ -100,7 +100,6 @@ class perform:
N[1] = self.fs['Ny'] N[1] = self.fs['Ny']
n = np.uint32(self.waves['N']) n = np.uint32(self.waves['N'])
gSize = (globalSize(N[0]),globalSize(N[1]),) gSize = (globalSize(N[0]),globalSize(N[1]),)
print(gSize)
# Kernel arguments # Kernel arguments
kernelargs = (self.fs['pos'], kernelargs = (self.fs['pos'],
self.fs['vel'], self.fs['vel'],
@ -108,10 +107,7 @@ class perform:
self.waves['data'], self.waves['data'],
self.fs['velPot'], self.fs['velPot'],
self.fs['accPot'], self.fs['accPot'],
N, n) N, n)
print('Launching...')
# Kernel launch # Kernel launch
self.program.FS(self.queue, gSize, None, *(kernelargs)) self.program.FS(self.queue, gSize, None, *(kernelargs))
print('Waiting...')
self.queue.finish() self.queue.finish()
print('OK!')