Ejemplo n.º 1
0
    def test_disordered_primitive_to_ordered_supercell(self):
        sm_atoms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                    primitive_cell=False, scale=True,
                                    attempt_supercell=True,
                                    allow_subset=True,
                                    supercell_size='num_atoms',
                                    comparator=OrderDisorderElementComparator())
        sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                    primitive_cell=False, scale=True,
                                    attempt_supercell=True,
                                    allow_subset=True,
                                    supercell_size='num_sites',
                                    comparator=OrderDisorderElementComparator())
        lp = Lattice.orthorhombic(10, 20, 30)
        pcoords = [[0, 0, 0],
                   [0.5, 0.5, 0.5]]
        ls = Lattice.orthorhombic(20, 20, 30)
        scoords = [[0, 0, 0],
                   [0.75, 0.5, 0.5]]
        prim = Structure(lp, [{'Na': 0.5}, {'Cl': 0.5}], pcoords)
        supercell = Structure(ls, ['Na', 'Cl'], scoords)
        supercell.make_supercell([[-1, 1, 0], [0, 1, 1], [1, 0, 0]])

        self.assertFalse(sm_sites.fit(prim, supercell))
        self.assertTrue(sm_atoms.fit(prim, supercell))

        self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell)
        self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
Ejemplo n.º 2
0
    def test_get_supercell_matrix(self):
        sm = StructureMatcher(ltol=0.1, stol=0.3, angle_tol=2,
                              primitive_cell=False, scale=True,
                              attempt_supercell=True)

        l = Lattice.orthorhombic(1, 2, 3)

        s1 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]])
        s1.make_supercell([2, 1, 1])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, 0], [0, 0.1, -0.95], [-.7, .5, .375]])
        result = sm.get_supercell_matrix(s1, s2)
        self.assertTrue((result == [[-2, 0, 0], [0, 1, 0], [0, 0, 1]]).all())

        s1 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]])
        s1.make_supercell([[1, -1, 0], [0, 0, -1], [0, 1, 0]])

        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, 0], [0, 0.1, -0.95], [-.7, .5, .375]])
        result = sm.get_supercell_matrix(s1, s2)
        self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all())

        # test when the supercell is a subset
        sm = StructureMatcher(ltol=0.1, stol=0.3, angle_tol=2,
                              primitive_cell=False, scale=True,
                              attempt_supercell=True, allow_subset=True)
        del s1[0]
        result = sm.get_supercell_matrix(s1, s2)
        self.assertTrue((result == [[-1, -1, 0], [0, 0, -1], [0, 1, 0]]).all())
    def get_min_distance(self, connected_nodes, loc):
        str_formula = str(self.structure.species_and_occu[loc].formula)
        nodes = np.array([node for node in connected_nodes \
            if self.structure.species_and_occu[node] == self.structure.species_and_occu[loc]])

        #get nearest magnetic_metal angle neighbors with a tolerance of 0.1 A.
        lattice_species = [
            self.structure.species_and_occu[node] for node in nodes
        ]
        s = Structure(self.structure.lattice, lattice_species,
                      self.frac_coords[nodes])
        s.make_supercell([3, 3, 3])
        new_frac_coords = np.round(s.frac_coords, decimals=3)
        new_frac_coords[new_frac_coords == 1.] = 0.
        distances = []
        for i in range(len(new_frac_coords)):
            distances.append(
                np.linalg.norm(
                    s.lattice.get_cartesian_coords(new_frac_coords[i]) -
                    s.lattice.get_cartesian_coords([0.5, 0.5, 0.5])))

        new_loc = np.argmin(distances)
        loc_cart_coords = s.lattice.get_cartesian_coords(
            new_frac_coords[new_loc])

        #identify the two closest same species to the specie under consideration (new_loc)
        nodes = np.arange(len(s))
        distances = [s.distance_matrix[node, new_loc] for node in nodes]
        nodes = nodes[np.argsort(distances)]
        distances = np.sort(distances)
        return distances[1]
Ejemplo n.º 4
0
    def test_find_match2(self):
        sm = StructureMatcher(ltol=0.2,
                              stol=0.3,
                              angle_tol=5,
                              primitive_cell=True,
                              scale=True,
                              attempt_supercell=False)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Si', 'Si'], [[0, 0, 0.1], [0, 0, 0.2]])
        s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [0, 0.1, -0.95]])

        s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False)

        match = sm._strict_match(s1,
                                 s2,
                                 fu,
                                 s1_supercell=False,
                                 use_rms=True,
                                 break_on_match=False)
        scale_matrix = match[2]
        s2.make_supercell(scale_matrix)
        s2.translate_sites(range(len(s2)), match[3])

        self.assertAlmostEqual(np.sum(s2.frac_coords), 0.3)
        self.assertAlmostEqual(np.sum(s2.frac_coords[:, :2]), 0)
Ejemplo n.º 5
0
    def to_xyz(self):
        u = Universe('reduced.xyz')
        name = []
        for a in u.atoms:
            name.append(a.name)
        a = [
            float(r) for r in
            '8.0136733451350004    2.7785351250530002    0.0000007466930000'.
            split()
        ]
        b = [
            float(r) for r in
            '-1.6027324335730000    8.3356053751600001    0.0000022400790000'.
            split()
        ]
        c = [
            float(r) for r in
            '0.0000000000000000    0.0000000000000000   25.3395087497430005'.
            split()
        ]
        lat = Lattice([a, b, c])

        s = Structure(lat, name, u.trajectory[0], coords_are_cartesian=True)
        s.make_supercell([2, 2, 1])
        print(s)
Ejemplo n.º 6
0
    def test_find_match1(self):
        sm = StructureMatcher(ltol=0.2,
                              stol=0.3,
                              angle_tol=5,
                              primitive_cell=True,
                              scale=True,
                              attempt_supercell=False)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0, 0.1], [0, 0, 0.2], [.7, .4, .5]])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, 0], [0, 0.1, -0.95], [.7, .5, .375]])

        s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False)
        match = sm._strict_match(s1,
                                 s2,
                                 fu,
                                 s1_supercell=True,
                                 use_rms=True,
                                 break_on_match=False)
        scale_matrix = match[2]
        s2.make_supercell(scale_matrix)
        fc = s2.frac_coords + match[3]
        fc -= np.round(fc)
        self.assertAlmostEqual(np.sum(fc), 0.9)
        self.assertAlmostEqual(np.sum(fc[:, :2]), 0.1)
        cart_dist = np.sum(match[1] * (l.volume / 3)**(1 / 3))
        self.assertAlmostEqual(cart_dist, 0.15)
Ejemplo n.º 7
0
    def test_get_mapping(self):
        sm = StructureMatcher(ltol=0.2,
                              stol=0.3,
                              angle_tol=5,
                              primitive_cell=False,
                              scale=True,
                              attempt_supercell=False,
                              allow_subset=True)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Ag', 'Si', 'Si'],
                       [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]])
        s1.make_supercell([2, 1, 1])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]])

        shuffle = [2, 0, 1, 3, 5, 4]
        s1 = Structure.from_sites([s1[i] for i in shuffle])
        #test the mapping
        s2.make_supercell([2, 1, 1])
        #equal sizes
        for i, x in enumerate(sm.get_mapping(s1, s2)):
            self.assertEqual(s1[x].species_and_occu, s2[i].species_and_occu)

        del s1[0]
        #s1 is subset of s2
        for i, x in enumerate(sm.get_mapping(s2, s1)):
            self.assertEqual(s1[i].species_and_occu, s2[x].species_and_occu)
        #s2 is smaller than s1
        del s2[0]
        del s2[1]
        self.assertRaises(ValueError, sm.get_mapping, s2, s1)
Ejemplo n.º 8
0
    def test_disordered_primitive_to_ordered_supercell(self):
        sm_atoms = StructureMatcher(
            ltol=0.2,
            stol=0.3,
            angle_tol=5,
            primitive_cell=False,
            scale=True,
            attempt_supercell=True,
            allow_subset=True,
            supercell_size='num_atoms',
            comparator=OrderDisorderElementComparator())
        sm_sites = StructureMatcher(
            ltol=0.2,
            stol=0.3,
            angle_tol=5,
            primitive_cell=False,
            scale=True,
            attempt_supercell=True,
            allow_subset=True,
            supercell_size='num_sites',
            comparator=OrderDisorderElementComparator())
        lp = Lattice.orthorhombic(10, 20, 30)
        pcoords = [[0, 0, 0], [0.5, 0.5, 0.5]]
        ls = Lattice.orthorhombic(20, 20, 30)
        scoords = [[0, 0, 0], [0.75, 0.5, 0.5]]
        prim = Structure(lp, [{'Na': 0.5}, {'Cl': 0.5}], pcoords)
        supercell = Structure(ls, ['Na', 'Cl'], scoords)
        supercell.make_supercell([[-1, 1, 0], [0, 1, 1], [1, 0, 0]])

        self.assertFalse(sm_sites.fit(prim, supercell))
        self.assertTrue(sm_atoms.fit(prim, supercell))

        self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell)
        self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
Ejemplo n.º 9
0
def create_TiAlN_structure(shuffle=True):
    ''' Attributes:
        number_of_lattice > maximum Total number of atoms in structure
        a                 > lattice parameter
        Returns:
        Pymatgen structure TiAlN. Creates possible largest square supercell '''
    lattice = Lattice.cubic(a=4.16)
    coords = [
        [0, 0, 0],
        [0.5, 0.5, 0],
        [0.5, 0, 0.5],
        [0, 0.5, 0.5],
        [0, 0, 0.5],
        [0.5, 0, 0],
        [0, 0.5, 0],
        [0.5, 0.5, 0.5],
    ]
    matrix = [[1, 0, 0], [0, 5, 0], [0, 0, 5]]

    struct = Structure(lattice, ["Ti", "Ti", "Al", "Al", "N", "N", "N", "N"],
                       coords)
    struct.make_supercell(matrix)
    site_size = len(struct)
    element_number = int(site_size / 4)
    Al_Ti_array = ['Al'] * element_number + ['Ti'] * element_number

    if shuffle == True:
        random.shuffle(Al_Ti_array)
        for e, i in enumerate(Al_Ti_array):
            struct.replace(e, i)
    return struct
Ejemplo n.º 10
0
    def test_get_mapping(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=False, scale=True,
                              attempt_supercell=False,
                              allow_subset=True)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Ag', 'Si', 'Si'],
                       [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]])
        s1.make_supercell([2, 1, 1])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]])

        shuffle = [2, 0, 1, 3, 5, 4]
        s1 = Structure.from_sites([s1[i] for i in shuffle])
        # test the mapping
        s2.make_supercell([2, 1, 1])
        # equal sizes
        for i, x in enumerate(sm.get_mapping(s1, s2)):
            self.assertEqual(s1[x].species,
                             s2[i].species)

        del s1[0]
        # s1 is subset of s2
        for i, x in enumerate(sm.get_mapping(s2, s1)):
            self.assertEqual(s1[i].species,
                             s2[x].species)
        # s2 is smaller than s1
        del s2[0]
        del s2[1]
        self.assertRaises(ValueError, sm.get_mapping, s2, s1)
    def test_apply_transformation_mult(self):
        # Test returning multiple structures from each transformation.
        disord = Structure(np.eye(3) * 4.209, [{"Cs+": 0.5, "K+": 0.5}, "Cl-"], [[0, 0, 0], [0.5, 0.5, 0.5]])
        disord.make_supercell([2, 2, 1])

        tl = [EnumerateStructureTransformation(), OrderDisorderedStructureTransformation()]
        t = SuperTransformation(tl, nstructures_per_trans=10)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 8)
        t = SuperTransformation(tl)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 2)
Ejemplo n.º 12
0
    def test_apply_transformation_mult(self):
        # Test returning multiple structures from each transformation.
        disord = Structure(np.eye(3) * 4.209, [{"Cs+": 0.5, "K+": 0.5}, "Cl-"],
                           [[0, 0, 0], [0.5, 0.5, 0.5]])
        disord.make_supercell([2, 2, 1])

        tl = [EnumerateStructureTransformation(),
              OrderDisorderedStructureTransformation()]
        t = SuperTransformation(tl, nstructures_per_trans=10)
        self.assertEqual(len(t.apply_transformation(disord,
                                                    return_ranked_list=20)), 8)
        t = SuperTransformation(tl)
        self.assertEqual(len(t.apply_transformation(disord,
                                                    return_ranked_list=20)), 2)
Ejemplo n.º 13
0
    def test_find_match2(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=True, scale=True,
                              attempt_supercell=False)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Si', 'Si'], [[0, 0, 0.1], [0, 0, 0.2]])
        s2 = Structure(l, ['Si', 'Si'], [[0, 0.1, 0], [0, 0.1, -0.95]])

        s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False)

        match = sm._strict_match(s1, s2, fu, s1_supercell=False,
                                 use_rms=True, break_on_match=False)
        scale_matrix = match[2]
        s2.make_supercell(scale_matrix)
        s2.translate_sites(range(len(s2)), match[3])

        self.assertAlmostEqual(np.sum(s2.frac_coords) % 1, 0.3)
        self.assertAlmostEqual(np.sum(s2.frac_coords[:, :2]) % 1, 0)
Ejemplo n.º 14
0
    def test_get_s2_large_s2(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=False, scale=False,
                              attempt_supercell=True, allow_subset=False,
                              supercell_size='volume')

        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Ag', 'Si', 'Si'],
                       [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]])

        l2 = Lattice.orthorhombic(1.01, 2.01, 3.01)
        s2 = Structure(l2, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]])
        s2.make_supercell([[0, -1, 0], [1, 0, 0], [0, 0, 1]])

        result = sm.get_s2_like_s1(s1, s2)

        for x, y in zip(s1, result):
            self.assertLess(x.distance(y), 0.08)
Ejemplo n.º 15
0
    def test_find_match1(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=True, scale=True,
                              attempt_supercell=False)
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0,0,0.1],[0,0,0.2],[.7,.4,.5]])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0,0.1,0],[0,0.1,-0.95],[.7,.5,.375]])

        s1, s2, fu, s1_supercell = sm._preprocess(s1, s2, False)
        match = sm._strict_match(s1, s2, fu, s1_supercell = True, use_rms = True, break_on_match = False)
        scale_matrix = match[2]
        s2.make_supercell(scale_matrix)
        fc = s2.frac_coords + match[3]
        fc -= np.round(fc)
        self.assertAlmostEqual(np.sum(fc), 0.9)
        self.assertAlmostEqual(np.sum(fc[:,:2]), 0.1)
        cart_dist = np.sum(match[1] * (l.volume/3) ** (1/3))
        self.assertAlmostEqual(cart_dist, 0.15)
Ejemplo n.º 16
0
def getFccEquilibrium():
    # alat = 1.0
    alat = math.sqrt(2.0)
    fcc = Structure(
        Lattice.cubic(alat), ["Co", "Co", "Co", "Co"],
        [[0.0, 0.0, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]])

    # fcc = Structure( Lattice.cubic(alat), ["Co"],
    #                    [[0.0, 0.0, 0.0]]
    #                   )

    # Find the primitive unit cell:
    from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
    sym_finder = SpacegroupAnalyzer(fcc)
    fcc = sym_finder.get_primitive_standard_structure()
    # new_structure.to(fmt='poscar', filename='POSCAR_test_2')

    # Make a supercell
    n = 3  #3
    fcc.make_supercell([n, n, n])
    return fcc
Ejemplo n.º 17
0
def run_displacement(file_primitive, prefix, scaling_matrix,
                     disp_magnitude_angstrom):

    qeobj = QEParser()
    qeobj.load_initial_structure(file_primitive)

    structure = Structure(qeobj.lattice_vector.transpose(), qeobj.kd_in_str,
                          qeobj.x_fractional)

    Structure.make_supercell(structure, scaling_matrix)

    print("Supercell generated. # Atoms: %i" % structure.num_sites)
    print("")

    prefix0 = 'supercell'
    disp = np.zeros((structure.num_sites, 3))

    # update structural information of qeobj
    qeobj_mod = update_qeobj(qeobj, structure)

    # create the supercell structure
    qeobj_mod.generate_structures(prefix0, ['original'], [disp])
    # rename the file
    command = ("mv %s1.pw.in %s0.scf.in" % (prefix0, prefix0))
    os.system(command)

    # Generate displacement files
    gen_alm_input('ALM0.in', prefix0, 'suggest', structure, 1, "*-* None")
    command = ("%s/alm/alm ALM0.in > ALM0.log" % ALAMODE_root)
    os.system(command)

    dispobj = AlamodeDisplace("fd", qeobj_mod, verbosity=0)
    header_list, disp_list \
        = dispobj.generate(file_pattern=["%s.pattern_HARMONIC" % prefix0],
                           magnitude=disp_magnitude_angstrom)

    qeobj_mod.generate_structures(prefix, header_list, disp_list)
Ejemplo n.º 18
0
def run_optimize(file_primitive, file_dfset, scaling_matrix):

    qeobj = QEParser()
    qeobj.load_initial_structure(file_primitive)

    structure = Structure(qeobj.lattice_vector.transpose(), qeobj.kd_in_str,
                          qeobj.x_fractional)

    Structure.make_supercell(structure, scaling_matrix)

    print("Supercell generated. # Atoms: %i" % structure.num_sites)
    print("")

    prefix0 = 'supercell'
    # Generate displacement files
    gen_alm_input('ALM1.in',
                  prefix0,
                  'optimize',
                  structure,
                  1,
                  "*-* None",
                  dfset=file_dfset)
    command = ("%s/alm/alm ALM1.in > ALM1.log" % ALAMODE_root)
    os.system(command)
def get_elem_info(
        structure: mg.Structure,
        makesupercell: bool = True) -> Tuple[Dict, Dict, mg.Structure]:
    """
    Helper function for calc_mx/mm/xx_distances()
    Get information on the element composition and the site indices for all element of a structure

    :param structure: Pymatgen Structure, the structure of a compound
    :param makesupercell: Boolean, whether or not to make a supercell
    :return: Tuple, (a dictionary with key-value pair - element: [list of indices],
                     a dictionary with key-value pair - element_type: [list of elements],
                     Pymatgen Structure)
    """
    # create a copy of the original structure
    structure = structure.copy()
    # create a list with all the elements
    elem_lst = structure.composition.element_composition.elements
    # initialize a dictionary with each element as the key and an empty list as the value
    elem_indices = {element: [] for element in elem_lst}
    # classify all elements into a metal group and a non-metal group
    elem_group = parse_element(structure)

    # iterate over all sites
    for i, site in enumerate(structure.sites):
        # record the site index for the all the element(s) on this site
        for element in site.species.element_composition.elements:
            elem_indices[element].append(i)

    # in the case that an element only appears in one site, make a supercell (inplace)
    if makesupercell and (np.sum(
        [len(lst) == 1 for lst in elem_indices.values()]) > 0):
        # make a supercell of a'=2a, b'=b, c'=c
        structure.make_supercell(scaling_matrix=[2, 1, 1])
        elem_indices, elem_group, structure = get_elem_info(structure)

    return elem_indices, elem_group, structure
class Test2D(unittest.TestCase):
    def setUp(self):

        ## simple toy structure for preliminary testing

        self.a0 = 3.0
        self.c = 20.0

        self.structure = Structure(
            Lattice.from_parameters(a=self.a0,
                                    b=self.a0,
                                    c=self.c,
                                    alpha=90,
                                    beta=90,
                                    gamma=90), ["O", "O"],
            [[0.0, 0.0, 0.1], [0.5, 0.5, 0.3]])

        self.nvecs = [3, 3, 1]
        self.vacuum = 20
        self.q = 0
        self.structure.make_supercell(self.nvecs)
        self.structure_bulk = self.structure.copy()

        self.initdef_list = []
        self.initdef_list.append(
            {"def1": {
                "type": "vac",
                "species": "O",
                "index": 0
            }})
        self.initdef_list.append({
            "def1": {
                "type": "sub",
                "index": -1,
                "species": "O",
                "species_new": "N"
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "sub",
                "index": -1,
                "species": "O",
                "species_new": "N"
            },
            "def2": {
                "type": "vac",
                "index": -1,
                "species": "O",
                "index_offset_n1n2": -1
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "ad",
                "index": [-1],
                "species": ["O"],
                "species_new": "N",
                "shift_z": "3.0"
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "int",
                "index": [0, 0, 0, 0],
                "index_offset_n1": [0, 1, 0, 0],
                "index_offset_n2": [0, 0, 0, 2],
                "index_offset_n1n2": [0, 0, 1, 1],
                "species": 4 * ["O"],
                "species_new": "N"
            }
        })
        self.create_defects()

        self.siteinds_list = [[0], [17], [17, 8], [[17]], [[0, 3, 9, 11]]]
        self.defcoords_list = [[[0.0, 0.0, 0.1]], [[0.833333, 0.833333, 0.3]],
                               [[0.833333, 0.833333, 0.3],
                                [0.666667, 0.666667, 0.1]],
                               [[0.833333, 0.833333, 0.45]],
                               [[0.166667, 0.0, 0.2]]]
        self.natoms_list = [17, 18, 17, 19, 19]

    def create_defects(self):

        ## create defects

        self.defects_list = []

        for initdef in self.initdef_list:

            ## initialize defect object
            defect = gen_defect_supercells.Defect(self.structure_bulk,
                                                  self.structure.copy(),
                                                  self.nvecs, self.vacuum,
                                                  self.q)

            ## set the defect info (type, site, species) for each defect
            for d in initdef:
                initdef[d]["index_offset_n1"] = initdef[d].get(
                    "index_offset_n1", 0)
                initdef[d]["index_offset_n2"] = initdef[d].get(
                    "index_offset_n2", 0)
                initdef[d]["index_offset_n1n2"] = initdef[d].get(
                    "index_offset_n1n2", 0)
                defect_site, siteinds = defect.get_defect_site(initdef[d])
                defect.add_defect_info(initdef[d], defect_site)

            ## create defect(s)
            defect.remove_atom()
            defect.replace_atom()
            defect.add_atom()
            self.defects_list.append(defect)

    def test_get_site_index(self):

        ## test get_site_index returns the correct absolute site indices

        ## initialize dummy "defect" object
        defect = gen_defect_supercells.Defect(self.structure_bulk,
                                              self.structure.copy(),
                                              self.nvecs, self.vacuum, self.q)

        for initdef, siteinds in zip(self.initdef_list, self.siteinds_list):
            for d, siteind_ref in zip(initdef, siteinds):

                if initdef[d]["type"][0] == "v" or initdef[d]["type"][0] == "s":
                    siteind = defect.get_site_ind(
                        initdef[d]["index"], initdef[d]["species"],
                        initdef[d]["index_offset_n1"],
                        initdef[d]["index_offset_n2"],
                        initdef[d]["index_offset_n1n2"])
                    self.assertEqual(siteind, siteind_ref)

                if initdef[d]["type"][0] == "a" or initdef[d]["type"][0] == "i":
                    for siteindi_ref,ind,sp,offset_n1,offset_n2,offset_n1n2 \
                        in zip(siteind_ref,
                               initdef[d]["index"],
                               initdef[d]["species"],
                               initdef[d]["index_offset_n1"],
                               initdef[d]["index_offset_n2"],
                               initdef[d]["index_offset_n1n2"]):
                        siteind = defect.get_site_ind(ind, sp, offset_n1,
                                                      offset_n2, offset_n1n2)
                        self.assertEqual(siteind, siteindi_ref)

    def test_defcoords(self):

        ## test that the defect(s) are created at the correct position
        ## essentially tests the get_defect_site function

        for defects, defcoords_ref in zip(self.defects_list,
                                          self.defcoords_list):
            for defect_site, defcoord_ref in zip(defects.defect_site,
                                                 defcoords_ref):
                defcoord = defect_site.lattice.get_fractional_coords(
                    defect_site.coords)
                #                defcoord = defect_site.frac_coords
                for j in range(3):
                    self.assertAlmostEqual(defcoord[j] % 1 % 1,
                                           defcoord_ref[j] % 1 % 1,
                                           places=6)

    def test_natoms(self):

        ## test that the defect creation results in the correct number of atoms

        for defect, natoms in zip(self.defects_list, self.natoms_list):
            self.assertEqual(defect.structure.num_sites, natoms)
Ejemplo n.º 21
0
    def test_supercell_subsets(self):
        sm = StructureMatcher(ltol=0.2,
                              stol=0.3,
                              angle_tol=5,
                              primitive_cell=False,
                              scale=True,
                              attempt_supercell=True,
                              allow_subset=True,
                              supercell_size='volume')
        sm_no_s = StructureMatcher(ltol=0.2,
                                   stol=0.3,
                                   angle_tol=5,
                                   primitive_cell=False,
                                   scale=True,
                                   attempt_supercell=True,
                                   allow_subset=False,
                                   supercell_size='volume')
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Ag', 'Si', 'Si'],
                       [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]])
        s1.make_supercell([2, 1, 1])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]])

        shuffle = [0, 2, 1, 3, 4, 5]
        s1 = Structure.from_sites([s1[i] for i in shuffle])

        #test when s1 is exact supercell of s2
        result = sm.get_s2_like_s1(s1, s2)
        for a, b in zip(s1, result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species_and_occu, b.species_and_occu)

        self.assertTrue(sm.fit(s1, s2))
        self.assertTrue(sm.fit(s2, s1))
        self.assertTrue(sm_no_s.fit(s1, s2))
        self.assertTrue(sm_no_s.fit(s2, s1))

        rms = (0.048604032430991401, 0.059527539448807391)
        self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2), rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2, s1), rms))

        #test when the supercell is a subset of s2
        subset_supercell = s1.copy()
        del subset_supercell[0]
        result = sm.get_s2_like_s1(subset_supercell, s2)
        self.assertEqual(len(result), 6)
        for a, b in zip(subset_supercell, result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species_and_occu, b.species_and_occu)

        self.assertTrue(sm.fit(subset_supercell, s2))
        self.assertTrue(sm.fit(s2, subset_supercell))
        self.assertFalse(sm_no_s.fit(subset_supercell, s2))
        self.assertFalse(sm_no_s.fit(s2, subset_supercell))

        rms = (0.053243049896333279, 0.059527539448807336)
        self.assertTrue(np.allclose(sm.get_rms_dist(subset_supercell, s2),
                                    rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2, subset_supercell),
                                    rms))

        #test when s2 (once made a supercell) is a subset of s1
        s2_missing_site = s2.copy()
        del s2_missing_site[1]
        result = sm.get_s2_like_s1(s1, s2_missing_site)
        for a, b in zip((s1[i] for i in (0, 2, 4, 5)), result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species_and_occu, b.species_and_occu)

        self.assertTrue(sm.fit(s1, s2_missing_site))
        self.assertTrue(sm.fit(s2_missing_site, s1))
        self.assertFalse(sm_no_s.fit(s1, s2_missing_site))
        self.assertFalse(sm_no_s.fit(s2_missing_site, s1))

        rms = (0.029763769724403633, 0.029763769724403987)
        self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2_missing_site), rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2_missing_site, s1), rms))
Ejemplo n.º 22
0
#%%

import math
from pymatgen import Structure, Molecule, Lattice
import os

os.chdir(
    '/home/jinho93/oxides/perobskite/lanthanum-aluminate/slab/gulp/nonstochio/La-vac/two'
)

m = Molecule.from_file('tail.xyz')
l = Lattice.from_lengths_and_angles([11.46615, 15.2882, 50], [90, 90, 90])

s = Structure(l, m.species, m.cart_coords, coords_are_cartesian=True)
s.make_supercell([[4, 0, 0], [0, 3, 0], [0, 0, 1]])
s.make_supercell([[1, 1, 0], [1, -1, 0], [0, 0, 1]])
s.sort()
# ll = Lattice.from_lengths_and_angles([s.lattice.a / 2, s.lattice.b / 2, s.lattice.c], s.lattice.angles)
ll = Lattice.from_lengths_and_angles(s.lattice.abc, s.lattice.angles)
s = Structure(ll, s.species, s.cart_coords, coords_are_cartesian=True)

indi = []
for i, site in enumerate(s.sites):
    if site.x + site.y < ll.b / math.sqrt(2):
        indi.append(i)

# s.remove_sites(indi)

# s = Structure(ll, s.species, s.cart_coords, coords_are_cartesian=True)

# s.to('POSCAR', 'POSCAR')
    def angle_calculation(self, connected_nodes, loc):
        angle = []
        nn_coords = []

        str_formula = str(self.structure.species_and_occu[loc].formula)
        nodes = np.array([node for node in connected_nodes \
            if self.structure.species_and_occu[node] == self.structure.species_and_occu[loc]])

        #get nearest magnetic_metal angle neighbors with a tolerance of 0.1 A.
        lattice_species = [
            self.structure.species_and_occu[node] for node in nodes
        ]
        s = Structure(self.structure.lattice, lattice_species,
                      self.frac_coords[nodes])
        s.make_supercell([3, 3, 3])
        new_frac_coords = np.round(s.frac_coords, decimals=3)
        new_frac_coords[new_frac_coords == 1.] = 0.
        distances = []
        for i in range(len(new_frac_coords)):
            distances.append(
                np.linalg.norm(
                    s.lattice.get_cartesian_coords(new_frac_coords[i]) -
                    s.lattice.get_cartesian_coords([0.5, 0.5, 0.5])))

        new_loc = np.argmin(distances)
        loc_cart_coords = s.lattice.get_cartesian_coords(
            new_frac_coords[new_loc])

        #identify the two closest same species to the specie under consideration (new_loc)
        nodes = np.arange(len(s))
        distances = [s.distance_matrix[node, new_loc] for node in nodes]
        nodes = nodes[np.argsort(distances)]
        distances = np.sort(distances)

        #identify other potential second closest atoms. Useful if there are multiple such atoms.
        min_dist_node1 = nodes[1]
        try:  #for 1D compounds. Not applicable now.
            min_dist_node2 = nodes[2]
        except IndexError:
            angle = '180.0'
            nn_coords = [
                s.lattice.get_cartesian_coords(new_frac_coords[nodes[1]]) -
                loc_cart_coords
            ]
            return angle, nn_coords

        nnn_list = [
            nodes[i] for i in range(2, len(nodes))
            if distances[i] < distances[2] + 0.1
        ]
        #get the image of the neighbors if they are closer than the one inside the cell

        nnn_coords = []
        for node in nnn_list:
            nnn_coords.append(
                s.lattice.get_cartesian_coords(new_frac_coords[node]))

        #get the angles between the atoms and take the non-zero minimum value.
        angles = []
        v1 = s.lattice.get_cartesian_coords(
            new_frac_coords[min_dist_node1]) - loc_cart_coords
        for coords in nnn_coords:
            v2 = coords - loc_cart_coords
            cos_theta = np.dot(v1,
                               v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
            if np.round(cos_theta, decimals=1) == -1.0:
                angles.append(180.0)
            else:
                angles.append(np.arccos(cos_theta) * 180 / np.pi)
        try:
            angle.append(min(i for i in angles if i > 0.1))
        except ValueError:
            angle.append(0.0)
        angle = str(np.round(min(angle), decimals=2))

        nn_list = [
            nodes[i] for i in range(1, len(nodes))
            if distances[i] <= distances[1] + 0.1
        ]
        for node in nn_list:
            nn_coords.append(
                s.lattice.get_cartesian_coords(new_frac_coords[node]))
        nn_coords = [coord - loc_cart_coords for coord in nn_coords]
        return angle, nn_coords
Ejemplo n.º 24
0
    def test_supercell_subsets(self):
        sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                              primitive_cell=False, scale=True,
                              attempt_supercell=True, allow_subset=True,
                              supercell_size='volume')
        sm_no_s = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                   primitive_cell=False, scale=True,
                                   attempt_supercell=True, allow_subset=False,
                                   supercell_size='volume')
        l = Lattice.orthorhombic(1, 2, 3)
        s1 = Structure(l, ['Ag', 'Si', 'Si'],
                       [[.7, .4, .5], [0, 0, 0.1], [0, 0, 0.2]])
        s1.make_supercell([2, 1, 1])
        s2 = Structure(l, ['Si', 'Si', 'Ag'],
                       [[0, 0.1, -0.95], [0, 0.1, 0], [-.7, .5, .375]])

        shuffle = [0, 2, 1, 3, 4, 5]
        s1 = Structure.from_sites([s1[i] for i in shuffle])

        # test when s1 is exact supercell of s2
        result = sm.get_s2_like_s1(s1, s2)
        for a, b in zip(s1, result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species, b.species)

        self.assertTrue(sm.fit(s1, s2))
        self.assertTrue(sm.fit(s2, s1))
        self.assertTrue(sm_no_s.fit(s1, s2))
        self.assertTrue(sm_no_s.fit(s2, s1))

        rms = (0.048604032430991401, 0.059527539448807391)
        self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2), rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2, s1), rms))

        # test when the supercell is a subset of s2
        subset_supercell = s1.copy()
        del subset_supercell[0]
        result = sm.get_s2_like_s1(subset_supercell, s2)
        self.assertEqual(len(result), 6)
        for a, b in zip(subset_supercell, result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species, b.species)

        self.assertTrue(sm.fit(subset_supercell, s2))
        self.assertTrue(sm.fit(s2, subset_supercell))
        self.assertFalse(sm_no_s.fit(subset_supercell, s2))
        self.assertFalse(sm_no_s.fit(s2, subset_supercell))

        rms = (0.053243049896333279, 0.059527539448807336)
        self.assertTrue(np.allclose(sm.get_rms_dist(subset_supercell, s2), rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2, subset_supercell), rms))

        # test when s2 (once made a supercell) is a subset of s1
        s2_missing_site = s2.copy()
        del s2_missing_site[1]
        result = sm.get_s2_like_s1(s1, s2_missing_site)
        for a, b in zip((s1[i] for i in (0, 2, 4, 5)), result):
            self.assertTrue(a.distance(b) < 0.08)
            self.assertEqual(a.species, b.species)

        self.assertTrue(sm.fit(s1, s2_missing_site))
        self.assertTrue(sm.fit(s2_missing_site, s1))
        self.assertFalse(sm_no_s.fit(s1, s2_missing_site))
        self.assertFalse(sm_no_s.fit(s2_missing_site, s1))

        rms = (0.029763769724403633, 0.029763769724403987)
        self.assertTrue(np.allclose(sm.get_rms_dist(s1, s2_missing_site), rms))
        self.assertTrue(np.allclose(sm.get_rms_dist(s2_missing_site, s1), rms))
class Test2D_WSe2(Test2D):
    def setUp(self):

        ## hexagonal WSe2 unitcell

        self.a0 = 3.287596
        self.c = 23.360843

        self.structure = Structure(
            Lattice.from_parameters(a=self.a0,
                                    b=self.a0,
                                    c=self.c,
                                    alpha=90,
                                    beta=90,
                                    gamma=120), ["W", "Se", "Se"],
            [[0.0, 0.0, 0.5], [0.333333, 0.666667, 0.571091],
             [0.333333, 0.666667, 0.428909]])

        self.nvecs = [4, 4, 1]
        self.vacuum = 20
        self.q = 0
        self.structure.make_supercell(self.nvecs)
        self.structure_bulk = self.structure.copy()

        self.initdef_list = []
        self.initdef_list.append(
            {"def1": {
                "type": "vac",
                "species": "Se",
                "index": 0
            }})
        self.initdef_list.append({
            "def1": {
                "type": "sub",
                "index": -1,
                "species": "W",
                "species_new": "Re"
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "sub",
                "index": -1,
                "species": "W",
                "species_new": "Re"
            },
            "def2": {
                "type": "vac",
                "index": -1,
                "species": "Se",
                "index_offset_n1n2": -1
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "ad-W",
                "index": [-1],
                "species": ["W"],
                "species_new": "Re",
                "shift_z": "3.36"
            }
        })
        self.initdef_list.append({
            "def1": {
                "type": "int-hex",
                "index": [0, 1, 0],
                "index_offset_n1": [1, 1, 0],
                "species": 3 * ["W"],
                "species_new": "Re"
            }
        })
        self.create_defects()

        self.siteinds_list = [[16], [15], [15, 31], [[15]], [[4, 5, 0]]]
        self.defcoords_list = [[[0.083333, 0.166667, 0.571091]],
                               [[0.75, 0.75, 0.5]],
                               [[0.75, 0.75, 0.5],
                                [0.833333, 0.916667, 0.571091]],
                               [[0.75, 0.75, 0.643830]],
                               [[0.166667, 0.083333, 0.5]]]
        self.natoms_list = [47, 48, 47, 49, 49]