Exemplo n.º 1
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}