Beispiel #1
0
def wannier_den_matrix_lda_chk3(wannier_path="./"):
    '''produce the file `wannier_den_matrix.dat` for the feedback from
    g-risb to dft.
    '''
    _, _, kpts, include_bands, wfwannier_list, bnd_es = mpiget_wannier_data(
        path=wannier_path)
    nktot = len(kpts)
    with h5py.File("GPARAMBANDS.h5", "r") as f:
        num_elec = f["/nelectron"][0]
    # set wk_list
    wklist = [1. / nktot for i in range(bnd_es.shape[1])]
    # get eigen-vector from interpolation
    bnd_es2 = [[]]
    bnd_ev2 = [[]]
    for ik in range(nktot):
        hk = wfwannier_list[0][ik].T.conj().dot(np.diag(bnd_es[0][ik])).dot(
            wfwannier_list[0][ik])
        w, v = np.linalg.eigh(hk)
        bnd_es2[0].append(w)
        bnd_ev2[0].append(v)
    bnd_ev2 = np.asarray(bnd_ev2)
    with h5py.File("ev_lda_ref.h5", "w") as f:
        f["e"] = bnd_es2
        f["v"] = bnd_ev2
    efermi = get_fermi_level(bnd_es2, wklist, num_elec, ismear=-1)
    # set fermi weight
    ferwes = get_fermi_weight(efermi, bnd_es2, wklist, ismear=-1)
    # setup trivial wannier_den data.
    wan_den = [[]]
    for ik in range(nktot):
        dm = np.diag(ferwes[0][ik] * nktot / (2 + 0.j))
        wan_den[0].append(bnd_ev2[0][ik].dot(dm).dot(bnd_ev2[0][ik].T.conj()))
    wan_den = np.asarray(wan_den)
    fwrt_wan_den(wan_den, wfwannier_list, include_bands)
Beispiel #2
0
def wannier_den_matrix_lda_chk(wannier_path="./"):
    '''produce the file `wannier_den_matrix.dat` for the feedback from
    g-risb to dft.
    '''
    _, _, kpts, include_bands, _, bnd_es = mpiget_wannier_data(
        path=wannier_path)
    nktot = len(kpts)
    with h5py.File("GPARAMBANDS.h5", "r") as f:
        num_elec = f["/nelectron"][0]

    # chop bnd_es
    nbnd = bnd_es.shape[2]
    nwan = int(num_elec / 2 + 3)
    bnd_es = bnd_es[:, :, :nwan]
    # set wk_list
    wklist = [1. / nktot for i in range(bnd_es.shape[1])]
    efermi = get_fermi_level(bnd_es, wklist, num_elec, ismear=-1)
    # set fermi weight
    ferwes = get_fermi_weight(efermi, bnd_es, wklist, ismear=-1)
    # setup trivial wannier_den data.
    wan_den = [[]]
    wfwannier_list = [[]]
    vmat = np.zeros((nbnd, nwan), dtype=np.complex)
    np.fill_diagonal(vmat, 1.0)
    for ik in range(nktot):
        wfwannier_list[-1].append(vmat)
        wan_den[0].append(np.diag(ferwes[0][ik] * nktot / (2 + 0.j)))
    wan_den = np.asarray(wan_den)
    wfwannier_list = np.asarray(wfwannier_list)
    fwrt_wan_den(wan_den, wfwannier_list, include_bands)
Beispiel #3
0
def wannier_den_matrix_lda_chk2(wannier_path="./"):
    '''produce the file `wannier_den_matrix.dat` for the feedback from
    g-risb to dft.
    '''
    _, _, kpts, include_bands, wfwannier_list, bnd_es = mpiget_wannier_data(
        path=wannier_path)
    nktot = len(kpts)
    with h5py.File("GPARAMBANDS.h5", "r") as f:
        num_elec = f["/nelectron"][0]
    # set wk_list
    wklist = [1. / nktot for i in range(bnd_es.shape[1])]
    efermi = get_fermi_level(bnd_es, wklist, num_elec, ismear=-1)
    # set fermi weight
    ferwes = get_fermi_weight(efermi, bnd_es, wklist, ismear=-1)
    # setup trivial wannier_den data.
    wan_den = [[]]
    for ik in range(nktot):
        dm = np.diag(ferwes[0][ik] * nktot / (2 + 0.j))
        wan_den[0].append(wfwannier_list[0][ik].T.conj().dot(dm).dot(
            wfwannier_list[0][ik]))
    wan_den = np.asarray(wan_den)
    wrt_wan_den(wan_den,
                wfwannier_list,
                include_bands,
                fwannier="{}/wannier.dat".format(wannier_path))
Beispiel #4
0
def wannier_den_matrix(wannier_path="./"):
    '''produce the file `wannier_den_matrix.dat` for the feedback from
    g-risb to dft.
    '''
    _, _, kpts, include_bands, wfwannier_list, bnd_es_in = \
            mpiget_wannier_data(path=wannier_path)
    bnd_es, bnd_vs = mpiget_bndev(kpts,
                                  wfwannier_list=wfwannier_list,
                                  bnd_es_in=bnd_es_in,
                                  mode="risb")
    nktot = len(kpts)
    with h5py.File("GPARAMBANDS.h5", "r") as f:
        delta = f["/delta"][0]
        ismear = f["/ismear"][0]
        iso = f["/iso"][0]
        num_elec = f["/nelectron"][0]
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    # set wk_list
    wklist = [1. / nktot for i in range(bnd_es.shape[1])]
    if rank == 0:
        efermi = get_fermi_level(bnd_es, wklist, num_elec, delta=delta, \
                ismear=ismear, iso=iso)
    else:
        efermi = None
    efermi = comm.bcast(efermi, root=0)
    ncpu = comm.Get_size()
    nk_cpu = nktot // ncpu
    if nk_cpu * ncpu < nktot:
        nk_cpu += 1
    # reduce bnd_es to local part only
    if rank == 0:
        bnd_es = bnd_es[:nk_cpu]
        wklist = wklist[:nk_cpu]
    # set fermi weight
    ferwes = get_fermi_weight(efermi,
                              bnd_es,
                              wklist,
                              delta=delta,
                              ismear=ismear,
                              iso=iso)
    # calculate wannier_den_matrix
    wan_den = get_wannier_den_matrix_risb(bnd_vs, ferwes, wklist, nktot)
    if rank == 0:
        wrt_wan_den(wan_den,
                    wfwannier_list,
                    include_bands,
                    fwannier="{}/wannier.dat".format(wannier_path))
Beispiel #5
0
def if_gwannier(corbs_list,
                delta_charge=0.,
                wpath="../wannier",
                lpath="../lattice",
                wprefix="wannier",
                lprefix="mdl",
                lrot_list=None,
                iso=1,
                ispin=1,
                ismear=0,
                delta=0.0258,
                icycle=0):
    cell, _, kpts, include_bands, wfwannier_list, bnd_es = \
            mpiget_wannier_data(path=wpath)
    # total number of valence electrons
    n_elec = get_total_valence_elec("{}/{}_1.out".format(lpath, lprefix))
    n_elec -= max(0, (include_bands[0] - 1) * (3 - iso))
    symbols, atomic_positions = wget_symbols_positions(path=wpath,
                                                       wprefix=wprefix)
    # convert to scaled position
    atomic_positions = np.asarray(atomic_positions).dot(np.linalg.inv(cell))
    numk = kpts.shape[0]
    # GMPI_x.h5 file
    kvec = set_kvec_para(numk)
    wk = 1. / numk
    nbmax = wfwannier_list.shape[3]
    # spin degeneracy
    spin_deg = 3 - max(ispin, iso)

    comm = MPI.COMM_WORLD
    myrank = comm.Get_rank()
    # wannier basis to complex spherical basis tranformation.
    u_wan2csh = get_wann2csh(nbmax, corbs_list)
    h1e_all = []
    nelectron = 0.
    # input file of dft bare band structure information for cygutz
    with h5py.File('BAREHAM_{}.h5'.format(myrank), 'w') as f:
        for isp in range(wfwannier_list.shape[0]):
            h1e_all.append(np.zeros((nbmax, nbmax), dtype=np.complex))
            for ik in range(kvec[0][2], kvec[0][2] + kvec[0][1]):
                # rescontruct dft hamiltonian matrix
                # in the wannier basis.
                # since it involves a downfolding,
                # some information outside of the frozen energy window
                # will be lost.
                hmat = wfwannier_list[isp][ik].T.conj().dot( \
                        np.diag(bnd_es[isp][ik])).dot(
                        wfwannier_list[isp][ik])
                # from wannier basis to correlated orbital-ordered
                # complex spherical harmonics basis,
                # which is the convention used in the cygutz
                # initialization script.
                hmat = u_wan2csh.T.conj().dot(hmat).dot(u_wan2csh)
                # record the onsite one-body part
                h1e_all[isp] += hmat * wk
                # save the downfolded dft hamiltonian
                f['/IKP_{}/ISYM_1/HK0_SPIN1'.format(ik + 1)] = hmat.T
                # get the eigen-value and eigen0vectors
                evals, evecs = np.linalg.eigh(hmat)
                # another way to evaluate total valence electrons
                # according to sangkook.
                nelectron += np.count_nonzero(evals < 0.) * (wk * spin_deg)
                # yes, here it is redundant here
                # but for the sake of consistent with wien2k interface.
                # here it implies the downfolding procedure is not necessary.
                f['/IKP_{}/ek0_spin1'.format(ik + 1)] = evals
                f['/IKP_{}/T_PSIK0_TO_HK0_BASIS_SPIN{}'.format( \
                        ik+1, isp+1)] = evecs.T
    nelectron = comm.reduce(nelectron, op=MPI.SUM)
    h1e_all = np.asarray(h1e_all)
    h1e_all = comm.reduce(h1e_all, op=MPI.SUM)
    if myrank == 0:
        h1e_list = []
        for isp in range(wfwannier_list.shape[0]):
            h1e_list.append([])
            base = 0
            for corbs in corbs_list:
                norbs = len(corbs)
                h1e_list[isp].append(h1e_all[isp][base:base+norbs, \
                        base:base+norbs])
                base += norbs
        nelectron = int(nelectron + 0.5)
        if np.abs(nelectron - n_elec) > 1.e-6:
            warnings.warn(" wannier valence electrons: {} vs {}!".format( \
                    nelectron, n_elec))
            n_elec = nelectron
        if icycle <= 1:
            wrt_ginit(symbols,
                      cell,
                      atomic_positions,
                      u_wan2csh,
                      lrot_list=lrot_list)
        else:
            update_ginit(u_wan2csh)

        ne_list = [[nbmax, 1, nbmax] for k in range(numk)]
        wk_list = [wk for k in range(numk)]
        nelectron = n_elec + delta_charge
        wrt_gparambands(numk,
                        nbmax,
                        ne_list,
                        wk_list,
                        kpts,
                        nelectron,
                        h1e_list,
                        iso=iso,
                        ispin=ispin,
                        ismear=ismear,
                        delta=delta)