def __init__(self, **kw): """ Iterative BSE a la PK, DF, OC JCTC additionally to the fields from tddft_iter_c, we add the dipole matrix elements dab[ixyz][a,b] which is constructed as list of numpy arrays $ d_i = \int f^a(r) r_i f^b(r) dr $ """ from pyscf.nao.m_fermi_dirac import fermi_dirac_occupations xc_code_kw = kw['xc_code'] if 'xc_code' in kw else None gw.__init__(self, **kw) #print(__name__, ' dtype ', self.dtype) self.l0_ncalls = 0 self.dip_ab = [d.toarray() for d in self.dipole_coo()] self.norbs2 = self.norbs**2 kernel_den = pack2den_l(self.kernel) n = self.norbs v_dab = self.v_dab cc_da = self.cc_da self.x = self.mo_coeff[0,:,:,:,0] self.kernel_4p = (((v_dab.T*(cc_da*kernel_den))*cc_da.T)*v_dab).reshape([n*n,n*n]) #print(type(self.kernel_4p), self.kernel_4p.shape, 'this is just a reference kernel, must be removed later for sure') self.xc_code = self.xc_code if xc_code_kw is None else xc_code_kw xc = self.xc_code.split(',')[0] if self.verbosity>0: print(__name__, ' xc_code_mf ', self.xc_code_mf) print(__name__, ' xc_code_kernel ', self.xc_code_kernel) print(__name__, ' xc_code_scf ', self.xc_code_scf) print(__name__, ' xc_code ', self.xc_code) if xc=='CIS' or xc=='HF' or xc=='GW': self.kernel_4p -= 0.5*einsum('abcd->bcad', self.kernel_4p.reshape([n,n,n,n])).reshape([n*n,n*n]) elif xc=='RPA' or xc=='LDA' or xc=='GGA': pass else : print(' ?? xc_code ', self.xc_code, xc) raise RuntimeError('??? xc_code ???') if xc=='GW': w_c_4p = (((v_dab.T*(cc_da* self.si_c([0.0])[0].real ))*cc_da.T)*v_dab).reshape([n*n,n*n]) self.kernel_4p -= 0.5*einsum('abcd->bcad', w_c_4p.reshape([n,n,n,n])).reshape([n*n,n*n]) if hasattr(self, 'mo_energy_gw') and xc=='GW': # Need to redefine eigenvectors previously set in the class tddft_iter self.ksn2e = require(zeros((1,self.nspin,self.norbs)), dtype=self.dtype, requirements='CW') self.ksn2e[0,0,:] = self.mo_energy_gw ksn2fd = fermi_dirac_occupations(self.telec, self.ksn2e, self.fermi_energy) if all(ksn2fd[0,0,:]>self.nfermi_tol): print(__name__, self.telec, nfermi_tol, ksn2fd[0,0,:]) raise RuntimeError('telec is too high?') self.ksn2f = (3-self.nspin)*ksn2fd self.x = self.mo_coeff_gw[0,:,:,:,0] self.nfermi = array([argmax(ksn2fd[0,s,:]<self.nfermi_tol) for s in range(self.nspin)], dtype=int) self.vstart = array([argmax(1.0-ksn2fd[0,s,:]>=self.nfermi_tol) for s in range(self.nspin)], dtype=int) self.xocc = [self.mo_coeff_gw[0,s,:nfermi,:,0] for s,nfermi in enumerate(self.nfermi)] self.xvrt = [self.mo_coeff_gw[0,s,vstart:,:,0] for s,vstart in enumerate(self.vstart)]
def __init__(self, **kw): gw.__init__(self, **kw) self.gw_iter_tol = kw['gw_iter_tol'] if 'gw_iter_tol' in kw else 1e-4 self.maxiter = kw['maxiter'] if 'maxiter' in kw else 1000 self.h0_vh_x_expval = self.get_h0_vh_x_expval()
def __init__(self, **kw): r""" Iterative BSE a la PK, DF, OC JCTC additionally to the fields from tddft_iter_c, we add the dipole matrix elements dab[ixyz][a,b] which is constructed as list of numpy arrays $ d_i = \int f^a(r) r_i f^b(r) dr $ """ xc_code_kw = kw['xc_code'] if 'xc_code' in kw else None gw.__init__(self, **kw) self.l0_ncalls = 0 self.dip_ab = [d.toarray() for d in self.dipole_coo()] self.norbs2 = self.norbs**2 self.xc_code = self.xc_code if xc_code_kw is None else xc_code_kw xc = self.xc_code.split(',')[0].upper() if self.verbosity > 0: print(__name__, ' xc_code_mf ', self.xc_code_mf) print(__name__, ' xc_code_kernel ', self.xc_code_kernel) print(__name__, ' xc_code_scf ', self.xc_code_scf) print(__name__, ' xc_code ', self.xc_code) assert self.xc_code_kernel.upper() == 'RPA', '{} ?'.format( self.xc_code_kernel) # Allocation of kernels in the product basis to be used in Hartree and exchange-type kernels dtype, ns, p = self.dtype, self.nspin, self.nprod self.q2hk = zeros((2 * ns - 1, p, p), dtype=dtype) if xc in ['LDA', 'GGA'] else zeros( (1, p, p), dtype=dtype) if xc in ['CIS', 'HF']: self.q2xk = self.q2hk elif xc in ['GW']: self.q2xk = zeros((1, p, p), dtype=dtype) else: self.q2xk = None # Computation of kernels in the product basis... for fh in self.q2hk: fh[:, :] = pack2den_u(self.kernel) if xc in ['LDA', 'GGA']: for q, m in enumerate(self.comp_fxc_pack(**kw)): self.q2hk[q] += pack2den_u(m) elif xc in ['GW']: self.q2xk[0] = pack2den_u(self.kernel) + self.si_c(np.array( [0.0]))[0].real # Allocation of the four-point kernel(s) which is to be used when RAM available n, v_dab, cc_da = self.norbs, self.v_dab, self.cc_da if xc in ['LDA', 'GGA']: self.q2k_4p = zeros((2 * ns - 1, n * n, n * n), dtype=dtype) elif xc in [ 'HF', 'CIS', 'GW' ]: # 1 or 2? Examples of UHF+TD of H2O and H2B(spin=3): 158, 159 self.q2k_4p = zeros((1, n * n, n * n), dtype=dtype) elif xc in ['RPA']: self.q2k_4p = zeros((1, n * n, n * n), dtype=dtype) else: raise RuntimeError('Unknown funct: ' + xc) q2k_4p = self.q2k_4p # q2k_4p is now alias to the self.q2k_4p # Computation of the four-point interaction kernel... for q, fhxc in enumerate( self.q2hk): # Start with Hartree interaction kernel q2k_4p[q] = (((v_dab.T * (cc_da * fhxc)) * cc_da.T) * v_dab).reshape([n * n, n * n]) if xc in ['CIS', 'HF', 'GW']: # Add Fock-like (exchange) interaction kernel w_xc_4p = (((v_dab.T * (cc_da * self.q2xk[0])) * cc_da.T) * v_dab).reshape([n * n, n * n]) q2k_4p[0] -= 0.5 * einsum('abcd->bcad', w_xc_4p.reshape([n, n, n, n])).reshape( [n * n, n * n]) if self.nspin == 1: self.ss2kernel_4p = [[q2k_4p[0]]] elif self.nspin == 2: if len(q2k_4p) == 1: self.ss2kernel_4p = [[q2k_4p[0], q2k_4p[0]], [q2k_4p[0], q2k_4p[0]]] elif len( q2k_4p ) == 2: # # 1 or 2? Examples of UHF+TD of H2O and H2B(spin=3): 158, 159 self.ss2kernel_4p = [[q2k_4p[0], q2k_4p[1]], [q2k_4p[1], q2k_4p[0]]] else: self.ss2kernel_4p = [[q2k_4p[0], q2k_4p[1]], [q2k_4p[1], q2k_4p[2]]] if xc == 'GW': self.define_e_x_l0(self.mo_energy_gw, self.mo_coeff_gw, **kw) else: self.define_e_x_l0(self.mo_energy, self.mo_coeff, **kw)