def test_udpate(self): """ LinkedListSPHNeighborLocator: test_update The two domain managers are used to independently bin and construct the neighbor list for each particle. The neighbors within a cell are then compared. This test establshes that OpenCL and Cython produce the same neighbor lists per cell, and thus are equivalent. """ name = self.cy_pa.name cy_manager = self.cy_manager cl_manager = self.cl_manager # update the structure cy_manager.update() cl_manager.update() # read the buffer contents for the OpenCL manager cl_manager.enqueue_copy() # the number of cells should be the same ncells = len(cy_manager.head[name]) self.assertEqual( len(cy_manager.head[name]), len(cl_manager.head[name]) ) # check the neighbor lists cy_bins = cy_manager.cellids[name] cy_head = cy_manager.head[name] cy_next = cy_manager.Next[name] cl_bins = cl_manager.cellids[name] cl_head = cl_manager.head[name] cl_next = cl_manager.Next[name] for i in range(self.np): cy_nbrs = nnps.ll_cell_neighbors( cy_bins[i], cy_head, cy_next ) cl_nbrs = nnps.ll_cell_neighbors( cl_bins[i], cl_head, cl_next ) cy_nbrs.sort() cl_nbrs.sort() # the number of neighbors should be the same nnbrs = len(cy_nbrs) self.assertEqual( len(cl_nbrs), nnbrs ) # the sorted list of neighbors should be the same for j in range( nnbrs ): self.assertEqual( cl_nbrs[j], cy_nbrs[j] )
def test(self): """Dynamic OpenCL binning test. """ # Create a ParticleArray with double precision pa = solver.shock_tube_solver.standard_shock_tube_data( name="test", cl_precision="double", type=base.Fluid) # get the coordinate array x = pa.get('x') # set the scale factor and cell size. Remember that in the # OpenCL DomainManager, we want the bin size to be (k+1)*maxH scale_fac = 2.0 h0 = pa.h[0] cell_size = (scale_fac + 1) * h0 # create a shock tube solver s = solver.ShockTubeSolver(dim=1, integrator_type=solver.EulerIntegrator) # create a Particles instance with a fixed cell size provided. particles = base.Particles(arrays=[pa,], min_cell_size=cell_size, max_cell_size=cell_size) s.setup(particles) s.set_final_time(0.15) s.set_time_step(3e-4) integrator = s.integrator cell_manager = particles.cell_manager # Setup the OpenCL domain manager ctx = solver.create_some_context() domain_manager = base.LinkedListManager(arrays=[pa,], context=ctx) assert ( domain_manager.with_cl == True ) # bin the particles on the OpenCL device domain_manager.update() # the cell sizes for Cython and OpenCL should be the same assert (domain_manager.cell_size == cell_manager.cell_size) cell_size = domain_manager.cell_size t = 0.0 tf = 0.15 dt = 3e-4 np = 400 while t < tf: # update the particles particles.update() # integrate integrator.integrate(dt) # call the cell manager's update cell_manager.update() # now bin the updated data using OpenCL domain_manager.update() domain_manager.enqueue_copy() head = domain_manager.head["test"] next = domain_manager.Next["test"] cellids = domain_manager.cellids["test"] # test the bin structure for each particle for i in range(np): # find the index of the particle pnt = base.Point(x[i]) index = py_find_cell_id(pnt, cell_size) # get the particles in the cell cell = cell_manager.cells_dict[index] cy_nbrs = cell.index_lists[0].get_npy_array() cy_nbrs.sort() # get the particle's index with OpenCL cl_index = cellids[i] # get the particles in the the cell with OpenCL cl_nbrs = ll_cell_neighbors( cellids[i], head, next ) cl_nbrs.sort() # the lenght of the neighbors should be the same nclnbrs = len(cl_nbrs) ncynbrs = len(cy_nbrs) assert ( nclnbrs == ncynbrs ) # test each neighbor for j in range(ncynbrs): assert ( cl_nbrs[j] == cy_nbrs[j] ) t += dt