Files
create/src/Mod/Ship/simRun/Simulation.py
2012-08-06 18:24:18 +02:00

138 lines
5.5 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 *
#* *
#***************************************************************************
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
# 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, simInstance, 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 simInstance Simulaation instance.
@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
if self.device == None: # Can't use OpenCL
self.context = None
self.queue = None
else:
self.context = cl.Context(devices=[self.device])
self.queue = cl.CommandQueue(self.context)
# Storage data
self.endTime = endTime
self.output = output
self.sim = simInstance
self.FSmesh = FSmesh
self.waves = waves
def run(self):
""" Runs the simulation.
"""
self.active = True
# Simulation stuff
if self.device == None:
from Sim import *
else:
from clSim import *
msg = Translator.translate("\t[Sim]: Initializating...\n")
FreeCAD.Console.PrintMessage(msg)
init = simInitialization(self.FSmesh,self.waves,self.context,self.queue)
matGen = simMatrixGen(self.context,self.queue)
solver = simComputeSources(self.context,self.queue)
fsEvol = simFSEvolution(self.context,self.queue)
A = init.A
FS = init.fs
waves = init.waves
dt = init.dt
t = 0.0
nx = FS['Nx']
ny = FS['Ny']
msg = Translator.translate("\t[Sim]: Iterating...\n")
FreeCAD.Console.PrintMessage(msg)
while self.active and t < self.endTime:
msg = Translator.translate("\t\t[Sim]: Generating linear system matrix...\n")
FreeCAD.Console.PrintMessage(msg)
matGen.execute(FS, A)
msg = Translator.translate("\t\t[Sim]: Solving linear systems...\n")
FreeCAD.Console.PrintMessage(msg)
solver.execute(FS, A)
msg = Translator.translate("\t\t[Sim]: Time integrating...\n")
FreeCAD.Console.PrintMessage(msg)
fsEvol.execute(FS, waves, dt, t)
t = t + dt
FreeCAD.Console.PrintMessage('t = %g s\n' % (t))
# Update FreeCAD
"""
pos = self.sim.FS_Position[:]
for i in range(0, nx):
for j in range(0, ny):
pos[i*ny+j].z = float(FS['pos'][i,j][2])
self.sim.FS_Position = pos[:]
FreeCAD.ActiveDocument.recompute()
"""
# 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