def __init__(self, name=None, calc=None, M=None, spinorbit=None): self.name = name self.calc = GPAW(calc, txt=None, communicator=mpi.serial_comm) self.M = np.array(M, dtype=float) self.spinorbit = spinorbit self.gd = self.calc.wfs.gd.new_descriptor() self.kd = self.calc.wfs.kd if self.calc.wfs.mode is 'pw': self.pd = self.calc.wfs.pd else: self.pd = PWDescriptor(ecut=None, gd=self.gd, kd=self.kd, dtype=complex) self.acell_cv = self.gd.cell_cv self.bcell_cv = 2 * np.pi * self.gd.icell_cv self.vol = self.gd.volume self.BZvol = (2 * np.pi)**3 / self.vol self.nb = self.calc.get_number_of_bands() self.v_Knm = None if spinorbit: if mpi.world.rank == 0: print('Calculating spinorbit Corrections') self.nb = 2 * self.calc.get_number_of_bands() self.e_mK, self.v_Knm = get_spinorbit_eigenvalues(self.calc, return_wfs=True) if mpi.world.rank == 0: print('Done with the spinorbit Corrections')
def get_spinorbit_corrections(self, return_spin=True, return_wfs=False, bands=None, gwqeh_file=None, dft=False, eig_file=None): """Gets the spinorbit corrections to the eigenvalues""" calc = self.calc bandrange = self.bandrange if not dft: try: e_kn = self.gw_file['qp'][0] except: e_kn = self.gw_file[b'qp'][0] else: if eig_file is not None: e_kn = pickle.load(open(eig_file))[0] else: e_kn = self.get_dft_eigenvalues()[:,bandrange[0]:bandrange[-1]] eSO_nk, s_nk, v_knm = get_spinorbit_eigenvalues( calc, return_spin=return_spin, return_wfs=return_wfs, bands=range(bandrange[0], bandrange[-1]+1), gw_kn=e_kn) e_kn = eSO_nk.T return e_kn, v_knm
def get_spinorbit_corrections(self, return_spin=True, return_wfs=False, bands=None, gwqeh_file=None, dft=False, eig_file=None): """Gets the spinorbit corrections to the eigenvalues""" calc = self.calc bandrange = self.bandrange print(bandrange[0]) if not dft: e_kn = self.gw_file['qp'][0] print('Shape') print(e_kn[:, bandrange[0]:bandrange[-1]].shape) else: if eig_file is not None: e_kn = pickle.load(open(eig_file))[0] else: e_kn = self.get_dft_eigenvalues() eSO_nk, s_nk, v_knm = get_spinorbit_eigenvalues( calc, return_spin=return_spin, return_wfs=return_wfs, bands=range(bandrange[0], bandrange[-1]), gw_kn=e_kn[:, :bandrange[-1] - bandrange[0]]) # eSO_kn = np.sort(e_skn,axis=2) e_kn = eSO_nk.T return e_kn, v_knm
def raw_spinorbit_orbital_LDOS(paw, a, spin, angular='spdf', theta=0, phi=0): """Like former, but with spinorbit coupling.""" from gpaw.spinorbit import get_spinorbit_eigenvalues from gpaw.spinorbit import get_spinorbit_projections e_mk, v_knm = get_spinorbit_eigenvalues(paw, return_wfs=True, theta=theta, phi=phi) e_mk /= Hartree ns = paw.wfs.nspins w_k = paw.wfs.kd.weight_k nk = len(w_k) nb = len(e_mk) if a < 0: # Allow list-style negative indices; we'll need the positive a for the # dictionary lookup later a = len(paw.wfs.setups) + a setup = paw.wfs.setups[a] energies = np.empty(nb * nk) weights_xi = np.empty((nb * nk, setup.ni)) x = 0 for k, w in enumerate(w_k): energies[x:x + nb] = e_mk[:, k] P_ami = get_spinorbit_projections(paw, k, v_knm[k]) if ns == 2: weights_xi[x:x + nb, :] = w * np.absolute(P_ami[a][:, spin::2])**2 else: weights_xi[x:x + nb, :] = w * np.absolute(P_ami[a][:, 0::2])**2 / 2 weights_xi[x:x + nb, :] += w * np.absolute(P_ami[a][:, 1::2])**2 / 2 x += nb if angular is None: return energies, weights_xi elif isinstance(angular, int): return energies, weights_xi[:, angular] else: projectors = get_angular_projectors(setup, angular, type='bound') weights = np.sum(np.take(weights_xi, indices=projectors, axis=1), axis=1) return energies, weights
# No spin-orbit ef = calc2.get_fermi_level() e_kn = np.array([ calc1.get_eigenvalues(kpt=k) for k in range(len(calc1.get_ibz_k_points())) ]) e_nk = e_kn.T e_nk -= ef for e_k in e_nk: plt.plot(x, e_k, '--', c='0.5') # Spin-orbit calculation e_nk = get_spinorbit_eigenvalues(calc2) set_calculator(calc2, e_nk.T) ef = calc2.get_fermi_level() e_nk = get_spinorbit_eigenvalues(calc1, scale=1.0) e_nk -= ef plt.xticks(X, [r'$\Gamma$', 'Z', 'F', r'$\Gamma$', 'L'], size=24) plt.yticks(size=20) for i in range(len(X))[1:-1]: plt.plot(2 * [X[i]], [1.1 * np.min(e_nk), 1.1 * np.max(e_nk)], c='0.5', linewidth=0.5) for e_k in e_nk: plt.plot(x, e_k, c='b') plt.ylabel(r'$\varepsilon_n(k)$ [eV]', size=24) plt.axis([0, x[-1], -1.7, 1.7])
#plt.rc('text', usetex=True) calc = GPAW('WS2_bands.gpw', txt=None) x = np.loadtxt('WS2_kpath.dat') X = np.loadtxt('WS2_highsym.dat') e_kn = np.array([ calc.get_eigenvalues(kpt=k)[:20] for k in range(len(calc.get_ibz_k_points())) ]) e_nk = e_kn.T e_nk -= calc.get_fermi_level() for e_k in e_nk: plt.plot(x, e_k, '--', c='0.5') e_nk, s_nk = get_spinorbit_eigenvalues(calc, return_spin=True, bands=range(20)) e_nk -= calc.get_fermi_level() s_nk = (s_nk + 1.0) / 2.0 plt.xticks(X, ['M', 'K', r'$\Gamma$', '-K', '-M'], size=20) plt.yticks(size=20) for i in range(len(X))[1:-1]: plt.plot(2 * [X[i]], [1.1 * np.min(e_nk), 1.1 * np.max(e_nk)], c='0.5', linewidth=0.5) plt.scatter(np.tile(x, len(e_nk)), e_nk.reshape(-1), c=s_nk.reshape(-1), edgecolor=plt.get_cmap('jet')(s_nk.reshape(-1)), s=2,
from ase import Atoms from gpaw import GPAW from gpaw.spinorbit import get_spinorbit_eigenvalues from gpaw.test import equal a = Atoms('Kr') a.center(vacuum=3.0) calc = GPAW(mode='pw', xc='LDA') a.calc = calc a.get_potential_energy() e_n = calc.get_eigenvalues() e_m = get_spinorbit_eigenvalues(calc) equal(e_n[0] - e_m[0], 0.0, 1.0e-3) equal(e_n[1] - e_m[2], 0.452, 1.0e-3) equal(e_n[2] - e_m[4], -0.226, 1.0e-3)
calc.get_eigenvalues(kpt=k, spin=s) for k in range(len(calc.get_ibz_k_points())) ] for s in range(2)]) e_kn = np.reshape(np.swapaxes(e_skn, 0, 1), (len(e_skn[0]), 2 * len(e_skn[0, 0]))) e_kn = np.sort(e_kn, 1) f_skn = np.array([[ calc.get_occupation_numbers(kpt=k, spin=s) for k in range(len(calc.get_ibz_k_points())) ] for s in range(2)]) f_kn = np.reshape(np.swapaxes(f_skn, 0, 1), (len(f_skn[0]), 2 * len(f_skn[0, 0]))) f_kn = np.sort(f_kn, 1)[:, ::-1] E = np.sum(e_kn * f_kn) # Spinorbit theta_i = [i * np.pi / 20 for i in range(21)] for theta in theta_i: calc = GPAW('gs_Co.gpw', txt=None) e_mk = get_spinorbit_eigenvalues(calc, theta=theta, phi=0.0) set_calculator(calc, e_mk.T) f_km = np.array([ calc.get_occupation_numbers(kpt=k) for k in range(len(calc.get_ibz_k_points())) ]) E_so = np.sum(e_mk.T * f_km) with open('anisotropy.dat', 'a') as f: print(theta, E, E_so, file=f)
def parallel_transport(calc, direction=0, spinors=True, name=None, scale=1.0, bands=None, theta=0.0, phi=0.0): if isinstance(calc, str): calc = GPAW(calc, txt=None, communicator=serial_comm) if bands is None: nv = int(calc.get_number_of_electrons()) bands = range(nv) cell_cv = calc.wfs.gd.cell_cv icell_cv = (2 * np.pi) * np.linalg.inv(cell_cv).T r_g = calc.wfs.gd.get_grid_point_coordinates() Ng = np.prod(np.shape(r_g)[1:]) * (spinors + 1) dO_aii = [] for ia in calc.wfs.kpt_u[0].P_ani.keys(): dO_ii = calc.wfs.setups[ia].dO_ii if spinors: # Spinor projections require doubling of the (identical) orbitals dO_jj = np.zeros((2 * len(dO_ii), 2 * len(dO_ii)), complex) dO_jj[::2, ::2] = dO_ii dO_jj[1::2, 1::2] = dO_ii dO_aii.append(dO_jj) else: dO_aii.append(dO_ii) N_c = calc.wfs.kd.N_c assert 1 in np.delete(N_c, direction) Nkx = N_c[0] Nky = N_c[1] Nkz = N_c[2] Nk = Nkx * Nky * Nkz Nloc = N_c[direction] Npar = Nk // Nloc # Parallelization stuff myKsize = -(-Npar // (world.size)) myKrange = range(rank * myKsize, min((rank + 1) * myKsize, Npar)) myKsize = len(myKrange) # Get array of k-point indices of the path. q index is loc direction kpts_kq = [] for k in range(Npar): if direction == 0: kpts_kq.append(list(range(k, Nkx * Nky, Nky))) if direction == 1: if Nkz == 1: kpts_kq.append(list(range(k * Nky, (k + 1) * Nky))) else: kpts_kq.append(list(range(k, Nkz * Nky, Nkz))) if direction == 2: kpts_kq.append(list(range(k * Nloc, (k + 1) * Nloc))) G_c = np.array([0, 0, 0]) G_c[direction] = 1 G_v = np.dot(G_c, icell_cv) kpts_kc = calc.get_bz_k_points() kpts_kv = np.dot(kpts_kc, icell_cv) if Nloc > 1: b_c = kpts_kc[kpts_kq[0][1]] - kpts_kc[kpts_kq[0][0]] b_v = np.dot(b_c, icell_cv) else: b_v = G_v e_mk, v_knm = get_spinorbit_eigenvalues(calc, return_wfs=True, scale=scale, theta=theta, phi=phi) phi_km = np.zeros((Npar, len(bands)), float) S_km = np.zeros((Npar, len(bands)), float) # Loop over the direction parallel components for k in myKrange: U_qmm = [np.eye(len(bands))] print(k) qpts_q = kpts_kq[k] # Loop over kpoints in the phase direction for q in range(Nloc - 1): iq1 = qpts_q[q] iq2 = qpts_q[q + 1] # print(kpts_kc[iq1], kpts_kc[iq2]) if q == 0: u1_nsG = get_spinorbit_wavefunctions(calc, iq1, v_knm[iq1])[bands] # Transform from psi-like to u-like u1_nsG[:] *= np.exp(-1.0j * gemmdot(kpts_kv[iq1], r_g, beta=0.0)) P1_ani = get_spinorbit_projections(calc, iq1, v_knm[iq1]) u2_nsG = get_spinorbit_wavefunctions(calc, iq2, v_knm[iq2])[bands] u2_nsG[:] *= np.exp(-1.0j * gemmdot(kpts_kv[iq2], r_g, beta=0.0)) P2_ani = get_spinorbit_projections(calc, iq2, v_knm[iq2]) M_mm = get_overlap(calc, bands, np.reshape(u1_nsG, (len(u1_nsG), Ng)), np.reshape(u2_nsG, (len(u2_nsG), Ng)), P1_ani, P2_ani, dO_aii, b_v) V_mm, sing_m, W_mm = np.linalg.svd(M_mm) U_mm = np.dot(V_mm, W_mm).conj() u_nysxz = np.dot(U_mm, np.swapaxes(u2_nsG, 0, 3)) u_nxsyz = np.swapaxes(u_nysxz, 1, 3) u_nsxyz = np.swapaxes(u_nxsyz, 1, 2) u2_nsG = u_nsxyz for a in range(len(calc.atoms)): P2_ni = P2_ani[a][bands] P2_ni = np.dot(U_mm, P2_ni) P2_ani[a][bands] = P2_ni U_qmm.append(U_mm) u1_nsG = u2_nsG P1_ani = P2_ani U_qmm = np.array(U_qmm) # Fix phases for last point iq0 = qpts_q[0] if Nloc == 1: u1_nsG = get_spinorbit_wavefunctions(calc, iq0, v_knm[iq0])[bands] u1_nsG[:] *= np.exp(-1.0j * gemmdot(kpts_kv[iq0], r_g, beta=0.0)) P1_ani = get_spinorbit_projections(calc, iq0, v_knm[iq0]) u2_nsG = get_spinorbit_wavefunctions(calc, iq0, v_knm[iq0])[bands] u2_nsG[:] *= np.exp(-1.0j * gemmdot(kpts_kv[iq0], r_g, beta=0.0)) u2_nsG[:] *= np.exp(-1.0j * gemmdot(G_v, r_g, beta=0.0)) P2_ani = get_spinorbit_projections(calc, iq0, v_knm[iq0]) for a in range(len(calc.atoms)): P2_ni = P2_ani[a][bands] # P2_ni *= np.exp(-1.0j * np.dot(G_v, r_av[a])) P2_ani[a][bands] = P2_ni M_mm = get_overlap(calc, bands, np.reshape(u1_nsG, (len(u1_nsG), Ng)), np.reshape(u2_nsG, (len(u2_nsG), Ng)), P1_ani, P2_ani, dO_aii, b_v) V_mm, sing_m, W_mm = np.linalg.svd(M_mm) U_mm = np.dot(V_mm, W_mm).conj() u_nysxz = np.dot(U_mm, np.swapaxes(u2_nsG, 0, 3)) u_nxsyz = np.swapaxes(u_nysxz, 1, 3) u_nsxyz = np.swapaxes(u_nxsyz, 1, 2) u2_nsG = u_nsxyz for a in range(len(calc.atoms)): P2_ni = P2_ani[a][bands] P2_ni = np.dot(U_mm, P2_ni) P2_ani[a][bands] = P2_ni # Get overlap between first kpts and its smoothly translated image u2_nsG[:] *= np.exp(1.0j * gemmdot(G_v, r_g, beta=0.0)) for a in range(len(calc.atoms)): P2_ni = P2_ani[a][bands] # P2_ni *= np.exp(1.0j * np.dot(G_v, r_av[a])) P2_ani[a][bands] = P2_ni u1_nsG = get_spinorbit_wavefunctions(calc, iq0, v_knm[iq0])[bands] u1_nsG[:] *= np.exp(-1.0j * gemmdot(kpts_kv[iq0], r_g, beta=0.0)) P1_ani = get_spinorbit_projections(calc, iq0, v_knm[iq0]) M_mm = get_overlap(calc, bands, np.reshape(u1_nsG, (len(u1_nsG), Ng)), np.reshape(u2_nsG, (len(u2_nsG), Ng)), P1_ani, P2_ani, dO_aii, np.array([0.0, 0.0, 0.0])) l_m, l_mm = np.linalg.eig(M_mm) phi_km[k] = np.angle(l_m) print(phi_km[k] / 2 / np.pi) A_mm = np.zeros_like(l_mm, complex) for q in range(Nloc): iq = qpts_q[q] U_mm = U_qmm[q] v_nm = U_mm.dot(v_knm[iq][:, bands].T).T A_mm += np.dot(v_nm[::2].T.conj(), v_nm[::2]) A_mm -= np.dot(v_nm[1::2].T.conj(), v_nm[1::2]) A_mm /= Nloc S_km[k] = np.diag(l_mm.T.conj().dot(A_mm).dot(l_mm)).real world.sum(phi_km) world.sum(S_km) np.savez('phases_%s.npz' % name, phi_km=phi_km, S_km=S_km)
def calculate(self, optical=True, ac=1.0): if self.spinors: """Calculate spinors. Here m is index of eigenvalues with SOC and n is the basis of eigenstates withour SOC. Below m is used for unoccupied states and n is used for occupied states so be careful!""" print('Diagonalizing spin-orbit Hamiltonian', file=self.fd) param = self.calc.parameters if not param['symmetry'] == 'off': print('Calculating KS wavefunctions without symmetry ' + 'for spin-orbit', file=self.fd) if not op.isfile('gs_nosym.gpw'): calc_so = GPAW(**param) calc_so.set(symmetry='off', fixdensity=True, txt='gs_nosym.txt') calc_so.atoms = self.calc.atoms calc_so.density = self.calc.density calc_so.get_potential_energy() calc_so.write('gs_nosym.gpw') calc_so = GPAW('gs_nosym.gpw', txt=None, communicator=serial_comm) e_mk, v_knm = get_spinorbit_eigenvalues(calc_so, return_wfs=True, scale=self.scale) del calc_so else: e_mk, v_knm = get_spinorbit_eigenvalues(self.calc, return_wfs=True, scale=self.scale) e_mk /= Hartree # Parallelization stuff nK = self.kd.nbzkpts myKrange, myKsize, mySsize = self.parallelisation_sizes() # Calculate exchange interaction qd0 = KPointDescriptor([self.q_c]) pd0 = PWDescriptor(self.ecut, self.calc.wfs.gd, complex, qd0) ikq_k = self.kd.find_k_plus_q(self.q_c) v_G = get_coulomb_kernel(pd0, self.kd.N_c, truncation=self.truncation, wstc=self.wstc) if optical: v_G[0] = 0.0 self.pair = PairDensity(self.calc, self.ecut, world=serial_comm, txt='pair.txt') # Calculate direct (screened) interaction and PAW corrections if self.mode == 'RPA': Q_aGii = self.pair.initialize_paw_corrections(pd0) else: self.get_screened_potential(ac=ac) if (self.qd.ibzk_kc - self.q_c < 1.0e-6).all(): iq0 = self.qd.bz2ibz_k[self.kd.where_is_q(self.q_c, self.qd.bzk_kc)] Q_aGii = self.Q_qaGii[iq0] else: Q_aGii = self.pair.initialize_paw_corrections(pd0) # Calculate pair densities, eigenvalues and occupations so = self.spinors + 1 Nv, Nc = so * self.nv, so * self.nc Ns = self.spins rhoex_KsmnG = np.zeros((nK, Ns, Nv, Nc, len(v_G)), complex) # rhoG0_Ksmn = np.zeros((nK, Ns, Nv, Nc), complex) df_Ksmn = np.zeros((nK, Ns, Nv, Nc), float) # -(ev - ec) deps_ksmn = np.zeros((myKsize, Ns, Nv, Nc), float) # -(fv - fc) if np.allclose(self.q_c, 0.0): optical_limit = True else: optical_limit = False get_pair = self.pair.get_kpoint_pair get_rho = self.pair.get_pair_density if self.spinors: # Get all pair densities to allow for SOC mixing # Use twice as many no-SOC states as BSE bands to allow mixing vi_s = [2 * self.val_sn[0, 0] - self.val_sn[0, -1] - 1] vf_s = [2 * self.con_sn[0, -1] - self.con_sn[0, 0] + 2] if vi_s[0] < 0: vi_s[0] = 0 ci_s, cf_s = vi_s, vf_s ni, nf = vi_s[0], vf_s[0] mvi = 2 * self.val_sn[0, 0] mvf = 2 * (self.val_sn[0, -1] + 1) mci = 2 * self.con_sn[0, 0] mcf = 2 * (self.con_sn[0, -1] + 1) else: vi_s, vf_s = self.val_sn[:, 0], self.val_sn[:, -1] + 1 ci_s, cf_s = self.con_sn[:, 0], self.con_sn[:, -1] + 1 for ik, iK in enumerate(myKrange): for s in range(Ns): pair = get_pair(pd0, s, iK, vi_s[s], vf_s[s], ci_s[s], cf_s[s]) m_m = np.arange(vi_s[s], vf_s[s]) n_n = np.arange(ci_s[s], cf_s[s]) if self.gw_skn is not None: iKq = self.calc.wfs.kd.find_k_plus_q(self.q_c, [iK])[0] epsv_m = self.gw_skn[s, iK, :self.nv] epsc_n = self.gw_skn[s, iKq, self.nv:] deps_ksmn[ik] = -(epsv_m[:, np.newaxis] - epsc_n) elif self.spinors: iKq = self.calc.wfs.kd.find_k_plus_q(self.q_c, [iK])[0] epsv_m = e_mk[mvi:mvf, iK] epsc_n = e_mk[mci:mcf, iKq] deps_ksmn[ik, s] = -(epsv_m[:, np.newaxis] - epsc_n) else: deps_ksmn[ik, s] = -pair.get_transition_energies(m_m, n_n) df_mn = pair.get_occupation_differences(self.val_sn[s], self.con_sn[s]) rho_mnG = get_rho(pd0, pair, m_m, n_n, optical_limit=optical_limit, direction=self.direction, Q_aGii=Q_aGii, extend_head=False) if self.spinors: if optical_limit: deps0_mn = -pair.get_transition_energies(m_m, n_n) rho_mnG[:, :, 0] *= deps0_mn df_Ksmn[iK, s, ::2, ::2] = df_mn df_Ksmn[iK, s, ::2, 1::2] = df_mn df_Ksmn[iK, s, 1::2, ::2] = df_mn df_Ksmn[iK, s, 1::2, 1::2] = df_mn vecv0_nm = v_knm[iK][::2][ni:nf, mvi:mvf] vecc0_nm = v_knm[iKq][::2][ni:nf, mci:mcf] rho_0mnG = np.dot(vecv0_nm.T.conj(), np.dot(vecc0_nm.T, rho_mnG)) vecv1_nm = v_knm[iK][1::2][ni:nf, mvi:mvf] vecc1_nm = v_knm[iKq][1::2][ni:nf, mci:mcf] rho_1mnG = np.dot(vecv1_nm.T.conj(), np.dot(vecc1_nm.T, rho_mnG)) rhoex_KsmnG[iK, s] = rho_0mnG + rho_1mnG if optical_limit: rhoex_KsmnG[iK, s, :, :, 0] /= deps_ksmn[ik, s] else: df_Ksmn[iK, s] = pair.get_occupation_differences(m_m, n_n) rhoex_KsmnG[iK, s] = rho_mnG if self.eshift is not None: deps_ksmn[np.where(df_Ksmn[myKrange] > 1.0e-3)] += self.eshift deps_ksmn[np.where(df_Ksmn[myKrange] < -1.0e-3)] -= self.eshift world.sum(df_Ksmn) world.sum(rhoex_KsmnG) self.rhoG0_S = np.reshape(rhoex_KsmnG[:, :, :, :, 0], -1) if hasattr(self, 'H_sS'): return # Calculate Hamiltonian t0 = time() print('Calculating %s matrix elements at q_c = %s' % (self.mode, self.q_c), file=self.fd) H_ksmnKsmn = np.zeros((myKsize, Ns, Nv, Nc, nK, Ns, Nv, Nc), complex) for ik1, iK1 in enumerate(myKrange): for s1 in range(Ns): kptv1 = self.pair.get_k_point(s1, iK1, vi_s[s1], vf_s[s1]) kptc1 = self.pair.get_k_point(s1, ikq_k[iK1], ci_s[s1], cf_s[s1]) rho1_mnG = rhoex_KsmnG[iK1, s1] #rhoG0_Ksmn[iK1, s1] = rho1_mnG[:, :, 0] rho1ccV_mnG = rho1_mnG.conj()[:, :] * v_G for s2 in range(Ns): for Q_c in self.qd.bzk_kc: iK2 = self.kd.find_k_plus_q(Q_c, [kptv1.K])[0] rho2_mnG = rhoex_KsmnG[iK2, s2] rho2_mGn = np.swapaxes(rho2_mnG, 1, 2) H_ksmnKsmn[ik1, s1, :, :, iK2, s2, :, :] += ( np.dot(rho1ccV_mnG, rho2_mGn)) if not self.mode == 'RPA' and s1 == s2: ikq = ikq_k[iK2] kptv2 = self.pair.get_k_point(s1, iK2, vi_s[s1], vf_s[s1]) kptc2 = self.pair.get_k_point(s1, ikq, ci_s[s1], cf_s[s1]) rho3_mmG, iq = self.get_density_matrix(kptv1, kptv2) rho4_nnG, iq = self.get_density_matrix(kptc1, kptc2) if self.spinors: vec0_nm = v_knm[iK1][::2][ni:nf, mvi:mvf] vec1_nm = v_knm[iK1][1::2][ni:nf, mvi:mvf] vec2_nm = v_knm[iK2][::2][ni:nf, mvi:mvf] vec3_nm = v_knm[iK2][1::2][ni:nf, mvi:mvf] rho_0mnG = np.dot(vec0_nm.T.conj(), np.dot(vec2_nm.T, rho3_mmG)) rho_1mnG = np.dot(vec1_nm.T.conj(), np.dot(vec3_nm.T, rho3_mmG)) rho3_mmG = rho_0mnG + rho_1mnG vec0_nm = v_knm[ikq_k[iK1]][::2][ni:nf, mci:mcf] vec1_nm = v_knm[ikq_k[iK1]][1::2][ni:nf,mci:mcf] vec2_nm = v_knm[ikq][::2][ni:nf, mci:mcf] vec3_nm = v_knm[ikq][1::2][ni:nf, mci:mcf] rho_0mnG = np.dot(vec0_nm.T.conj(), np.dot(vec2_nm.T, rho4_nnG)) rho_1mnG = np.dot(vec1_nm.T.conj(), np.dot(vec3_nm.T, rho4_nnG)) rho4_nnG = rho_0mnG + rho_1mnG rho3ccW_mmG = np.dot(rho3_mmG.conj(), self.W_qGG[iq]) W_mmnn = np.dot(rho3ccW_mmG, np.swapaxes(rho4_nnG, 1, 2)) W_mnmn = np.swapaxes(W_mmnn, 1, 2) * Ns * so H_ksmnKsmn[ik1, s1, :, :, iK2, s1] -= 0.5 * W_mnmn if iK1 % (myKsize // 5 + 1) == 0: dt = time() - t0 tleft = dt * myKsize / (iK1 + 1) - dt print(' Finished %s pair orbitals in %s - Estimated %s left' % ((iK1 + 1) * Nv * Nc * Ns * world.size, timedelta(seconds=round(dt)), timedelta(seconds=round(tleft))), file=self.fd) #if self.mode == 'BSE': # del self.Q_qaGii, self.W_qGG, self.pd_q H_ksmnKsmn /= self.vol mySsize = myKsize * Nv * Nc * Ns if myKsize > 0: iS0 = myKrange[0] * Nv * Nc * Ns #world.sum(rhoG0_Ksmn) #self.rhoG0_S = np.reshape(rhoG0_Ksmn, -1) self.df_S = np.reshape(df_Ksmn, -1) if not self.td: self.excludef_S = np.where(np.abs(self.df_S) < 0.001)[0] # multiply by 2 when spin-paired and no SOC self.df_S *= 2.0 / nK / Ns / so self.deps_s = np.reshape(deps_ksmn, -1) H_sS = np.reshape(H_ksmnKsmn, (mySsize, self.nS)) for iS in range(mySsize): # Multiply by occupations and adiabatic coupling H_sS[iS] *= self.df_S[iS0 + iS] * ac # add bare transition energies H_sS[iS, iS0 + iS] += self.deps_s[iS] self.H_sS = H_sS if self.write_h: self.par_save('H_SS.ulm', 'H_SS', self.H_sS)
from gpaw import GPAW from gpaw.spinorbit import get_spinorbit_eigenvalues #plt.rc('text', usetex=True) calc = GPAW('WS2_bands.gpw', txt=None) x = np.loadtxt('WS2_kpath.dat') X = np.loadtxt('WS2_highsym.dat') e_kn = np.array( [calc.get_eigenvalues(kpt=k) for k in range(len(calc.get_ibz_k_points()))]) e_nk = e_kn.T e_nk -= calc.get_fermi_level() for e_k in e_nk: plt.plot(x, e_k, '--', c='0.5') e_nk, s_kvn = get_spinorbit_eigenvalues(calc, return_spin=True) e_nk -= calc.get_fermi_level() s_nk = (s_kvn[:, 2].T + 1.0) / 2.0 plt.xticks(X, [ r'$\mathrm{M}$', r'$\mathrm{K}$', r'$\Gamma$', r'$\mathrm{-K}$', r'$\mathrm{-M}$' ], size=20) plt.yticks(size=20) for i in range(len(X))[1:-1]: plt.plot(2 * [X[i]], [1.1 * np.min(e_nk), 1.1 * np.max(e_nk)], c='0.5', linewidth=0.5) plt.scatter(np.tile(x, len(e_nk)),
import os import gpaw.wannier90 as w90 from gpaw import GPAW from gpaw.spinorbit import get_spinorbit_eigenvalues seed = 'Fe' calc = GPAW('Fe.gpw', txt=None) e_mk, v_knm = get_spinorbit_eigenvalues(calc, return_wfs=True) w90.write_input(calc, bands=range(30), spinors=True, num_iter=200, dis_num_iter=500, dis_mix_ratio=1.0, dis_froz_max=15.0, seed=seed) os.system('wannier90.x -pp ' + seed) w90.write_projections(calc, v_knm=v_knm, seed=seed) w90.write_eigenvalues(calc, e_km=e_mk.T, seed=seed) w90.write_overlaps(calc, v_knm=v_knm, seed=seed) os.system('wannier90.x ' + seed)
params = dict(mode='pw', kpts={'size': (3, 3, 1), 'gamma': True}) # Selfconsistent: a.calc = GPAW(experimental={ 'magmoms': np.zeros((3, 3)), 'soc': True }, convergence={'bands': 28}, **params) a.get_potential_energy() E1 = a.calc.get_eigenvalues(kpt=2) # Non-selfconsistent: a.calc = GPAW(convergence={'bands': 14}, **params) a.get_potential_energy() E2 = get_spinorbit_eigenvalues(a.calc, bands=np.arange(14))[:, 2] def test(E, hsplit, lsplit): print(E) h1, h2, l1, l2 = E[24:28] # H**O-1, H**O, LUMO, LUMP+1 print(h2 - h1) print(l2 - l1) assert abs(h2 - h1 - hsplit) < 0.01 assert abs(l2 - l1 - lsplit) < 0.002 equal(E1[:28], E2, tolerance=1e-1) test(E1, 0.15, 0.002) test(E2, 0.15, 0.007)