Ejemplo n.º 1
0
    def set_nsc(self, nsc=None, a=None, b=None, c=None):
        """ Sets the number of supercells in the 3 different cell directions

        nsc: list of int, optional
           number of supercells in each direction
        a: integer, optional
           number of supercells in the first unit-cell vector direction
        b: integer, optional
           number of supercells in the second unit-cell vector direction
        c: integer, optional
           number of supercells in the third unit-cell vector direction
        """
        if not nsc is None:
            for i in range(3):
                if not nsc[i] is None:
                    self.nsc[i] = nsc[i]
        if a:
            self.nsc[0] = a
        if b:
            self.nsc[1] = b
        if c:
            self.nsc[2] = c
        # Correct for misplaced number of unit-cells
        for i in range(3):
            if self.nsc[i] == 0:
                self.nsc[i] = 1
        if np.sum(self.nsc % 2) != 3:
            raise ValueError(
                "Supercells has to be of un-even size. The primary cell counts "
                + "one, all others count 2")

        # We might use this very often, hence we store it
        self.n_s = _a.prodi(self.nsc)
        self._sc_off = _a.zerosi([self.n_s, 3])
        self._isc_off = _a.zerosi(self.nsc)

        n = self.nsc

        # We define the following ones like this:

        def ret_range(val):
            i = val // 2
            return range(-i, i + 1)

        x = ret_range(n[0])
        y = ret_range(n[1])
        z = ret_range(n[2])
        i = 0
        for iz in z:
            for iy in y:
                for ix in x:
                    if ix == 0 and iy == 0 and iz == 0:
                        continue
                    # Increment index
                    i += 1
                    # The offsets for the supercells in the
                    # sparsity pattern
                    self._sc_off[i, 0] = ix
                    self._sc_off[i, 1] = iy
                    self._sc_off[i, 2] = iz

        self._update_isc_off()
Ejemplo n.º 2
0
    def read_geometry(self):
        """ Reading a geometry in regular Hamiltonian format """

        cell = np.zeros([3, 3], np.float64)
        Z = []
        xyz = []

        nsc = _a.zerosi([3])

        def Z2no(i, no):
            try:
                # pure atomic number
                return int(i), no
            except Exception:
                # both atomic number and no
                j = i.replace('[', ' ').replace(']', ' ').split()
                return int(j[0]), int(j[1])

        # The format of the geometry file is
        keys = ['atoms', 'cell', 'supercell', 'nsc']
        for _ in range(len(keys)):
            _, l = self.step_to(keys, case=False)
            l = l.strip()
            if 'supercell' in l.lower() or 'nsc' in l.lower():
                # We have everything in one line
                l = l.split()[1:]
                for i in range(3):
                    nsc[i] = int(l[i])
            elif 'cell' in l.lower():
                if 'begin' in l.lower():
                    for i in range(3):
                        l = self.readline().split()
                        cell[i, 0] = float(l[0])
                        cell[i, 1] = float(l[1])
                        cell[i, 2] = float(l[2])
                    self.readline()  # step past the block
                else:
                    # We have everything in one line
                    l = l.split()[1:]
                    for i in range(3):
                        cell[i, i] = float(l[i])
                    # TODO incorporate rotations
            elif 'atoms' in l.lower():
                l = self.readline()
                while not l.startswith('end'):
                    ls = l.split()
                    try:
                        no = int(ls[4])
                    except Exception:
                        no = 1
                    z, no = Z2no(ls[0], no)
                    Z.append({'Z': z, 'orbital': [-1. for _ in range(no)]})
                    xyz.append([float(f) for f in ls[1:4]])
                    l = self.readline()
                xyz = _a.arrayd(xyz)
                xyz.shape = (-1, 3)
                self.readline()  # step past the block

        # Create geometry with associated supercell and atoms
        geom = Geometry(xyz, atoms=Atom[Z], sc=SuperCell(cell, nsc))

        return geom