Esempio n. 1
0
    def test_get_symmetry_operations(self):
        for sg, structure in [(self.sg, self.structure),
                              (self.sg4, self.structure4)]:

            pgops = sg.get_point_group_operations()
            fracsymmops = sg.get_symmetry_operations()
            symmops = sg.get_symmetry_operations(True)
            latt = structure.lattice
            for fop, op, pgop in zip(fracsymmops, symmops, pgops):
                self.assertArrayAlmostEqual(fop.rotation_matrix,
                                            pgop.rotation_matrix)
                for site in 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 structure:
                        if newsite.is_periodic_image(testsite, 1e-3):
                            found = True
                            break
                    self.assertTrue(found)

                # Make sure this works for any position, not just the atomic
                # ones.
                random_fcoord = np.random.uniform(size=(3))
                random_ccoord = latt.get_cartesian_coords(random_fcoord)
                newfrac = fop.operate(random_fcoord)
                newcart = op.operate(random_ccoord)
                self.assertTrue(np.allclose(latt.get_fractional_coords(newcart),
                                            newfrac))
Esempio n. 2
0
 def setUp(self):
     self.lattice = Lattice.cubic(10.0)
     self.si = Element("Si")
     self.site = PeriodicSite("Fe", [0.25, 0.35, 0.45], self.lattice)
     self.site2 = PeriodicSite({"Si": 0.5}, [0, 0, 0], self.lattice)
     self.assertEqual(self.site2.species_and_occu, Composition({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}
     )
     self.dummy_site = PeriodicSite("X", [0, 0, 0], self.lattice)
Esempio n. 3
0
 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)
     site3 = PeriodicSite({"Si": 0.5, "Fe": 0.5}, [0, 0, 0], self.lattice)
     d = site3.to_dict
     site = PeriodicSite.from_dict(d)
     self.assertEqual(site.species_and_occu, site3.species_and_occu)
Esempio n. 4
0
    def test_as_from_dict(self):
        d = self.site2.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site, self.site2)
        self.assertNotEqual(site, self.site)
        d = self.propertied_site.as_dict()
        site3 = PeriodicSite({"Si": 0.5, "Fe": 0.5}, [0, 0, 0], self.lattice)
        d = site3.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site.species_and_occu, site3.species_and_occu)

        d = self.dummy_site.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site.species_and_occu, self.dummy_site.species_and_occu)
Esempio n. 5
0
 def _supercell_with_defect(self, scaling_matrix, defect_site):
     sc = self._structure.copy()
     sc.make_supercell(scaling_matrix)
     oldf_coords = defect_site.frac_coords
     coords = defect_site.lattice.get_cartesian_coords(oldf_coords)
     newf_coords = sc.lattice.get_fractional_coords(coords)
     sc_defect_site = PeriodicSite(
         defect_site.species_and_occu, newf_coords, sc.lattice, properties=defect_site.properties
     )
     for i in range(len(sc.sites)):
         # if sc_defect_site == sc.sites[i]:
         if sc_defect_site.distance(sc.sites[i]) < 1e-3:
             del sc[i]
             return sc
     raise ValueError("Something wrong if reached here")
Esempio n. 6
0
 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.assertAlmostEqual(distance, 6.22494979899, 5)
     self.assertTrue(([-1, -1, -1] == image).all())
     (distance, image) = self.site.distance_and_image(other_site, [1, 0, 0])
     self.assertAlmostEqual(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.assertAlmostEqual(get_distance_and_image_old(site1, 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(get_distance_and_image_old(site1, site2)[0] >
                     site1.distance_and_image(site2)[0])
     site2 = PeriodicSite("Fe", np.random.rand(3), lattice)
     (dist_old, jimage_old) = get_distance_and_image_old(site1, site2)
     (dist_new, jimage_new) = site1.distance_and_image(site2)
     self.assertTrue(dist_old - dist_new > -1e-8,
                     "New distance algo should give smaller answers!")
     self.assertFalse((abs(dist_old - dist_new) < 1e-8) ^
                      (jimage_old == jimage_new).all(),
                      "If old dist == new dist, images must be the same!")
     latt = Lattice.from_parameters(3.0, 3.1, 10.0, 2.96, 2.0, 1.0)
     site = PeriodicSite("Fe", [0.1, 0.1, 0.1], latt)
     site2 = PeriodicSite("Fe", [0.99, 0.99, 0.99], latt)
     (dist, img) = site.distance_and_image(site2)
     self.assertAlmostEqual(dist, 0.15495358379511573)
     self.assertEqual(list(img), [-11, 6, 0])
Esempio n. 7
0
    def from_dict(cls, d):
        lattice = Lattice.from_dict(d["lattice"])
        sites = [PeriodicSite.from_dict(sd, lattice) for sd in d["sites"]]
        s = Structure.from_sites(sites)

        return Slab(
            lattice=lattice,
            species=s.species_and_occu, coords=s.frac_coords,
            miller_index=d["miller_index"],
            oriented_unit_cell=Structure.from_dict(d["oriented_unit_cell"]),
            shift=d["shift"], scale_factor=d["scale_factor"],
            site_properties=s.site_properties, energy=d["energy"]
        )
Esempio n. 8
0
    def test_get_symmetry_operations(self):

        for sg, structure in [(self.sg, self.structure), (self.sg4, self.structure4)]:

            pgops = sg.get_point_group_operations()
            fracsymmops = sg.get_symmetry_operations()
            symmops = sg.get_symmetry_operations(True)
            latt = structure.lattice
            for fop, op, pgop in zip(fracsymmops, symmops, pgops):
                # translation vector values should all be 0 or 0.5
                t = fop.translation_vector * 2
                self.assertArrayAlmostEqual(t - np.round(t), 0)

                self.assertArrayAlmostEqual(fop.rotation_matrix, pgop.rotation_matrix)
                for site in 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, newcart, latt, coords_are_cartesian=True
                    )
                    for testsite in structure:
                        if newsite.is_periodic_image(testsite, 1e-3):
                            found = True
                            break
                    self.assertTrue(found)

                # Make sure this works for any position, not just the atomic
                # ones.
                random_fcoord = np.random.uniform(size=(3))
                random_ccoord = latt.get_cartesian_coords(random_fcoord)
                newfrac = fop.operate(random_fcoord)
                newcart = op.operate(random_ccoord)
                self.assertTrue(
                    np.allclose(latt.get_fractional_coords(newcart), newfrac)
                )
Esempio n. 9
0
    def test_structures(self):
        import itertools
        import numpy as np

        from pymatgen.core.structure import Structure
        from pymatgen.core.lattice import Lattice
        from pymatgen.core.sites import PeriodicSite

        from supercellor.supercell import make_supercell

        NTESTS = 100  #100
        RADIUS = 100.0
        EPS = 1e-3
        DIAG = 4
        NOISE_R = 2
        tests_run = 0
        np.random.seed(10)
        while (tests_run < NTESTS):
            R = DIAG * np.eye(3, dtype=int) - np.random.randint(
                NOISE_R, size=(3, 3)) + NOISE_R
            #np.random.randint(10, size=(3,3)) -5
            S = RADIUS * np.eye(3)
            try:
                P = np.dot(np.linalg.inv(R), S)
            except np.linalg.LinAlgError:
                continue
            lattice = Lattice(P)
            if lattice.volume < 0.01 * RADIUS**3 / DIAG:
                print('skipping', lattice.volume)
                continue
            sites = []
            try:
                for pos in itertools.product([-0.5, 0.5], repeat=3):
                    sites.append(
                        PeriodicSite("H",
                                     pos,
                                     lattice,
                                     coords_are_cartesian=True))
            except np.linalg.LinAlgError:
                continue
            structure = Structure.from_sites(sites)

            supercell, scale = make_supercell(structure,
                                              distance=RADIUS - EPS,
                                              verbosity=0,
                                              wrap=True,
                                              standardize=True,
                                              do_niggli_first=True)
            self.assertTrue(
                np.sum(np.abs(supercell._lattice.matrix - S)) < EPS)
            tests_run += 1
Esempio n. 10
0
    def _get_structures(self, num_structs):
        structs = []
        rs = subprocess.Popen(
            ["makestr.x", "struct_enum.out",
             str(0),
             str(num_structs - 1)],
            stdout=subprocess.PIPE,
            stdin=subprocess.PIPE,
            close_fds=True)
        rs.communicate()
        if len(self.ordered_sites) > 0:
            original_latt = self.ordered_sites[0].lattice
            ordered_structure = Structure.from_sites(self.ordered_sites)
            inv_org_latt = np.linalg.inv(original_latt.matrix)

        for n in range(1, num_structs + 1):
            with open("vasp.{:06d}".format(n)) as f:
                data = f.read()
                data = re.sub("scale factor", "1", data)
                data = re.sub("(\d+)-(\d+)", r"\1 -\2", data)
                poscar = Poscar.from_string(data, self.index_species)
                sub_structure = poscar.structure
                #Enumeration may have resulted in a super lattice. We need to
                #find the mapping from the new lattice to the old lattice, and
                #perform supercell construction if necessary.
                new_latt = sub_structure.lattice

                sites = []

                if len(self.ordered_sites) > 0:
                    transformation = np.dot(new_latt.matrix, inv_org_latt)
                    transformation = [[int(round(cell)) for cell in row]
                                      for row in transformation]
                    logger.debug("Supercell matrix: {}".format(transformation))
                    s = Structure.from_sites(ordered_structure)
                    s.make_supercell(transformation)
                    sites.extend([site.to_unit_cell for site in s])
                    super_latt = sites[-1].lattice
                else:
                    super_latt = new_latt

                for site in sub_structure:
                    if site.specie.symbol != "X":  # We exclude vacancies.
                        sites.append(
                            PeriodicSite(site.species_and_occu,
                                         site.frac_coords,
                                         super_latt).to_unit_cell)
                structs.append(Structure.from_sites(sorted(sites)))

        logger.debug("Read in a total of {} structures.".format(num_structs))
        return structs
Esempio n. 11
0
    def test_vacancy(self):
        struc = PymatgenTest.get_structure("VO2")
        V_index = struc.indices_from_symbol("V")[0]
        vac = Vacancy(struc, struc[V_index])

        # test generation and super cell
        vac_struc = vac.generate_defect_structure(1)
        self.assertEqual(vac_struc.composition.as_dict(), {"V": 1, "O": 4})

        vac_struc = vac.generate_defect_structure(2)
        self.assertEqual(vac_struc.composition.as_dict(), {"V": 15, "O": 32})

        vac_struc = vac.generate_defect_structure(3)
        self.assertEqual(vac_struc.composition.as_dict(), {"V": 53, "O": 108})

        vac_struc = vac.generate_defect_structure([[2.0, 0, 0], [0, 0, -3.0], [0, 2.0, 0]])
        self.assertEqual(vac_struc.composition.as_dict(), {"V": 23, "O": 48})

        # test charge
        vac = Vacancy(struc, struc[V_index])
        vac_struc = vac.generate_defect_structure(1)
        self.assertEqual(vac_struc.charge, 0.0)

        vac = Vacancy(struc, struc[V_index], charge=1.0)
        vac_struc = vac.generate_defect_structure(1)
        self.assertEqual(vac_struc.charge, 1.0)

        vac = Vacancy(struc, struc[V_index], charge=-1.0)
        vac_struc = vac.generate_defect_structure(1)
        self.assertEqual(vac_struc.charge, -1.0)

        # test multiplicity
        vac = Vacancy(struc, struc[V_index])
        self.assertEqual(vac.multiplicity, 2)

        O_index = struc.indices_from_symbol("O")[0]
        vac = Vacancy(struc, struc[O_index])
        self.assertEqual(vac.multiplicity, 4)

        # Test composition
        self.assertEqual(dict(vac.defect_composition.as_dict()), {"V": 2, "O": 3})

        # test lattice value error occurs for different lattices
        sc_scaled_struc = struc.copy()
        sc_scaled_struc.make_supercell(2)
        self.assertRaises(ValueError, Vacancy, struc, sc_scaled_struc[V_index])
        self.assertRaises(ValueError, Vacancy, sc_scaled_struc, struc[V_index])

        # test value error raised for site not in the structure
        non_site = PeriodicSite("V", struc[V_index].frac_coords + [0.0, 0.0, 0.1], struc.lattice)
        self.assertRaises(ValueError, Vacancy, struc, non_site)
Esempio n. 12
0
 def setUp(self):
     self.lattice = Lattice.cubic(10.0)
     self.si = Element("Si")
     self.site = PeriodicSite("Fe", [0.25, 0.35, 0.45], self.lattice)
     self.site2 = PeriodicSite({"Si": 0.5}, [0, 0, 0], self.lattice)
     self.assertEqual(self.site2.species, Composition({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
                                         })
     self.dummy_site = PeriodicSite("X", [0, 0, 0], self.lattice)
Esempio n. 13
0
 def _supercell_with_defect(self, scaling_matrix, defect_site):
     sc = self._structure.copy()
     sc.make_supercell(scaling_matrix)
     oldf_coords = defect_site.frac_coords
     coords = defect_site.lattice.get_cartesian_coords(oldf_coords)
     newf_coords = sc.lattice.get_fractional_coords(coords)
     sc_defect_site = PeriodicSite(defect_site.species_and_occu,
                                   newf_coords,
                                   sc.lattice,
                                   properties=defect_site.properties)
     for i in range(len(sc.sites)):
         if sc_defect_site == sc.sites[i]:
             sc.remove(i)
             return sc
Esempio n. 14
0
 def apply_tags(self):
     """
     Apply tags.
     """
     tags = {}
     for tag in self.tags:
         istruct = tag.get('istruct', 'all')
         if istruct != 'all':
             if istruct != self.istruct:
                 continue
         site_index = tag['site_index']
         color = tag.get('color', [0.5, 0.5, 0.5])
         opacity = tag.get('opacity', 0.5)
         if site_index == 'unit_cell_all':
             struct_radii = self.all_vis_radii[self.istruct]
             for isite, site in enumerate(self.current_structure):
                 vis_radius = 1.5 * tag.get('radius', struct_radii[isite])
                 tags[(isite, (0, 0, 0))] = {'radius': vis_radius,
                                             'color': color,
                                             'opacity': opacity}
             continue
         cell_index = tag['cell_index']
         if 'radius' in tag:
             vis_radius = tag['radius']
         elif 'radius_factor' in tag:
             vis_radius = tag['radius_factor'] * self.all_vis_radii[self.istruct][site_index]
         else:
             vis_radius = 1.5 * self.all_vis_radii[self.istruct][site_index]
         tags[(site_index, cell_index)] = {'radius': vis_radius,
                                           'color': color,
                                           'opacity': opacity}
     for site_and_cell_index, tag_style in tags.items():
         isite, cell_index = site_and_cell_index
         site = self.current_structure[isite]
         if cell_index == (0, 0, 0):
             coords = site.coords
         else:
             fcoords = site.frac_coords + np.array(cell_index)
             site_image = PeriodicSite(site.species, fcoords,
                                       self.current_structure.lattice, to_unit_cell=False,
                                       coords_are_cartesian=False,
                                       properties=site.properties)
             self.add_site(site_image)
             coords = site_image.coords
         vis_radius = tag_style['radius']
         color = tag_style['color']
         opacity = tag_style['opacity']
         self.add_partial_sphere(coords=coords, radius=vis_radius,
                                 color=color, start=0, end=360,
                                 opacity=opacity)
Esempio n. 15
0
    def from_dict(cls, d):
        lattice = Lattice.from_dict(d["lattice"])
        sites = [PeriodicSite.from_dict(sd, lattice) for sd in d["sites"]]
        s = Structure.from_sites(sites)

        return Interface(
            lattice=lattice,
            species=s.species_and_occu, coords=s.frac_coords,
            sub_plane=d["sub_plane"], film_plane=d["film_plane"],
            sub_init_cell=d["sub_init_cell"], film_init_cell=d["film_init_cell"],
            modified_sub_structure=d["modified_sub_structure"], modified_film_structure=d["modified_film_structure"],
            strained_sub_structure=d["strained_sub_structure"], strained_film_structure=d["strained_film_structure"],
            site_properties=s.site_properties, init_inplane_shift=d["init_inplane_shift"]
        )
Esempio n. 16
0
    def replace_site(self, index, species_n_occu):
        """
        Replace a single site. Takes either a species or a dict of species and
        occupations.

        Args:
            index: The index of the site in the _sites list.
            species: A species object.
        """
        self._sites[index] = PeriodicSite(
            species_n_occu,
            self._sites[index].frac_coords,
            self._lattice,
            properties=self._sites[index].properties)
Esempio n. 17
0
    def get_sitej(self, site_index, image_index):
        """
        Assuming there is some value in the connectivity array at indices
        (1, 3, 12). sitei can be obtained directly from the input structure
        (structure[1]). sitej can be obtained by passing 3, 12 to this function

        Args:
            site_index (int): index of the site (3 in the example)
            image_index (int): index of the image (12 in the example)
        """
        atoms_n_occu = self.s[site_index].species
        lattice = self.s.lattice
        coords = self.s[site_index].frac_coords + self.offsets[image_index]
        return PeriodicSite(atoms_n_occu, coords, lattice)
Esempio n. 18
0
    def test_niggli(self):
        from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
        from pymatgen.core.structure import Structure
        from pymatgen.core.lattice import Lattice
        from pymatgen.core.sites import PeriodicSite
        from supercellor.supercell import make_supercell
        import numpy as np
        import itertools

        np.random.seed(4)
        DIST = 0.99

        lattice = Lattice(1 * np.eye(3) + 0.5 *
                          (np.random.random((3, 3)) - 0.5))
        sites = []
        for pos in itertools.product([-0.5, 0.5], repeat=3):
            sites.append(
                PeriodicSite("H", pos, lattice, coords_are_cartesian=True))

        structure = Structure.from_sites(sites)

        supercell1, scale1 = make_supercell(structure,
                                            distance=DIST,
                                            verbosity=1,
                                            wrap=True,
                                            standardize=True,
                                            do_niggli_first=False)
        supercell2, scale2 = make_supercell(structure,
                                            distance=DIST,
                                            verbosity=1,
                                            wrap=True,
                                            standardize=True,
                                            do_niggli_first=True)

        sa = SpacegroupAnalyzer(supercell1, symprec=1e-21, angle_tolerance=-1)
        supercell_refine = sa.get_refined_structure()
        for i in range(3):
            for j in range(3):
                self.assertTrue(
                    abs(supercell1._lattice.matrix[i, j] -
                        supercell2._lattice.matrix[i, j]) < 1e-1,
                    '{} != {} for i,j={},{}'.format(
                        supercell1._lattice.matrix[i, j],
                        supercell2._lattice.matrix[i, j], i, j))
                self.assertTrue(
                    abs(supercell1._lattice.matrix[i, j] -
                        supercell_refine._lattice.matrix[i, j]) < 1e-1,
                    '{} != {} for i,j={},{}'.format(
                        supercell1._lattice.matrix[i, j],
                        supercell_refine._lattice.matrix[i, j], i, j))
Esempio n. 19
0
    def test_equivalence_fort_py(self):
        from datetime import datetime
        import itertools
        import numpy as np

        from pymatgen.core.structure import Structure
        from pymatgen.core.lattice import Lattice
        from pymatgen.core.sites import PeriodicSite

        from supercellor.supercell import make_supercell

        NTESTS = 10 #100
        VERBOSITY = 0
        for radius in np.arange(1.0, 3.1, 1.0):
            #RADIUS = 5.0
            tests_run = 0
            np.random.seed(10) # reinitialize seed!
            timings_f = 0.0
            timings_p = 0.0
            while (tests_run < NTESTS):
                P = np.eye(3)+ 0.1*(np.random.random((3,3)) -0.5)
                lattice = Lattice(P)
                if lattice.volume < 0.1:
                    print('skipping', lattice.volume)
                    continue
                sites = []
                try:
                    for pos in itertools.product([-0.5,0.5], repeat=3):
                        sites.append(PeriodicSite("H", pos, lattice, coords_are_cartesian=True))
                except np.linalg.LinAlgError:
                    continue
                structure = Structure.from_sites(sites)
                n = datetime.now()
                supercell_p, scale_p = make_supercell(structure, distance=radius,
                        verbosity=VERBOSITY, wrap=True, standardize=True, do_niggli_first=True,
                        implementation='pyth')
                timings_p += (datetime.now()-n).microseconds
                n = datetime.now()
                supercell_f, scale_f = make_supercell(structure, distance=radius,
                        verbosity=VERBOSITY, wrap=True, standardize=True, do_niggli_first=True,
                        implementation='fort')
                timings_f += (datetime.now()-n).microseconds
                self.assertTrue(np.sum((scale_p-scale_f)**2) ==0)
                self.assertTrue(np.sum((supercell_f._lattice.matrix -supercell_p._lattice.matrix)**2) < 1e-6)

                #~ self.assertTrue(np.sum(np.abs(supercell._lattice.matrix - S))< EPS)
                tests_run += 1
            print('Avg timing fortran impl rad={} {:.2e}'.format(radius, 1e-6*timings_f/ tests_run))
            print('Avg timing python  impl rad={} {:.2e}'.format(radius, 1e-6*timings_p/ tests_run))
Esempio n. 20
0
    def setUp(self):

        self.epsilon = 15.

        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        vac = Vacancy(struc, struc.sites[0], charge=-3)

        # load neccessary parameters for defect_entry to make use
        # of Freysoldt and Kumagai corrections
        p = {}
        ids = vac.generate_defect_structure(1)
        abc = struc.lattice.abc
        axisdata = [np.arange(0., lattval, 0.2) for lattval in abc]
        bldata = [np.array([1. for u in np.arange(0., lattval, 0.2)]) for lattval in abc]
        dldata = [
            np.array([(-1 - np.cos(2 * np.pi * u / lattval)) for u in np.arange(0., lattval, 0.2)]) for lattval in abc
        ]
        p.update({'axis_grid': axisdata, 'bulk_planar_averages': bldata, 'defect_planar_averages': dldata,
                  'initial_defect_structure': ids, 'defect_frac_sc_coords': struc.sites[0].frac_coords,
                  'bulk_sc_structure': struc})

        bulk_atomic_site_averages, defect_atomic_site_averages = [], []
        defect_site_with_sc_lattice = PeriodicSite( struc.sites[0].specie, struc.sites[0].coords,
                                                    struc.lattice, coords_are_cartesian = True)
        max_dist = 9.6
        pert_amnt = 1.
        for site_ind, site in enumerate(struc.sites):
            if site.specie.symbol == "O":
                Oval = -30.6825
                bulk_atomic_site_averages.append( Oval)
                if site_ind:
                    dist_to_defect = site.distance_and_image( defect_site_with_sc_lattice)[0]
                    defect_site_val = Oval - .3 + pert_amnt * ((max_dist - dist_to_defect)/max_dist)**2
                    defect_atomic_site_averages.append( defect_site_val)
            else:
                Vval = -51.6833
                bulk_atomic_site_averages.append( Vval)
                if site_ind:
                    dist_to_defect = site.distance_and_image( defect_site_with_sc_lattice)[0]
                    defect_site_val = Vval - .3 + pert_amnt * ((max_dist - dist_to_defect)/max_dist)**2
                    defect_atomic_site_averages.append( defect_site_val)

        site_matching_indices = [[ind, ind-1] for ind in range(len(struc.sites)) if ind != 0]

        p.update({ "bulk_atomic_site_averages": bulk_atomic_site_averages,
                   "defect_atomic_site_averages": defect_atomic_site_averages,
                   "site_matching_indices": site_matching_indices})
        self.defect_entry = DefectEntry( vac, 0., parameters = p)
Esempio n. 21
0
 def mod_site(site):
     new_atom_occu = collections.defaultdict(int)
     for sp, amt in site.species_and_occu.items():
         if sp in species_mapping:
             if isinstance(species_mapping[sp], (Element, Specie)):
                 new_atom_occu[species_mapping[sp]] += amt
             elif isinstance(species_mapping[sp], dict):
                 for new_sp, new_amt in species_mapping[sp].items():
                     new_atom_occu[new_sp] += amt * new_amt
         else:
             new_atom_occu[sp] += amt
     return PeriodicSite(new_atom_occu,
                         site.frac_coords,
                         self._lattice,
                         properties=site.properties)
Esempio n. 22
0
 def remove_oxidation_states(self):
     """
     Removes oxidation states from a structure.
     """
     for i, site in enumerate(self._sites):
         new_sp = collections.defaultdict(float)
         for el, occu in site.species_and_occu.items():
             sym = el.symbol
             new_sp[Element(sym)] += occu
         new_site = PeriodicSite(new_sp,
                                 site.frac_coords,
                                 self._lattice,
                                 coords_are_cartesian=False,
                                 properties=site.properties)
         self._sites[i] = new_site
Esempio n. 23
0
    def get_defect_site(self, initdef):

        ## this is relatively simple for vacancies and substitutionals
        ## which by definition are a pre-existing site in the structure
        if initdef["type"][0] == "v" or initdef["type"][0] == "s":
            siteind_new = self.get_site_ind(initdef["index"],
                                            initdef["species"],
                                            initdef["index_offset_n1"],
                                            initdef["index_offset_n2"],
                                            initdef["index_offset_n1n2"])
            defect_site = structure_bulk[siteind_new]

        ## for interstitials/adatoms, the defect site coords are defined
        ## by the center (average) of the user-provided list of sites
        if initdef["type"][0] == "i" or initdef["type"][0] == "a":
            if len(initdef["index"]) != len(initdef["species"]):
                raise ValueError(
                    "inconsistency between index and species lists")
            for offset in [
                    "index_offset_n1", "index_offset_n2", "index_offset_n1n2"
            ]:
                if initdef[offset] == 0:
                    initdef[offset] = [0] * len(initdef["index"])

            defect_coords = np.array([0., 0., 0.])
            ## loop through the list of sites
            for ind, sp, offset_n1, offset_n2, offset_n1n2 in zip(
                    initdef["index"], initdef["species"],
                    initdef["index_offset_n1"], initdef["index_offset_n2"],
                    initdef["index_offset_n1n2"]):
                siteind_new = self.get_site_ind(ind, sp, offset_n1, offset_n2,
                                                offset_n1n2)
                defect_coords += np.array(
                    structure_bulk[siteind_new].frac_coords)
            ## get the averaged position
            defect_coords = defect_coords / len(initdef["index"])
            if initdef.get("shift_z") != None:
                #            if initdef["shift_z"]:;
                ## we may want to shift the z position, e.g. in the case of an adatom
                defect_coords[2] += float(
                    initdef["shift_z"]) / self.structure.lattice.c
            ## create the defect_site as a PeriodicSite object
            defect_site = PeriodicSite(initdef["species_new"],
                                       defect_coords,
                                       lattice=self.structure.lattice,
                                       coords_are_cartesian=False)

        return defect_site
Esempio n. 24
0
def cube_read_structure_mesh_data(file):
    with open(file, 'r') as fh:
        # The two first lines are comments
        for ii in range(2):
            fh.readline()
        # Number of atoms
        natoms = int(fh.readline().split()[0])
        # The next three lines give the mesh and the vectors
        sp = fh.readline().split()
        nx = int(sp[0])
        dvx = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        ny = int(sp[0])
        dvy = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        nz = int(sp[0])
        dvz = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        uc_matrix = np.array([nx * dvx, ny * dvy, nz * dvz])
        sites = []
        lattice = Lattice(uc_matrix)
        for ii in range(natoms):
            sp = fh.readline().split()
            cc = np.array([float(sp[ii])
                           for ii in range(2, 5)]) * bohr_to_angstrom
            sites.append(
                PeriodicSite(int(sp[0]),
                             coords=cc,
                             lattice=lattice,
                             to_unit_cell=False,
                             coords_are_cartesian=True))
        data = np.zeros((nx, ny, nz))
        ii = 0
        for line in fh:
            for val in line.split():
                data[ii // (ny * nz), (ii // nz) % ny, ii % nz] = float(val)
                ii += 1
        data = data / (bohr_to_angstrom**3)
        if ii != nx * ny * nz:
            raise ValueError('Wrong number of data points ...')
        from abipy.core.structure import Structure
        structure = Structure.from_sites(sites=sites)
        from abipy.core.mesh3d import Mesh3D
        mesh = Mesh3D(shape=[nx, ny, nz], vectors=uc_matrix)

        return structure, mesh, data
Esempio n. 25
0
 def plot_images(self, outfile):
     """
     Generates a POSCAR with the calculated diffusion path with respect to the first endpoint.
     :param outfile: Output file for the POSCAR
     """
     sum_struct = self.__images[0].sites
     for image in self.__images:
         for site_i in self.__relax_sites:
             sum_struct.append(PeriodicSite(image.sites[site_i].specie,
                                            image.sites[site_i].frac_coords,
                                            self.__images[0].lattice,
                                            to_unit_cell=True,
                                            coords_are_cartesian=False))
     sum_struct = Structure.from_sites(sum_struct, validate_proximity=False)
     p = Poscar(sum_struct)
     p.write_file(outfile)
Esempio n. 26
0
 def setUp(self):
     entry_file = os.path.join(file_loc, 'vac_cr2o3_struct_entry.json')
     entry = loadfn(entry_file, cls=MontyDecoder)
     lattice = Lattice([[9.995004137201189, -2.1469568e-08, 0.0],
                        [-4.997501105922451, 8.655927903729987, 0.0],
                        [0.0, 0.0, 13.67956098598296]])
     coords = [0.1666665000000016, 0.3333334999999984, 0.014505185117094302]
     site_in_bulk = PeriodicSite('Cr', coords, lattice)
     multiplicity = 12
     supercell_size = [2, 2, 1]
     q = -2
     q_corr = 0.98716
     o_corr = 0.39139821874799996
     name = "vac_1_Cr"
     self.com_def = ComputedDefect(entry, site_in_bulk, multiplicity,
                                   supercell_size, q, q_corr, o_corr, name)
Esempio n. 27
0
    def test_interstitial(self):
        struc = PymatgenTest.get_structure("VO2")
        V_index = struc.indices_from_symbol("V")[0]

        int_site = PeriodicSite("V", struc[V_index].coords + [0.1, 0.1, 0.1],
                                struc.lattice)
        interstitial = Interstitial(struc, int_site)

        # test generation and super cell
        int_struc = interstitial.generate_defect_structure(1)
        self.assertEqual(int_struc.composition.as_dict(), {"V": 3, "O": 4})
        # Ensure the site is in the right place
        self.assertEqual(
            int_site,
            int_struc.get_sites_in_sphere(int_site.coords, 0.1)[0][0])

        int_struc = interstitial.generate_defect_structure(2)
        self.assertEqual(int_struc.composition.as_dict(), {"V": 17, "O": 32})

        int_struc = interstitial.generate_defect_structure(3)
        self.assertEqual(int_struc.composition.as_dict(), {"V": 55, "O": 108})

        # test charge
        interstitial = Interstitial(struc, int_site)
        int_struc = interstitial.generate_defect_structure(1)
        self.assertEqual(int_struc.charge, 0.0)

        interstitial = Interstitial(struc, int_site, charge=1.0)
        int_struc = interstitial.generate_defect_structure(1)
        self.assertEqual(int_struc.charge, 1.0)

        interstitial = Interstitial(struc, int_site, charge=-1.0)
        int_struc = interstitial.generate_defect_structure(1)
        self.assertEqual(int_struc.charge, -1.0)

        # test multiplicity
        interstitial = Interstitial(struc, int_site)
        self.assertEqual(interstitial.multiplicity, 1.0)

        interstitial = Interstitial(struc, int_site, multiplicity=4.0)
        self.assertEqual(interstitial.multiplicity, 4.0)

        # Test composoition
        self.assertEqual(dict(interstitial.defect_composition.as_dict()), {
            "V": 3,
            "O": 4
        })
Esempio n. 28
0
    def write_input(self, output_dir, make_dir_if_not_present=True,
                    write_cif=False, write_path_cif=False,
                    write_endpoint_inputs=False):
        """
        NEB inputs has a special directory structure where inputs are in 00,
        01, 02, ....

        Args:
            output_dir (str): Directory to output the VASP input files
            make_dir_if_not_present (bool): Set to True if you want the
                directory (and the whole path) to be created if it is not
                present.
            write_cif (bool): If true, writes a cif along with each POSCAR.
            write_path_cif (bool): If true, writes a cif for each image.
            write_endpoint_inputs (bool): If true, writes input files for
                running endpoint calculations.
        """

        if make_dir_if_not_present and not os.path.exists(output_dir):
            os.makedirs(output_dir)
        self.incar.write_file(os.path.join(output_dir, 'INCAR'))
        self.kpoints.write_file(os.path.join(output_dir, 'KPOINTS'))
        self.potcar.write_file(os.path.join(output_dir, 'POTCAR'))

        for i, p in enumerate(self.poscars):
            d = os.path.join(output_dir, str(i).zfill(2))
            if not os.path.exists(d):
                os.makedirs(d)
            p.write_file(os.path.join(d, 'POSCAR'))
            if write_cif:
                p.structure.to(filename=os.path.join(d, '{}.cif'.format(i)))
        if write_endpoint_inputs:
            end_point_param = MPRelaxSet(
                self.structures[0],
                user_incar_settings=self.user_incar_settings)

            for image in ['00', str(len(self.structures) - 1).zfill(2)]:
                end_point_param.incar.write_file(os.path.join(output_dir, image, 'INCAR'))
                end_point_param.kpoints.write_file(os.path.join(output_dir, image, 'KPOINTS'))
                end_point_param.potcar.write_file(os.path.join(output_dir, image, 'POTCAR'))
        if write_path_cif:
            sites = set()
            l = self.structures[0].lattice
            for site in chain(*(s.sites for s in self.structures)):
                sites.add(PeriodicSite(site.species_and_occu, site.frac_coords, l))
            path = Structure.from_sites(sorted(sites))
            path.to(filename=os.path.join(output_dir, 'path.cif'))
Esempio n. 29
0
def makeNewPos(specs, frac_coords, new_latt, dim):
    """
    Make a new POSCAR file using input species, coordinates, and lattice.
    Used in conjunction with functions "getNewLattice","alignMono",
    "alignChains"
    
    inputs
    --------
        specs (list):       List of species associated with each coordinate
        
        frac_coords (list): List of fractional coordinates of each species,
                            relative to the new lattice
                            
        new_latt (list):    List of vectors representing the new lattice 
                            vectors of the low-dimensional material
                            
        dim (int):  Number of periodic directions in the crystal
        
    outputs
    --------
        new_struct (Structure): Structure object for low-dimensional material
                                with non-periodic directions being 
                                orthogonal to the periodic directions
    
    """

    a, b, c = magni(new_latt[0]), magni(new_latt[1]), magni(new_latt[2])
    if dim == 2:
        ang = getAngle(new_latt[0], new_latt[1]) / 2
        new_latt = [[np.cos(ang) * a, -np.sin(ang) * a, 0],
                    [np.cos(ang) * b, np.sin(ang) * b, 0], [0, 0, c]]
    elif dim == 1:
        new_latt = [[a, 0, 0], [0, b, 0], [0, 0, c]]
    i = 0
    new_sites = []
    for site in frac_coords:
        p = PeriodicSite(species=Element(specs[i]),
                         lattice=Lattice(new_latt),
                         coords=np.dot(site, new_latt),
                         coords_are_cartesian=True)
        new_sites.append(p)
        i += 1

    new_struct = Structure.from_sites(new_sites)
    return (new_struct)
Esempio n. 30
0
    def modify_lattice(self, new_lattice):
        """
        Modify the lattice of the structure.  Mainly used for changing the
        basis.

        Args:
            new_lattice:
                New lattice
        """
        self._lattice = new_lattice
        new_sites = []
        for site in self._sites:
            new_sites.append(
                PeriodicSite(site.species_and_occu,
                             site.frac_coords,
                             self._lattice,
                             properties=site.properties))
        self._sites = new_sites
Esempio n. 31
0
    def __init__(self,
                 structure,
                 scaling_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1))):
        """
        Create a supercell.

        Args:
            structure:
                pymatgen.core.structure Structure object.
            scaling_matrix:
                a matrix of transforming the lattice vectors. Defaults to the
                identity matrix. Has to be all integers. e.g.,
                [[2,1,0],[0,3,0],[0,0,1]] generates a new structure with
                lattice vectors a' = 2a + b, b' = 3b, c' = c where a, b, and c
                are the lattice vectors of the original structure.
        """
        self._original_structure = structure
        old_lattice = structure.lattice
        scale_matrix = np.array(scaling_matrix)
        new_lattice = Lattice(np.dot(scale_matrix, old_lattice.matrix))
        new_sites = []

        def range_vec(i):
            return range(
                max(scale_matrix[:][:, i]) - min(scale_matrix[:][:, i]) + 1)

        for site in structure.sites:
            for (i, j, k) in itertools.product(range_vec(0), range_vec(1),
                                               range_vec(2)):
                fcoords = site.frac_coords + np.array([i, j, k])
                coords = old_lattice.get_cartesian_coords(fcoords)
                new_coords = new_lattice.get_fractional_coords(coords)
                new_site = PeriodicSite(site.species_and_occu,
                                        new_coords,
                                        new_lattice,
                                        properties=site.properties)
                contains_site = False
                for s in new_sites:
                    if s.is_periodic_image(new_site):
                        contains_site = True
                        break
                if not contains_site:
                    new_sites.append(new_site)
        self._modified_structure = Structure.from_sites(new_sites)
Esempio n. 32
0
    def are_symmetrically_equivalent(self, sites1, sites2, symm_prec=1e-3):
        """
        Given two sets of PeriodicSites, test if they are actually
        symmetrically equivalent under this space group.  Useful, for example,
        if you want to test if selecting atoms 1 and 2 out of a set of 4 atoms
        are symmetrically the same as selecting atoms 3 and 4, etc.

        One use is in PartialRemoveSpecie transformation to return only
        symmetrically distinct arrangements of atoms.

        Args:
            sites1:
                1st set of sites
            sites2:
                2nd set of sites
            symm_prec:
                The tolerance in atomic distance to test if atoms are
                symmetrically similar.

        Returns:
            Boolean indicating whether the two sets of sites are symmetrically
            equivalent.
        """
        def in_sites(site):
            for test_site in sites1:
                if test_site.is_periodic_image(site, symm_prec, False):
                    return True
            return False

        for op in self.symmops:
            newsites2 = [
                PeriodicSite(site.species_and_occu,
                             op.operate(site.frac_coords), site.lattice)
                for site in sites2
            ]
            ismapping = True
            for site in newsites2:
                if not in_sites(site):
                    ismapping = False
                    break
            if ismapping:
                return True
        return False
Esempio n. 33
0
    def test_as_from_dict(self):
        d = self.site2.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site, self.site2)
        self.assertNotEqual(site, self.site)
        d = self.propertied_site.as_dict()
        site3 = PeriodicSite({"Si": 0.5, "Fe": 0.5}, [0, 0, 0], self.lattice)
        d = site3.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site.species, site3.species)

        d = self.dummy_site.as_dict()
        site = PeriodicSite.from_dict(d)
        self.assertEqual(site.species, self.dummy_site.species)
Esempio n. 34
0
    def test_hnf_dmpi(self):
        import json, numpy as np, itertools, os

        from pymatgen.core.structure import Structure
        from pymatgen.core.lattice import Lattice
        from pymatgen.core.sites import PeriodicSite
        from supercellor.supercell import make_supercell
        np.random.seed(50)
        N = 1
        RMIN = 2
        RMAX = 3

        for trial in range(N):
            #~ for implementation in ('pyth', ):
            for implementation in ('fort', ):
                lattice = Lattice(1.0 * np.eye(3) + 0.2 *
                                  (np.random.random((3, 3)) - 0.5))
                sites = []
                for pos in itertools.product([-0.5, 0.5], repeat=3):
                    sites.append(
                        PeriodicSite("H",
                                     pos,
                                     lattice,
                                     coords_are_cartesian=True))
                structure = Structure.from_sites(sites)

                for rad in range(RMIN, RMAX):
                    supercell1, scale1 = make_supercell(
                        structure,
                        distance=rad,
                        method='hnf',
                        implementation=implementation,
                        verbosity=0,
                        wrap=True,
                        standardize=False,
                        do_niggli_first=False)
                    reduced_supercell1 = supercell1.get_reduced_structure(
                        reduction_algo=u'LLL')
                    for dim in range(3):
                        self.assertTrue(
                            np.linalg.norm(reduced_supercell1._lattice.
                                           matrix[dim]) >= rad)
Esempio n. 35
0
def from_bson_voronoi_list(bson_nb_voro_list, structure):
    """
    Returns the voronoi_list needed for the VoronoiContainer object from a bson-encoded voronoi_list (composed of
    vlist and bson_nb_voro_list).
    :param vlist: List of voronoi objects
    :param bson_nb_voro_list: List of periodic sites involved in the Voronoi
    :return: The voronoi_list needed for the VoronoiContainer (with PeriodicSites as keys of the dictionary - not
    allowed in the BSON format)
    """
    voronoi_list = [None] * len(bson_nb_voro_list)
    for isite, voro in enumerate(bson_nb_voro_list):
        if voro is None or voro == 'None':
            continue
        voronoi_list[isite] = []
        for psd, dd in voro:
            struct_site = structure[dd['index']]
            periodic_site = PeriodicSite(struct_site._species, struct_site.frac_coords + psd[1],
                                         struct_site._lattice, properties=struct_site._properties)
            voronoi_list[isite].append((periodic_site, dd))
    return voronoi_list
Esempio n. 36
0
 def test_symmetrized_structure(self):
     t = OrderDisorderedStructureTransformation(symmetrized_structures=True)
     c = []
     sp = []
     c.append([0.5, 0.5, 0.5])
     sp.append("Si4+")
     c.append([0.45, 0.45, 0.45])
     sp.append({"Si4+": 0.5})
     c.append([0.56, 0.56, 0.56])
     sp.append({"Si4+": 0.5})
     c.append([0.25, 0.75, 0.75])
     sp.append({"Si4+": 0.5})
     c.append([0.75, 0.25, 0.25])
     sp.append({"Si4+": 0.5})
     l = Lattice.cubic(5)
     s = Structure(l, sp, c)
     test_site = PeriodicSite("Si4+", c[2], l)
     s = SymmetrizedStructure(s, "not_real", [0, 1, 1, 2, 2],
                              ["a", "b", "b", "c", "c"])
     output = t.apply_transformation(s)
     self.assertTrue(test_site in output.sites)