Exemple #1
0
  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)]
Exemple #2
0
  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()
Exemple #3
0
    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)