def test_ref_point_ne_points(self): """Verify the behavior of LocalDescriptors by explicitly calculating spherical harmonics manually and verifying them.""" from scipy.special import sph_harm atol = 1e-5 L = 8 N = 100 box, points = make_box_and_random_points(L, N) ref_points = np.random.rand(N, 3)*L - L/2 num_neighbors = 1 r_max = 2 l_max = 2 # We want to provide the NeighborList ourselves since we need to use it # again later anyway. nn = freud.locality.NearestNeighbors(r_max, num_neighbors) nl = nn.compute(box, ref_points, points).nlist ld = freud.environment.LocalDescriptors( num_neighbors, l_max, r_max) ld.compute(box, num_neighbors, ref_points, points, mode='global', nlist=nl) # Loop over the sphs and compute them explicitly. for idx, (i, j) in enumerate(nl): bond = box.wrap(points[j] - ref_points[i]) r = np.linalg.norm(bond) theta = np.arccos(bond[2]/r) phi = np.arctan2(bond[1], bond[0]) count = 0 for l in range(l_max+1): for m in range(l+1): # Explicitly calculate the spherical harmonic with scipy # and check the output. Arg order is theta, phi for scipy, # but we need to pass the swapped angles because it uses # the opposite convention from fsph (which LocalDescriptors # uses internally). scipy_val = sph_harm(m, l, phi, theta) ld_val = (-1)**abs(m) * ld.sph[idx, count] self.assertTrue(np.isclose( scipy_val, ld_val, atol=atol), msg=("Failed for l={}, m={}, x={}, y = {}" "\ntheta={}, phi={}").format( l, m, scipy_val, ld_val, theta, phi)) count += 1 for neg_m in range(1, l+1): m = -neg_m scipy_val = sph_harm(m, l, phi, theta) ld_val = ld.sph[idx, count] self.assertTrue(np.isclose( scipy_val, ld_val, atol=atol), msg=("Failed for l={}, m={}, x={}, y = {}" "\ntheta={}, phi={}").format( l, m, scipy_val, ld_val, theta, phi)) count += 1
def test_basic(self): # Test that voronoi tessellations of random systems have the same # number of points and polytopes L = 10 # Box length N = 50 # Number of particles box, positions = util.make_box_and_random_points(L, N, True) vor = freud.voronoi.Voronoi(box) with self.assertRaises(AttributeError): vor.polytopes with self.assertRaises(AttributeError): vor.nlist with self.assertRaises(AttributeError): vor.volumes with self.assertRaises(AttributeError): vor.getNeighbors(0) vor.compute(positions, box=box, buff=L / 2) with self.assertRaises(AttributeError): vor.nlist with self.assertRaises(AttributeError): vor.volumes with self.assertRaises(AttributeError): vor.getNeighbors(0) result = vor.polytopes npt.assert_equal(len(result), len(positions))
def test_getNP(self): boxlen = 10 N = 500 num_neigh = 8 rmax = 3 box, points = make_box_and_random_points(boxlen, N, True) ors = [] for i in range(N): ors.append(quatRandom()) ors = np.asarray(ors, dtype=np.float32) equiv_quats = np.asarray([[1, 0, 0, 0]], dtype=np.float32) ang = freud.environment.AngularSeparation(rmax, num_neigh) # test access with self.assertRaises(AttributeError): ang.neighbor_angles with self.assertRaises(AttributeError): ang.global_angles with self.assertRaises(AttributeError): ang.n_p with self.assertRaises(AttributeError): ang.n_global with self.assertRaises(AttributeError): ang.n_ref ang.computeNeighbor(box, ors, ors, points, points, equiv_quats) npt.assert_equal(ang.n_p, N)
def test_summation(self): # Causes the correlation function to add lots of small numbers together # This leads to vastly different results with different numbers of # threads if the summation is not done robustly N = 20000 L = 1000 phi = np.random.rand(N) box, pos2d = make_box_and_random_points(L, N, True) # With a small number of particles, we won't get the average exactly # right, so we check for different behavior with different numbers of # threads freud.parallel.setNumThreads(1) # A very large bin size exacerbates the problem cf = freud.density.ComplexCF(L / 2.1, 40) cf.compute(box, pos2d, phi) c1 = cf.counts f1 = np.real(cf.RDF) freud.parallel.setNumThreads(20) cf.compute(box, pos2d, phi) c2 = cf.counts f2 = np.real(cf.RDF) npt.assert_allclose(f1, f2) npt.assert_array_equal(c1, c2)
def test_random_point_with_cell_list(self): from scipy.fftpack import fft, fftshift width = 100 rcut = 10.0 sigma = 0.1 num_points = 10000 box_size = rcut * 3.1 box, points = make_box_and_random_points(box_size, num_points, True) diff = freud.density.GaussianDensity(width, rcut, sigma) # Test access with self.assertRaises(AttributeError): diff.box with self.assertRaises(AttributeError): diff.gaussian_density diff.compute(box, points) # Test access diff.box diff.gaussian_density myDiff = diff.gaussian_density myFFT = fft(fft(myDiff[:, :], axis=1), axis=0) myDiff = (myFFT * np.conj(myFFT)).real myDiff = fftshift(myDiff)[:, :] npt.assert_equal(np.where(myDiff == np.max(myDiff)), (np.array([50]), np.array([50])))
def test_shape(self): N = 1000 Nneigh = 4 lmax = 8 rmax = 0.5 L = 10 box, positions = make_box_and_random_points(L, N) positions.flags['WRITEABLE'] = False comp = freud.environment.LocalDescriptors(Nneigh, lmax, rmax, True) # Test access with self.assertRaises(AttributeError): comp.sph with self.assertRaises(AttributeError): comp.num_particles with self.assertRaises(AttributeError): comp.num_neighbors comp.compute(box, Nneigh, positions) # Test access comp.sph comp.num_particles comp.num_neighbors self.assertEqual(comp.sph.shape[0], N*Nneigh) self.assertEqual(comp.num_particles, positions.shape[0]) self.assertEqual(comp.num_neighbors/comp.num_particles, Nneigh) self.assertEqual(comp.l_max, lmax)
def test_box(self): boxlen = 10 N = 500 num_neigh = 8 rmax = 3 box, points = make_box_and_random_points(boxlen, N) ors = [] for i in range(N): ors.append(quatRandom()) ors = np.asarray(ors, dtype=np.float32) equiv_quats = np.asarray([[1, 0, 0, 0]], dtype=np.float32) proj_vecs = np.asarray([[0, 0, 1]]) ang = freud.environment.LocalBondProjection(rmax, num_neigh) ang.compute(box, proj_vecs, points, ors, points, equiv_quats) npt.assert_equal(ang.box.Lx, boxlen) npt.assert_equal(ang.box.Ly, boxlen) npt.assert_equal(ang.box.Lz, boxlen) npt.assert_equal(ang.box.xy, 0) npt.assert_equal(ang.box.xz, 0) npt.assert_equal(ang.box.yz, 0)
def test_cube(self): L = 10 # Box length N = 50 # Number of particles np.random.seed(0) fbox, positions = util.make_box_and_random_points(L, N, False) positions.flags['WRITEABLE'] = False pbuff = freud.box.ParticleBuffer(fbox) # Compute with zero buffer distance pbuff.compute(positions, buffer=0, images=False) self.assertEqual(len(pbuff.buffer_particles), 0) self.assertEqual(len(pbuff.buffer_ids), 0) npt.assert_array_equal(pbuff.buffer_box.L, np.asarray(fbox.L)) # Compute with buffer distances pbuff.compute(positions, buffer=0.5 * L, images=False) self.assertEqual(len(pbuff.buffer_particles), 7 * N) self.assertEqual(len(pbuff.buffer_ids), 7 * N) npt.assert_array_equal(pbuff.buffer_box.L, 2 * np.asarray(fbox.L)) # Compute with different buffer distances pbuff.compute(positions, buffer=[L, 0, L], images=False) self.assertEqual(len(pbuff.buffer_particles), 8 * N) self.assertEqual(len(pbuff.buffer_ids), 8 * N) npt.assert_array_equal(pbuff.buffer_box.L, fbox.L * np.array([3, 1, 3])) # Compute with zero images pbuff.compute(positions, buffer=0, images=True) self.assertEqual(len(pbuff.buffer_particles), 0) self.assertEqual(len(pbuff.buffer_ids), 0) npt.assert_array_equal(pbuff.buffer_box.L, np.asarray(fbox.L)) # Compute with images pbuff.compute(positions, buffer=1, images=True) self.assertEqual(len(pbuff.buffer_particles), 7 * N) self.assertEqual(len(pbuff.buffer_ids), 7 * N) npt.assert_array_equal(pbuff.buffer_box.L, 2 * np.asarray(fbox.L)) # Compute with images-success pbuff.compute(positions, buffer=2, images=True) self.assertEqual(len(pbuff.buffer_particles), 26 * N) self.assertEqual(len(pbuff.buffer_ids), 26 * N) npt.assert_array_equal(pbuff.buffer_box.L, 3 * np.asarray(fbox.L)) # Compute with two images in x axis pbuff.compute(positions, buffer=np.array([1, 0, 0]), images=True) self.assertEqual(len(pbuff.buffer_particles), N) self.assertEqual(len(pbuff.buffer_ids), N) npt.assert_array_equal(pbuff.buffer_box.Lx, 2 * np.asarray(fbox.Lx)) # Compute with different images pbuff.compute(positions, buffer=[1, 0, 1], images=True) self.assertEqual(len(pbuff.buffer_particles), 3 * N) self.assertEqual(len(pbuff.buffer_ids), 3 * N) npt.assert_array_equal(pbuff.buffer_box.L, fbox.L * np.array([2, 1, 2]))
def test_query_to_nlist(self): """Test that generated NeighborLists are identical to the results of querying""" L = 10 # Box Dimensions N = 400 # number of particles box, ref_points = make_box_and_random_points(L, N, seed=0) _, points = make_box_and_random_points(L, N, seed=1) nq = self.build_query_object(box, ref_points, L / 10) result_list = list(nq.query(points, 2)) result_list = [(b[0], b[1]) for b in result_list] nlist = nq.query(points, 2).toNList() list_nlist = list(zip(nlist.index_i, nlist.index_j)) npt.assert_equal(set(result_list), set(list_nlist))
def test_getNP(self): boxlen = 10 N = 500 rmax = 3 box, points = make_box_and_random_points(boxlen, N, True) hop = freud.order.HexOrderParameter(rmax) hop.compute(box, points) npt.assert_equal(hop.num_particles, N)
def test_shape(self): N = 1000 L = 10 box, positions = util.make_box_and_random_points(L, N) comp = freud.order.LocalWl(box, 1.5, 6) comp.compute(positions) npt.assert_equal(comp.Wl.shape[0], N)
def test_reciprocal_twoset(self): """Test that, for a random set of points, for each (i, j) neighbor pair there also exists a (j, i) neighbor pair for two sets of different points """ L, rcut, N = (10, 2.01, 1024) box, points = make_box_and_random_points(L, N, seed=0) _, points2 = make_box_and_random_points(L, N // 6, seed=1) nq = self.build_query_object(box, points, rcut) nq2 = self.build_query_object(box, points2, rcut) result = list(nq.queryBall(points2, rcut)) result2 = list(nq2.queryBall(points, rcut)) ij = {(x[0], x[1]) for x in result} ij2 = {(x[1], x[0]) for x in result2} self.assertEqual(ij, ij2)
def test_compute_random(self): boxlen = 10 N = 500 rmax = 3 box, points = make_box_and_random_points(boxlen, N, True) hop = freud.order.HexOrderParameter(rmax) hop.compute(box, points) npt.assert_allclose(np.mean(hop.psi), 0. + 0.j, atol=1e-1) self.assertTrue(hop.box == box)
def test_shape(self): N = 1000 L = 10 box, positions = util.make_box_and_random_points(L, N) comp = freud.order.Steinhardt(1.5, 6) comp.compute(box, positions) npt.assert_equal(comp.order.shape[0], N)
def setup_nl(self, L=10, rcut=3, N=40, num_neighbors=6): # Define values self.L = L self.rcut = rcut self.N = N self.num_neighbors = num_neighbors # Initialize Box and cell list self.cl = locality.NearestNeighbors(self.rcut, self.num_neighbors) self.fbox, self.points = make_box_and_random_points(L, N)
def test_chaining(self): N = 500 L = 10 rcut = 1 box, points = make_box_and_random_points(L, N) nlist1 = freud.locality.LinkCell(box, 1.0, points).queryBall( points, rcut, exclude_ii=True).toNList() lc = freud.locality.LinkCell(box, 1.0, points) nlist2 = lc.queryBall(points, rcut, exclude_ii=True).toNList() self.assertTrue(nlist_equal(nlist1, nlist2))
def test_shape(self): N = 1000 L = 10 box, positions = util.make_box_and_random_points(L, N) # Use a really small cutoff to ensure that it is used as a soft cutoff comp = freud.order.LocalQlNear(box, 0.1, 6, 12) comp.compute(positions) npt.assert_equal(comp.Ql.shape[0], N)
def test_shape(self): N = 1000 L = 10 box, positions = util.make_box_and_random_points(L, N) positions.flags['WRITEABLE'] = False comp = freud.order.LocalQl(box, 1.5, 6) comp.compute(positions) npt.assert_equal(comp.Ql.shape[0], N)
def test_compute_twice_norm(self): """Test that computing norm twice works as expected.""" L = 5 num_points = 100 box, points = util.make_box_and_random_points(L, num_points, seed=0) ql = freud.order.LocalQl(box, 1.5, 6) first_result = ql.computeNorm(points).norm_Ql.copy() second_result = ql.computeNorm(points).norm_Ql npt.assert_array_almost_equal(first_result, second_result)
def test_unknown_modes(self): N = 1000 Nneigh = 4 lmax = 8 L = 10 box, positions = make_box_and_random_points(L, N) comp = freud.environment.LocalDescriptors(Nneigh, lmax, .5, True) with self.assertRaises(RuntimeError): comp.compute(box, Nneigh, positions, mode='particle_local_wrong')
def test_basic(self): # Test that voronoi tessellations of random systems have the same # number of points and polytopes L = 10 # Box length N = 50 # Number of particles vor = freud.locality._Voronoi() box, positions = util.make_box_and_random_points(L, N, True) vor.compute(box=box, positions=positions, buffer=L / 2) result = vor.polytopes npt.assert_equal(len(result), len(positions))
def test_reciprocal(self): """Test that, for a random set of points, for each (i, j) neighbor pair there also exists a (j, i) neighbor pair for one set of points""" L, rcut, N = (10, 2.01, 1024) fbox, points = make_box_and_random_points(L, N) lc = locality.LinkCell(fbox, rcut).compute(fbox, points) ij = set(zip(lc.nlist.index_i, lc.nlist.index_j)) ji = set((j, i) for (i, j) in ij) self.assertEqual(ij, ji)
def test_change_box_dimension(self): width = 100 rcut = 10.0 sigma = 0.1 num_points = 100 box_size = rcut * 3.1 box, points = make_box_and_random_points(box_size, num_points, True) diff = freud.density.GaussianDensity(width, rcut, sigma) diff.compute(box, points) testBox = freud.box.Box.cube(box_size) diff.compute(testBox, points)
def test_reciprocal(self): """Test that, for a random set of points, for each (i, j) neighbor pair there also exists a (j, i) neighbor pair for one set of points""" L, rcut, N = (10, 2.01, 1024) box, points = make_box_and_random_points(L, N, seed=0) nq = self.build_query_object(box, points, rcut) result = list(nq.queryBall(points, rcut)) ij = {(x[0], x[1]) for x in result} ji = set((j, i) for (i, j) in ij) self.assertEqual(ij, ji)
def test_zero_points(self): rmax = 10.0 dr = 1.0 num_points = 1000 box_size = rmax * 3.1 box, points = make_box_and_random_points(box_size, num_points, True) ang = np.zeros(int(num_points), dtype=np.float64) ocf = freud.density.FloatCF(rmax, dr) ocf.accumulate(box, points, ang) correct = np.zeros(int(rmax / dr), dtype=np.float32) absolute_tolerance = 0.1 npt.assert_allclose(ocf.RDF, correct, atol=absolute_tolerance)
def test_neighbor_count(self): L = 10 # Box Dimensions rcut = 3 # Cutoff radius N = 40 # number of particles num_neighbors = 6 # Initialize cell list cl = locality.NearestNeighbors(rcut, num_neighbors) fbox, points = make_box_and_random_points(L, N) cl.compute(fbox, points, points) self.assertEqual(cl.num_neighbors, num_neighbors) self.assertEqual(len(cl.getNeighbors(0)), num_neighbors)
def test_shape_twosets(self): N = 1000 Nneigh = 4 lmax = 8 L = 10 box, positions = make_box_and_random_points(L, N) positions2 = np.random.uniform(-L/2, L/2, size=(N//3, 3)).astype(np.float32) comp = freud.environment.LocalDescriptors(Nneigh, lmax, .5, True) comp.compute(box, Nneigh, positions, positions2) sphs = comp.sph self.assertEqual(sphs.shape[0], N*Nneigh)
def setUp(self): """Initialize a box with randomly placed particles""" box_size = 10 num_points = 10000 self.box, self.pos = make_box_and_random_points(box_size, num_points) self.ld = freud.density.LocalDensity(3, 1, 1) # Test access with self.assertRaises(AttributeError): self.ld.density with self.assertRaises(AttributeError): self.ld.num_neighbors with self.assertRaises(AttributeError): self.ld.box
def test_repr_png(self): rmax = 10.0 dr = 1.0 num_points = 10 box_size = rmax * 3.1 box, points = make_box_and_random_points(box_size, num_points) rdf = freud.density.RDF(rmax, dr) with self.assertRaises(AttributeError): rdf.plot() self.assertEqual(rdf._repr_png_(), None) rdf.accumulate(box, points) rdf._repr_png_()
def test_global(self): N = 1000 Nneigh = 4 lmax = 8 L = 10 box, positions = make_box_and_random_points(L, N) comp = freud.environment.LocalDescriptors(Nneigh, lmax, .5, True) comp.compute(box, Nneigh, positions, mode='global') sphs = comp.sph self.assertEqual(sphs.shape[0], N*Nneigh)