Esempio n. 1
0
 def get_bands_node(self):
     bnode = DataFactory('array.bands')()
     bdat, bkp, bgnu = self.get_bands_plot()
     if not (bdat and bkp):
         return None
     with open(bkp) as bk:
         self.line(bk)  # contains num kpoints
         kp = re.split(self.empty_line, bk.read())
         kp = filter(None, kp)
         kp = map(self.splitlines, kp)
         kp = filter(None, kp[0])
         kp = np.array(kp)
         bnode.set_kpoints(kp[:, :3], weights=kp[:, 3])
     with open(bdat) as bd:
         data = re.split(self.empty_line, bd.read())
         data = filter(None, data)
         data = map(self.splitlines, data)
         data = np.array(data)
     bnode.set_bands(data[:, :, 1].transpose())
     kppath = self._calc.inp.settings.get_dict().get('kpoint_path')
     kpl = [[kpp[0], kpp[1:4]] for kpp in kppath]
     kpl.append([kppath[-1][4], kppath[-1][5:8]])
     counter = {i[0]: 0 for i in kpl}
     kplab = []
     for kpi in kpl:
         ci = counter[kpi[0]]
         idx = self._find_special_kpoint(kp[:, :3], kpi[1], num=ci)
         kplab.append((idx, kpi[0]))
         counter[kpi[0]] += 1
     bnode.labels = kplab
     return bnode
Esempio n. 2
0
    def _get_bands(self):
        """
        Create a bands and a kpoints node from values in eigenvalue.

        :returns: bsnode, kpout

        * bsnode: BandsData containing eigenvalues from EIGENVAL
                and occupations from vasprun.xml
        * kpout: KpointsData containing kpoints from EIGENVAL,
        both bsnode as well as kpnode come with cell unset
        """
        eig = self.get_file('EIGENVAL')
        if not eig:
            return {'bands': None, 'kpoints': None}

        _, kpoints, bands = EigParser.parse_eigenval(eig)
        bsnode = DataFactory('array.bands')()
        kpout = DataFactory('array.kpoints')()
        # Take the output structure if available.
        structure = None
        if 'structure' in self._output_nodes:
            structure = self._output_nodes['structure']
        if structure is None:
            structure = self._calc.inp.structure
        bsnode.set_cell(structure.get_ase().get_cell())
        kpout.set_cell(structure.get_ase().get_cell())
        if self._calc.inp.kpoints.get_attrs().get('array|kpoints'):
            bsnode.set_kpointsdata(self._calc.inp.kpoints)
        if self._calc.inp.kpoints.labels:
            bsnode.labels = self._calc.inp.kpoints.labels
        else:
            bsnode.set_kpoints(kpoints[:, :3],
                               weights=kpoints[:, 3],
                               cartesian=False)
        bsnode.set_bands(bands,
                         occupations=self._parsers['vasprun.xml'].occupations)
        kpout.set_kpoints(kpoints[:, :3],
                          weights=kpoints[:, 3],
                          cartesian=False)
        return {'bands': bsnode, 'kpoints': kpout}
Esempio n. 3
0
    def read_eigenval(self):
        '''
        Create a bands and a kpoints node from values in eigenvalue.

        returns: bsnode, kpout
        - bsnode: BandsData containing eigenvalues from EIGENVAL
                and occupations from vasprun.xml
        - kpout: KpointsData containing kpoints from EIGENVAL,

        both bsnode as well as kpnode come with cell unset
        '''
        eig = self.get_file('EIGENVAL')
        if not eig:
            self.logger.warning('EIGENVAL not found')
            return None, None, None
        header, kp, bs = EigParser.parse_eigenval(eig)
        bsnode = DataFactory('array.bands')()
        kpout = DataFactory('array.kpoints')()

        structure = None  # get output structure if not static
        if self.vrp.is_md or self.vrp.is_relaxation:
            structure = self.read_cont()

        if self.vrp.is_md:  # set cell from input or output structure
            cellst = structure
        else:
            cellst = self._calc.inp.structure
        bsnode.set_cell(cellst.get_ase().get_cell())
        kpout.set_cell(cellst.get_ase().get_cell())

        if self._calc.inp.kpoints.get_attrs().get('array|kpoints'):
            bsnode.set_kpointsdata(self._calc.inp.kpoints)
        if self._calc.inp.kpoints.labels:
            bsnode.labels = self._calc.inp.kpoints.labels
        else:
            bsnode.set_kpoints(kp[:, :3], weights=kp[:, 3], cartesian=False)
        bsnode.set_bands(bs, occupations=self.vrp.occupations)
        kpout.set_kpoints(kp[:, :3], weights=kp[:, 3], cartesian=False)
        return bsnode, kpout, structure
Esempio n. 4
0
def make_reference_bands_inline(wannier_bands, vasp_bands, efermi=None):
    """
    Compare bandstructure results from wannier and vasp.

    Takes two input array.bands nodes, stores them if they're not already
    stored. Takes the relevant bands from the vasp bandstructure and stores and outputs
    them in a node with linkname 'bandcmp'.

    Also returns a parameter data node with linkname 'bandinfo' containing
    fermi energy, bandgap etc of the reference bandstructure.
    """
    import numpy as np
    assert isinstance(wannier_bands, BANDS_CLS)
    assert isinstance(vasp_bands, BANDS_CLS)
    assert hasattr(wannier_bands, 'labels')
    assert hasattr(vasp_bands, 'labels')
    if vasp_bands.labels:
        assert vasp_bands.labels == wannier_bands.labels
    kpcomp = vasp_bands.get_kpoints() == wannier_bands.get_kpoints()
    assert kpcomp.all(), 'kpoints may not differ'

    owindow = get_outer_window(wannier_bands)

    wbands = wannier_bands.get_bands()
    vbands, vocc = vasp_bands.get_bands(also_occupations=True)

    # throw away spin dimension if appropriate
    if vbands.ndim == 3:
        vbands = vbands[0]
        vocc = vocc[0]

    # grab the vbands within the outer_window
    # find wich bands within the window match
    # by searching for the best fit using the sum of square errors
    vbands_window = np.empty(wbands.shape)
    vocc_window = np.empty(wbands.shape)
    w_nbands = wbands.shape[1]
    ref_nbands = vbands.shape[1]
    for band_idx in range(w_nbands):
        errs = [band_error(wbands[:, band_idx], vbands[:, i]) for i in range(ref_nbands)]
        minerr = np.argmin(errs)
        vbands_window[:, band_idx] = vbands[:, minerr]
        vocc_window[:, band_idx] = vocc[:, minerr]

    # For the future:
    # * find each band's index (s, px, py, ...)
    # * store the legend with the comparison node

    # find fermi energy from vasp_bands parent or work without it
    if not efermi:
        try:
            efermi = vasp_bands.inp.bands.out.results.get_dict()['efermi']
        except Exception:  # pylint: disable=broad-except
            pass

    ref_gap_info = band_gap(vbands_window, vocc_window, efermi)
    ref_info = DataFactory('parameter')()
    ref_info.update_dict({'bandgap': ref_gap_info})
    ref_info.update_dict({'efermi': efermi})
    ref_info.update_dict({'outer_window': owindow})

    ref_bands = DataFactory('array.bands')()
    ref_bands.set_kpointsdata(wannier_bands)
    ref_bands.set_bands(vbands_window, occupations=vocc_window)

    return {'bands': ref_bands, 'info': ref_info}