Example #1
0
def project_mo_r2r(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    t22 = mol2.intor_symmetric('int1e_spsp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_spinor', mol2, mol1)
    t21 = mole.intor_cross('int1e_spsp_spinor', mol2, mol1)
    n2c = s21.shape[1]
    pl = lib.cho_solve(s22, s21)
    ps = lib.cho_solve(t22, t21)
    return numpy.vstack((numpy.dot(pl, mo1[:n2c]), numpy.dot(ps, mo1[n2c:])))
Example #2
0
def project_mo_r2r(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('cint1e_ovlp')
    t22 = mol2.intor_symmetric('cint1e_spsp')
    s21 = mole.intor_cross('cint1e_ovlp', mol2, mol1)
    t21 = mole.intor_cross('cint1e_spsp', mol2, mol1)
    n2c = s21.shape[1]
    pl = pyscf.lib.cho_solve(s22, s21)
    ps = pyscf.lib.cho_solve(t22, t21)
    return numpy.vstack((numpy.dot(pl, mo1[:n2c]),
                         numpy.dot(ps, mo1[n2c:])))
Example #3
0
def project_dm_r2r(mol1, dm1, mol2):
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    t22 = mol2.intor_symmetric('int1e_spsp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_spinor', mol2, mol1)
    t21 = mole.intor_cross('int1e_spsp_spinor', mol2, mol1)
    pl = lib.cho_solve(s22, s21, strict_sym_pos=False)
    ps = lib.cho_solve(t22, t21, strict_sym_pos=False)
    p21 = scipy.linalg.block_diag(pl, ps)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #4
0
def project_mo_r2r(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    t22 = mol2.intor_symmetric('int1e_spsp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_spinor', mol2, mol1)
    t21 = mole.intor_cross('int1e_spsp_spinor', mol2, mol1)
    n2c = s21.shape[1]
    pl = lib.cho_solve(s22, s21, strict_sym_pos=False)
    ps = lib.cho_solve(t22, t21, strict_sym_pos=False)
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        return numpy.vstack((numpy.dot(pl, mo1[:n2c]),
                             numpy.dot(ps, mo1[n2c:])))
    else:
        return [numpy.vstack((numpy.dot(pl, x[:n2c]),
                              numpy.dot(ps, x[n2c:]))) for x in mo1]
Example #5
0
def project_dm_r2r(mol1, dm1, mol2):
    __doc__ = project_dm_nr2nr.__doc__

    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    t22 = mol2.intor_symmetric('int1e_spsp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_spinor', mol2, mol1)
    t21 = mole.intor_cross('int1e_spsp_spinor', mol2, mol1)
    n2c = s21.shape[1]
    pl = lib.cho_solve(s22, s21)
    ps = lib.cho_solve(t22, t21)
    p21 = scipy.linalg.block_diag(pl, ps)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #6
0
def project_dm_nr2nr(mol1, dm1, mol2):
    r''' Project density matrix representation from basis set 1 (mol1) to basis
    set 2 (mol2).

    .. math::

        |AO2\rangle DM_AO2 \langle AO2|

        = |AO2\rangle P DM_AO1 P \langle AO2|

        DM_AO2 = P DM_AO1 P

        P = S_{AO2}^{-1}\langle AO2|AO1\rangle

    There are three relevant functions:
    :func:`project_dm_nr2nr` is the projection for non-relativistic (scalar) basis.
    :func:`project_dm_nr2r` projects from non-relativistic to relativistic basis.
    :func:`project_dm_r2r`  is the projection between relativistic (spinor) basis.
    '''
    s22 = mol2.intor_symmetric('int1e_ovlp')
    s21 = mole.intor_cross('int1e_ovlp', mol2, mol1)
    p21 = lib.cho_solve(s22, s21)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #7
0
def project_mo_r2r(mol1, mo1, mol2):
    __doc__ = project_mo_nr2nr.__doc__

    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    t22 = mol2.intor_symmetric('int1e_spsp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_spinor', mol2, mol1)
    t21 = mole.intor_cross('int1e_spsp_spinor', mol2, mol1)
    n2c = s21.shape[1]
    pl = lib.cho_solve(s22, s21)
    ps = lib.cho_solve(t22, t21)
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        return numpy.vstack((numpy.dot(pl, mo1[:n2c]),
                             numpy.dot(ps, mo1[n2c:])))
    else:
        return [numpy.vstack((numpy.dot(pl, x[:n2c]),
                              numpy.dot(ps, x[n2c:]))) for x in mo1]
Example #8
0
def project_dm_nr2nr(mol1, dm1, mol2):
    r''' Project density matrix representation from basis set 1 (mol1) to basis
    set 2 (mol2).

    .. math::

        |AO2\rangle DM_AO2 \langle AO2|

        = |AO2\rangle P DM_AO1 P \langle AO2|

        DM_AO2 = P DM_AO1 P

        P = S_{AO2}^{-1}\langle AO2|AO1\rangle

    There are three relevant functions:
    :func:`project_dm_nr2nr` is the projection for non-relativistic (scalar) basis.
    :func:`project_dm_nr2r` projects from non-relativistic to relativistic basis.
    :func:`project_dm_r2r`  is the projection between relativistic (spinor) basis.
    '''
    s22 = mol2.intor_symmetric('int1e_ovlp')
    s21 = mole.intor_cross('int1e_ovlp', mol2, mol1)
    p21 = lib.cho_solve(s22, s21)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #9
0
File: x2c.py Project: eronca/pyscf
    def get_hcore(self, mol=None):
        if mol is None: mol = self.mol
        xmol, contr_coeff = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert('1E' in self.approx.upper())
        t = xmol.intor_symmetric('cint1e_kin_sph')
        v = xmol.intor_symmetric('cint1e_nuc_sph')
        s = xmol.intor_symmetric('cint1e_ovlp_sph')
        w = xmol.intor_symmetric('cint1e_pnucp_sph')
        if 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_nr_by_atom()
            nao = xmol.nao_nr()
            x = numpy.zeros((nao,nao))
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                t1 = xmol.intor('cint1e_kin_sph', shls_slice=shls_slice)
                v1 = xmol.intor('cint1e_nuc_sph', shls_slice=shls_slice)
                s1 = xmol.intor('cint1e_ovlp_sph', shls_slice=shls_slice)
                w1 = xmol.intor('cint1e_pnucp_sph', shls_slice=shls_slice)
                x[p0:p1,p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)
        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('cint1e_ovlp_sph')
            s21 = mole.intor_cross('cint1e_ovlp_sph', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T, h1, c))
        if self.xuncontract and contr_coeff is not None:
            h1 = reduce(numpy.dot, (contr_coeff.T, h1, contr_coeff))
        return h1
Example #10
0
def project_mo_nr2nr(mol1, mo1, mol2):
    r''' Project orbital coefficients from basis set 1 (C1 for mol1) to basis
    set 2 (C2 for mol2).

    .. math::

        |\psi1\rangle = |AO1\rangle C1

        |\psi2\rangle = P |\psi1\rangle = |AO2\rangle S^{-1}\langle AO2| AO1\rangle> C1 = |AO2\rangle> C2

        C2 = S^{-1}\langle AO2|AO1\rangle C1

    There are three relevant functions:
    :func:`project_mo_nr2nr` is the projection for non-relativistic (scalar) basis.
    :func:`project_mo_nr2r` projects from non-relativistic to relativistic basis.
    :func:`project_mo_r2r`  is the projection between relativistic (spinor) basis.
    '''
    s22 = mol2.intor_symmetric('int1e_ovlp')
    s21 = mole.intor_cross('int1e_ovlp', mol2, mol1)
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        return lib.cho_solve(s22, numpy.dot(s21, mo1), strict_sym_pos=False)
    else:
        return [
            lib.cho_solve(s22, numpy.dot(s21, x), strict_sym_pos=False)
            for x in mo1
        ]
Example #11
0
File: x2c.py Project: zzy2014/pyscf
    def picture_change(self, even_operator=(None, None), odd_operator=None):
        '''Picture change for even_operator + odd_operator

        even_operator has two terms at diagonal blocks
        [ v  0 ]
        [ 0  w ]

        odd_operator has the term at off-diagonal blocks
        [ 0    p ]
        [ p^T  0 ]

        v, w, and p can be strings (integral name) or matrices.
        '''
        mol = self.mol
        xmol, contr_coeff_nr = self.get_xmol(mol)
        pc_mat = self._picture_change(xmol, even_operator, odd_operator)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp_spinor')
            s21 = mole.intor_cross('int1e_ovlp_spinor', xmol, mol)
            c = lib.cho_solve(s22, s21)

        elif self.xuncontract:
            np, nc = contr_coeff_nr.shape
            c = numpy.zeros((np * 2, nc * 2))
            c[0::2, 0::2] = contr_coeff_nr
            c[1::2, 1::2] = contr_coeff_nr

        else:
            return pc_mat

        if pc_mat.ndim == 2:
            return lib.einsum('pi,pq,qj->ij', c.conj(), pc_mat, c)
        else:
            return lib.einsum('pi,xpq,qj->xij', c.conj(), pc_mat, c)
Example #12
0
    def get_hcore(self, mol=None):
        if mol is None: mol = self.mol
        xmol, contr_coeff = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert ('1E' in self.approx.upper())
        t = xmol.intor_symmetric('cint1e_kin_sph')
        v = xmol.intor_symmetric('cint1e_nuc_sph')
        s = xmol.intor_symmetric('cint1e_ovlp_sph')
        w = xmol.intor_symmetric('cint1e_pnucp_sph')
        if 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_nr_by_atom()
            nao = xmol.nao_nr()
            x = numpy.zeros((nao, nao))
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                t1 = xmol.intor('cint1e_kin_sph', shls_slice=shls_slice)
                v1 = xmol.intor('cint1e_nuc_sph', shls_slice=shls_slice)
                s1 = xmol.intor('cint1e_ovlp_sph', shls_slice=shls_slice)
                w1 = xmol.intor('cint1e_pnucp_sph', shls_slice=shls_slice)
                x[p0:p1, p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)
        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('cint1e_ovlp_sph')
            s21 = mole.intor_cross('cint1e_ovlp_sph', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T, h1, c))
        if self.xuncontract and contr_coeff is not None:
            h1 = reduce(numpy.dot, (contr_coeff.T, h1, contr_coeff))
        return h1
Example #13
0
def project_mo_nr2r(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('cint1e_ovlp')
    s21 = mole.intor_cross('cint1e_ovlp_sph', mol2, mol1)

    ua, ub = symm.cg.real2spinor_whole(mol2)
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21) # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    mo2 = numpy.dot(s21, mo1)
    return numpy.linalg.solve(s22, mo2)
Example #14
0
def project_mo_nr2r(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('cint1e_ovlp')
    s21 = mole.intor_cross('cint1e_ovlp_sph', mol2, mol1)

    ua, ub = symm.cg.real2spinor_whole(mol2)
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21)  # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    mo2 = numpy.dot(s21, mo1)
    return pyscf.lib.cho_solve(s22, mo2)
Example #15
0
File: x2c.py Project: zzy2014/pyscf
    def get_hcore(self, mol=None):
        '''2-component X2c Foldy-Wouthuysen (FW) Hamiltonian (including
        spin-free and spin-dependent terms) in the j-adapted spinor basis.
        '''
        if mol is None: mol = self.mol
        if mol.has_ecp():
            raise NotImplementedError

        xmol, contr_coeff_nr = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert ('1E' in self.approx.upper())
        s = xmol.intor_symmetric('int1e_ovlp_spinor')
        t = xmol.intor_symmetric('int1e_spsp_spinor') * .5
        v = xmol.intor_symmetric('int1e_nuc_spinor')
        w = xmol.intor_symmetric('int1e_spnucsp_spinor')
        if 'get_xmat' in self.__dict__:
            # If the get_xmat method is overwritten by user, build the X
            # matrix with the external get_xmat method
            x = self.get_xmat(xmol)
            h1 = _get_hcore_fw(t, v, w, s, x, c)

        elif 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_2c_by_atom()
            n2c = xmol.nao_2c()
            x = numpy.zeros((n2c, n2c), dtype=numpy.complex)
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                s1 = xmol.intor('int1e_ovlp_spinor', shls_slice=shls_slice)
                t1 = xmol.intor('int1e_spsp_spinor',
                                shls_slice=shls_slice) * .5
                with xmol.with_rinv_at_nucleus(ia):
                    z = -xmol.atom_charge(ia)
                    v1 = z * xmol.intor('int1e_rinv_spinor',
                                        shls_slice=shls_slice)
                    w1 = z * xmol.intor('int1e_sprinvsp_spinor',
                                        shls_slice=shls_slice)
                x[p0:p1, p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)

        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp_spinor')
            s21 = mole.intor_cross('int1e_ovlp_spinor', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T.conj(), h1, c))
        elif self.xuncontract:
            np, nc = contr_coeff_nr.shape
            contr_coeff = numpy.zeros((np * 2, nc * 2))
            contr_coeff[0::2, 0::2] = contr_coeff_nr
            contr_coeff[1::2, 1::2] = contr_coeff_nr
            h1 = reduce(numpy.dot, (contr_coeff.T.conj(), h1, contr_coeff))
        return h1
Example #16
0
    def get_hcore(self, mol=None):
        if mol is None: mol = self.mol
        if mol.has_ecp():
            raise NotImplementedError

        xmol, contr_coeff = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert ('1E' in self.approx.upper())

        t = _block_diag(xmol.intor_symmetric('int1e_kin'))
        v = _block_diag(xmol.intor_symmetric('int1e_nuc'))
        s = _block_diag(xmol.intor_symmetric('int1e_ovlp'))
        w = _sigma_dot(xmol.intor('int1e_spnucsp'))
        if 'get_xmat' in self.__dict__:
            # If the get_xmat method is overwritten by user, build the X
            # matrix with the external get_xmat method
            x = self.get_xmat(xmol)
            h1 = _get_hcore_fw(t, v, w, s, x, c)

        elif 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_nr_by_atom()
            # spin-orbital basis is twice the size of NR basis
            atom_slices[:, 2:] *= 2
            nao = xmol.nao_nr() * 2
            x = numpy.zeros((nao, nao))
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                t1 = _block_diag(xmol.intor('int1e_kin',
                                            shls_slice=shls_slice))
                s1 = _block_diag(
                    xmol.intor('int1e_ovlp', shls_slice=shls_slice))
                with xmol.with_rinv_at_nucleus(ia):
                    z = -xmol.atom_charge(ia)
                    v1 = _block_diag(
                        z * xmol.intor('int1e_rinv', shls_slice=shls_slice))
                    w1 = _sigma_dot(
                        z *
                        xmol.intor('int1e_sprinvsp', shls_slice=shls_slice))
                x[p0:p1, p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)

        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp')
            s21 = mole.intor_cross('int1e_ovlp', xmol, mol)
            c = _block_diag(lib.cho_solve(s22, s21))
            h1 = reduce(lib.dot, (c.T, h1, c))
        if self.xuncontract and contr_coeff is not None:
            contr_coeff = _block_diag(contr_coeff)
            h1 = reduce(lib.dot, (contr_coeff.T, h1, contr_coeff))
        return h1
Example #17
0
def project_mo_nr2nr(mol1, mo1, mol2):
    r''' Project orbital coefficients

    .. math::

        |\psi1> = |AO1> C1

        |\psi2> = P |\psi1> = |AO2>S^{-1}<AO2| AO1> C1 = |AO2> C2

        C2 = S^{-1}<AO2|AO1> C1
    '''
    s22 = mol2.intor_symmetric('int1e_ovlp')
    s21 = mole.intor_cross('int1e_ovlp', mol2, mol1)
    return lib.cho_solve(s22, numpy.dot(s21, mo1))
Example #18
0
def project_dm_nr2r(mol1, dm1, mol2):
    assert(not mol1.cart)
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_sph', mol2, mol1)

    ua, ub = mol2.sph2spinor_coeff()
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21) # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    p21 = lib.cho_solve(s22, s21, strict_sym_pos=False)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #19
0
def project_mo_nr2nr(mol1, mo1, mol2):
    r''' Project orbital coefficients

    .. math::

        |\psi1> = |AO1> C1

        |\psi2> = P |\psi1> = |AO2>S^{-1}<AO2| AO1> C1 = |AO2> C2

        C2 = S^{-1}<AO2|AO1> C1
    '''
    s22 = mol2.intor_symmetric('cint1e_ovlp_sph')
    s21 = mole.intor_cross('cint1e_ovlp_sph', mol2, mol1)
    return numpy.linalg.solve(s22, numpy.dot(s21, mo1))
Example #20
0
def project_mo_nr2r(mol1, mo1, mol2):
    assert(not mol1.cart)
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_sph', mol2, mol1)

    ua, ub = mol2.sph2spinor_coeff()
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21) # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        mo2 = numpy.dot(s21, mo1)
        return lib.cho_solve(s22, mo2, strict_sym_pos=False)
    else:
        return [lib.cho_solve(s22, numpy.dot(s21, x), strict_sym_pos=False)
                for x in mo1]
Example #21
0
def project_mo_nr2r(mol1, mo1, mol2):
    __doc__ = project_mo_nr2nr.__doc__

    assert(not mol1.cart)
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_sph', mol2, mol1)

    ua, ub = mol2.sph2spinor_coeff()
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21) # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        mo2 = numpy.dot(s21, mo1)
        return lib.cho_solve(s22, mo2)
    else:
        return [lib.cho_solve(s22, numpy.dot(s21, x)) for x in mo1]
Example #22
0
def project_dm_nr2r(mol1, dm1, mol2):
    __doc__ = project_dm_nr2nr.__doc__

    assert(not mol1.cart)
    s22 = mol2.intor_symmetric('int1e_ovlp_spinor')
    s21 = mole.intor_cross('int1e_ovlp_sph', mol2, mol1)

    ua, ub = mol2.sph2spinor_coeff()
    s21 = numpy.dot(ua.T.conj(), s21) + numpy.dot(ub.T.conj(), s21) # (*)
    # mo2: alpha, beta have been summed in Eq. (*)
    # so DM = mo2[:,:nocc] * 1 * mo2[:,:nocc].H
    p21 = lib.cho_solve(s22, s21)
    if isinstance(dm1, numpy.ndarray) and dm1.ndim == 2:
        return reduce(numpy.dot, (p21, dm1, p21.conj().T))
    else:
        return lib.einsum('pi,nij,qj->npq', p21, dm1, p21.conj())
Example #23
0
    def get_hcore(self, mol=None):
        '''2-component X2c hcore Hamiltonian (including spin-free and
        spin-dependent terms) in the j-adapted spinor basis.
        '''
        if mol is None: mol = self.mol
        xmol, contr_coeff_nr = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert ('1E' in self.approx.upper())
        s = xmol.intor_symmetric('int1e_ovlp_spinor')
        t = xmol.intor_symmetric('int1e_spsp_spinor') * .5
        v = xmol.intor_symmetric('int1e_nuc_spinor')
        w = xmol.intor_symmetric('int1e_spnucsp_spinor')
        if 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_2c_by_atom()
            n2c = xmol.nao_2c()
            x = numpy.zeros((n2c, n2c), dtype=numpy.complex)
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                s1 = xmol.intor('int1e_ovlp_spinor', shls_slice=shls_slice)
                t1 = xmol.intor('int1e_spsp_spinor',
                                shls_slice=shls_slice) * .5
                v1 = xmol.intor('int1e_nuc_spinor', shls_slice=shls_slice)
                w1 = xmol.intor('int1e_spnucsp_spinor', shls_slice=shls_slice)
                x[p0:p1, p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)
        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp_spinor')
            s21 = mole.intor_cross('int1e_ovlp_spinor', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T.conj(), h1, c))
        elif self.xuncontract:
            np, nc = contr_coeff_nr.shape
            contr_coeff = numpy.zeros((np * 2, nc * 2))
            contr_coeff[0::2, 0::2] = contr_coeff_nr
            contr_coeff[1::2, 1::2] = contr_coeff_nr
            h1 = reduce(numpy.dot, (contr_coeff.T.conj(), h1, contr_coeff))
        return h1
Example #24
0
    def picture_change(self, even_operator=(None, None), odd_operator=None):
        mol = self.mol
        xmol, c = self.get_xmol(mol)
        pc_mat = self._picture_change(xmol, even_operator, odd_operator)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('int1e_ovlp')
            s21 = mole.intor_cross('int1e_ovlp', xmol, mol)
            c = lib.cho_solve(s22, s21)

        elif self.xuncontract:
            pass

        else:
            return pc_mat

        c = _block_diag(c)
        if pc_mat.ndim == 2:
            return lib.einsum('pi,pq,qj->ij', c, pc_mat, c)
        else:
            return lib.einsum('pi,xpq,qj->xij', c, pc_mat, c)
Example #25
0
def project_mo_nr2nr(mol1, mo1, mol2):
    r''' Project orbital coefficients from basis set 1 (C1 for mol1) to basis
    set 2 (C2 for mol2).

    .. math::

        |\psi1\rangle = |AO1\rangle C1

        |\psi2\rangle = P |\psi1\rangle = |AO2\rangle S^{-1}\langle AO2| AO1\rangle> C1 = |AO2\rangle> C2

        C2 = S^{-1}\langle AO2|AO1\rangle C1

    There are three relevant functions:
    :func:`project_mo_nr2nr` is the projection for non-relativistic (scalar) basis.
    :func:`project_mo_nr2r` projects from non-relativistic to relativistic basis.
    :func:`project_mo_r2r`  is the projection between relativistic (spinor) basis.
    '''
    s22 = mol2.intor_symmetric('int1e_ovlp')
    s21 = mole.intor_cross('int1e_ovlp', mol2, mol1)
    if isinstance(mo1, numpy.ndarray) and mo1.ndim == 2:
        return lib.cho_solve(s22, numpy.dot(s21, mo1))
    else:
        return [lib.cho_solve(s22, numpy.dot(s21, x)) for x in mo1]
Example #26
0
File: x2c.py Project: eronca/pyscf
    def get_hcore(self, mol=None):
        if mol is None: mol = self.mol
        xmol, contr_coeff_nr = self.get_xmol(mol)
        c = lib.param.LIGHT_SPEED
        assert('1E' in self.approx.upper())
        s = xmol.intor_symmetric('cint1e_ovlp')
        t = xmol.intor_symmetric('cint1e_spsp') * .5
        v = xmol.intor_symmetric('cint1e_nuc')
        w = xmol.intor_symmetric('cint1e_spnucsp')
        if 'ATOM' in self.approx.upper():
            atom_slices = xmol.offset_2c_by_atom()
            n2c = xmol.nao_2c()
            x = numpy.zeros((n2c,n2c), dtype=numpy.complex)
            for ia in range(xmol.natm):
                ish0, ish1, p0, p1 = atom_slices[ia]
                shls_slice = (ish0, ish1, ish0, ish1)
                s1 = xmol.intor('cint1e_ovlp', shls_slice=shls_slice)
                t1 = xmol.intor('cint1e_spsp', shls_slice=shls_slice) * .5
                v1 = xmol.intor('cint1e_nuc', shls_slice=shls_slice)
                w1 = xmol.intor('cint1e_spnucsp', shls_slice=shls_slice)
                x[p0:p1,p0:p1] = _x2c1e_xmatrix(t1, v1, w1, s1, c)
            h1 = _get_hcore_fw(t, v, w, s, x, c)
        else:
            h1 = _x2c1e_get_hcore(t, v, w, s, c)

        if self.basis is not None:
            s22 = xmol.intor_symmetric('cint1e_ovlp')
            s21 = mole.intor_cross('cint1e_ovlp', xmol, mol)
            c = lib.cho_solve(s22, s21)
            h1 = reduce(numpy.dot, (c.T.conj(), h1, c))
        elif self.xuncontract:
            np, nc = contr_coeff_nr.shape
            contr_coeff = numpy.zeros((np*2,nc*2))
            contr_coeff[0::2,0::2] = contr_coeff_nr
            contr_coeff[1::2,1::2] = contr_coeff_nr
            h1 = reduce(numpy.dot, (contr_coeff.T.conj(), h1, contr_coeff))
        return h1
Example #27
0
def project_mo_nr2nr(mol1, mo1, mol2):
    s22 = mol2.intor_symmetric('cint1e_ovlp_sph')
    s21 = mole.intor_cross('cint1e_ovlp_sph', mol2, mol1)
    return numpy.linalg.solve(s22, numpy.dot(s21, mo1))
Example #28
0
def MakeActiveSpace(mol,mf):
   np.set_printoptions(precision=4,linewidth=10000,edgeitems=3,suppress=False)

   # PiAtoms list contains the set of main-group atoms involved in the pi-system 
   # indices are 1-based.
   Anthracene = [28,29,30,32, 34,36,38, 39,40,41, 43,45,47,49]
   Phenol = [1,7,9,10,12,14,15]
   Pyridine = [3,16,17,19,20,22]

   mol2=mol.copy()
   mol2.basis = 'MINAO'
   mol2.build()
 
  # make a minimal AO basis for our atoms. We load the basis from a library
   # just to have access to its shell-composition. Need that to find the indices
   # of all atoms, and the AO indices of the px/py/pz functions.

   Elements,Coords = Atoms_w_Coords(mol2)
   Shells = MakeShells(mol2,Elements)

#====================This function is used when 
#1) you study reactions and # of electrons is changing for some atoms in your pi-systems; 
#2) you have O or N atoms which can have different number of electrons in different molecules, then you might want to specify # of electrons to make sure the total number is even
#3) you have a charge on your pi-system. For ferrocene you should assign one more electron to one of C in your pi-systems
   def AssignTag(Elements,iAt, Element, Tag):
      assert(Elements[iAt-1] == Element)
      Elements[iAt-1]= Element+Tag
   # fix type of atom for the donor-acceptor which are exchanging the hydrogens.
   # During the process, the hydrogens are moving and the Huckel-Theory
   # formal number of contributed pi-electrons may change.
   # These settings override the auto-detection of number of pi electrons
   # based on atomic connectivity in GetNumPiElec() below.
    
   AssignTag(Elements,3, "N", "1e")
   AssignTag(Elements,1, "O", "2e")


   Elements =np.asarray(Elements)
 

   OrbBasis=mol.basis
   C = mf.mo_coeff
   S1=mol.intor_symmetric("cint1e_ovlp_sph")
   S2=mol2.intor_symmetric("cint1e_ovlp_sph")
   S12 = mole.intor_cross('cint1e_ovlp_sph', mol, mol2)
   SMo = mdot(C.T, S1, C)
   print ("    MO deviation from orthogonality  {:8.2e} \n".format(rmsd(SMo - np.eye(SMo.shape[0]))))

   # make arrays of occupation numbers and orbital eigenvalues.
   Occ = mf.mo_occ  
   Eps = mf.mo_energy    

   nOrb = C.shape[1]
   if (mol.spin==0):
     nOcc = np.sum(Occ == 2)
   else:
     nOcc = np.sum(Occ == 2)+np.sum(Occ == 1)
     n1=np.sum(Occ == 1)
     print ("    Number of singly occupied orbitals      {} ".format(n1))

   nVir = np.sum(Occ == 0)
   assert(nOcc + nVir == nOrb)
   print ("    Number of occupied orbitals      {} ".format(nOcc))
   print ("    Number of unoccupied orbitals    {} ".format(nVir))

   # Compute Fock matrix from orbital eigenvalues (SCF has to be fully converged)
   Fock = mdot(S1, C, np.diag(Eps), C.T, S1.T)
   Rdm = mdot(C, np.diag(Occ), C.T)


   COcc = C[:,:nOcc]
   CVir = C[:,nOcc:]

   Smh1 = MakeSmh(S1)
   Sh1 = np.dot(S1, Smh1)

   # Compute IAO basis (non-orthogonal). Will be used to identify the
   # pi-MO-space of the target atom groups.
   CIb = MakeIaosRaw(COcc, S1, S2, S12)
   CIbOcc = np.linalg.lstsq(CIb, COcc)[0]
   Err = np.dot(Sh1, np.dot(CIb, CIbOcc) - COcc)

   # check orthogonality of IAO basis occupied orbitals
   SIb = mdot(CIb.T, S1, CIb)
   SIbOcc = mdot(CIbOcc.T, SIb, CIbOcc)
   nIb = SIb.shape[0]


   if 0:
      # make the a representation of the virtual valence space.
      SmhIb = MakeSmh(SIb)
      
      
      nIbVir = nIb - nOcc  # number of virtual valence orbitals

      CTargetIb = CIb
      STargetIb = mdot(CTargetIb.T, S1, CTargetIb)
      SmhTargetIb = MakeSmh(STargetIb)
      STargetIbVir = mdot(SmhTargetIb, CTargetIb.T, S1, CVir)
      U,sig,Vt = np.linalg.svd(STargetIbVir, full_matrices=False)
      print ("    Number of target MINAO basis fn     {}\n".format(CTargetIb.shape[1]))

      print("SIbVir Singular Values (n={})".format(len(sig)))
      print("    [{}]".format(', '.join('{:.4f}'.format(k) for k in sig)))


      assert(np.abs(sig[nIbVir-1] - 1.0) < 1e-4)
      assert(np.abs(sig[nIbVir] - 0.0) < 1e-4)
      
      # for pi systems: do it like here -^ for the virtuals, but
      # for COcc and CVir both. What we should do is:
      #   - instead of CIb, we use CTargetIb = CIb * (AO-linear-comb-matrix)
      #   - instead of SmhIb, we use its corresponding target-AO overlap matrix:
      #     SmhTargetIb = MakeSmh(mdot(CTargetIb.T, S1, CTargetIb))
      #   - instead of using nOcc/nVir/nIb to determine the target number
      #     of orbitals, we obtain the target number of pi electrons by counting
      #     their subset from the selected main group atoms (see CHEM 408 u11).
      #     From this determine the number of occupied pi-orbitals this system
      #     is supposed to have, and virtual orbitals as nTargetIb - nPiOcc
      # The AoMix matrix is made from the pi-system's inertial tensor to get the
      # local z-direction, and then linearly-combining this onto the highest-N p-AOs.

   CActOcc = []
   CActVir = []
   


   # add two pi-HOMOs and two pi-LUMOs from anthracene
   CFragOcc, CFragVir,OccOrbExpected,nVirtOrbExpected, = MakePiSystemOrbitals("Antracene-Fragment", Anthracene, None, Elements,Coords, CIb, Shells, S1, S12, S2, Fock, COcc, CVir)
   CActOcc.append(CFragOcc[:,-2])
   CActOcc.append(CFragOcc[:,-1])
   CActVir.append(CFragVir[:,0])
   CActVir.append(CFragVir[:,1])

   # add two pi-HOMOs and two pi-LUMOs from phenol
   CFragOcc, CFragVir,nOccOrbExpected,nVirtOrbExpected = MakePiSystemOrbitals("Phenol-Fragment", Phenol, None, Elements,Coords, CIb, Shells, S1, S12, S2, Fock, COcc, CVir)
   CActOcc.append(CFragOcc[:,-2])
   CActOcc.append(CFragOcc[:,-1])
   CActVir.append(CFragVir[:,0])
   CActVir.append(CFragVir[:,1])

   # add two pi-HOMOs and two pi-LUMOs from pyridine
   CFragOcc, CFragVir,nOccOrbExpected,nVirtOrbExpected = MakePiSystemOrbitals("Pyridine", Pyridine, None, Elements,Coords, CIb, Shells, S1, S12, S2, Fock, COcc, CVir)
   CActOcc.append(CFragOcc[:,-2])
   CActOcc.append(CFragOcc[:,-1])
   CActVir.append(CFragVir[:,0])
   CActVir.append(CFragVir[:,1])



   nActOcc = len(CActOcc)
   nActVir = len(CActVir)


   print("\n -- Joining active spaces")
   if (mol.spin==0):
     nElec = 2*len(CActOcc)
   else:
     nElec = 2*len(CActOcc)-n1
   CAct = np.array(CActOcc + CActVir).T
   if 0:
      # orthogonalize and semi-canonicalize
      SAct = mdot(CAct.T, S1, CAct)
      ew, ev = np.linalg.eigh(SAct)
      print("    CAct initial overlap (if all ~approx 1, then the initial active orbitals are near-orthogonal. That is good.)")
      print("    [{}]".format(', '.join('{:.4f}'.format(k) for k in ew)))

      CAct = np.dot(CAct, MakeSmh(SAct))
      CAct = SemiCanonicalize(CAct, Fock, S1, "active")

   print ("    Number of Active Electrons     {} ".format(nElec))
   print ("    Number of Active Orbitals      {} ".format( CAct.shape[1]))

   # make new non-active occupied and non-active virtual orbitals,
   # in order to rebuild a full MO matrix.
   def MakeInactiveSpace(Name, CActList, COrb1):
      CAct = np.array(CActList).T
      SAct = mdot(CAct.T, S1, CAct)
      CAct = np.dot(CAct, MakeSmh(SAct))

      SActMo = mdot(COrb1.T, S1.T, CAct, CAct.T, S1, COrb1)
      ew, ev = np.linalg.eigh(SActMo) # small ews first (orbs not overlapping with active orbs).
      
      nRest = COrb1.shape[1] - CAct.shape[1]
      if 0:
         for i in range(len(ew)):
            print("{:4} {:15.6f}  {}".format(i,ew[i], i == nRest))
      assert(np.abs(ew[nRest-1] - 0.0) < 1e-8)
      assert(np.abs(ew[nRest] - 1.0) < 1e-8)
      CNewOrb1 = np.dot(COrb1, ev[:,:nRest])
      return SemiCanonicalize(CNewOrb1, Fock, S1, Name, Print=False)
   
   CNewClo = MakeInactiveSpace("NewClo", CActOcc, COcc)
   CNewExt = MakeInactiveSpace("NewVir", CActVir, CVir)
   nNewClo = CNewClo.shape[1]
   nNewExt = CNewExt.shape[1]

   # re-orthogonalize (should be orthogonal already, but just to be sure).
   COrbNew = np.hstack([CAct])
   if 1:
      COrbNew = np.hstack([CNewClo, CAct, CNewExt])
      SMo = mdot(COrbNew.T, S1, COrbNew)
      COrbNew = np.dot(COrbNew, MakeSmh(SMo))

   print ("    Number of Core Orbitals        {} ".format(CNewClo.shape[1]))
   print ("    Number of Virtual Orbitals     {} ".format(CNewExt.shape[1]))
   print ("    Total Number of Orbitals       {} ".format(COrbNew.shape[1]))

   return CNewClo.shape[1],CAct.shape[1],CNewExt.shape[1],nElec, COrbNew