예제 #1
0
  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
예제 #2
0
    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