Beispiel #1
0
    def __init__(self, mf, frozen=None, auxbasis=None):
        '''
        Args:
            mf : RHF instance
            frozen : number of frozen orbitals or list of frozen orbitals
            auxbasis : name of auxiliary basis set, otherwise determined automatically
        '''

        if not isinstance(mf, scf.rhf.RHF):
            raise TypeError('Class initialization with non-RHF object')
        self.mo_coeff = mf.mo_coeff
        self.mo_energy = mf.mo_energy
        self.nocc = np.count_nonzero(mf.mo_occ)
        self.nmo = self.mo_coeff.shape[1]
        self.e_scf = mf.e_tot
        self._scf = mf

        # Process the frozen core option correctly as an integer or a list.
        # self.frozen_mask sets a flag for each orbital if it is frozen (True) or not (False).
        # Only occupied orbitals can be frozen.
        self.frozen_mask = np.zeros(self.nmo, dtype=bool)
        if frozen is None:
            pass
        elif lib.isinteger(frozen):
            if frozen > self.nocc:
                raise ValueError('only occupied orbitals can be frozen')
            self.frozen_mask[:frozen] = True
        elif lib.isintsequence(frozen):
            if max(frozen) > self.nocc - 1:
                raise ValueError('only occupied orbitals can be frozen')
            self.frozen_mask[frozen] = True
        else:
            raise TypeError('frozen must be an integer or a list of integers')

        # mask for occupied orbitals that are not frozen
        self.occ_mask = np.zeros(self.nmo, dtype=bool)
        self.occ_mask[:self.nocc] = True
        self.occ_mask[self.frozen_mask] = False

        self.mol = mf.mol
        if not auxbasis:
            auxbasis = df.make_auxbasis(self.mol, mp2fit=True)
        self.auxmol = df.make_auxmol(self.mol, auxbasis)

        self.verbose = self.mol.verbose
        self.stdout = self.mol.stdout
        self.max_memory = self.mol.max_memory

        self._intsfile = None
        self.e_corr = None

        # Spin component scaling factors
        self.ps = 1.0
        self.pt = 1.0

        self.cphf_max_cycle = 100
        self.cphf_tol = mf.conv_tol
Beispiel #2
0
def energy_mol(newbasis, moldata):

  mol       = moldata['mol'      ]
  rho       = moldata['rho'      ]
  coords    = moldata['coords'   ]
  weights   = moldata['weights'  ]
  self      = moldata['self'     ]

  newmol = df.make_auxmol(mol, newbasis)
  ao = dft.numint.eval_ao(newmol, coords).T
  w = np.einsum('pi,i,i->p', ao,rho,weights)
  S = np.einsum('pi,qi,i->pq', ao,ao,weights)
  c = np.linalg.solve(S, w)
  E = self-c@w
  return E
Beispiel #3
0
    def initialize(self, xbas=None):
        """Summary: Construct a fixed part of fock matrix F0

        .. math::

            F_{0} = T + V_{ext} + V_{h} + V_{g}

        """
        self.get_ovlp = lambda *args: self.S
        self.internal_b = np.ones_like(self.b)

        if self.dm_aux is None:
            self.dm_aux = self.dm_tar
        if xbas is None:
            xbas = self.tbas

        if self.guide is None:
            self.V0 = np.zeros_like(self.dm_tar)
        else:
            fac_faxc, dft_xc = util.parse_guide(self.guide)

            N = self.mol.nelectron
            self.xmol = df.make_auxmol(self.mol, auxbasis=xbas)
            dm_aux_ao = scf.addons.project_dm_nr2nr(self.xmol, self.dm_aux, self.mol)

            J_tar = scf.hf.get_jk(self.mol, dm_aux_ao)[0]
            VFA = -(1./N)*(J_tar[0]+J_tar[1])

            mydft = dft.UKS(self.mol)
            mydft.xc = dft_xc
            Vxcdft = mydft.get_veff(self.mol, dm=dm_aux_ao)

            if self.Smnt is not None:
                #Generate potential matrix in target DM basis representation
                dm_aux_tbas = scf.addons.project_dm_nr2nr(self.xmol, self.dm_aux, self.tmol)

                self.V_tbas = self.tmol.intor('int1e_nuc')
                J_tbas = scf.hf.get_jk(self.tmol, dm_aux_tbas)[0]
                VFA_tbas = -(1./N)*(J_tbas[0]+J_tbas[1])
                mydft_tbas = dft.UKS(self.tmol)
                mydft_tbas.xc = dft_xc
                Vxcdft_tbas = mydft_tbas.get_veff(self.tmol, dm=dm_aux_tbas)
                self.V0_tbas = fac_faxc * VFA_tbas + Vxcdft_tbas

            self.V0 = fac_faxc * np.array((VFA, VFA)) + Vxcdft

        self.F0 = (self.T+self.V+self.V0[0],
                   self.T+self.V+self.V0[1])
Beispiel #4
0
def gradient_mol(nexp, newbasis, moldata):

  mol       = moldata['mol'      ]
  rho       = moldata['rho'      ]
  coords    = moldata['coords'   ]
  weights   = moldata['weights'  ]
  self      = moldata['self'     ]
  idx       = moldata['idx'      ]
  centers   = moldata['centers'  ]
  distances = moldata['distances']

  newmol = df.make_auxmol(mol, newbasis)
  ao = dft.numint.eval_ao(newmol, coords).T

  w = np.einsum('pi,i,i->p', ao,rho,weights)
  dw_da = np.zeros((nexp, newmol.nao))
  for p in range(newmol.nao):
    iat = centers[p]
    r2  = distances[iat]
    dw_da[idx[p],p] = np.einsum('i,i,i,i->', ao[p],rho,r2,weights)

  S  = np.einsum('pi,qi,i->pq', ao,ao,weights)
  dS_da = np.zeros((nexp, newmol.nao, newmol.nao))

  for p in range(newmol.nao):
    for q in range(p,newmol.nao):
      ip = idx[p]
      iq = idx[q]
      iatp = centers[p]
      iatq = centers[q]
      r2p = distances[iatp]
      r2q = distances[iatq]
      ao_ao_w = np.einsum('i,i,i->i', ao[p],ao[q],weights)
      ip_p_q  = np.einsum('i,i->', ao_ao_w,r2p)
      iq_p_q  = np.einsum('i,i->', ao_ao_w,r2q)
      dS_da[ip,p,q] += ip_p_q
      dS_da[iq,p,q] += iq_p_q
      if p!=q:
        dS_da[ip,q,p] += ip_p_q
        dS_da[iq,q,p] += iq_p_q

  c = np.linalg.solve(S, w)
  part1 = np.einsum('p,ip->i',  c, dw_da)
  part2 = np.einsum('p,ipq,q->i',  c, dS_da, c)
  dE_da = 2.0*part1 - part2
  E = self - c@w
  return E, dE_da
Beispiel #5
0
    def test_rdf_rhf_eng(self):
        mol = gto.Mole()
        mol.atom = """
        N  0.  0.  0.
        H  1.5 0.  0.2
        H  0.1 1.2 0.
        H  0.  0.  1.
        """
        mol.basis = "cc-pVDZ"
        mol.verbose = 0
        mol.build()
        mf_scf = scf.RHF(mol).density_fit(auxbasis="cc-pVDZ-jkfit").run()
        mf_mp2 = mp.MP2(mf_scf)
        mf_mp2.with_df = df.DF(mol, auxbasis="cc-pVDZ-ri")
        mf_mp2.run()

        aux_ri = df.make_auxmol(mol, "cc-pVDZ-ri")
        config = {"scf_eng": mf_scf, "aux_ri": aux_ri}
        helper = GradDFMP2(config)
        assert np.allclose(helper.eng, mf_mp2.e_tot, rtol=1e-10, atol=1e-12)
def main():
    xyzfile = sys.argv[1]
    state_id = [int(sys.argv[2]) - 1, int(sys.argv[3]) - 1]
    azo_id = [int(sys.argv[4]) - 1, int(sys.argv[5]) - 1]

    mol = readmol(xyzfile, qm_config.basis)
    coeff = np.load(xyzfile + '.mo.npy')
    X = np.load(xyzfile + '.X.npy')

    auxmol = df.make_auxmol(mol, qm_config.basis2)
    eri3c = eri_pqi(mol, auxmol)
    eri2c = auxmol.intor('int2c2e_sph')

    occ = mol.nelectron // 2
    azo_ao = auxmol.offset_ao_by_atom()[azo_id[0]:azo_id[1] + 1, 2:]
    q = number_of_electrons_vec(auxmol)

    for i, state in enumerate(state_id):

        x_mo = X[state]
        x_ao = coeff[:, :occ] @ x_mo @ coeff[:, occ:].T

        coulomb = compute_j(mol, x_ao)
        b = np.einsum('ijp,ij->p', eri3c, x_ao)
        c = np.linalg.solve(eri2c, b)
        error = coulomb - np.dot(c, b)

        cq = c * q
        n = sum(cq)
        n1 = sum(cq[azo_ao[0, 0]:azo_ao[0, 1]])
        n2 = sum(cq[azo_ao[1, 0]:azo_ao[1, 1]])
        if (n1 < 0.0):
            c = -c

        print(
            xyzfile, 'state' + str(i + 1),
            "Error: % .3e Eh ( %.1e %%)  Electrons: % .1e total, % .2e left N, % .2e right N"
            % (error, error / coulomb * 100.0, n, n1, n2))
        np.savetxt(xyzfile + '.st' + str(i + 1) + '_transition_fit.dat', c)
Beispiel #7
0
def main():
    xyzfile = sys.argv[1]
    mol = readmol(xyzfile, qm_config.basis)
    auxmol = df.make_auxmol(mol, qm_config.basis2)

    eri3c = eri_pqi(mol, auxmol)
    eri2c = auxmol.intor('int2c2e_sph')
    np.save(xyzfile + '.jmat.npy', eri2c)

    N = mol.nelectron
    files = (('ground', xyzfile + '.coulomb.dat', xyzfile + '.dm.dat', N,
              xyzfile + '.dm_fit.dat'), ('hole_1',
                                         xyzfile + '.st1_coulomb_hole.dat',
                                         xyzfile + '.st1_dm_hole.dat', 1,
                                         xyzfile + '.st1_dm_hole_fit.dat'),
             ('part_1', xyzfile + '.st1_coulomb_part.dat',
              xyzfile + '.st1_dm_part.dat', 1,
              xyzfile + '.st1_dm_part_fit.dat'),
             ('hole_2', xyzfile + '.st2_coulomb_hole.dat',
              xyzfile + '.st2_dm_hole.dat', 1,
              xyzfile + '.st2_dm_hole_fit.dat'),
             ('part_2', xyzfile + '.st2_coulomb_part.dat',
              xyzfile + '.st2_dm_part.dat', 1,
              xyzfile + '.st2_dm_part_fit.dat'))

    for i in files:
        (title, file_coul, file_dm, n_correct, file_out) = i
        dm = np.loadtxt(file_dm)
        ej = np.loadtxt(file_coul)
        b = np.einsum('ijp,ij->p', eri3c, dm)
        c = np.linalg.solve(eri2c, b)
        error = ej - np.dot(c, b)
        n = number_of_electrons(c, auxmol)
        print(
            xyzfile + '\t' + title,
            "Error: % .3e Eh ( %.1e %%)  Electrons: %.3e ( % .1e )" %
            (error, error / ej * 100.0, n, n - n_correct))
        np.savetxt(file_out, c)
Beispiel #8
0
def basic(mw, mol, pbas, Sijt, tbas, Smnt):
    """Summary: Common basic initialization function for RWY and UWY objects

    Args:
        mw : RWY or UWY object
        mol : an instance of :class:`Mole`
        pbas (dict or str) : potential basis set for WY
        Sijt (ndarray) : three-center overlap integral with shape ((no, no, np))
          where no is the length of atomic orbital basis set defined in mol,
          while np is the length of potential basis set
          Only effective for model systems and molecular systems with user-defined pbs.
          Otherwise, this is ignored and analytical integration is performed.
        tbas (dict or str) : basis set of target density matrix
        Smnt (ndarray) : three-center overlap integral with shape ((nt, nt, np))
          where nt is the length of atomic orbital basis set that defines target density matrix,
          while np is the length of potential basis set
          Only effective for model systems and molecular systems with user-defined pbs.
          Otherwise, this is ignored and analytical integration is performed.
    """

    mw.mol = mol
    mw.guide = 'faxc'
    mw.reg = 0.
    mw.tol = 1e-6
    mw.method = 'trust-exact'
    mw.verbose = mw.mol.verbose
    mw.stdout = mw.mol.stdout

    mw.Sijt = None
    mw.Smnt = None
    mw.Tp = None
    mw.pbas = pbas
    mw.tbas = tbas

    is_model1 = len(mw.mol._atm) == 0
    is_model2 = len(mw.mol._bas) == 0
    mw.model = is_model1 and is_model2
    if mw.model: #Check if defined mol is a molecule or model
        mw.guide = None
        if Sijt is None:
            raise AssertionError("Three-center overlap integeral should be given for model system")
        if kf_imported:
            mw.Sijt = np.array(Sijt, order='F')
            if Smnt is not None:
                mw.Smnt = np.array(Smnt, order='F')
        else:
            mw.Sijt = np.array(Sijt, order='C')
            if Smnt is not None:
                mw.Smnt = np.array(Smnt, order='C')
        return

    mw.S = mw.mol.intor_symmetric('int1e_ovlp')
    mw.T = mw.mol.intor_symmetric('int1e_kin')
    mw.V = mw.mol.intor_symmetric('int1e_nuc')

    if tbas is None:
        mw.tbas = mol.basis
    mw.tmol = df.make_auxmol(mol, auxbasis=mw.tbas)

    if pbas is not None and callable(pbas[0]):
        #potential basis is given as a list of user-defined functions
        #In this case, mw.Tp should be given by the user to use regularization
        mw.Sijt = Sijt
        if Sijt is None:
            mw.Sijt = numint_3c2b(mol, pbas)

        if not gto.mole.same_basis_set(mol, mw.tmol):
            mw.Smnt = Smnt
            if Smnt is None:
                mw.Smnt = numint_3c2b(mw.tmol, pbas)

    else:
        #potential basis is given as a pyscf-supported format
        if pbas is None:
            mw.pbas = mol.basis

        mw.pmol = df.make_auxmol(mol, auxbasis=mw.pbas)

        mw.Tp = mw.pmol.intor_symmetric('int1e_kin')
        mw.Sijt = df.incore.aux_e2(mol, mw.pmol, intor='int3c1e')

        if not gto.mole.same_basis_set(mol, mw.tmol):
            mw.Smnt = df.incore.aux_e2(mw.tmol, mw.pmol, intor='int3c1e')

    mw.nbas = len(mw.Sijt[:, 0, 0])
    mw.npot = len(mw.Sijt[0, 0, :])
Beispiel #9
0
    def __init__(self, mf, frozen=None, auxbasis=None):
        '''
        Args:
            mf : UHF instance
            frozen : number of frozen orbitals or list of frozen orbitals
            auxbasis : name of auxiliary basis set, otherwise determined automatically
        '''

        if not isinstance(mf, scf.uhf.UHF):
            raise TypeError('Class initialization with non-UHF object')

        # UHF quantities are stored as numpy arrays
        self.mo_coeff = np.array(mf.mo_coeff)
        self.mo_energy = np.array(mf.mo_energy)
        self.nocc = np.array(
            [np.count_nonzero(mf.mo_occ[0]),
             np.count_nonzero(mf.mo_occ[1])])
        # UHF MO coefficient matrix shape: (2, number of AOs, number of MOs)
        self.nmo = self.mo_coeff.shape[2]
        self.e_scf = mf.e_tot
        self._scf = mf

        # Process the frozen core option correctly as either an integer or two lists (alpha, beta).
        # self.frozen_mask sets a flag for each orbital if it is frozen (True) or not (False).
        # Only occupied orbitals can be frozen.
        self.frozen_mask = np.zeros((2, self.nmo), dtype=bool)
        if frozen is None:
            pass
        elif lib.isinteger(frozen):
            if frozen > min(self.nocc):
                raise ValueError('only occupied orbitals can be frozen')
            self.frozen_mask[:, :frozen] = True
        else:
            try:
                if len(frozen) != 2:
                    raise ValueError
                for s in 0, 1:
                    if not lib.isintsequence(frozen[s]):
                        raise TypeError
            except (TypeError, ValueError):
                raise TypeError(
                    'frozen must be an integer or two integer lists')
            if len(frozen[0]) != len(frozen[1]):
                raise ValueError('frozen orbital lists not of equal length')
            for s in 0, 1:
                self.frozen_mask[s, frozen[s]] = True

        # mask for occupied orbitals that are not frozen
        self.occ_mask = np.zeros((2, self.nmo), dtype=bool)
        for s in 0, 1:
            self.occ_mask[s, :self.nocc[s]] = True
        self.occ_mask[self.frozen_mask] = False

        self.mol = mf.mol
        if not auxbasis:
            auxbasis = df.make_auxbasis(self.mol, mp2fit=True)
        self.auxmol = df.make_auxmol(self.mol, auxbasis)

        self.verbose = self.mol.verbose
        self.stdout = self.mol.stdout
        self.max_memory = self.mol.max_memory

        # _intsfile will be a list with two elements for the alpha and beta integrals
        self._intsfile = []
        self.e_corr = None

        # Spin component scaling factors
        self.ps = 1.0
        self.pt = 1.0

        self.cphf_max_cycle = 100
        self.cphf_tol = mf.conv_tol