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)
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)
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))
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))
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)