def test_barycentric(self): #2d test simplex1 = np.array([[0.3, 0.1], [0.2, -1.2], [1.3, 2.3]]) pts1 = np.array([[0.6, 0.1], [1.3, 2.3], [0.5, 0.5], [.7, 1]]) output1 = barycentric_coords(pts1, simplex1) #do back conversion to cartesian o_dot_s = np.sum(output1[:, :, None] * simplex1[None, :, :], axis=1) self.assertTrue(np.allclose(pts1, o_dot_s)) #do 3d tests simplex2 = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0]]) pts2 = np.array([[0, 0, 1], [0, 0.5, 0.5], [1./3, 1./3, 1./3]]) output2 = barycentric_coords(pts2, simplex2) self.assertTrue(np.allclose(output2[1], [0.5, 0.5, 0, 0])) #do back conversion to cartesian o_dot_s = np.sum(output2[:, :, None] * simplex2[None, :, :], axis=1) self.assertTrue(np.allclose(pts2, o_dot_s)) #test single point self.assertTrue(np.allclose(output2[2], barycentric_coords(pts2[2], simplex2)))
def _voronoi_points(self, structure): """ returns the voronoi points for a structure. returns in the format of a list of lists, where the first index corresponds to the index of the site in the original structure that neighbors the point. I.e. simplices[0] is the list of points around the site structure[0] """ all_coords = self._fake_periodic(structure) logging.debug("Starting calculating Voronoi points") vt = VoronoiTess(all_coords) simplices = [] # only return the coordinates associated with the # points in the original structure for i, r in enumerate(vt.regions[: len(structure)]): points = [] for v in r: if self._interior: new_site = PeriodicSite("X", vt.vertices[v], structure.lattice, coords_are_cartesian=True) d = structure[i].distance(new_site) s_points = structure.get_neighbors_in_shell(new_site.coords, d, 0.01) s_points = map(lambda x: x[0].coords, s_points) # brute force check that point is in its polyhedron # (len(s_points) should usually be 4, except in high # symmetry cases) for simplex in itertools.combinations(s_points, 4): try: bcs = barycentric_coords(vt.vertices[v], np.array(simplex)) if np.min(bcs) > 0: points.append(vt.vertices[v]) break except np.linalg.LinAlgError as err: if "Singular matrix" not in err.message: raise else: points.append(vt.vertices[v]) simplices.append(points) logging.debug("Finished calculating Voronoi points") return simplices