def test_corner_case_1d_few_cells(cls): x, y, z = [0.131, 0.359], [1.544, 1.809], [-3.6489999, -2.8559999] pa = get_particle_array(name='fluid', x=x, y=y, z=z, h=1.0) nbrs = UIntArray() bf_nbrs = UIntArray() nps = cls(dim=3, particles=[pa], radius_scale=0.7) for i in range(2): nps.get_nearest_particles(0, 0, i, nbrs) nps.brute_force_neighbors(0, 0, i, bf_nbrs) assert sorted(nbrs) == sorted(bf_nbrs), 'Failed for particle: %d' % i
def _test_neighbors_by_particle(self, src_index, dst_index, dst_numPoints): # nnps and the two neighbor lists nps = self.nps nbrs1 = UIntArray() nbrs2 = UIntArray() nps.set_context(src_index, dst_index) # get the neighbors and sort the result for i in range(dst_numPoints): nps.get_nearest_particles(src_index, dst_index, i, nbrs1) nps.brute_force_neighbors(src_index, dst_index, i, nbrs2) # ensure that the neighbor lists are the same self._assert_neighbors(nbrs1, nbrs2)
def test_compressed_octree_works_for_large_domain(self): # Given pa = self._make_particles(20) # We turn on cache so it computes all the neighbors quickly for us. nps = nnps.CompressedOctreeNNPS(dim=3, particles=[pa], cache=True) nbrs = UIntArray() direct = UIntArray() nps.set_context(0, 0) for i in range(pa.get_number_of_particles()): nps.get_nearest_particles(0, 0, i, nbrs) nps.brute_force_neighbors(0, 0, i, direct) x = nbrs.get_npy_array() y = direct.get_npy_array() x.sort() y.sort() assert numpy.all(x == y)
def test_use_3d_for_1d_data_with_llnps(): y = numpy.array([1.0, 1.5]) h = numpy.ones_like(y) pa = get_particle_array(name='fluid', y=y, h=h) nps = nnps.LinkedListNNPS(dim=3, particles=[pa], cache=False) nbrs = UIntArray() nps.get_nearest_particles(0, 0, 0, nbrs) print(nbrs.length) assert nbrs.length == len(y)
def _check_summation_density(self): fluid = self.fluid nnps = self.nnps kernel = self.kernel nnps.update_domain() nnps.update() # get the fluid arrays fx, fy, fz, fh, frho, fV, fm = fluid.get('x', 'y', 'z', 'h', 'rho', 'V', 'm', only_real_particles=True) # the source arrays. First source is also the fluid sx, sy, sz, sh, sm = fluid.get('x', 'y', 'z', 'h', 'm', only_real_particles=False) # initialize the fluid density and volume frho[:] = 0.0 fV[:] = 0.0 # compute density on the fluid nbrs = UIntArray() for i in range(fluid.num_real_particles): hi = fh[i] # compute density from the fluid from the source arrays nnps.get_nearest_particles(src_index=0, dst_index=0, d_idx=i, nbrs=nbrs) nnbrs = nbrs.length for indexj in range(nnbrs): j = nbrs[indexj] hij = 0.5 * (hi + sh[j]) frho[i] += sm[j] * kernel.kernel(fx[i], fy[i], fz[i], sx[j], sy[j], sz[j], hij) fV[i] += kernel.kernel(fx[i], fy[i], fz[i], sx[j], sy[j], sz[j], hij) # check the number density and density by summation voli = 1. / fV[i] #print voli, frho[i], fm[i], self.vol self.assertAlmostEqual(voli, self.vol, 5) self.assertAlmostEqual(frho[i], fm[i] / voli, 14)
def test_large_number_of_neighbors_octree(): x = numpy.random.random(1 << 14) * 0.1 y = x.copy() z = x.copy() h = numpy.ones_like(x) pa = get_particle_array(name='fluid', x=x, y=y, z=z, h=h) nps = nnps.OctreeNNPS(dim=3, particles=[pa], cache=False) nbrs = UIntArray() nps.get_nearest_particles(0, 0, 0, nbrs) # print(nbrs.length) assert nbrs.length == len(x)
def test_cache_updates_with_changed_particles(self): # Given pa1 = self._make_random_parray('pa1', 5) particles = [pa1] nnps = LinkedListNNPS(dim=3, particles=particles) cache = NeighborCache(nnps, dst_index=0, src_index=0) cache.update() # When pa2 = self._make_random_parray('pa2', 2) pa1.add_particles(x=pa2.x, y=pa2.y, z=pa2.z) nnps.update() cache.update() nb_cached = UIntArray() nb_direct = UIntArray() for i in range(len(particles[0].x)): nnps.get_nearest_particles_no_cache(0, 0, i, nb_direct, False) cache.get_neighbors(0, i, nb_cached) nb_e = nb_direct.get_npy_array() nb_c = nb_cached.get_npy_array() self.assertTrue(np.all(nb_e == nb_c))
def test_neighbors_cached_properly(self): # Given pa1 = self._make_random_parray('pa1', 5) pa2 = self._make_random_parray('pa2', 4) particles = [pa1, pa2] nnps = LinkedListNNPS(dim=3, particles=particles) for dst_index in (0, 1): for src_idx in (0, 1): # When cache = NeighborCache(nnps, dst_index, src_idx) cache.update() nb_cached = UIntArray() nb_direct = UIntArray() # Then. for i in range(len(particles[dst_index].x)): nnps.get_nearest_particles_no_cache( src_idx, dst_index, i, nb_direct, False) cache.get_neighbors(src_idx, i, nb_cached) nb_e = nb_direct.get_npy_array() nb_c = nb_cached.get_npy_array() self.assertTrue(np.all(nb_e == nb_c))
def test_empty_neigbors_works_correctly(self): # Given pa1 = self._make_random_parray('pa1', 5) pa2 = self._make_random_parray('pa2', 2) pa2.x += 10.0 particles = [pa1, pa2] # When nnps = LinkedListNNPS(dim=3, particles=particles) # Cache for neighbors of destination 0. cache = NeighborCache(nnps, dst_index=0, src_index=1) cache.update() # Then nb_cached = UIntArray() nb_direct = UIntArray() for i in range(len(particles[0].x)): nnps.get_nearest_particles_no_cache(1, 0, i, nb_direct, False) # Get neighbors from source 1 on destination 0. cache.get_neighbors(src_index=1, d_idx=i, nbrs=nb_cached) nb_e = nb_direct.get_npy_array() nb_c = nb_cached.get_npy_array() self.assertEqual(len(nb_e), 0) self.assertTrue(np.all(nb_e == nb_c))
def test_nnps_sorts_without_gids(self): # Given pa, nps = self._make_particles(10) # When nps.set_context(0, 0) # Test the that gids are actually huge and invalid. self.assertEqual(numpy.max(pa.gid), numpy.min(pa.gid)) self.assertTrue(numpy.max(pa.gid) > pa.gid.size) # Then nbrs = UIntArray() for i in range(pa.get_number_of_particles()): nps.get_nearest_particles(0, 0, i, nbrs) nb = nbrs.get_npy_array() sorted_nbrs = sorted(nb.copy()) self.assertTrue(numpy.all(nb == sorted_nbrs))
def sd_evaluate(nnps, pm, mass, src_index, dst_index): # the destination particle array dst = nnps.particles[dst_index] src = nnps.particles[src_index] # particle coordinates dx, dy, dz, dh, drho = dst.get('x', 'y', 'z', 'h', 'rho', only_real_particles=True) sx, sy, sz, sh, srho = src.get('x', 'y', 'z', 'h', 'rho', only_real_particles=False) neighbors = UIntArray() cubic = get_compiled_kernel(CubicSpline(dim=dim)) # compute density for each destination particle num_particles = dst.num_real_particles # the number of local particles should have tag Local assert (num_particles == pm.num_local[dst_index]) for i in range(num_particles): hi = dh[i] nnps.get_nearest_particles(src_index, dst_index, i, neighbors) nnbrs = neighbors.length rho_sum = 0.0 for indexj in range(nnbrs): j = neighbors[indexj] wij = cubic.kernel(dx[i], dy[i], dz[i], sx[j], sy[j], sz[j], hi) rho_sum = rho_sum + mass * wij drho[i] += rho_sum
def test_nnps_sorts_with_valid_gids(self): # Given pa, nps = self._make_particles(10) pa.gid[:] = numpy.arange(pa.x.size) nps.update() # When nps.set_context(0, 0) # Test the that gids are actually valid. self.assertEqual(numpy.max(pa.gid), pa.gid.size - 1) self.assertEqual(numpy.min(pa.gid), 0) # Then nbrs = UIntArray() for i in range(pa.get_number_of_particles()): nps.get_nearest_particles(0, 0, i, nbrs) nb = nbrs.get_npy_array() sorted_nbrs = nb.copy() sorted_nbrs.sort() self.assertTrue(numpy.all(nb == sorted_nbrs))
def test_setting_use_cache_does_cache(self): # Given pa = self._make_random_parray('pa1', 3) pa.h[:] = 1.0 nnps = LinkedListNNPS(dim=3, particles=[pa], cache=False) n = pa.get_number_of_particles() # When nnps.set_use_cache(True) nbrs = UIntArray() nnps.set_context(0, 0) for i in range(n): nnps.get_nearest_particles(0, 0, i, nbrs) # Then self.assertEqual(nbrs.length, n) # Find the length of all cached neighbors, # in this case, each particle has n neighbors, # so we should have n*n neighbors in all. total_length = sum(x.length for x in nnps.cache[0]._neighbor_arrays) self.assertEqual(total_length, n * n)
def _test_summation_density(self): "NNPS :: testing for summation density" fluid, channel = self.particles nnps = self.nnps kernel = self.kernel # get the fluid arrays fx, fy, fh, frho, fV, fm = fluid.get('x', 'y', 'h', 'rho', 'V', 'm', only_real_particles=True) # initialize the fluid density and volume frho[:] = 0.0 fV[:] = 0.0 # compute density on the fluid nbrs = UIntArray() for i in range(fluid.num_real_particles): hi = fh[i] # compute density from the fluid from the source arrays nnps.get_nearest_particles(src_index=0, dst_index=0, d_idx=i, nbrs=nbrs) nnbrs = nbrs.length # the source arrays. First source is also the fluid sx, sy, sh, sm = fluid.get('x', 'y', 'h', 'm', only_real_particles=False) for indexj in range(nnbrs): j = nbrs[indexj] hij = 0.5 * (hi + sh[j]) frho[i] += sm[j] * \ kernel.kernel(fx[i], fy[i], 0.0, sx[j], sy[j], 0.0, hij) fV[i] += kernel.kernel(fx[i], fy[i], 0.0, sx[j], sy[j], 0.0, hij) # compute density from the channel nnps.get_nearest_particles(src_index=1, dst_index=0, d_idx=i, nbrs=nbrs) nnbrs = nbrs.length sx, sy, sh, sm = channel.get('x', 'y', 'h', 'm', only_real_particles=False) for indexj in range(nnbrs): j = nbrs[indexj] hij = 0.5 * (hi + sh[j]) frho[i] += sm[j] * \ kernel.kernel(fx[i], fy[i], 0.0, sx[j], sy[j], 0.0, hij) fV[i] += kernel.kernel(fx[i], fy[i], 0.0, sx[j], sy[j], 0.0, hij) # check the number density and density by summation voli = 1. / fV[i] self.assertAlmostEqual(voli, self.vol, 6) self.assertAlmostEqual(frho[i], fm[i] / voli, 6)