Exemplo n.º 1
0
    def get_lm(self):
        '''Extract lm from either dos block or projected block'''

        projected = self.copy_block(self.calculation_block[-1],
                                    'projected',
                                    level=2)
        if len(projected) != 0:
            self.proj_band = self.get_eigenvalues(projected[0], level=3)
            array = self.copy_block(projected, 'array', level=3)
            self.lm = []
            for line in array[0][5:]:
                if '<field>' not in line: break
                self.lm.append(utils.str_extract(line, '>', '<').strip())
            if 'dx2' in self.lm: self.lm[self.lm.index('dx2')] = 'dx2-y2'
            if 'x2-y2' in self.lm: self.lm[self.lm.index('x2-y2')] = 'dx2-y2'
        else:
            DOS = self.copy_block(self.calculation_block[-1], 'dos', level=2)
            if len(DOS) != 0:
                partial = self.copy_block(DOS, 'partial', level=3)
                if len(partial) == 1:
                    self.lm = []
                    for line in partial[0][6:]:
                        if '<field>' not in line: break
                        self.lm.append(
                            utils.str_extract(line, '>', '<').strip())
                    if 'dx2' in self.lm:
                        self.lm[self.lm.index('dx2')] = 'dx2-y2'
                    if 'x2-y2' in self.lm:
                        self.lm[self.lm.index('x2-y2')] = 'dx2-y2'
                else:
                    print("There is no lm information in vasprun.xml")
            else:
                print("There is no lm information in vasprun.xml")

        return self.lm
Exemplo n.º 2
0
    def extract_param(self, block):
        ''' This extracting function is used for a block containing data with keywords.
            Get the keyword and corresponding value and put them in a dictionary '''

        if len(block) == 1: block = block[0]

        dict = {}
        for line in block[1:-1]:
            if 'name="' in line:
                key = utils.str_extract(line, 'name="', '"')
                data_type = None

                if 'type="' in line:
                    data_type = utils.str_extract(line, 'type="', '"')
                value = utils.str_extract(line, '>', '<').strip()

                if '<v' in line:
                    value = value.split()
                if data_type == None:
                    value = np.float64(value)
                elif data_type == 'int':
                    value = np.int64(value)
                elif data_type == 'logical':
                    if value == 'T':
                        value = True
                    else:
                        value = False

                dict[key] = value

        return dict
Exemplo n.º 3
0
    def get_sc(self, calculation):
        '''Get <scstep> block for each <calcualtion> block'''

        scstep = self.copy_block(calculation, 'scstep', level=2)

        # Get info from the first and the last scstep:
        sc_first_last = []
        for i in [0, -1]:
            energy = self.copy_block(scstep[i], 'energy', level=3)[0][1:-1]
            values = []
            for line in energy:
                val = np.float64(utils.str_extract(line, '>', '<').strip())
                values.append(val)
            sc_first_last.append(values)

        sc_list = []
        sc_list.append(sc_first_last[0])
        for sc in scstep[1:-1]:
            energy = self.copy_block(sc, 'energy', level=3)[0][1:-1]
            values = []
            for line in energy:
                val = np.float64(utils.str_extract(line, '>', '<').strip())
                values.append(val)
            sc_list.append(values)

        sc_list.append(sc_first_last[1])

        return sc_list
Exemplo n.º 4
0
    def get_atominfo(self):
        ''' Extract the <atominfo> block'''

        atominfo = self.copy_block(self.vasprun, 'atominfo', level=1)
        atoms = self.copy_block(atominfo, 'array', 'atoms', level=2)
        atoms_set = self.copy_block(atoms, 'set', level=3)[0][1:-1]
        atomtypes = self.copy_block(atominfo, 'array', 'atomtypes', level=2)
        atomtypes_set = self.copy_block(atomtypes, 'set', level=3)[0][1:-1]

        self.natom = np.int64(
            utils.str_extract(atominfo[0][1], '>', '<').strip())
        self.ntypes = np.int64(
            utils.str_extract(atominfo[0][2], '>', '<').strip())

        # atom = [element], atm = [element, atomtype]
        self.atom = []
        self.atm = []
        for line in atoms_set:
            temp = utils.str_extract(line, '<c>', '</c>')
            atom = temp[0].strip()
            type = np.int64(temp[1].strip()) - 1
            self.atm.append([atom, type])
            self.atom.append(atom)

        # types = [atoms_per_type, element, mass, valence, pseudopotential]
        self.types = []
        for line in atomtypes_set:
            temp = utils.str_extract(line, '<c>', '</c>')
            natom = np.int64(temp[0].strip())
            atom = temp[1].strip()
            mass = np.float64(temp[2].strip())
            elec = np.int64(np.float64(temp[3].strip()))
            paw = temp[4].strip()
            self.types.append([natom, atom, mass, elec, paw])
Exemplo n.º 5
0
    def get_calculation(self, calculation_block):
        '''Get info from the <calculation> block(s)'''

        calculation = []
        for calc in calculation_block:
            # Get <scstep>
            scstep = self.get_sc(calc)

            # Get <structure>
            structure = self.copy_block(calc, 'structure', level=2)
            cell = self.get_cell(structure, level=2)

            # Get <varray name="forces" >
            forces = self.copy_block(calc, 'varray', 'forces', level=2)
            forces_mat = self.extract_vec(forces)

            # Get <varray name="stress" >
            stress = self.copy_block(calc, 'varray', 'stress', level=2)
            stress_mat = self.extract_vec(stress)

            # Get <time name="totalsc">
            time = self.copy_line(calc, 'time', level=2)
            time = np.float64(
                utils.str_extract(time, '>', '<').strip().split())
            calculation.append([cell, scstep, forces_mat, stress_mat, time])

        return calculation
Exemplo n.º 6
0
    def extract_vec(self, block):
        '''This extracting function is used for a block containing a matrix or vector'''

        if len(block) == 1: block = block[0]

        array = []
        for line in block[1:-1]:
            vec = utils.str_extract(line, '>', '<').strip().split()
            vec = np.float64(vec)
            array.append(vec)

        return np.asarray(array)
Exemplo n.º 7
0
    def get_kpoints(self):
        ''' Extract the <kpoints> block'''

        kpoints = self.copy_block(self.vasprun, 'kpoints', level=1)
        generation = self.copy_block(kpoints, 'generation', level=2)
        kpointlist = self.copy_block(kpoints, 'varray', 'kpointlist', level=2)
        weights = self.copy_block(kpoints, 'varray', 'weights', level=2)
        kpoints_dict = {}
        kpoint_type = 0  # for hybrid band structure calculation

        if len(generation) == 1:
            if 'listgenerated' in generation[0][0]:
                kpoints_dict['type'] = 'listgenerated'
                kpoints_dict['divisions'] = np.int64(
                    utils.str_extract(generation[0][1], '>', '<').strip())
                kpoints_dict['points'] = self.extract_vec(generation[0][1:])
                kpoint_type = 1  # for conventional band structure calculation
            elif 'Gamma' in generation[0][0] or 'Monkhorst-Pack' in generation[
                    0][0]:
                if 'Gamma' in generation[0][0]:
                    kpoints_dict['type'] = 'Gamma'
                else:
                    kpoints_dict['type'] = 'Monkhorst-Pack'
                kpoints_dict['divisions'] = np.int64(
                    utils.str_extract(generation[0][1], '>',
                                      '<').strip().split())
                kpoints_dict['usershift'] = np.float64(
                    utils.str_extract(generation[0][2], '>',
                                      '<').strip().split())
                kpoints_dict['genvec'] = self.extract_vec(generation[0][2:-1])
                kpoints_dict['usershift'] = np.float64(
                    utils.str_extract(generation[0][2], '>',
                                      '<').strip().split())
                kpoint_type = 2  # for a normal SCF or geometry optimization

        kpoints_dict['kpointlist'] = self.extract_vec(kpointlist)  # fractional
        kpoints_dict['weights'] = self.extract_vec(weights)
        kpoints_dict['type'] = kpoint_type

        return kpoints_dict
Exemplo n.º 8
0
    def get_cell(self, structure, level=1):
        '''Get info from a <structure> block
           the structure could be at level 1 or level 2 inside the <calculation> block
           Return: lattice, reciprocal lattice, volume, ions positions'''

        basis = self.copy_block(structure, 'varray', 'basis', level=level + 2)
        rec_basis = self.copy_block(structure,
                                    'varray',
                                    'rec_basis',
                                    level=level + 2)
        positions = self.copy_block(structure,
                                    'varray',
                                    'positions',
                                    level=level + 1)
        volume = np.float64(
            utils.str_extract(structure[0][7], '>', '<').strip())

        lattice = self.extract_vec(basis)  # row vector format, Unit: A
        recip_lattice = 2 * np.pi * self.extract_vec(
            rec_basis
        )  # row vector format, Unit: A^-1, vaspxml uses 2pi.A^-1 unit
        positions = self.extract_vec(positions)

        return lattice, recip_lattice, positions, volume
Exemplo n.º 9
0
    def get_dos(self):
        '''Get info from the <dos> block
        
        #################################################
           tdos = [spin,epsilon,ith]   
                ith = 0: epsilon
                ith = 1: DOS
               
           dos = \bar{n}(\epsilon_i) = (N(\epsilon_i) - \epsilon_{i-1})\Delta\epsilon
           N(\epsilon_i) = \int_{-infty}^{epsilon_i} n(\epsilon) d\epsilon
            
        #################################################
           tdos = [atom,spin,epsilon,ith]           
                ith = 0     : epsilon
                ith = 1-9   : lm =  pz     px    dxy    dyz    dz2    dxz  x2-y2
           
           if ISPIN = 1 and ISPIN = 2:
               spin 0           : proj_wf for alpha electrons 
               spin 1           : proj_wf for beta electrons
               
           if LSORBIT = .TRUE.
               spin 0           : total magnetization m 
               spin 1,2,3       : partial magnetization mx, my, mz   

        IMPORTANT NOTE: the total dos provided in vasprun.xml and the one calculated from pdos do not
                        neccessarily equal.
        '''

        DOS = self.copy_block(self.calculation_block[-1], 'dos', level=2)

        if len(DOS) == 0:
            print('DOS was not computed')
        else:
            # print('Get total density of states (tdos)')
            self.efermi = np.float64(
                utils.str_extract(DOS[0][1], '>', '<').strip())

            # Total DOS
            total = self.copy_block(DOS, 'total', level=3)
            dos_spin = self.copy_block(total, 'set', 'spin', level=6)
            total_out = []
            for spin in dos_spin:
                total_out.append(self.extract_vec(spin))

            self.tdos = np.asarray(total_out)

            # Partial DOS
            partial = self.copy_block(DOS, 'partial', level=3)
            self.pdos_exist = False
            if len(partial) == 1:
                # Get lm
                if self.lm == None: self.get_lm()

                # Get pdos
                dos_ion = self.copy_block(partial, 'set', 'ion', level=6)
                partial_out = []
                for ion in dos_ion:
                    dos_spin = self.copy_block(ion, 'set', 'spin', level=7)
                    out_ion = []
                    for spin in dos_spin:
                        out_ion.append(self.extract_vec(spin))
                    partial_out.append(out_ion)

                self.pdos = np.asarray(partial_out)
                self.pdos_exist = True