def get_snmw2sf(self, optimize="greedy"): """ This computes a matrix elements of W_c: <\Psi\Psi | W_c |\Psi\Psi>. sf[spin,n,m,w] = X^n V_mu X^m W_mu_nu X^n V_nu X^m, where n runs from s...f, m runs from 0...norbs, w runs from 0...nff_ia, spin=0...1 or 2. """ wpq2si0 = self.si_c(ww = 1j*self.ww_ia).real v_pab = self.pb.get_ac_vertex_array() #self.snmw2sf_ncalls += 1 snmw2sf = [] for s in range(self.nspin): nmw2sf = zeros((len(self.nn[s]), self.norbs, self.nff_ia), dtype=self.dtype) #nmw2sf = zeros((len(self.nn), self.norbs, self.nff_ia), dtype=self.dtype) # n runs from s...f or states will be corrected: # self.nn = [range(self.start_st[s], self.finish_st[s]) xna = self.mo_coeff[0,s,self.nn[s],:,0] #xna = self.mo_coeff[0,s,self.nn,:,0] # m runs from 0...norbs xmb = self.mo_coeff[0,s,:,:,0] # This calculates nmp2xvx= X^n V_mu X^m for each side nmp2xvx = einsum('na,pab,mb->nmp', xna, v_pab, xmb, optimize=optimize) for iw,si0 in enumerate(wpq2si0): # This calculates nmp2xvx(outer loop)*real.W_mu_nu*nmp2xvx nmw2sf[:,:,iw] = einsum('nmp,pq,nmq->nm', nmp2xvx, si0, nmp2xvx, optimize=optimize) snmw2sf.append(nmw2sf) if self.write_w: from pyscf.nao.m_restart import write_rst_h5py print(write_rst_h5py(data = snmw2sf, filename= 'SCREENED_COULOMB.hdf5')) return snmw2sf
def get_snmw2sf_iter(self, optimize="greedy"): """ This computes a matrix elements of W_c: <\Psi(r)\Psi(r) | W_c(r,r',\omega) |\Psi(r')\Psi(r')>. sf[spin,n,m,w] = X^n V_mu X^m W_mu_nu X^n V_nu X^m, where n runs from s...f, m runs from 0...norbs, w runs from 0...nff_ia, spin=0...1 or 2. 1- XVX is calculated using dominant product in COO format: gw_xvx('dp_coo') 2- I_nm = W XVX = (1-v\chi_0)^{-1}v\chi_0v 3- S_nm = XVX W XVX = XVX * I_nm """ from scipy.sparse.linalg import LinearOperator, lgmres ww = 1j * self.ww_ia xvx = self.gw_xvx('blas') snm2i = [] #convert k_c as full matrix into Operator k_c_opt = LinearOperator((self.nprod, self.nprod), matvec=self.gw_vext2veffmatvec, dtype=self.dtypeComplex) for s in range(self.nspin): sf_aux = np.zeros((len(self.nn[s]), self.norbs, self.nprod), dtype=self.dtypeComplex) inm = np.zeros((len(self.nn[s]), self.norbs, len(ww)), dtype=self.dtypeComplex) # w is complex plane for iw, w in enumerate(ww): self.comega_current = w #print('k_c_opt',k_c_opt.shape) for n in range(len(self.nn[s])): for m in range(self.norbs): # v XVX a = np.dot(self.kernel_sq, xvx[s][n, m, :]) # \chi_{0}v XVX by using matrix vector b = self.gw_chi0_mv(a, self.comega_current) # v\chi_{0}v XVX, this should be equals to bxvx in last approach a = np.dot(self.kernel_sq, b) sf_aux[n, m, :], exitCode = lgmres(k_c_opt, a, atol=self.gw_iter_tol, maxiter=self.maxiter) if exitCode != 0: print( "LGMRES has not achieved convergence: exitCode = {}" .format(exitCode)) # I= XVX I_aux inm[:, :, iw] = np.einsum('nmp,nmp->nm', xvx[s], sf_aux, optimize=optimize) snm2i.append(np.real(inm)) if (self.write_w == True): from pyscf.nao.m_restart import write_rst_h5py print(write_rst_h5py(data=snm2i, filename='SCREENED_COULOMB.hdf5')) return snm2i