Beispiel #1
0
    def cons_max_volume(self, sites, max_volume, min_volume=1, dimension=3, symprec=1e-5):
        """
        parameters:

        pcell: Cell object, The primitive cell to be extended
        sites: disorderd sites infomation.

        yield:

        Cell object, a list of non-redundant configurations to max volume supercells.

        """
        # 该函数产生所有构型用于确定基态相图
        for volume in range(min_volume, max_volume + 1):
            hnfs = non_dup_hnfs(self._pcell, volume, dimension, symprec)
            dict_trans = {}  # 记录已经产生过的snf,相同snf的平移操作相同。
            for h in hnfs:
                hfpg = PermutationGroup(self._pcell, h)
                # 此处的平移操作不必每次重新计算,因为相同snf平移操作相同
                # 可以用字典来标记查询。若没有这样的操作,那么就没有snf带来的效率提升。
                # quotient = hfpg.get_quotient()
                # if not quotient in dict_trans:
                #     dict_trans[quotient] = hfpg.get_pure_translations(symprec)
                # trans = dict_trans[quotient]
                # rots = hfpg.get_pure_rotations(symprec)
                perms = hfpg.get_symmetry_perms(symprec)

                supercell = self._pcell.extend(h)
                _sites = numpy.repeat(sites, volume, axis=0)

                for mol, _ in remove_redundant(supercell.positions, _sites, perms):
                    c = Cell(supercell.lattice, mol[0], mol[1])
                    if c.is_primitive(symprec):
                        yield c
Beispiel #2
0
    def test_check(self):
        lattice = numpy.array([0.0, 2.75, 2.75,
                               2.75, 0.0, 2.75,
                               2.75, 2.75, 0.0])
        si_pos = [-0.125, -0.125, -0.125,
                  0.125, 0.125, 0.125]
        si_atoms = [14, 14]
        cell = Cell(lattice, si_pos, si_atoms)
        self.assertTrue(cell.check(limit=0.1))

        si_pos = [-0.125, -0.125, -0.125,
                  0.125, 0.125, 0.125,
                  0.13, 0.125, 0.125]
        si_atoms = [14, 14, 8]
        cell = Cell(lattice, si_pos, si_atoms)
        self.assertFalse(cell.check(limit=0.1))
        # 测试元素
        self.assertTrue(cell.check(limit=0.1, elements=['O']))

        lattice = numpy.array([1.0, 0.0, 0.0,
                               0.0, 1.0, 0.0,
                               0.0, 0.0, 1.0])
        si_pos = [-0.01, 0.0, 0.0,
                  0.01, 0.0, 0.0]
        si_atoms = [14, 14]
        # 两点之间的距离为0.02<0.05, 但在没有考虑边界条件时距离是0.98
        cell = Cell(lattice, si_pos, si_atoms)
        self.assertFalse(cell.check(limit=0.05))
Beispiel #3
0
 def test_get_primitive(self):
     fcc_latt = [5, 0, 0, 0, 5, 0, 0, 0, 5]
     fcc_pos = [(0, 0, 0), (0, 0.5, 0.5), (0.5, 0, 0.5), (0.5, 0.5, 0)]
     fcc_atoms = [0, 0, 0, 0]
     con_cell = Cell(fcc_latt, fcc_pos, fcc_atoms)
     pcell = con_cell.get_primitive_cell()
     self.assertEqual(pcell.atoms, [0])
Beispiel #4
0
    def test_extend_not_hnf(self):
        fcc_latt = [0, 5, 5,
                    5, 0, 5,
                    5, 5, 0]
        fcc_pos = [(0, 0, 0),
                   (0.5, 0.5, 0.5)]
        fcc_atoms = [1, 2]
        fcc_pcell = Cell(fcc_latt, fcc_pos, fcc_atoms)
        op_ext = numpy.array([-1, 1, 1,
                              1, -1, 1,
                              1, 1, -1]).reshape((3, 3))
        ext_fcc = fcc_pcell.extend(op_ext)

        wanted_latt = numpy.array([10, 0, 0,
                                   0, 10, 0,
                                   0, 0, 10]).reshape((3, 3))
        wanted_pos = numpy.array([(0, 0, 0),
                                  (0.5, 0.5, 0),
                                  (0.5, 0, 0.5),
                                  (0, 0.5, 0.5),
                                  (0.5, 0.5, 0.5),
                                  (0, 0, 0.5),
                                  (0, 0.5, 0),
                                  (0.5, 0, 0)])
        wanted_atoms = numpy.array([1, 1, 1, 1, 2, 2, 2, 2])
        numpy.testing.assert_almost_equal(ext_fcc.lattice, wanted_latt)
        numpy.testing.assert_almost_equal(ext_fcc.positions, wanted_pos)
        numpy.testing.assert_almost_equal(ext_fcc.atoms, wanted_atoms)
Beispiel #5
0
 def test_extend_bug(self):
     sc_latt = [4, 0, 0, 0, 4, 0, 0, 0, 4]
     sc_pos = [(0, 0, 0)]
     sc_atoms = [1]
     sc_pcell = Cell(sc_latt, sc_pos, sc_atoms)
     op_ext = numpy.array([1, 0, 0, 0, 1, 0, 0, 0, 5]).reshape((3, 3))
     ext_sc = sc_pcell.extend(op_ext)  # raise ValueError
     pass
Beispiel #6
0
 def test_is_primitive(self):
     bcc_latt = [0.5, 0.5, -0.5,
                 -0.5, 0.5, 0.5,
                 0.5, -0.5, 0.5]
     bcc_pos = [(0, 0, 0)]
     bcc_atoms = [0]
     bcc_pcell = Cell(bcc_latt, bcc_pos, bcc_atoms)
     self.assertTrue(bcc_pcell.is_primitive())
Beispiel #7
0
    def setUp(self):
        # BCC
        bcc_latt = [0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5]
        bcc_pos = [(0, 0, 0)]
        bcc_atoms = [0]
        self.bcc_pcell = Cell(bcc_latt, bcc_pos, bcc_atoms)

        # FCC
        fcc_latt = [0, 5, 5, 5, 0, 5, 5, 5, 0]
        fcc_pos = [(0, 0, 0)]
        fcc_atoms = [0]
        self.fcc_pcell = Cell(fcc_latt, fcc_pos, fcc_atoms)
Beispiel #8
0
    def cons_specific_volume(self, sites, volume=2, e_num=None, dimension=3, symprec=1e-5):
        """
        parameters:

        sites: 2D list, disorderd sites infomation.
        volume: int, certain volume with subperiodic.
        symprec: float, precision for symmetry find.

        yield:

        a tuple
        tuple[0]: Cell object, a list of non-redundant configurations of certain volume supercell.
        tuple[1]: int object, degeneracy of the configuration in all configurations of this volume.
        """
        # 该函数产生特定体积下所有构型(包括超胞)和简并度,用于统计平均
        hnfs = non_dup_hnfs(self._pcell, volume, dimension, symprec)
        dict_trans = {}
        for h in hnfs:
            hfpg = PermutationGroup(self._pcell, h)
            # 此处的平移操作不必每次重新计算,因为相同snf平移操作相同
            # 可以用字典来标记查询。若没有这样的操作,那么就没有snf带来的效率提升。
            # For hnf with same snf, translations are same.
            # quotient = hfpg.get_quotient()
            # if not quotient in dict_trans:
            #     dict_trans[quotient] = hfpg.get_pure_translations(symprec)
            # trans = dict_trans[quotient]
            # rots = hfpg.get_pure_rotations(symprec)
            perms = hfpg.get_symmetry_perms(symprec)

            supercell = self._pcell.extend(h)
            _sites = numpy.repeat(sites, volume, axis=0)

            for mol, d in remove_redundant(supercell.positions, _sites, perms, e_num):
                c = Cell(supercell.lattice, mol[0], mol[1])
                yield (c, d)
Beispiel #9
0
    def test_Cart_string(self):
        data = '''C2
1.0
        4.9208798409         0.0000000000         0.0000000000
       -2.4604404879         4.2616066235         0.0000000000
        0.0000000000         0.0000000000        10.0000000000
    C
    8
Cartesian
     0.000000000         0.000000000         0.000000000
    -1.230220199         2.130803347         0.000000000
     2.460439920         0.000000000         0.000000000
     1.230219722         2.130803347         0.000000000
     1.230232477         0.710260868         0.000000000
     0.000012159         2.841064692         0.000000000
     3.690671921         0.710260868         0.000000000
     2.460451603         2.841064692         0.000000000
'''
        latt = [[4.9208798409, 0.0000000000, 0.0000000000],
                [-2.4604404879, 4.2616066235, 0.0000000000],
                [0.0000000000, 0.0000000000, 10.0000000000]]
        positions = [[0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
                     [1.32703105e-08, 5.00000008e-01, 0.00000000e+00],
                     [5.00000000e-01, 0.00000000e+00, 0.00000000e+00],
                     [5.00000013e-01, 5.00000008e-01, 0.00000000e+00],
                     [3.33335086e-01, 1.66665047e-01, 0.00000000e+00],
                     [3.33335131e-01, 6.66665167e-01, 0.00000000e+00],
                     [8.33334989e-01, 1.66665047e-01, 0.00000000e+00],
                     [8.33335035e-01, 6.66665167e-01, 0.00000000e+00]]
        atoms = ['C' for i in range(8)]
        wanted = Cell(latt, positions, atoms)
        got = _read_string(data)
        self.assertLess(numpy.sum(abs(got.positions - wanted.positions)), 1e-4)
Beispiel #10
0
    def setUp(self):
        lattice = numpy.array([7.1, 0, 0, 0, 7.1, 0, 0, 0, 7.1]).reshape(
            (3, 3))
        positions = numpy.array([
            0.00, 0.00, 0.00, 0.00, 0.00, 0.50, 0.00, 0.50, 0.00, 0.00, 0.50,
            0.50, 0.50, 0.00, 0.00, 0.50, 0.00, 0.50, 0.50, 0.50, 0.00, 0.50,
            0.50, 0.50, 0.00, 0.25, 0.25, 0.00, 0.25, 0.75, 0.00, 0.75, 0.25,
            0.00, 0.75, 0.75, 0.50, 0.25, 0.25, 0.50, 0.25, 0.75, 0.50, 0.75,
            0.25, 0.50, 0.75, 0.75, 0.25, 0.00, 0.25, 0.25, 0.00, 0.75, 0.25,
            0.50, 0.25, 0.25, 0.50, 0.75, 0.75, 0.00, 0.25, 0.75, 0.00, 0.75,
            0.75, 0.50, 0.25, 0.75, 0.50, 0.75, 0.25, 0.25, 0.00, 0.25, 0.25,
            0.50, 0.25, 0.75, 0.00, 0.25, 0.75, 0.50, 0.75, 0.25, 0.00, 0.75,
            0.25, 0.50, 0.75, 0.75, 0.00, 0.75, 0.75, 0.50
        ])
        atoms = numpy.array([28] * 32)
        cell = Cell(lattice, positions, atoms)

        mcell = cell_to_mcell(cell)
        mcell.set_site(0, ([0, 0, 0], 'Co'))
        mcell.set_site(16, ([0.25, 0, 0.25], 'Co'))
        self.cell_nearest_1 = mcell.to_cell()

        mcell = cell_to_mcell(cell)
        mcell.set_site(0, ([0, 0, 0], 'Co'))
        mcell.set_site(21, ([0.75, 0, 0.75], 'Co'))
        self.cell_nearest_2 = mcell.to_cell()

        mcell = cell_to_mcell(cell)
        mcell.set_site(1, ([0, 0, 0.5], 'Co'))
        mcell.set_site(5, ([0.5, 0, 0.5], 'Co'))
        self.cell_far = mcell.to_cell()
Beispiel #11
0
    def cons_specific_cell(self, sites, e_num=None, symprec=1e-5):
        """
        cons_specific_cell_and_c generate configurations of specific cell
        and specific concentration.

        parameters:
        sites: list of (lists or tuples), represent element disorder of each sites
        e_num: tuple, number of atoms in disorderd sites.

        e_num 特指无序位点的浓度,也就是原子比,而不是整体构型的元素原子比。有可能其他位点存在相同构型。
        !!限制,无序位点的组成必须是相同的,而上面几个函数的无序位点是可以不同的。!!
        """
        lat_cell = self._cell.lattice
        lat_pcell = self._pcell.lattice
        mat = numpy.matmul(lat_cell, numpy.linalg.inv(lat_pcell))
        if is_int_np_array(mat):
            mat = numpy.around(mat).astype('intc')
        else:
            print("cell:\n", lat_cell)
            print("primitive cell:\n", lat_pcell)
            raise ValueError(
                "cell lattice and its primitive cell lattice not convertable")
        hfpg = PermutationGroup(self._pcell, mat)

        perms = hfpg.get_symmetry_perms(symprec)

        supercell = self._pcell.extend(mat)
        for mol, d in remove_redundant(supercell.positions, sites, perms, e_num=e_num):
            c = Cell(supercell.lattice, mol[0], mol[1])
            yield (c, d)
Beispiel #12
0
def get_max_volume(pcell, sites, max_volume, min_volume=1, dimension=3, symprec=1e-5):
    for volume in range(min_volume, max_volume + 1):
        hnfs = non_dup_hnfs(pcell, volume, dimension, symprec)
        dict_trans = {}  # 记录已经产生过的snf,相同snf的平移操作相同。
        for h in hnfs:
            hfpg = PG(pcell, h)
            perms = hfpg.get_symmetry_perms(symprec)
            if dimension == 2:
                supercell = pcell.extend(h)._get_niggli_2D()
            else:
                supercell = pcell.extend(h)._get_niggli_3D()
            _sites = np.repeat(sites, volume, axis=0)
            for mol, _ in remove_redundant(supercell.positions, _sites, perms):
                c = Cell(supercell.lattice, mol[0], mol[1])
                if c.is_primitive(symprec):
                    yield c
Beispiel #13
0
 def setUp(self):
     fcc_latt = [0, 5, 5,
                 5, 0, 5,
                 5, 5, 0]
     fcc_pos = [(0, 0, 0), (0.5, 0.5, 0.5)]
     fcc_atoms = [1, 2]
     self.fcc_pcell = Cell(fcc_latt, fcc_pos, fcc_atoms)
Beispiel #14
0
def read(ase_atoms):
    if isinstance(ase_atoms, Atoms):
        lattice = ase_atoms.get_cell(complete=False)
        positions = ase_atoms.get_positions(wrap=False)
        atoms = ase_atoms.get_atomic_numbers()
        return Cell(lattice, positions, atoms)
    else:
        raise TypeError("The value is not an ase.Atoms object")
Beispiel #15
0
 def setUp(self):
     lattice = numpy.array([5.5, 0, 0, 0, 5.5, 0, 0, 0, 5.5]).reshape(
         (3, 3))
     positions = numpy.array([
         0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.5, 0.5, 0.5, 0.0, 0.5,
         0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5
     ])
     atoms = numpy.array([11, 11, 11, 11, 17, 17, 17, 17])
     self.cell = Cell(lattice, positions, atoms)
Beispiel #16
0
    def test_cons_specific_cell_and_c(self):
        # FCC conventional cell
        fcc_latt = [5, 0, 0,
                    0, 5, 0,
                    0, 0, 5]
        fcc_pos = [(0, 0, 0),
                   (0, 0.5, 0.5),
                   (0.5, 0, 0.5),
                   (0.5, 0.5, 0)]
        fcc_atoms = [0, 0, 0, 0]
        con_cell = Cell(fcc_latt, fcc_pos, fcc_atoms)
        cg = CG(con_cell)
        con = cg.cons_specific_cell(
            [(2, 3, 4), (2, 3, 4), (2, 3, 4), (2, 3, 4)], e_num=(2, 1, 1))

        # number of all configurations
        wanted = 1
        got = len([i for i in con])

        self.assertEqual(got, wanted)

        # Zinc-blende conventional cell
        fcc_latt = [5, 0, 0,
                    0, 5, 0,
                    0, 0, 5]
        fcc_pos = [(0, 0, 0),
                   (0, 0.5, 0.5),
                   (0.5, 0, 0.5),
                   (0.5, 0.5, 0),
                   (0.25, 0.25, 0.25),
                   (0.75, 0.75, 0.25),
                   (0.75, 0.25, 0.75),
                   (0.25, 0.75, 0.75)]
        fcc_atoms = [0, 0, 0, 0, 1, 1, 1, 1]
        con_cell = Cell(fcc_latt, fcc_pos, fcc_atoms)
        cg = CG(con_cell)
        con = cg.cons_specific_cell(
            [(2, 3, 4), (2, 3, 4), (2, 3, 4), (2, 3, 4), (1, ), (1, ), (1, ), (1,)], e_num=(2, 1, 1))

        # number of all configurations
        wanted = 1
        got = len([i for i in con])

        self.assertEqual(got, wanted)
Beispiel #17
0
 def setUp(self):
     lattice = [3.0, 0, 0, 0, 2.0, 0, 0, 0, 1.0]
     positions = [(0.00000, 0.00000, 0.00000), (0.00000, 0.50000, 0.00000),
                  (0.33333, 0.00000, 0.00000), (0.33333, 0.50000, 0.00000),
                  (0.66666, 0.00000, 0.00000), (0.66666, 0.50000, 0.00000),
                  (0.16666, 0.25000, 0.50000), (0.16666, 0.75000, 0.50000),
                  (0.50000, 0.25000, 0.50000), (0.50000, 0.75000, 0.50000),
                  (0.83333, 0.25000, 0.50000), (0.83333, 0.75000, 0.50000)]
     atoms = ['C'] * 12
     self.cell = Cell(lattice, positions, atoms)
Beispiel #18
0
    def setUp(self):
        # BCC
        bcc_latt = [1, 1, -1, -1, 1, 1, 1, -1, 1]
        bcc_pos = [(0, 0, 0)]
        bcc_atoms = [0]
        self.bcc_pcell = Cell(bcc_latt, bcc_pos, bcc_atoms)

        # FCC
        fcc_latt = [0, 5, 5, 5, 0, 5, 5, 5, 0]
        fcc_pos = [(0, 0, 0)]
        fcc_atoms = [0]
        self.fcc_pcell = Cell(fcc_latt, fcc_pos, fcc_atoms)

        # HCP
        hcp_b = [
            2.51900005, 0., 0., -1.25950003, 2.18151804, 0., 0., 0., 4.09100008
        ]
        hcp_positions = [(0.33333334, 0.66666669, 0.25),
                         (0.66666663, 0.33333331, 0.75)]
        hcp_numbers = [0, 0]
        self.hcp_pcell = Cell(hcp_b, hcp_positions, hcp_numbers)
Beispiel #19
0
    def test_cell_to_mcell(self):
        si_pos = [(-0.125, -0.125, -0.125), (0.125, 0.125, 0.125)]
        si_atoms = [14, 14]
        c = Cell(self.lattice, si_pos, si_atoms)
        mc = cell_to_mcell(c)
        self.assertTrue(isinstance(mc, MutableCell))

        # 转换回去,并测试返回后的数据结构
        c = mc.to_cell()
        numpy.testing.assert_almost_equal(
            c.positions,
            numpy.array([0.875, 0.875, 0.875, 0.125, 0.125, 0.125]).reshape(
                (2, 3)))
        numpy.testing.assert_almost_equal(c.atoms, numpy.array([14, 14]))
Beispiel #20
0
    def setUp(self):
        self.string = '''H1 He1
 1.000000
    0.000000   0.500000   0.533333
    0.500000   0.000000   0.566667
    0.500000   0.500000   0.000000
H He
1 1
Direct
  0.000000 0.000000 0.000000 H
  0.250000 0.250000 0.250000 He
'''
        latt = [0., 0.5, 0.53333333333, 0.5, 0., 0.56666666667, 0.5, 0.5, 0.]
        positions = [0., 0., 0., 0.25, 0.25, 0.25]
        atoms = ['H', 'He']
        self.cell = Cell(latt, positions, atoms)
Beispiel #21
0
    def test_cons_specific_cell(self):
        fcc_latt = [5, 0, 0,
                    0, 5, 0,
                    0, 0, 5]
        fcc_pos = [(0, 0, 0),
                   (0, 0.5, 0.5),
                   (0.5, 0, 0.5),
                   (0.5, 0.5, 0)]
        fcc_atoms = [0, 0, 0, 0]
        con_cell = Cell(fcc_latt, fcc_pos, fcc_atoms)
        cg = CG(con_cell)
        con = cg.cons_specific_cell([(2, 3), (2, 3), (2, 3), (2, 3)])

        # number of all configurations
        wanted = 5
        got = len([i for i in con])

        self.assertEqual(got, wanted)
Beispiel #22
0
    def test_from_cell(self):
        lattice = numpy.copy(self.lattice)
        positions = numpy.array([0.0, 0.0, 0.0,
                                 0.25, 0.25, 0.25]).reshape((2, 3))
        atoms = numpy.array([6, 6])
        origin_lattice = numpy.copy(lattice)
        origin_positions = numpy.copy(positions)
        origin_atoms = numpy.copy(atoms)

        cell = Cell(lattice, positions, atoms)
        mcell = MutableCell.from_cell(cell)
        self.assertTrue(isinstance(mcell, MutableCell))

        # Make sure mcell modified not change the cell
        mcell.remove_site(0)
        numpy.testing.assert_almost_equal(cell.lattice, origin_lattice)
        numpy.testing.assert_almost_equal(cell.positions, origin_positions)
        numpy.testing.assert_almost_equal(cell.atoms, origin_atoms)
Beispiel #23
0
    def test_write_string_vacc(self):
        wanted = '''H1
 1.000000
    0.000000   0.500000   0.533333
    0.500000   0.000000   0.566667
    0.500000   0.500000   0.000000
H
1
Direct
  0.000000 0.000000 0.000000 H
'''
        latt = [0., 0.5, 0.53333333333, 0.5, 0., 0.56666666667, 0.5, 0.5, 0.]
        positions = [0., 0., 0., 0.25, 0.25, 0.25]
        atoms = ['H', 'Vacc']
        cell = Cell(latt, positions, atoms)

        got = _write_string(cell, long_format=False)

        self.assertEqual(got, wanted)
Beispiel #24
0
 def get_tetrahedral_defect(self,
                            isunique=False,
                            doped_in='H',
                            min_d=1.5,
                            folder='tetrahedral-defect'):
     all_basis = generate_all_basis(1, 1, 1)
     direct_lattice = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
     extend_S = np.zeros((0, 3))
     for basis in all_basis:
         new_basis = np.sum([(direct_lattice[ii] * basis[ii]).tolist()
                             for ii in range(3)],
                            axis=0)
         extend_S = np.vstack(
             (extend_S,
              self.positions + np.tile(new_basis, len(self.atoms)).reshape(
                  (-1, 3))))
     idx = np.sum((extend_S <= 1.2) & (extend_S >= -0.2), axis=1)
     idx = np.where(idx == 3)[0]
     extend_S = np.dot(extend_S[idx], self.lattice)
     n = extend_S.shape[0]
     d = np.zeros((n, n))
     for ii in range(n):
         d[ii, ii + 1:] = np.linalg.norm(extend_S[ii] - extend_S[ii + 1:],
                                         axis=1)
     d = d + d.T
     first_tetra, sec_tetra, third_tetra = [], [], []
     for ii in range(n):
         temp_d = sorted(d[ii])
         idx = np.where(abs(d[ii] - temp_d[1]) < min_d)[0]
         if len(idx) < 3:
             continue
         for comb in combinations(idx, 3):
             comb_list = list(comb)
             tmp = d[comb_list][:, comb_list]
             comb_list.append(ii)
             if np.std(tmp[tmp > 0]) < 0.01:
                 if abs(tmp[0, 1] - temp_d[1]) < 0.1:
                     first_tetra.append(comb_list)
                 else:
                     sec_tetra.append(comb_list)
             else:
                 tmp = d[comb_list][:, comb_list]
                 tmp = np.triu(tmp)
                 tmp = sorted(tmp[tmp > 0])
                 if (np.std(tmp[0:4]) < 0.1 or np.std(tmp[1:5]) < 0.1
                         or np.std(tmp[2:]) < 0.1) and np.std(tmp) < 0.5:
                     third_tetra.append(comb_list)
     all_tetra = []
     if len(first_tetra) != 0:
         first_tetra = np.unique(np.sort(first_tetra, axis=1), axis=0)
         first_tetra = refine_points(first_tetra,
                                     extend_S,
                                     self.lattice,
                                     min_d=min_d)
         all_tetra.append(first_tetra)
     if len(sec_tetra) != 0:
         sec_tetra = np.unique(np.sort(sec_tetra, axis=1), axis=0)
         sec_tetra = refine_points(sec_tetra,
                                   extend_S,
                                   self.lattice,
                                   min_d=min_d)
         all_tetra.append(sec_tetra)
     if len(third_tetra) != 0:
         third_tetra = np.unique(np.sort(third_tetra, axis=1), axis=0)
         third_tetra = refine_points(third_tetra,
                                     extend_S,
                                     self.lattice,
                                     min_d=min_d)
         all_tetra.append(third_tetra)
     if isunique:
         if not os.path.exists(folder):
             os.mkdir(folder)
         else:
             rmtree(folder)
             os.mkdir(folder)
         idx = 0
         # deg = []
         for tetra in all_tetra:
             if len(tetra) == 0:
                 continue
             new_pos = np.vstack((self.positions, tetra))
             new_atoms = np.hstack((self.atoms, s2n(doped_in) * np.ones(
                 (tetra.shape[0], ))))
             new_cell = Cell(self.lattice, new_pos, new_atoms)
             equi_atoms = new_cell.get_symmetry()['equivalent_atoms']
             purity_atom_type = np.unique(equi_atoms[-tetra.shape[0]:])
             for atom_type in purity_atom_type:
                 new_uniq_pos = np.vstack(
                     (self.positions, new_pos[atom_type]))
                 new_uniq_atoms = np.hstack(
                     (self.atoms, s2n(doped_in) * np.ones((1, ))))
                 new_uniq_cell = Cell(self.lattice, new_uniq_pos,
                                      new_uniq_atoms)
                 # deg.append(len(np.where(equi_atoms == atom_type)[0]))
                 write_poscar(new_uniq_cell, folder, idx)
                 idx += 1
         # np.savetxt(folder+'/deg.txt',deg,fmt='%d')
     else:
         if not os.path.exists(folder):
             os.mkdir(folder)
         else:
             rmtree(folder)
             os.mkdir(folder)
         idx = 0
         for tetra in all_tetra:
             if len(tetra) == 0:
                 continue
             new_pos = np.vstack((self.positions, tetra))
             new_atoms = np.hstack((self.atoms, s2n(doped_in) * np.ones(
                 (tetra.shape[0], ))))
             new_cell = Cell(self.lattice, new_pos, new_atoms)
             write_poscar(new_cell, folder, idx)
             idx += 1
Beispiel #25
0
neig_list = np.zeros((n, 6))
for ii in range(pos.shape[0]):
    d = np.linalg.norm(pos[ii] - extend_pos, axis=1)
    idx = np.where(abs(d - d[np.argsort(d)[1]]) < 0.01)[0]
    neig_list[ii] = idx % n

pos = np.dot(pos, np.linalg.inv(latt))
vac_str = [np.array([0])]
for vac in range(2, 6):
    last_vac_str = vac_str[-1]
    tmp_vac_str = []
    n_prev = last_vac_str.shape[0]
    for i in range(n_prev):
        each_str = last_vac_str[i]
        idx = np.setdiff1d(np.setdiff1d(range(n), each_str),
                           neig_list[each_str][:])
        for ii in idx:
            tmp_vac_str.append(get_min_serial(perms, np.hstack(
                (each_str, ii))))
    vac_str.append(np.unique(tmp_vac_str, axis=0))
    idx = 0
    os.makedirs('vac-' + str(vac))
    for _str in vac_str[-1]:
        _pos = pos[np.setdiff1d(range(n), _str), :]
        _latt, _atoms = latt, np.ones((n - vac, )) * 5
        write_vasp(Cell(_latt, _pos, _atoms),
                   'vac-' + str(vac) + '/POSCAR' + str(idx))
        idx += 1
    print(vac_str[-1].shape)
Beispiel #26
0
class TestHnf(unittest.TestCase):
    def test(self):
        pass

    def setUp(self):
        # BCC
        bcc_latt = [1, 1, -1, -1, 1, 1, 1, -1, 1]
        bcc_pos = [(0, 0, 0)]
        bcc_atoms = [0]
        self.bcc_pcell = Cell(bcc_latt, bcc_pos, bcc_atoms)

        # FCC
        fcc_latt = [0, 5, 5, 5, 0, 5, 5, 5, 0]
        fcc_pos = [(0, 0, 0)]
        fcc_atoms = [0]
        self.fcc_pcell = Cell(fcc_latt, fcc_pos, fcc_atoms)

        # HCP
        hcp_b = [
            2.51900005, 0., 0., -1.25950003, 2.18151804, 0., 0., 0., 4.09100008
        ]
        hcp_positions = [(0.33333334, 0.66666669, 0.25),
                         (0.66666663, 0.33333331, 0.75)]
        hcp_numbers = [0, 0]
        self.hcp_pcell = Cell(hcp_b, hcp_positions, hcp_numbers)

    def test_hnf_cells(self):
        # Results from <PHYSICAL REVIEW B 80, 014120 (2009)>

        # BCC
        wanted = [1, 2, 3, 7, 5, 10, 7]
        got = [len(non_dup_hnfs(self.bcc_pcell, i)) for i in range(1, 8)]
        # for h in non_dup_hnfs(self.bcc_pcell, 7):
        #     print(h)
        self.assertEqual(got, wanted)

        # FCC
        wanted = [1, 2, 3, 7, 5, 10, 7]
        got = [len(non_dup_hnfs(self.fcc_pcell, i)) for i in range(1, 8)]
        self.assertEqual(got, wanted)

        # HCP
        wanted = [1, 3, 5, 11, 7, 19, 11, 34]
        got = [len(non_dup_hnfs(self.hcp_pcell, i)) for i in range(1, 9)]
        self.assertEqual(got, wanted)

    def test_is_hnf_dup(self):
        hnf_x = numpy.array([[1, 0, 0], [0, 1, 0], [0, 0, 2]])
        hnf_y = numpy.array([[1, 0, 0], [0, 2, 0], [0, 0, 1]])
        rot_syms = self.bcc_pcell.get_rotations(1e-3)
        is_dup = _is_hnf_dup(hnf_x, hnf_y, rot_syms, prec=1e-3)
        self.assertTrue(is_dup)

        # debug for compare method
        # numpy.mod problem!
        hnf_x = numpy.array([[1, 0, 0], [0, 1, 2], [0, 0, 5]])
        hnf_y = numpy.array([[1, 0, 3], [0, 1, 3], [0, 0, 5]])
        rot_syms = self.bcc_pcell.get_rotations(1e-3)

        is_dup = _is_hnf_dup(hnf_x, hnf_y, rot_syms, prec=1e-5)
        self.assertTrue(is_dup)

        # debug for compare method
        # numpy.astype problem!
        hnf_x = numpy.array([[1, 0, 6], [0, 1, 6], [0, 0, 7]])
        hnf_y = numpy.array([[1, 0, 3], [0, 1, 6], [0, 0, 7]])
        rot_syms = self.bcc_pcell.get_rotations(1e-3)

        is_dup = _is_hnf_dup(hnf_x, hnf_y, rot_syms, prec=1e-5)
        self.assertTrue(is_dup)
Beispiel #27
0
def _read_string(data):
    """
    _read_string make io easy to be tested.

    parameter: string of vasp input

    return: Cell object
    """
    lines = [l for l in data.split('\n') if l.rstrip()]

    name = lines[0]

    lattice_scale = float(lines[1].split()[0])

    # lattice vectors
    lattice = []
    for i in [2, 3, 4]:
        s = lines[i].split()
        vec = float(s[0]), float(s[1]), float(s[2])
        lattice.append(vec)
    lattice = numpy.array(lattice)

    if lattice_scale < 0:
        # In vasp , a negative scale factor is treated as a volume.
        # http://pymatgen.org/_modules/pymatgen/io/vasp/inputs.html#POSCAR
        vol = abs(numpy.linalg.det(lattice))
        lattice *= (-lattice_scale / vol)**(1 / 3)
    else:
        lattice *= lattice_scale

    # atoms
    vasp5 = False
    _fifth_line = lines[5].split()
    # VASP 5.x use the fifth line to represent atomic symbols
    try:
        for i in _fifth_line:
            int(i)
        numofatoms = _fifth_line
    except ValueError:
        vasp5 = True
        atomtypes = _fifth_line
        numofatoms = lines[6].split()  # list of string here

    if not vasp5:
        warnings.warn(
            "symbols of elements in fifth line are missing, "
            "all atoms are init to NaN_i (i=0,1,2...)",
            UserWarning,
            stacklevel=2)
        atomtypes = [str("NaN_{:}".format(i)) for i in range(len(numofatoms))]

    atoms = []
    for i, num in enumerate(numofatoms):
        # https://gitlab.com/ase/ase/blob/master/ase/io/vasp.py
        numofatoms[i] = int(num)
        [atoms.append(atomtypes[i]) for na in range(numofatoms[i])]

    if not vasp5:
        line_coortype = 6
    else:
        line_coortype = 7

    # TODO: Supporting Cartesian coordinates vasp input
    coortype = lines[line_coortype].split()[0]
    if coortype[0] in "sS":
        warnings.warn("Sorry! Selective dynamics "
                      "are not supported now",
                      FutureWarning,
                      stacklevel=2)
        line_coortype += 1
        coortype = lines[line_coortype].split()[0]

    if coortype[0] in "cCkK":
        line_first_pos = line_coortype + 1
        iscart = True
    else:
        iscart = False

    if coortype[0] in "dD":
        line_first_pos = line_coortype + 1

    positions = []
    total_atoms = sum(numofatoms)
    for i in range(line_first_pos, line_first_pos + total_atoms):
        s = lines[i].split()
        vec = float(s[0]), float(s[1]), float(s[2])
        positions.append(vec)
    if iscart:
        positions = numpy.dot(numpy.array(positions),
                              numpy.linalg.inv(lattice))
    return Cell(lattice, positions, atoms)
Beispiel #28
0
 def test_init(self):
     lattice = [1.0, 0, 0, 0, 1.0, 0, 0, 0, 1.0]
     positions = [0, 0, 0]
     atoms = ['NaN_10']
     cell = Cell(lattice, positions, atoms)
     self.assertEqual(cell.atoms.tolist(), [1010])