From d9e4e036887a024649e5dc3072315e6cee60efa8 Mon Sep 17 00:00:00 2001 From: Jean-Matthieu Etancelin <jean-matthieu.etancelin@imag.fr> Date: Fri, 31 Aug 2012 10:12:46 +0000 Subject: [PATCH] Add analytical Velocity time dependant --- Examples/levelSet2D.cl | 12 ++-- Examples/levelSet2D.py | 7 ++- Examples/levelSet3D.cl | 25 ++++---- Examples/levelSet3D.py | 5 +- HySoP/hysop/__init__.py.in | 2 + HySoP/hysop/operator/Velocity.py | 52 +++++++++++++++++ HySoP/hysop/operator/advection_d.py | 1 + HySoP/hysop/operator/remeshing.py | 1 + HySoP/hysop/operator/splitting.py | 1 + HySoP/hysop/operator/velocity_d.py | 78 +++++++++++++++++++++++++ HySoP/hysop/particular_solvers/basic.py | 4 +- HySoP/hysop/particular_solvers/gpu.py | 19 ++++-- 12 files changed, 178 insertions(+), 29 deletions(-) create mode 100644 HySoP/hysop/operator/Velocity.py create mode 100644 HySoP/hysop/operator/velocity_d.py diff --git a/Examples/levelSet2D.cl b/Examples/levelSet2D.cl index 6f48b9e74..49e711316 100644 --- a/Examples/levelSet2D.cl +++ b/Examples/levelSet2D.cl @@ -13,17 +13,21 @@ __kernel void initScalar(__global float* scalar, scalar[i+gidY*(WIDTH)] = ((distance(pos, center)<0.15f) ? 1.0f : 0.0f); } } -__kernel void initVelocity(__global float* veloX,__global float* veloY, - float4 minPos, - float4 size) + + +__kernel void velocity(__global float* veloX,__global float* veloY, + float t, + float4 minPos, + float4 size) { uint gidX = get_global_id(0); uint gidY = get_global_id(1); uint i; float v; + float time_term = cos(t*M_PI_F/3.0f); for(i=gidX; i<WIDTH; i+=WGN) { - v = veloX[i+gidY*(WIDTH)] = -sin(i*size.x * M_PI_F)*sin(i*size.x * M_PI_F)*sin(gidY*size.y * M_PI_F * 2); + v = veloX[i+gidY*(WIDTH)] = -sin(i*size.x * M_PI_F)*sin(i*size.x * M_PI_F)*sin(gidY*size.y * M_PI_F * 2)*time_term; veloX[i+gidY*(WIDTH)] = v; // = Vx(x,y) veloY[i+gidY*(WIDTH)] = -v;// = Vy(y,x) = -Vx(x,y) } diff --git a/Examples/levelSet2D.py b/Examples/levelSet2D.py index e5eb0d243..4fd1bcbd2 100644 --- a/Examples/levelSet2D.py +++ b/Examples/levelSet2D.py @@ -20,14 +20,14 @@ def scalaire(x, y): def run(): dim = 2 - nb = 512 + nb = 256 boxLength = [1., 1.] boxMin = [0., 0.] nbElem = [nb, nb] timeStep = 0.05 #period = 10. - finalTime = timeStep*2 + finalTime = 3. outputFilePrefix = './res/levelSet_2D_' outputModulo = 1 @@ -44,12 +44,13 @@ def run(): ## Operators advec = pp.Transport(velo, scal) + velocity = pp.Velocity(velo) ## Solver creation (discretisation of objects is done in solver initialisation) topo3D = pp.CartesianTopology(domain=box, resolution=nbElem, dim=dim) ##Problem - pb = pp.Problem(topo3D, [advec]) + pb = pp.Problem(topo3D, [velocity, advec]) ## Setting solver to Problem pb.setSolver(finalTime, timeStep, 'gpu', diff --git a/Examples/levelSet3D.cl b/Examples/levelSet3D.cl index 0f11c1a71..9a22b8ed8 100644 --- a/Examples/levelSet3D.cl +++ b/Examples/levelSet3D.cl @@ -15,30 +15,29 @@ __kernel void initScalar(__global float* scalar, } } -__kernel void initVelocity(__global float* veloX,__global float* veloY,__global float* veloZ, - float4 minPos, - float4 size) +__kernel void velocity(__global float* veloX, + __global float* veloY, + __global float* veloZ, + float t, + float4 minPos, + float4 size) { uint gidX = get_global_id(0); uint gidY = get_global_id(1); uint gidZ = get_global_id(2); uint i; float pix,piy,piz,v; + float time_term = cos(t*M_PI_F/3.0f); + for(i=gidX; i<WIDTH; i+=WGN) { pix = i*size.x*M_PI_F; piy = gidY*size.y*M_PI_F; piz = gidZ*size.z*M_PI_F; - veloX[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = 2.0f * sin(pix)*sin(pix)*sin(2.0f*piy)*sin(2.0f*piz); // Vx(x,y,z) - veloY[gidY+i*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -sin(2.0f*pix)*sin(piy)*sin(piy)*sin(2.0f*piz);// Vy(y,x,z) - //veloY[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -sin(2.0f*piy)*sin(pix)*sin(pix)*sin(2.0f*piz);// Vy(y,x,z) - veloZ[gidZ+i*(WIDTH)+gidY*(WIDTH*WIDTH)] = -sin(2.0f*pix)*sin(2.0f*piy)*sin(piz)*sin(piz);//Vz(z,x,y) - //veloZ[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -sin(2.0f*piz)*sin(2.0f*pix)*sin(piy)*sin(piy);//Vz(z,x,y) - /* - v =-sin(piy)*sin(piy)*sin(2.0f*piz); - veloX[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = 0.0f; // = Vx(x,y,z) - veloY[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = v;// = Vy(y,x,z) = -Vx(x,y,z) - veloZ[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -v; // Vz(z,x,y) = -Vy(y,x,z)*/ + + veloX[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = 2.0f * sin(pix)*sin(pix)*sin(2.0f*piy)*sin(2.0f*piz)*time_term; // Vx(x,y,z) + veloY[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -sin(2.0f*piy)*sin(pix)*sin(pix)*sin(2.0f*piz)*time_term;// Vy(y,x,z) + veloZ[i+gidY*(WIDTH)+gidZ*(WIDTH*WIDTH)] = -sin(2.0f*piy)*sin(2.0f*piz)*sin(pix)*sin(pix)*time_term;//Vz(z,x,y) } } diff --git a/Examples/levelSet3D.py b/Examples/levelSet3D.py index 2db0da470..ecaf52bbd 100644 --- a/Examples/levelSet3D.py +++ b/Examples/levelSet3D.py @@ -13,7 +13,7 @@ def run(): timeStep = 0.05 #period = 10. - finalTime = 20*timeStep#3. + finalTime = 3. outputFilePrefix = './res/levelSet_3D_' outputModulo = 1 @@ -30,12 +30,13 @@ def run(): ## Operators advec = pp.Transport(velo, scal) + velocity = pp.Velocity(velo) ## Solver creation (discretisation of objects is done in solver initialisation) topo3D = pp.CartesianTopology(domain=box, resolution=nbElem, dim=dim) ##Problem - pb = pp.Problem(topo3D, [advec]) + pb = pp.Problem(topo3D, [velocity, advec]) ## Setting solver to Problem pb.setSolver(finalTime, timeStep, 'gpu', diff --git a/HySoP/hysop/__init__.py.in b/HySoP/hysop/__init__.py.in index 435cd62c9..dd25d5474 100755 --- a/HySoP/hysop/__init__.py.in +++ b/HySoP/hysop/__init__.py.in @@ -38,7 +38,9 @@ AnalyticalField = fields.analytical.AnalyticalField ## Operators import operator.Transport +import operator.Velocity Transport = operator.Transport.Transport +Velocity = operator.Velocity.Velocity ## Problem import problem.problem diff --git a/HySoP/hysop/operator/Velocity.py b/HySoP/hysop/operator/Velocity.py new file mode 100644 index 000000000..f03384b5a --- /dev/null +++ b/HySoP/hysop/operator/Velocity.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +""" +@package parmepy.operator.Advection + +Advection operator representation +""" +from .continuous import ContinuousOperator +from .velocity_d import Velocity_P + + +class Velocity(ContinuousOperator): + """ + Velocity operator representation + """ + + def __init__(self, velocity): + """ + Constructor. + Create an Advection operator from given variables velocity and scalar. + + @param velocity ContinuousField : velocity variable. + @param scalar ContinuousField : scalar variable. + """ + ContinuousOperator.__init__(self) + ## velocity variable + self.velocity = velocity + self.addVariable([velocity]) + + def discretize(self, idVelocityD=0, method=None): + """ + Advection operator discretization method. + Create an AdvectionDOp.AdvectionDOp from given specifications. + + @param spec : discretization specifications, not used. + """ + if self.discreteOperator is None: + self.discreteOperator = Velocity_P(self, idVelocityD) + + def __str__(self): + """ToString method""" + s = "Velocity operator (ContinuousOperator)" + if self.discreteOperator is not None: + s += " with the following discretization:\n" + s += str(self.discreteOperator) + else: + s += ". Not discretised" + return s + "\n" + +if __name__ == "__main__": + print __doc__ + print "- Provided class : Advection" + print Advection.__doc__ diff --git a/HySoP/hysop/operator/advection_d.py b/HySoP/hysop/operator/advection_d.py index 01a4b53c6..090c695ec 100644 --- a/HySoP/hysop/operator/advection_d.py +++ b/HySoP/hysop/operator/advection_d.py @@ -43,6 +43,7 @@ class Advection_P(DiscreteOperator): self.compute_time = [0., 0., 0.] self.compute_time_copy = [0., 0., 0.] self.compute_time_transpose = [0., 0., 0.] + self.name = "advection" def apply(self, t, dt, splittingDirection): c_time, c_time_init = 0., 0. diff --git a/HySoP/hysop/operator/remeshing.py b/HySoP/hysop/operator/remeshing.py index 0bd0fa807..779aa93db 100644 --- a/HySoP/hysop/operator/remeshing.py +++ b/HySoP/hysop/operator/remeshing.py @@ -42,6 +42,7 @@ class Remeshing(DiscreteOperator): self.output = [self.res_scalar] self.needSplitting = True self.compute_time = [0., 0., 0.] + self.name = "remeshing" def apply(self, t, dt, splittingDirection): """ diff --git a/HySoP/hysop/operator/splitting.py b/HySoP/hysop/operator/splitting.py index 286345303..c904e54d8 100644 --- a/HySoP/hysop/operator/splitting.py +++ b/HySoP/hysop/operator/splitting.py @@ -31,6 +31,7 @@ class Splitting(DiscreteOperator): self.splitting.append((dim - 1, 1.)) [self.splitting.append((dim - 2 - i, 0.5)) for i in xrange(dim - 1)] self.compute_time_details = [[0. for i in xrange(dim)] for op in self.operators] + self.name = "splitting" def apply(self, t, dt): """ diff --git a/HySoP/hysop/operator/velocity_d.py b/HySoP/hysop/operator/velocity_d.py new file mode 100644 index 000000000..2af16d6ae --- /dev/null +++ b/HySoP/hysop/operator/velocity_d.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +""" +@package operator +Discrete velocity +""" +from ..constants import * +from .discrete import DiscreteOperator +import pyopencl as cl +import numpy as np +import time + + +class Velocity_P(DiscreteOperator): + """ + Velocity computation + DiscreteOperator.DiscreteOperator specialization. + """ + + def __init__(self, advec, idVelocityD=0, method=None): + """ + Constructor. + Create a Velocity operator on a given continuous domain. + + """ + DiscreteOperator.__init__(self) + ## Velocity. + self.velocity = advec.velocity.discreteField[idVelocityD] + ## input fields + self.input = [self.velocity] + ## output fields + self.output = [self.velocity] + self.numMethod = method + self.needSplitting = False + self.old_splitting_direction = None + self.compute_time = 0. + self.name = "velocity" + + def apply(self, t, dt): + c_time = 0. + if self.numMethod is not None: + # Compute velocity field + dim = self.velocity.topology.dim + coord_min = np.ones(4, dtype=PARMES_REAL_GPU) + mesh_size = np.ones(4, dtype=PARMES_REAL_GPU) + coord_min[0:dim] = self.velocity.topology.mesh.start + mesh_size[0:dim] = self.velocity.topology.mesh.size + if len(self.velocity.gpu_data) == 3: + evt = self.numMethod.launch(self.velocity.gpu_data[0], + self.velocity.gpu_data[1], + self.velocity.gpu_data[2], + PARMES_REAL_GPU(t), + coord_min, + mesh_size) + else: + evt = self.numMethod.launch(self.velocity.gpu_data[0], + self.velocity.gpu_data[1], + PARMES_REAL_GPU(t), + coord_min, + mesh_size) + for df in self.output: + df.contains_data = False + self.numMethod.queue.finish() + c_time = (evt.profile.end - evt.profile.start) * 1e-9 + self.compute_time += c_time + self.total_time += c_time + return c_time + + def printComputeTime(self): + print "Velocity total time : ", self.total_time + + def __str__(self): + s = "Velocity_P (DiscreteOperator). " + DiscreteOperator.__str__(self) + return s + +if __name__ == "__main__": + print __doc__ + print "- Provided class : AdvectionDOp" + print AdvectionDOp.__doc__ diff --git a/HySoP/hysop/particular_solvers/basic.py b/HySoP/hysop/particular_solvers/basic.py index 7613d458b..4cdb74de8 100644 --- a/HySoP/hysop/particular_solvers/basic.py +++ b/HySoP/hysop/particular_solvers/basic.py @@ -80,7 +80,7 @@ class ParticleSolver(Solver): else: op.discretize() ## Create remeshing operator - self.remesh = Remeshing(partPositions=self.advection.discreteOperator.res_position, + self.remeshing = Remeshing(partPositions=self.advection.discreteOperator.res_position, partScalar=self.advection.discreteOperator.res_scalar, resscal=self.advection.discreteOperator.scalar, method=self.RemeshingMethod) @@ -88,7 +88,7 @@ class ParticleSolver(Solver): if op.discreteOperator.needSplitting: if op is self.advection: index = self.problem.operators.index(op) - self.problem.operators[index] = Splitting([op, self.remesh], dim=self.problem.topology.dim) + self.problem.operators[index] = Splitting([op, self.remeshing], dim=self.problem.topology.dim) else: self.problem.operators[index] = Splitting([op], dim=self.problem.topology.dim) self.isInitialized = True diff --git a/HySoP/hysop/particular_solvers/gpu.py b/HySoP/hysop/particular_solvers/gpu.py index fcf2dec8b..a8dd50c8a 100644 --- a/HySoP/hysop/particular_solvers/gpu.py +++ b/HySoP/hysop/particular_solvers/gpu.py @@ -223,7 +223,20 @@ class GPUParticleSolver(ParticleSolver): if compute_time > 0.: print "Total Computing : ", compute_time, "sec" ## Setting advection and remeshing kernels: - self.advection.setMethod(KernelLauncher(self.prg.advection, self.queue, global_wg, local_wg)) + for op in self.problem.operators: + if op.discreteOperator.name == "splitting": + for sop in op.operators: + print sop.discreteOperator.name + sop.setMethod(KernelLauncher(eval("self.prg."+sop.discreteOperator.name), + self.queue, + global_wg, + local_wg)) + else: + print op.discreteOperator.name + op.setMethod(KernelLauncher(eval("self.prg."+op.discreteOperator.name), + self.queue, + global_wg, + local_wg)) self.advection.discreteOperator.init_copy = KernelLauncher(self.prg.advec_init_copy, self.queue, global_wg, @@ -262,10 +275,6 @@ class GPUParticleSolver(ParticleSolver): ], [(64, 1, 1), (64, 1, 1)]) - self.remesh.setMethod(KernelLauncher(self.prg.remeshing, - self.queue, - global_wg, - local_wg)) self.problem.io.set_get_data_method(self.get_data_from_device) print "===\n" -- GitLab