def test_get_symmetry_operations(self): fracsymmops = self.sg.get_symmetry_operations() symmops = self.sg.get_symmetry_operations(True) self.assertEqual(len(symmops), 8) latt = self.structure.lattice for fop, op in zip(fracsymmops, symmops): for site in self.structure: newfrac = fop.operate(site.frac_coords) newcart = op.operate(site.coords) self.assertTrue(np.allclose(latt.get_fractional_coords(newcart), newfrac)) found = False newsite = PeriodicSite(site.species_and_occu, newcart, latt, coords_are_cartesian=True) for testsite in self.structure: if newsite.is_periodic_image(testsite, 1e-3): found = True break self.assertTrue(found)
def get_primitive_standard_structure(self): """ Gives a structure with a primitive cell according to certain standards the standards are defined in Setyawan, W., & Curtarolo, S. (2010). High-throughput electronic band structure calculations: Challenges and tools. Computational Materials Science, 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010 Returns: The structure in a primitive standardized cell """ conv = self.get_conventional_standard_structure() lattice = self.get_lattice_type() if "P" in self.get_spacegroup_symbol() or lattice == "hexagonal": return conv if lattice == "rhombohedral": conv = self.get_refined_structure() lengths, angles = conv.lattice.lengths_and_angles a = lengths[0] alpha = math.pi * angles[0] / 180 new_matrix = [ [a * cos(alpha / 2), -a * sin(alpha / 2), 0], [a * cos(alpha / 2), a * sin(alpha / 2), 0], [a * cos(alpha) / cos(alpha / 2), 0, a * math.sqrt(1 - (cos(alpha) ** 2 / (cos(alpha / 2) ** 2)))]] new_sites = [] for s in conv.sites: new_s = PeriodicSite( s.specie, s.frac_coords, Lattice(new_matrix), to_unit_cell=True, properties=s.properties) unique = True for t in new_sites: if new_s.is_periodic_image(t): unique = False if unique: new_sites.append(new_s) return Structure.from_sites(new_sites) transf = np.eye(3) if "I" in self.get_spacegroup_symbol(): transf = np.array([[-1, 1, 1], [1, -1, 1], [1, 1, -1]], dtype=np.float) / 2 elif "F" in self.get_spacegroup_symbol(): transf = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]], dtype=np.float) / 2 elif "C" in self.get_spacegroup_symbol(): if self.get_crystal_system() == "monoclinic": transf = np.array([[1, 1, 0], [-1, 1, 0], [0, 0, 2]], dtype=np.float) / 2 else: transf = np.array([[1, -1, 0], [1, 1, 0], [0, 0, 2]], dtype=np.float) / 2 new_sites = [] for s in conv.sites: new_s = PeriodicSite( s.specie, s.coords, Lattice(np.dot(transf, conv.lattice.matrix)), to_unit_cell=True, coords_are_cartesian=True, properties=s.properties) unique = True for t in new_sites: if new_s.is_periodic_image(t): unique = False if unique: new_sites.append(new_s) return Structure.from_sites(new_sites)
class PeriodicSiteTest(unittest.TestCase): def setUp(self): self.lattice = Lattice.cubic(10.0) self.si = Element("Si") self.site = PeriodicSite("Fe", np.array([0.25, 0.35, 0.45]), self.lattice) self.site2 = PeriodicSite({"Si":0.5}, np.array([0, 0, 0]), self.lattice) self.assertEquals(self.site2.species_and_occu, {Element('Si'): 0.5}, "Inconsistent site created!") self.propertied_site = PeriodicSite(Specie("Fe", 2), [0.25, 0.35, 0.45], self.lattice, properties={'magmom':5.1, 'charge':4.2}) def test_properties(self): """ Test the properties for a site """ self.assertEquals(self.site.a, 0.25) self.assertEquals(self.site.b, 0.35) self.assertEquals(self.site.c, 0.45) self.assertEquals(self.site.x, 2.5) self.assertEquals(self.site.y, 3.5) self.assertEquals(self.site.z, 4.5) self.assertTrue(self.site.is_ordered) self.assertFalse(self.site2.is_ordered) self.assertEqual(self.propertied_site.magmom, 5.1) self.assertEqual(self.propertied_site.charge, 4.2) def test_distance(self): other_site = PeriodicSite("Fe", np.array([0, 0, 0]), self.lattice) self.assertAlmostEquals(self.site.distance(other_site), 6.22494979899, 5) def test_distance_from_point(self): self.assertNotAlmostEqual(self.site.distance_from_point(np.array([0.1, 0.1, 0.1])), 6.22494979899, 5) self.assertAlmostEqual(self.site.distance_from_point(np.array([0.1, 0.1, 0.1])), 6.0564015718906887, 5) def test_distance_and_image(self): other_site = PeriodicSite("Fe", np.array([1, 1, 1]), self.lattice) (distance, image) = self.site.distance_and_image(other_site) self.assertAlmostEquals(distance, 6.22494979899, 5) self.assertTrue(([-1, -1, -1] == image).all()) (distance, image) = self.site.distance_and_image(other_site, [1, 0, 0]) self.assertAlmostEquals(distance, 19.461500456028563, 5) # Test that old and new distance algo give the same ans for "standard lattices" lattice = Lattice(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])) site1 = PeriodicSite("Fe", np.array([0.01, 0.02, 0.03]), lattice) site2 = PeriodicSite("Fe", np.array([0.99, 0.98, 0.97]), lattice) self.assertTrue(site1.distance_and_image_old(site2)[0] == site1.distance_and_image(site2)[0]) lattice = Lattice.from_parameters(1, 0.01, 1, 10, 10, 10) site1 = PeriodicSite("Fe", np.array([0.01, 0.02, 0.03]), lattice) site2 = PeriodicSite("Fe", np.array([0.99, 0.98, 0.97]), lattice) self.assertTrue(site1.distance_and_image_old(site2)[0] > site1.distance_and_image(site2)[0]) site2 = PeriodicSite("Fe", np.random.rand(3), lattice) (dist_old, jimage_old) = site1.distance_and_image_old(site2) (dist_new, jimage_new) = site1.distance_and_image(site2) self.assertTrue(dist_old >= dist_new, "New distance algo should always give smaller answers!") self.assertFalse((dist_old == dist_new) ^ (jimage_old == jimage_new).all(), "If old dist == new dist, the images returned must be the same!") def test_is_periodic_image(self): other = PeriodicSite("Fe", np.array([1.25, 2.35, 4.45]), self.lattice) self.assertTrue(self.site.is_periodic_image(other), "This other site should be a periodic image.") other = PeriodicSite("Fe", np.array([1.25, 2.35, 4.46]), self.lattice) self.assertFalse(self.site.is_periodic_image(other), "This other site should not be a periodic image.") other = PeriodicSite("Fe", np.array([1.25, 2.35, 4.45]), Lattice.rhombohedral(2)) self.assertFalse(self.site.is_periodic_image(other), "Different lattices should result in different periodic sites.") def test_equality(self): other_site = PeriodicSite("Fe", np.array([1, 1, 1]), self.lattice) self.assertTrue(self.site.__eq__(self.site)) self.assertFalse(other_site.__eq__(self.site)) self.assertFalse(self.site.__ne__(self.site)) self.assertTrue(other_site.__ne__(self.site)) def test_to_from_dict(self): d = self.site2.to_dict site = PeriodicSite.from_dict(d) self.assertEqual(site, self.site2) self.assertNotEqual(site, self.site) d = self.propertied_site.to_dict site = Site.from_dict(d) self.assertEqual(site.magmom, 5.1) self.assertEqual(site.charge, 4.2)