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 remove_overlap_particles(fluid_parray, solid_parray, dx_solid, dim=3): """ This function will take 2 particle arrays as input and will remove all the particles of the first particle array which are in the vicinity of the particles from second particle array. The function will remove all the particles within the dx_solid vicinity so some particles are removed at the outer surface of the particles from the second particle array. This uses a pysph nearest neighbour particles search which will output the particles within some range for every given particle. Parameters ---------- fluid_parray : a pysph particle array object solid_parray : a pysph particle array object dx_solid : a number which is the dx of the second particle array dim : dimensionality of the problem The particle arrays should atleast contain x, y and h values for a 2d case and atleast x, y, z and h values for a 3d case Returns ------- particle_array : pysph wcsph_particle_array with x, y, z and h values """ x = fluid_parray.x x1 = solid_parray.x y = fluid_parray.y y1 = solid_parray.y z = fluid_parray.z z1 = solid_parray.z h = fluid_parray.h if dim == 2: z = np.zeros_like(x) z1 = np.zeros_like(x1) modified_points = [] h_new = [] ll_nnps = LinkedListNNPS(dim, [fluid_parray, solid_parray]) for i in range(len(x)): nbrs = UIntArray() ll_nnps.get_nearest_particles(1, 0, i, nbrs) point_i = np.array([x[i], y[i], z[i]]) near_points = nbrs.get_npy_array() distances = [] for ind in near_points: dest = [x1[ind], y1[ind], z1[ind]] distances.append(distance(point_i, dest)) if len(distances) == 0: modified_points.append(point_i) h_new.append(h[i]) elif min(distances) >= (dx_solid * (1.0 - 1.0e-07)): modified_points.append(point_i) h_new.append(h[i]) modified_points = np.array(modified_points) x_new = modified_points[:, 0] y_new = modified_points[:, 1] z_new = modified_points[:, 2] p_array = get_particle_array_wcsph(x=x_new, y=y_new, z=z_new, h=h_new) return p_array
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 find_overlap_particles(fluid_parray, solid_parray, dx_solid, dim=3): """This function will take 2 particle arrays as input and will find all the particles of the first particle array which are in the vicinity of the particles from second particle array. The function will find all the particles within the dx_solid vicinity so some particles may be identified at the outer surface of the particles from the second particle array. The particle arrays should atleast contain x, y and h values for a 2d case and atleast x, y, z and h values for a 3d case. Parameters ---------- fluid_parray : a pysph particle array object solid_parray : a pysph particle array object dx_solid : a number which is the dx of the second particle array dim : dimensionality of the problem Returns ------- list of particle indices to remove from the first array. """ x = fluid_parray.x x1 = solid_parray.x y = fluid_parray.y y1 = solid_parray.y z = fluid_parray.z z1 = solid_parray.z if dim == 2: z = np.zeros_like(x) z1 = np.zeros_like(x1) to_remove = [] ll_nnps = LinkedListNNPS(dim, [fluid_parray, solid_parray]) for i in range(len(x)): nbrs = UIntArray() ll_nnps.get_nearest_particles(1, 0, i, nbrs) point_i = np.array([x[i], y[i], z[i]]) near_points = nbrs.get_npy_array() distances = [] for ind in near_points: dest = [x1[ind], y1[ind], z1[ind]] distances.append(distance(point_i, dest)) if len(distances) == 0: continue elif min(distances) < (dx_solid * (1.0 - 1.0e-07)): to_remove.append(i) return to_remove
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 = nb.copy() sorted_nbrs.sort() self.assertTrue(numpy.all(nb == sorted_nbrs))
# container for neighbors nbrs = UIntArray() # arrays including ghosts x, y, h, m = pa.get('x', 'y', 'h', 'm', only_real_particles=False) # iterate over destination particles t1 = time() max_ngb = -1 for i in range( pa.num_real_particles ): xi = x[i]; yi = y[i]; hi = h[i] # get list of neighbors nps.get_nearest_particles(0, 0, i, nbrs) neighbors = nbrs.get_npy_array() max_ngb = max( neighbors.size, max_ngb ) # iterate over the neighbor set rho_sum = 0.0; wij_sum = 0.0 for j in neighbors: xij = xi - x[j] yij = yi - y[j] rij = numpy.sqrt( xij**2 + yij**2 ) hij = 0.5 * (h[i] + h[j]) _wij = k.kernel( [xij, yij, 0.0], rij, hij) # contribution from this neibhor
print "Neighbor search",nl_updates pa = get_particle_array(name='prot', x=rx, y=ry, z=rz, h=1.0) #h=1.0 must not be changed as it affects radius_scale in nnps.LinkedListNNPS nps = nnps.LinkedListNNPS(dim=3, particles=[pa], radius_scale=rcut2) #nps = nnps.SpatialHashNNPS(dim=3, particles=[pa], radius_scale=rcut2) src_index = 0 dst_index = 0 neighbors = [] tot = 0 for i in range(nca): nbrs = UIntArray() nps.get_nearest_particles(src_index, dst_index, i, nbrs) tmp = nbrs.get_npy_array().tolist() # patch if tmp.count(i) > 1: print "Problems: nbrs has multiple occurrences of residue %d, which might indicate something wrong in pysph (for certain radius_scale values)" %(i) print "Patching this problem by assuming that residue %d has no neighbors other than itself" % (i) tmp = [i] else: pass nneigh = len(tmp) tot += nneigh #I do not want neighbors that are only the i-th particle (i.e. self) #I want the "central" atom as the first element: THIS IS FUNDAMENTAL FOR HOW all_pairs_in_nl WORKS if (nneigh > 1):
nbrs = UIntArray() # arrays including ghosts x, y, h, m = pa.get('x', 'y', 'h', 'm', only_real_particles=False) # iterate over destination particles t1 = time() max_ngb = -1 for i in range(pa.num_real_particles): xi = x[i] yi = y[i] hi = h[i] # get list of neighbors nps.get_nearest_particles(0, 0, i, nbrs) neighbors = nbrs.get_npy_array() max_ngb = max(neighbors.size, max_ngb) # iterate over the neighbor set rho_sum = 0.0 wij_sum = 0.0 for j in neighbors: xij = xi - x[j] yij = yi - y[j] rij = numpy.sqrt(xij**2 + yij**2) hij = 0.5 * (h[i] + h[j]) _wij = k.kernel([xij, yij, 0.0], rij, hij)