def test_identical_environments_ql_near(self): box, positions = freud.data.UnitCell.fcc().generate_system(4) r_max = 1.5 n = 12 test_set = util.make_raw_query_nlist_test_set(box, positions, positions, 'nearest', r_max, n, True) for nq, neighbors in test_set: comp = freud.order.Steinhardt(6) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_Q6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) self.assertAlmostEqual(comp.order, PERFECT_FCC_Q6, delta=1e-5) comp = freud.order.Steinhardt(6, average=True) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_Q6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) self.assertAlmostEqual(comp.order, PERFECT_FCC_Q6, delta=1e-5) # Perturb one position perturbed_positions = positions.copy() perturbed_positions[-1] += [0.1, 0, 0] test_set = util.make_raw_query_nlist_test_set(box, perturbed_positions, perturbed_positions, 'nearest', r_max, n, True) # Ensure exactly 13 values change for the perturbed system for nq, neighbors in test_set: comp = freud.order.Steinhardt(6) comp.compute(nq, neighbors=neighbors) self.assertEqual( sum(~np.isclose(comp.ql, PERFECT_FCC_Q6, rtol=1e-6)), 13) # More than 13 particles should change for # ql averaged over neighbors comp = freud.order.Steinhardt(6, average=True) comp.compute(nq, neighbors=neighbors) self.assertGreater( sum(~np.isclose(comp.particle_order, PERFECT_FCC_Q6, rtol=1e-6) ), 13)
def test_simple(self): box = freud.box.Box.square(10) # make a square grid xs = np.linspace(-box.Lx / 2, box.Lx / 2, 10, endpoint=False) positions = np.zeros((len(xs)**2, 3), dtype=np.float32) positions[:, :2] = np.array(list(itertools.product(xs, xs)), dtype=np.float32) r_max = 1.1 n = 4 with pytest.warns(FreudDeprecationWarning): trans = freud.order.Translational(4) # Test access with pytest.raises(AttributeError): trans.particle_order test_set = util.make_raw_query_nlist_test_set(box, positions, positions, "nearest", r_max, n, True) for nq, neighbors in test_set: trans.compute(nq, neighbors=neighbors) # Test access trans.particle_order npt.assert_allclose(trans.particle_order, 0, atol=1e-6)
def test_points_ne_query_points(self): lattice_size = 10 # big box to ignore periodicity box = freud.box.Box.square(lattice_size * 5) angle = np.pi / 30 query_points, points = util.make_alternating_lattice(lattice_size, angle) r_max = 1.6 num_neighbors = 12 n_bins_theta = 30 n_bins_phi = 2 test_set = util.make_raw_query_nlist_test_set( box, points, query_points, "nearest", r_max, num_neighbors, False ) for nq, neighbors in test_set: bod = freud.environment.BondOrder(bins=(n_bins_theta, n_bins_phi)) # orientations are not used in bod mode orientations = np.array([[1, 0, 0, 0]] * len(points)) query_orientations = np.array([[1, 0, 0, 0]] * len(query_points)) bod.compute( nq, orientations, query_points, query_orientations, neighbors=neighbors ) # we want to make sure that we get 12 nonzero places, so we can # test whether we are not considering neighbors between points assert np.count_nonzero(bod.bond_order) == 12 assert len(np.unique(bod.bond_order)) == 2
def test_identical_environments_wl_near(self): box, positions = freud.data.UnitCell.fcc().generate_system(4) r_max = 1.5 n = 12 test_set = util.make_raw_query_nlist_test_set(box, positions, positions, "nearest", r_max, n, True) for nq, neighbors in test_set: comp = freud.order.Steinhardt(6, wl=True) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_W6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) assert abs(comp.order - PERFECT_FCC_W6) < 1e-5 comp = freud.order.Steinhardt(6, wl=True, average=True) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_W6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) assert abs(comp.order - PERFECT_FCC_W6) < 1e-5
def test_identical_environments_ql(self): box, positions = freud.data.UnitCell.fcc().generate_system(4, scale=2) r_max = 1.5 test_set = util.make_raw_query_nlist_test_set(box, positions, positions, 'ball', r_max, 0, True) for nq, neighbors in test_set: comp = freud.order.Steinhardt(6) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_Q6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) self.assertAlmostEqual(comp.order, PERFECT_FCC_Q6, delta=1e-5) comp = freud.order.Steinhardt(6, average=True) comp.compute(nq, neighbors=neighbors) npt.assert_allclose(np.average(comp.particle_order), PERFECT_FCC_Q6, atol=1e-5) npt.assert_allclose(comp.particle_order, comp.particle_order[0], atol=1e-5) self.assertAlmostEqual(comp.order, PERFECT_FCC_Q6, delta=1e-5)
def test_points_ne_query_points_complex(self): # Helper function to give complex number representation of a point def value_func(_p): return _p[0] + 1j * _p[1] r_max = 10.0 bins = 100 dr = r_max / bins box_size = r_max * 5 box = freud.box.Box.square(box_size) ocf = freud.density.CorrelationFunction(bins, r_max) query_points = [] query_values = [] N = 300 # We are essentially generating all n-th roots of unity # scalar multiplied by the each bin centers # with the value of a point being its complex number representation. # Therefore, the correlation should be uniformly zero # since the roots of unity add up to zero, if we set our ref_point in # the origin. # Nice proof for this fact is that when the n-th roots of unity # are viewed as vectors, we can draw a regular n-gon # so that we start at the origin and come back to origin. for r in ocf.bin_centers: for k in range(N): point = [ r * np.cos(2 * np.pi * k / N), r * np.sin(2 * np.pi * k / N), 0, ] query_points.append(point) query_values.append(value_func(point)) supposed_correlation = np.zeros(ocf.bin_centers.shape) # points are within distances closer than dr, so their impact on # the result should be minimal. points = [[dr / 4, 0, 0], [-dr / 4, 0, 0], [0, dr / 4, 0], [0, -dr / 4, 0]] test_set = util.make_raw_query_nlist_test_set(box, points, query_points, "ball", r_max, 0, False) for nq, neighbors in test_set: ocf = freud.density.CorrelationFunction(bins, r_max) # try for different scalar values. for rv in [0, 1, 2, 7]: values = [rv] * 4 ocf.compute(nq, values, query_points, query_values, neighbors=neighbors) correct = supposed_correlation npt.assert_allclose(ocf.correlation, correct, atol=1e-6)
def test_compute(self): boxlen = 10 r_max = 3 box = freud.box.Box.square(boxlen) points = [[0.0, 0.0, 0.0]] for i in range(6): points.append([ np.cos(float(i) * 2.0 * np.pi / 6.0), np.sin(float(i) * 2.0 * np.pi / 6.0), 0.0 ]) points = np.asarray(points, dtype=np.float32) points[:, 2] = 0.0 hop = freud.order.Hexatic() # Test access hop.k with self.assertRaises(AttributeError): hop.particle_order test_set = util.make_raw_query_nlist_test_set(box, points, points, 'nearest', r_max, 6, True) for nq, neighbors in test_set: hop.compute(nq, neighbors=neighbors) # Test access hop.k hop.particle_order npt.assert_allclose(hop.particle_order[0], 1. + 0.j, atol=1e-1)
def test_two_particles(self): (box, points), orientations = self.make_two_particle_system() correct_bin_counts = np.zeros(self.bins, dtype=np.int32) correct_bin_counts[self.get_bin(points[0], points[1], orientations[0], orientations[1])] = 1 correct_bin_counts[self.get_bin(points[1], points[0], orientations[1], orientations[0])] = 1 absoluteTolerance = 0.1 # No angular terms should have entries in the limits array, so this # should work in all cases. r_max = np.linalg.norm(self.limits) test_set = util.make_raw_query_nlist_test_set(box, points, points, "ball", r_max, 0, True) for nq, neighbors in test_set: pmft = self.make_pmft() pmft.compute(nq, orientations, neighbors=neighbors, reset=False) npt.assert_allclose(pmft.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test with resetting. pmft.compute(nq, orientations, neighbors=neighbors) npt.assert_allclose(pmft.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test with angles. pmft.compute(nq, rowan.geometry.angle(orientations), neighbors=neighbors) npt.assert_allclose(pmft.bin_counts, correct_bin_counts, atol=absoluteTolerance)
def test_points_ne_query_points(self): r_max = 2.3 nbins = 10 lattice_size = 10 box = freud.box.Box.square(lattice_size * 5) points, query_points = util.make_alternating_lattice( lattice_size, 0.01, 2) orientations = np.array([0] * len(points)) query_orientations = np.array([0] * len(query_points)) test_set = util.make_raw_query_nlist_test_set(box, points, query_points, "ball", r_max, 0, False) for nq, neighbors in test_set: pmft = freud.pmft.PMFTR12(r_max, nbins) pmft.compute(nq, orientations, query_points, query_orientations, neighbors=neighbors) assert np.count_nonzero(np.isinf(pmft.pmft) == 0) == 12 assert len(np.unique(pmft.pmft)) == 3
def test_points_ne_query_points(self): x_max = 2.5 y_max = 2.5 n_x = 10 n_y = 10 n_t = 4 lattice_size = 10 box = freud.box.Box.square(lattice_size * 5) points, query_points = util.make_alternating_lattice( lattice_size, 0.01, 2) orientations = np.array([0] * len(points)) query_orientations = np.array([0] * len(query_points)) r_max = np.sqrt(x_max**2 + y_max**2) test_set = util.make_raw_query_nlist_test_set(box, points, query_points, "ball", r_max, 0, False) for nq, neighbors in test_set: pmft = freud.pmft.PMFTXYT(x_max, y_max, (n_x, n_y, n_t)) pmft.compute(nq, orientations, query_points, query_orientations, neighbors=neighbors) # when rotated slightly, for each ref point, each quadrant # (corresponding to two consecutive bins) should contain 3 points. for i in range(n_t): assert np.count_nonzero(np.isinf(pmft.pmft[..., i]) == 0) == 3 assert len(np.unique(pmft.pmft)) == 2
def test_random_points_complex(self): r_max = 10.0 bins = 10 num_points = 1000 box_size = r_max*3.1 box, points = freud.data.make_random_system( box_size, num_points, is2D=True) ang = np.random.random_sample((num_points)).astype(np.float64) \ * 2.0 * np.pi comp = np.exp(1j*ang) correct = np.zeros(bins, dtype=np.complex64) absolute_tolerance = 0.1 # first bin is bad test_set = util.make_raw_query_nlist_test_set( box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: ocf = freud.density.CorrelationFunction(bins, r_max) ocf.compute(nq, comp, neighbors=neighbors) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) self.assertEqual(box, ocf.box) # Test setting that the reset flag works as expected. ocf.compute(nq, comp, neighbors=neighbors, reset=False) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) ocf.compute(nq, comp, neighbors=neighbors) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance)
def test_random_points_real(self): r_max = 10.0 bins = 10 num_points = 1000 box_size = r_max*3.1 box, points = freud.data.make_random_system( box_size, num_points, is2D=True) ang = np.random.random_sample((num_points)).astype(np.float64) - 0.5 correct = np.zeros(bins, dtype=np.float64) absolute_tolerance = 0.1 # first bin is bad test_set = util.make_raw_query_nlist_test_set( box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: ocf = freud.density.CorrelationFunction(bins, r_max) ocf.compute(nq, ang, neighbors=neighbors, reset=False) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) ocf.compute(nq, ang, neighbors=neighbors) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) ocf.compute(nq, ang, points, ang, neighbors=neighbors, reset=False) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) ocf.compute(nq, ang, query_values=ang, neighbors=neighbors, reset=False) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) ocf.compute(nq, ang, neighbors=neighbors) npt.assert_allclose(ocf.correlation, correct, atol=absolute_tolerance) self.assertEqual(freud.box.Box.square(box_size), ocf.box)
def test_cluster_props(self): Nlattice = 4 Nrep = 5 np.random.seed(0) positions = [] for _ in range(Nrep): (box, pos) = freud.data.UnitCell.fcc().generate_system( Nlattice, sigma_noise=1e-2 ) positions.append(pos) positions = np.array(positions).reshape((-1, 3)) clust = freud.cluster.Cluster() # Test protected attribute access with pytest.raises(AttributeError): clust.num_clusters with pytest.raises(AttributeError): clust.num_particles with pytest.raises(AttributeError): clust.cluster_idx # Test with explicit box provided clust.compute((box, positions), neighbors={"r_max": 0.5}) idx = np.copy(clust.cluster_idx) test_set = util.make_raw_query_nlist_test_set( box, positions, positions, "ball", 0.5, 0, True ) for nq, neighbors in test_set: clust.compute(nq, neighbors=neighbors) assert np.all(clust.cluster_idx == idx) # Test if attributes are accessible now clust.num_clusters clust.cluster_idx # Test all property APIs props = freud.cluster.ClusterProperties() # Test protected attribute access with pytest.raises(AttributeError): props.num_clusters with pytest.raises(AttributeError): props.centers with pytest.raises(AttributeError): props.gyrations with pytest.raises(AttributeError): props.sizes props.compute((box, positions), clust.cluster_idx) # Test if attributes are accessible now props.centers props.gyrations props.sizes assert np.all(props.sizes == Nrep)
def test_two_particles(self): boxSize = 16.0 box = freud.box.Box.square(boxSize) points = np.array([[-1.0, 0.0, 0.0], [1.0, 0.1, 0.0]], dtype=np.float32) angles = np.array([0.0, np.pi / 2], dtype=np.float32) maxX = 3.6 maxY = 4.2 nbinsX = 20 nbinsY = 30 nbinsT = 40 dx = (2.0 * maxX / float(nbinsX)) dy = (2.0 * maxY / float(nbinsY)) dT = (2.0 * np.pi / float(nbinsT)) # calculation for array idxs def get_bin(query_point, point, query_point_angle, point_angle): r_ij = point - query_point orientation = rowan.from_axis_angle([0, 0, 1], -point_angle) rot_r_ij = rowan.rotate(orientation, r_ij) xy_bins = np.floor( (rot_r_ij[:2] + [maxX, maxY]) / [dx, dy]).astype(np.int32) angle_bin = np.floor( ((query_point_angle - np.arctan2(-r_ij[1], -r_ij[0])) % (2. * np.pi)) / dT).astype(np.int32) return [xy_bins[0], xy_bins[1], angle_bin] correct_bin_counts = np.zeros(shape=(nbinsX, nbinsY, nbinsT), dtype=np.int32) bins = get_bin(points[0], points[1], angles[0], angles[1]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 bins = get_bin(points[1], points[0], angles[1], angles[0]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 absoluteTolerance = 0.1 r_max = np.sqrt(maxX**2 + maxY**2) test_set = util.make_raw_query_nlist_test_set(box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: myPMFT = freud.pmft.PMFTXYT(maxX, maxY, (nbinsX, nbinsY, nbinsT)) myPMFT.compute(nq, angles, neighbors=neighbors, reset=False) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance)
def test_two_particles(self): boxSize = 16.0 box = freud.box.Box.square(boxSize) points = np.array([[-1.0, 0.0, 0.0], [1.0, 0.1, 0.0]], dtype=np.float32) points.flags['WRITEABLE'] = False angles = np.array([0.0, np.pi / 2], dtype=np.float32) angles.flags['WRITEABLE'] = False maxR = 5.23 nbinsR = 10 nbinsT1 = 20 nbinsT2 = 30 dr = (maxR / float(nbinsR)) dT1 = (2.0 * np.pi / float(nbinsT1)) dT2 = (2.0 * np.pi / float(nbinsT2)) # calculation for array idxs def get_bin(query_point, point, query_point_angle, point_angle): r_ij = point - query_point r_bin = np.floor(np.linalg.norm(r_ij) / dr) delta_t1 = np.arctan2(r_ij[1], r_ij[0]) delta_t2 = np.arctan2(-r_ij[1], -r_ij[0]) t1_bin = np.floor(((point_angle - delta_t1) % (2. * np.pi)) / dT1) t2_bin = np.floor( ((query_point_angle - delta_t2) % (2. * np.pi)) / dT2) return np.array([r_bin, t1_bin, t2_bin], dtype=np.int32) correct_bin_counts = np.zeros(shape=(nbinsR, nbinsT1, nbinsT2), dtype=np.int32) bins = get_bin(points[0], points[1], angles[0], angles[1]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 bins = get_bin(points[1], points[0], angles[1], angles[0]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 absoluteTolerance = 0.1 r_max = maxR test_set = util.make_raw_query_nlist_test_set(box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: myPMFT = freud.pmft.PMFTR12(maxR, (nbinsR, nbinsT1, nbinsT2)) myPMFT.compute(nq, angles, neighbors=neighbors, reset=False) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance)
def test_points_ne_query_points_real(self): def value_func(_r): return np.sin(_r) r_max = 10.0 bins = 100 dr = r_max / bins box_size = r_max * 5 box = freud.box.Box.square(box_size) ocf = freud.density.CorrelationFunction(bins, r_max) query_points = [] query_values = [] supposed_correlation = [] N = 300 # We are generating the values so that they are sine wave from 0 to 2pi # rotated around z axis. Therefore, the correlation should be a scalar # multiple sin if we set our ref_point to be in the origin. for r in ocf.bin_centers: for k in range(N): query_points.append([ r * np.cos(2 * np.pi * k / N), r * np.sin(2 * np.pi * k / N), 0 ]) query_values.append(value_func(r)) supposed_correlation.append(value_func(r)) supposed_correlation = np.array(supposed_correlation) # points are within distances closer than dr, so their impact on # the result should be minimal. points = [[dr / 4, 0, 0], [-dr / 4, 0, 0], [0, dr / 4, 0], [0, -dr / 4, 0]] test_set = util.make_raw_query_nlist_test_set(box, points, query_points, "ball", r_max, 0, False) for nq, neighbors in test_set: ocf = freud.density.CorrelationFunction(bins, r_max) # try for different scalar values. for rv in [0, 1, 2, 7]: values = [rv] * 4 ocf.compute(nq, values, query_points, query_values, neighbors=neighbors) correct = supposed_correlation * rv npt.assert_allclose(ocf.correlation, correct, atol=1e-6)
def test_weighted(self): box, positions = freud.data.UnitCell.fcc().generate_system(4) r_max = 1.5 n = 12 test_set = util.make_raw_query_nlist_test_set( box, positions, positions, "nearest", r_max, n, True ) # Skip test sets without an explicit neighbor list for nq, neighbors in filter( lambda ts: type(ts[1]) == freud.locality.NeighborList, test_set ): nlist = neighbors for wt in [0, 0.1, 0.9, 1.1, 10, 1e6]: # Change the weight of the first bond for each particle weights = nlist.weights.copy() weights[nlist.segments] = wt weighted_nlist = freud.locality.NeighborList.from_arrays( len(positions), len(positions), nlist.query_point_indices, nlist.point_indices, nlist.distances, weights, ) comp = freud.order.Steinhardt(6, weighted=True) comp.compute(nq, neighbors=weighted_nlist) # Unequal neighbor weighting in a perfect FCC structure # appears to increase the Q6 order parameter npt.assert_array_less(PERFECT_FCC_Q6, comp.particle_order) npt.assert_allclose( comp.particle_order, comp.particle_order[0], atol=1e-5 ) npt.assert_array_less(PERFECT_FCC_Q6, comp.order) # Ensure that W6 values are altered by changing the weights comp = freud.order.Steinhardt(6, wl=True, weighted=True) comp.compute(nq, neighbors=weighted_nlist) with pytest.raises(AssertionError): npt.assert_allclose( np.average(comp.particle_order), PERFECT_FCC_W6, rtol=1e-5 ) with pytest.raises(AssertionError): npt.assert_allclose(comp.order, PERFECT_FCC_W6, rtol=1e-5)
def test_alternating_points(self): lattice_size = 10 # big box to ignore periodicity box = freud.box.Box.square(lattice_size * 5) query_points, points = util.make_alternating_lattice(lattice_size) r_max = 1.6 num_neighbors = 12 test_set = util.make_raw_query_nlist_test_set( box, points, query_points, "nearest", r_max, num_neighbors, False ) nlist = test_set[-1][1] for nq, neighbors in test_set: if not isinstance(nq, freud.locality.NeighborQuery): continue check_nlist = nq.query(query_points, neighbors).toNeighborList() assert nlist_equal(nlist, check_nlist)
def test_two_particles(self): boxSize = 16.0 box = freud.box.Box.square(boxSize) points = np.array([[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]], dtype=np.float32) angles = np.array([0.0, 0.0], dtype=np.float32) maxX = 3.6 maxY = 4.2 nbinsX = 100 nbinsY = 110 dx = (2.0 * maxX / float(nbinsX)) dy = (2.0 * maxY / float(nbinsY)) correct_bin_counts = np.zeros(shape=(nbinsX, nbinsY), dtype=np.int32) # calculation for array idxs def get_bin(query_point, point): return np.floor((query_point - point + [maxX, maxY, 0]) / [dx, dy, 1]).astype(np.int32)[:2] bins = get_bin(points[0], points[1]) correct_bin_counts[bins[0], bins[1]] = 1 bins = get_bin(points[1], points[0]) correct_bin_counts[bins[0], bins[1]] = 1 absoluteTolerance = 0.1 r_max = np.sqrt(maxX**2 + maxY**2) test_set = util.make_raw_query_nlist_test_set(box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: myPMFT = freud.pmft.PMFTXY(maxX, maxY, (nbinsX, nbinsY)) myPMFT.compute(nq, angles, neighbors=neighbors, reset=False) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, angles, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance)
def test_density(self): """Test that LocalDensity computes the correct density at each point""" r_max = self.r_max + 0.5 * self.diameter test_set = util.make_raw_query_nlist_test_set( self.box, self.pos, self.pos, "ball", r_max, 0, True ) for nq, neighbors in test_set: self.ld.compute(nq, neighbors=neighbors) # Test attribute access after calling compute self.ld.density self.ld.num_neighbors self.ld.box assert self.ld.box == freud.box.Box.cube(10) npt.assert_array_less(np.fabs(self.ld.density - 10.0), 1.5) npt.assert_array_less(np.fabs(self.ld.num_neighbors - 1130.973355292), 200)
def test_two_particles(self): """Override base class function to test equivalent orientations.""" (box, points), orientations = self.make_two_particle_system() correct_bin_counts = np.zeros(self.bins, dtype=np.int32) correct_bin_counts[self.get_bin(points[0], points[1], orientations[0], orientations[1])] = 1 correct_bin_counts[self.get_bin(points[1], points[0], orientations[1], orientations[0])] = 1 absoluteTolerance = 0.1 # No angular terms should have entries in the limits array, so this # should work in all cases. r_max = np.linalg.norm(self.limits) test_set = util.make_raw_query_nlist_test_set(box, points, points, "ball", r_max, 0, True) for nq, neighbors in test_set: pmft = self.make_pmft() pmft.compute(nq, orientations, neighbors=neighbors, reset=False) npt.assert_allclose(pmft.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test with resetting. pmft.compute(nq, orientations, neighbors=neighbors) npt.assert_allclose(pmft.bin_counts, correct_bin_counts, atol=absoluteTolerance) orig_pmft = pmft.pmft # Test with equivalent orientations. pmft.compute( nq, orientations, neighbors=neighbors, equiv_orientations=[[1, 0, 0, 0]] * 2, ) npt.assert_allclose(pmft.bin_counts, 2 * correct_bin_counts, atol=absoluteTolerance) npt.assert_allclose(pmft.pmft, orig_pmft, atol=absoluteTolerance)
def test_random_point(self): r_max = 10.0 bins = 10 num_points = 10000 tolerance = 0.1 box_size = r_max * 3.1 for i, r_min in enumerate([0, 0.05, 0.1, 1.0, 3.0]): box, points = freud.data.make_random_system(box_size, num_points) test_set = util.make_raw_query_nlist_test_set( box, points, points, "ball", r_max, 0, True) for nq, neighbors in test_set: rdf = freud.density.RDF(bins, r_max, r_min) if i < 3: rdf.compute(nq, neighbors=neighbors, reset=False) else: rdf.compute(nq, neighbors=neighbors) assert rdf.box == box correct = np.ones(bins, dtype=np.float32) npt.assert_allclose(rdf.rdf, correct, atol=tolerance) # Numerical integration to compute the running coordination # number will be highly inaccurate, so we can only test up to # a limited precision. Also, since dealing with nonzero r_min # values requires extrapolation, we only test when r_min=0. ndens = points.shape[0] / box.volume dr = (r_max - r_min) / bins bin_boundaries = np.array([ r_min + dr * i for i in range(bins + 1) if r_min + dr * i <= r_max ]) bin_volumes = 4 / 3 * np.pi * np.diff(bin_boundaries**3) avg_counts = rdf.rdf * ndens * bin_volumes npt.assert_allclose(rdf.n_r, np.cumsum(avg_counts), rtol=tolerance)
def test_points_ne_query_points(self): r_max = 100.0 bins = 100 box_size = r_max * 5 box = freud.box.Box.square(box_size) rdf = freud.density.RDF(bins, r_max) query_points = [] supposed_RDF = [0] N = 100 # With points closely centered around the origin, # the cumulative average bin counts should be same as # having a single point at the origin. # Also, we can check for whether points are not considered against # each other. dr = r_max / bins points = [[dr / 4, 0, 0], [-dr / 4, 0, 0], [0, dr / 4, 0], [0, -dr / 4, 0]] for r in rdf.bin_centers: for k in range(N): query_points.append([ r * np.cos(2 * np.pi * k / N), r * np.sin(2 * np.pi * k / N), 0 ]) supposed_RDF.append(supposed_RDF[-1] + N) supposed_RDF = np.array(supposed_RDF[1:]) test_set = util.make_raw_query_nlist_test_set(box, points, query_points, "ball", r_max, 0, False) for nq, neighbors in test_set: rdf = freud.density.RDF(bins, r_max) rdf.compute(nq, query_points, neighbors=neighbors) npt.assert_allclose(rdf.n_r, supposed_RDF, atol=1e-6)
def test_points_ne_query_points(self): x_max = 2.5 y_max = 2.5 nbins = 20 lattice_size = 10 box = freud.box.Box.square(lattice_size * 5) points, query_points = util.make_alternating_lattice( lattice_size, 0.01, 2) query_orientations = np.array([0] * len(query_points)) r_max = np.sqrt(x_max**2 + y_max**2) test_set = util.make_raw_query_nlist_test_set(box, points, query_points, 'ball', r_max, 0, False) for nq, neighbors in test_set: pmft = freud.pmft.PMFTXY(x_max, y_max, nbins) pmft.compute(nq, query_orientations, query_points, neighbors) self.assertEqual(np.count_nonzero(np.isinf(pmft.pmft) == 0), 12) self.assertEqual(len(np.unique(pmft.pmft)), 2)
def test_two_particles(self): boxSize = 25.0 box = freud.box.Box.cube(boxSize) points = np.array([[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]], dtype=np.float32) query_orientations = np.array([[1, 0, 0, 0], [1, 0, 0, 0]], dtype=np.float32) maxX = 5.23 maxY = 6.23 maxZ = 7.23 nbinsX = 100 nbinsY = 110 nbinsZ = 120 dx = (2.0 * maxX / float(nbinsX)) dy = (2.0 * maxY / float(nbinsY)) dz = (2.0 * maxZ / float(nbinsZ)) correct_bin_counts = np.zeros(shape=(nbinsX, nbinsY, nbinsZ), dtype=np.int32) # calculation for array idxs def get_bin(query_point, point): return np.floor((query_point - point + [maxX, maxY, maxZ]) / [dx, dy, dz]).astype(np.int32) bins = get_bin(points[0], points[1]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 bins = get_bin(points[1], points[0]) correct_bin_counts[bins[0], bins[1], bins[2]] = 1 absoluteTolerance = 0.1 r_max = np.sqrt(maxX**2 + maxY**2 + maxZ**2) test_set = util.make_raw_query_nlist_test_set(box, points, points, 'ball', r_max, 0, True) for nq, neighbors in test_set: myPMFT = freud.pmft.PMFTXYZ(maxX, maxY, maxZ, (nbinsX, nbinsY, nbinsZ)) myPMFT.compute(nq, query_orientations, neighbors=neighbors, reset=False) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, query_orientations, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test face_orientations, shape (N_faces, 4) face_orientations = np.array([[1., 0., 0., 0.]]) myPMFT.compute(nq, query_orientations, neighbors=neighbors, face_orientations=face_orientations) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test face_orientations, shape (1, N_faces, 4) face_orientations = np.array([[[1., 0., 0., 0.]]]) myPMFT.compute(nq, query_orientations, neighbors=neighbors, face_orientations=face_orientations) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) # Test face_orientations, shape (N_particles, N_faces, 4) face_orientations = np.array([[[1., 0., 0., 0.]], [[1., 0., 0., 0.]]]) myPMFT.compute(nq, query_orientations, neighbors=neighbors, face_orientations=face_orientations) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance) myPMFT.compute(nq, query_orientations, neighbors=neighbors) npt.assert_allclose(myPMFT.bin_counts, correct_bin_counts, atol=absoluteTolerance)
def test_bond_order(self): """Test the bond order diagram calculation.""" box, positions = freud.data.UnitCell.fcc().generate_system(4) quats = np.array([[1, 0, 0, 0]] * len(positions)) r_max = 1.5 num_neighbors = 12 n_bins_theta = n_bins_phi = nbins = 6 bo = freud.environment.BondOrder(nbins) # Test access with pytest.raises(AttributeError): bo.box with pytest.raises(AttributeError): bo.bond_order # Test that there are exactly 12 non-zero bins for a perfect FCC # structure. bo.compute( (box, positions), quats, neighbors={"num_neighbors": num_neighbors, "r_max": r_max}, ) op_value = bo.bond_order.copy() assert np.sum(op_value > 0) == 12 # Test access bo.box bo.bond_order # Test all the basic attributes. assert bo.nbins[0] == n_bins_theta assert bo.nbins[1] == n_bins_phi assert bo.box == box assert np.allclose( bo.bin_centers[0], (2 * np.arange(n_bins_theta) + 1) * np.pi / n_bins_theta ) assert np.allclose( bo.bin_centers[1], (2 * np.arange(n_bins_phi) + 1) * np.pi / (n_bins_phi * 2), ) test_set = util.make_raw_query_nlist_test_set( box, positions, positions, "nearest", r_max, num_neighbors, True ) for nq, neighbors in test_set: # Test that lbod gives identical results when orientations are the # same. # TODO: Find a way to test a rotated system to ensure that lbod gives # the desired results. bo = freud.environment.BondOrder(nbins, mode="lbod") bo.compute(nq, quats, neighbors=neighbors, reset=False) assert np.allclose(bo.bond_order, op_value) # Test access bo.box bo.bond_order # Test that obcd gives identical results when orientations are the # same. bo = freud.environment.BondOrder(nbins, mode="obcd") bo.compute(nq, quats, neighbors=neighbors) assert np.allclose(bo.bond_order, op_value) # Test that normal bod looks ordered for randomized orientations. np.random.seed(10893) random_quats = rowan.random.rand(len(positions)) bo = freud.environment.BondOrder(nbins) bo.compute(nq, random_quats, neighbors=neighbors) assert np.allclose(bo.bond_order, op_value) # Ensure that obcd looks random for the randomized orientations. bo = freud.environment.BondOrder(nbins, mode="obcd") bo.compute(nq, random_quats, neighbors=neighbors) assert not np.allclose(bo.bond_order, op_value) assert np.sum(bo.bond_order > 0) == bo.bond_order.size # Test that oocd shows exactly one peak when all orientations # are the same. bo = freud.environment.BondOrder(nbins, mode="oocd") bo.compute(nq, quats, neighbors=neighbors, reset=False) assert np.sum(bo.bond_order > 0) == 1 assert bo.bond_order[0, 0] > 0 # Test that oocd is highly disordered with random quaternions. In # practice, the edge bins may still not get any values, so just # check that we get a lot of values. bo = freud.environment.BondOrder(nbins, mode="oocd") bo.compute(nq, random_quats, neighbors=neighbors) assert np.sum(bo.bond_order > 0) > 30