예제 #1
0
def vxc_pack(self, **kw):
  """
    Computes the exchange-correlation matrix elements packed version (upper triangular)
    Args:
      sv : (System Variables), this must have arrays of coordinates and species, etc
    Returns:
      vxc,exc
  """
  from pyscf.nao.m_xc_scalar_ni import xc_scalar_ni
  from pyscf.nao.m_ao_matelem import ao_matelem_c

  #sv, dm, xc_code, deriv, kernel=None, ao_log=None, dtype=float64, **kvargs
  sv = self
  dm = kw['dm'] if 'dm' in kw else self.make_rdm1()
  kernel = kw['kernel'] if 'kernel' in kw else None
  ao_log = kw['ao_log'] if 'ao_log' in kw else self.ao_log
  (xc_code,iskw) = (kw['xc_code'],True) if 'xc_code' in kw else (self.xc_code,False)
  dtype = kw['dtype'] if 'dtype' in kw else float64

  aome = ao_matelem_c(ao_log.rr, ao_log.pp, sv, dm)
  me = aome.init_one_set(ao_log)
  atom2s = zeros((sv.natm+1), dtype=int64)
  for atom,sp in enumerate(sv.atom2sp): atom2s[atom+1]=atom2s[atom]+me.ao1.sp2norbs[sp]
  sp2rcut = array([max(mu2rcut) for mu2rcut in me.ao1.sp_mu2rcut])
  norbs = atom2s[-1]

  #ind = triu_indices(norbs)
  if kernel is None: kernel = zeros(norbs*(norbs+1)//2, dtype=dtype)

  if kernel.size != int(norbs*(norbs+1)//2):
    print('kernel.size        ', kernel.size)
    print('norbs*(norbs+1)//2 ', int(norbs*(norbs+1)//2))
    raise ValueError("wrong dimension for kernel")
    

  for atom1,[sp1,rv1,s1,f1] in enumerate(zip(sv.atom2sp,sv.atom2coord,atom2s,atom2s[1:])):
    for atom2,[sp2,rv2,s2,f2] in enumerate(zip(sv.atom2sp,sv.atom2coord,atom2s,atom2s[1:])):
      if atom2>atom1: continue
      if (sp2rcut[sp1]+sp2rcut[sp2])**2<=sum((rv1-rv2)**2) : continue
      
      xc = xc_scalar_ni(me,sp1,rv1,sp2,rv2,**kw) if iskw else xc_scalar_ni(me,sp1,rv1,sp2,rv2,xc_code=xc_code,**kw)
      
      if use_numba:
          fill_triu_v2(xc, kernel, s1, f1, s2, f2, norbs, add=True)
      else:
          for i1 in range(s1,f1):
            for i2 in range(s2, min(i1+1, f2)):
                ind = 0
                if i2 > 0:
                    for beta in range(1, i2+1):
                        ind += norbs -beta
                ind += i1
                kernel[ind] += xc[i1-s1,i2-s2] 
  return kernel
예제 #2
0
def vxc_lil(sv, dm, xc_code, deriv, ao_log=None, dtype=float64, **kvargs):
    """
    Computes the exchange-correlation matrix elements
    Args:
      sv : (System Variables), this must have arrays of coordinates and species, etc
    Returns:
      vxc,exc
  """
    from pyscf.nao.m_xc_scalar_ni import xc_scalar_ni
    from pyscf.nao.m_ao_matelem import ao_matelem_c
    from scipy.sparse import lil_matrix

    aome = ao_matelem_c(sv.ao_log.rr, sv.ao_log.pp, sv, dm)
    me = aome.init_one_set(
        sv.ao_log) if ao_log is None else aome.init_one_set(ao_log)
    atom2s = zeros((sv.natm + 1), dtype=int64)
    for atom, sp in enumerate(sv.atom2sp):
        atom2s[atom + 1] = atom2s[atom] + me.ao1.sp2norbs[sp]
    sp2rcut = array([max(mu2rcut) for mu2rcut in me.ao1.sp_mu2rcut])

    lil = lil_matrix((atom2s[-1], atom2s[-1]), dtype=dtype)

    for atom1, [sp1, rv1, s1, f1] in enumerate(
            zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
        for atom2, [sp2, rv2, s2, f2] in enumerate(
                zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
            if (sp2rcut[sp1] + sp2rcut[sp2])**2 <= sum((rv1 - rv2)**2):
                continue
            lil[s1:f1, s2:f2] = xc_scalar_ni(me, sp1, rv1, sp2, rv2, xc_code,
                                             deriv, **kvargs)

    return lil
예제 #3
0
파일: m_vxc_pack.py 프로젝트: zzy2014/pyscf
def vxc_pack(self, **kw):
    """
    Computes the exchange-correlation matrix elements packed version (upper triangular)
    Args:
      sv : (System Variables), this must have arrays of coordinates and species, etc
    Returns:
      vxc,exc
  """
    from pyscf.nao.m_xc_scalar_ni import xc_scalar_ni
    from pyscf.nao.m_ao_matelem import ao_matelem_c
    from pyscf.nao.m_pack2den import cp_block_pack_u, pack2den_u

    #sv, dm, xc_code, deriv, kernel=None, ao_log=None, dtype=float64, **kvargs
    sv = self
    dm = kw['dm'] if 'dm' in kw else self.make_rdm1()
    ao_log = kw['ao_log'] if 'ao_log' in kw else self.ao_log
    xc_code = kw['xc_code'] if 'xc_code' in kw else self.xc_code
    kw.pop('xc_code', None)
    dtype = kw['dtype'] if 'dtype' in kw else self.dtype

    aome = ao_matelem_c(ao_log.rr, ao_log.pp, sv, dm)
    me = aome.init_one_set(ao_log)
    atom2s = zeros((sv.natm + 1), dtype=int64)
    for atom, sp in enumerate(sv.atom2sp):
        atom2s[atom + 1] = atom2s[atom] + me.ao1.sp2norbs[sp]
    sp2rcut = array([max(mu2rcut) for mu2rcut in me.ao1.sp_mu2rcut])
    norbs = atom2s[-1]

    nq, npk = (self.nspin - 1) * 2 + 1, norbs * (norbs + 1) // 2
    kernel = kw['kernel'].reshape((nq, npk)) if 'kernel' in kw else zeros(
        (nq, npk), dtype=dtype)

    for atom1, [sp1, rv1, s1, f1] in enumerate(
            zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
        for atom2, [sp2, rv2, s2, f2] in enumerate(
                zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
            if atom2 > atom1: continue
            if (sp2rcut[sp1] + sp2rcut[sp2])**2 <= sum((rv1 - rv2)**2):
                continue

            iab2block = xc_scalar_ni(me,
                                     sp1,
                                     rv1,
                                     sp2,
                                     rv2,
                                     xc_code=xc_code,
                                     **kw)
            for i, ab2v in enumerate(iab2block):
                cp_block_pack_u(ab2v, s1, f1, s2, f2, kernel[i], add=True)

    return kernel
예제 #4
0
def vxc_lil(self, **kw):
    """
    Computes the exchange-correlation matrix elements
    Args:
      sv : (System Variables), this must have arrays of coordinates and species, etc
    Returns:
      fxc,vxc,exc
  """
    from pyscf.nao.m_xc_scalar_ni import xc_scalar_ni
    from pyscf.nao.m_ao_matelem import ao_matelem_c
    from scipy.sparse import lil_matrix

    #dm, xc_code, deriv, ao_log=None, dtype=float64, **kvargs

    dm = kw['dm'] if 'dm' in kw else self.make_rdm1()
    kernel = kw['kernel'] if 'kernel' in kw else None
    ao_log = kw['ao_log'] if 'ao_log' in kw else self.ao_log
    xc_code = kw['xc_code'] if 'xc_code' in kw else self.xc_code
    kw.pop('xc_code', None)
    dtype = kw['dtype'] if 'dtype' in kw else self.dtype

    aome = ao_matelem_c(self.ao_log.rr, self.ao_log.pp, self, dm)
    me = aome.init_one_set(
        self.ao_log) if ao_log is None else aome.init_one_set(ao_log)
    atom2s = zeros((self.natm + 1), dtype=int64)
    for atom, sp in enumerate(self.atom2sp):
        atom2s[atom + 1] = atom2s[atom] + me.ao1.sp2norbs[sp]

    lil = [
        lil_matrix((atom2s[-1], atom2s[-1]), dtype=dtype)
        for i in range((self.nspin - 1) * 2 + 1)
    ]

    for atom1, [sp1, rv1, s1, f1] in enumerate(
            zip(self.atom2sp, self.atom2coord, atom2s, atom2s[1:])):
        for atom2, [sp2, rv2, s2, f2] in enumerate(
                zip(self.atom2sp, self.atom2coord, atom2s, atom2s[1:])):
            blk = xc_scalar_ni(me, sp1, rv1, sp2, rv2, xc_code=xc_code, **kw)
            for i, b in enumerate(blk):
                lil[i][s1:f1, s2:f2] = b[:, :]

    return lil
예제 #5
0
def vxc_pack(sv,
             dm,
             xc_code,
             deriv,
             kernel=None,
             ao_log=None,
             dtype=float64,
             **kvargs):
    """
    Computes the exchange-correlation matrix elements packed version (upper triangular)
    Args:
      sv : (System Variables), this must have arrays of coordinates and species, etc
    Returns:
      vxc,exc
  """
    from pyscf.nao.m_xc_scalar_ni import xc_scalar_ni
    from pyscf.nao.m_ao_matelem import ao_matelem_c
    from pyscf.nao.m_pack2den import triu_indices

    aome = ao_matelem_c(sv.ao_log.rr, sv.ao_log.pp, sv, dm)
    me = aome.init_one_set(
        sv.ao_log) if ao_log is None else aome.init_one_set(ao_log)
    atom2s = zeros((sv.natm + 1), dtype=int64)
    for atom, sp in enumerate(sv.atom2sp):
        atom2s[atom + 1] = atom2s[atom] + me.ao1.sp2norbs[sp]
    sp2rcut = array([max(mu2rcut) for mu2rcut in me.ao1.sp_mu2rcut])
    norbs = atom2s[-1]

    ind = triu_indices(norbs)
    if kernel is None:
        kernel = zeros(norbs * (norbs + 1) // 2, dtype=dtype)
        for atom1, [sp1, rv1, s1, f1] in enumerate(
                zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
            for atom2, [sp2, rv2, s2, f2] in enumerate(
                    zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
                if (sp2rcut[sp1] + sp2rcut[sp2])**2 <= sum((rv1 - rv2)**2):
                    continue
                xc = xc_scalar_ni(me, sp1, rv1, sp2, rv2, xc_code, deriv,
                                  **kvargs)
                if use_numba:
                    fill_triu(xc, ind, kernel, s1, f1, s2, f2)
                else:
                    for i1 in range(s1, f1):
                        for i2 in range(s2, f2):
                            if ind[i1, i2] >= 0:
                                kernel[ind[i1, i2]] = xc[i1 - s1, i2 - s2]
        return kernel

    else:
        if kernel.size != int(norbs * (norbs + 1) // 2):
            raise ValueError("wrong dimension for kernel")

        for atom1, [sp1, rv1, s1, f1] in enumerate(
                zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
            for atom2, [sp2, rv2, s2, f2] in enumerate(
                    zip(sv.atom2sp, sv.atom2coord, atom2s, atom2s[1:])):
                if (sp2rcut[sp1] + sp2rcut[sp2])**2 <= sum((rv1 - rv2)**2):
                    continue
                xc = xc_scalar_ni(me, sp1, rv1, sp2, rv2, xc_code, deriv,
                                  **kvargs)
                if use_numba:
                    fill_triu(xc, ind, kernel, s1, f1, s2, f2, add=True)
                else:
                    for i1 in range(s1, f1):
                        for i2 in range(s2, f2):
                            if ind[i1, i2] >= 0:
                                kernel[ind[i1, i2]] += xc[i1 - s1, i2 - s2]