예제 #1
0
def rhf_simple(geo,basisname='sto3g',maxiter=25,verbose=False):
    bfs = basisset(geo,basisname)
    i1 = onee_integrals(bfs,geo)
    i2 = twoe_integrals(bfs)
    if verbose: print ("S=\n%s" % i1.S)
    h = i1.T + i1.V
    if verbose: print ("h=\n%s" % h)
    if verbose: print ("T=\n%s" % i1.T)
    if verbose: print ("V=\n%s" % i1.V)
    E,U = geigh(h,i1.S)
    if verbose: print ("E=\n%s" % E)
    if verbose: print ("U=\n%s" % U)
    Enuke = geo.nuclear_repulsion()
    nocc = geo.nocc()
    Eold = Energy = 0
    if verbose: print ("2e ints\n%s" % i2)
    for i in xrange(maxiter):
        D = dmat(U,nocc)
        if verbose: print ("D=\n%s" % D)
        Eone = trace2(h,D)
        G = i2.get_2jk(D)
        H = h+G
        Etwo = trace2(H,D)
        E,U = geigh(H,i1.S)
        Energy = Enuke+Eone+Etwo
        print ("HF: %d   %10.4f : %10.4f %10.4f %10.4f" % ((i+1),Energy,Enuke,Eone,Etwo))
        if np.isclose(Energy,Eold):
            break
        Eold = Energy
    else:
        print ("Warning: Maxiter %d hit in scf_simple" % maxiter)
    return Energy,E,U
예제 #2
0
def uhf_simple(geo,basisname='sto3g',maxiter=25,verbose=False):
    if geo.nopen() == 0: return scf_simple(geo,basisname,maxiter,verbose)
    bfs = basisset(geo,basisname)
    i1 = onee_integrals(bfs,geo)
    i2 = twoe_integrals(bfs)
    h = i1.T + i1.V
    E,U = geigh(h,i1.S)
    Enuke = geo.nuclear_repulsion()
    Eold = Energy = 0
    ca = cb = U
    na,nb = geo.nup(),geo.ndown()

    for i in xrange(maxiter):
        Energy = Enuke
        Da = dmat(ca,na)
        Db = dmat(cb,nb)
        h = i1.T + i1.V
        Energy += trace2(Da+Db,h)/2
        Ja,Ka = i2.get_j(Da),i2.get_k(Da)
        Jb,Kb = i2.get_j(Db),i2.get_k(Db)
        Fa = h + Ja + Jb - Ka
        Fb = h + Ja + Jb - Kb
        orbea,ca = geigh(Fa,i1.S)
        orbeb,cb = geigh(Fb,i1.S)
        Energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2
        print ("UHF: %d   %10.4f : %10.4f" % ((i+1),Energy,Enuke))
        if np.isclose(Energy,Eold):
            break
        Eold = Energy
    else:
        print ("Warning: Maxiter %d hit in scf_simple" % maxiter)
    return Energy,E,U
예제 #3
0
def scf_simple(geo,basisname='sto-3g',maxiter=25,verbose=False):
    bfs = basisset(geo,basisname)
    i1 = onee_integrals(bfs,geo)
    i2 = twoe_integrals(bfs)
    if verbose: print ("S=\n%s" % i1.S)
    h = i1.T + i1.V
    if verbose: print ("h=\n%s" % h)
    if verbose: print ("T=\n%s" % i1.T)
    if verbose: print ("V=\n%s" % i1.V)
    E,U = geigh(h,i1.S)
    if verbose: print ("E=\n%s" % E)
    if verbose: print ("U=\n%s" % U)
    Enuke = geo.nuclear_repulsion()
    nocc = geo.nocc()
    Eold = Energy = 0
    if verbose: print ("2e ints\n%s" % i2)
    for i in xrange(maxiter):
        D = dmat(U,nocc)
        if verbose: print ("D=\n%s" % D)
        Eone = trace2(h,D)
        G = i2.get_2jk(D)
        H = h+G
        Etwo = trace2(H,D)
        E,U = geigh(H,i1.S)
        Energy = Enuke+Eone+Etwo
        print ("HF: %d   %10.4f : %10.4f %10.4f %10.4f" % ((i+1),Energy,Enuke,Eone,Etwo))
        if np.isclose(Energy,Eold):
            break
        Eold = Energy
    else:
        print ("Warning: Maxiter %d hit in scf_simple" % maxiter)
    return Energy,E,U
예제 #4
0
def uhf_simple(geo,basisname='sto3g',maxiter=25,verbose=False):
    if geo.nopen() == 0: return scf_simple(geo,basisname,maxiter,verbose)
    bfs = basisset(geo,basisname)
    i1 = onee_integrals(bfs,geo)
    i2 = twoe_integrals(bfs)
    h = i1.T + i1.V
    E,U = geigh(h,i1.S)
    Enuke = geo.nuclear_repulsion()
    Eold = Energy = 0
    ca = cb = U
    na,nb = geo.nup(),geo.ndown()

    for i in xrange(maxiter):
        Energy = Enuke
        Da = dmat(ca,na)
        Db = dmat(cb,nb)
        h = i1.T + i1.V
        Energy += trace2(Da+Db,h)/2
        Ja,Ka = i2.get_j(Da),i2.get_k(Da)
        Jb,Kb = i2.get_j(Db),i2.get_k(Db)
        Fa = h + Ja + Jb - Ka
        Fb = h + Ja + Jb - Kb
        orbea,ca = geigh(Fa,i1.S)
        orbeb,cb = geigh(Fb,i1.S)
        Energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2
        print ("UHF: %d   %10.4f : %10.4f" % ((i+1),Energy,Enuke))
        if np.isclose(Energy,Eold):
            break
        Eold = Energy
    else:
        print ("Warning: Maxiter %d hit in scf_simple" % maxiter)
    return Energy,E,U
예제 #5
0
 def update(self,Da,Db):
     self.energy = self.geo.nuclear_repulsion()
     h = self.i1.T + self.i1.V
     self.energy += trace2(Da+Db,h)/2
     Ja,Ka = self.i2.get_j(Da),self.i2.get_k(Da)
     Jb,Kb = self.i2.get_j(Db),self.i2.get_k(Db)
     Fa = h + Ja + Jb - Ka
     Fb = h + Ja + Jb - Kb
     orbea,ca = geigh(Fa,self.i1.S)
     orbeb,cb = geigh(Fb,self.i1.S)
     self.energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2
     self.orbea = orbea
     self.orbsa = ca
     self.orbeb = orbeb
     self.orbsb = cb
     return ca,cb
예제 #6
0
 def update(self,Da,Db):
     self.energy = self.geo.nuclear_repulsion()
     h = self.i1.T + self.i1.V
     self.energy += trace2(Da+Db,h)/2
     Ja,Ka = self.i2.get_j(Da),self.i2.get_k(Da)
     Jb,Kb = self.i2.get_j(Db),self.i2.get_k(Db)
     Fa = h + Ja + Jb - Ka
     Fb = h + Ja + Jb - Kb
     orbea,ca = geigh(Fa,self.i1.S)
     orbeb,cb = geigh(Fb,self.i1.S)
     self.energy += trace2(Fa,Da)/2 + trace2(Fb,Db)/2
     self.orbea = orbea
     self.orbsa = ca
     self.orbeb = orbeb
     self.orbsb = cb
     return ca,cb
예제 #7
0
def two_electron_solve(atomic_number, maximum_order, spin):
    Z = atomic_number
    H, S = pekeris(Z, maximum_order, spin)
    E, V = geigh(H, S)
    epsilon = E[0]
    E2 = [-Ei**2 for Ei in E]
    #print "Energy (h) for order %d: %15.12f %15.12f" % (len(E),E2[0],epsilon)
    return E2[0]
예제 #8
0
def two_electron_solve(atomic_number,maximum_order,spin):
    Z = atomic_number
    H,S = pekeris(Z,maximum_order,spin)
    E,V = geigh(H,S)
    epsilon = E[0]
    E2 = [-Ei**2 for Ei in E]
    #print "Energy (h) for order %d: %15.12f %15.12f" % (len(E),E2[0],epsilon)
    return E2[0]
예제 #9
0
 def update(self,D):
     self.energy = self.geo.nuclear_repulsion()
     H = self.i1.T + self.i1.V
     self.energy += trace2(H,D)
     JK = self.i2.get_2jk(D)
     H = H + JK
     self.energy += trace2(H,D)
     E,c = geigh(H,self.i1.S)
     self.orbe = E
     self.orbs = c
     return c
예제 #10
0
 def update(self,D):
     self.energy = self.geo.nuclear_repulsion()
     H = self.i1.T + self.i1.V
     self.energy += trace2(H,D)
     JK = self.i2.get_2jk(D)
     H = H + JK
     self.energy += trace2(H,D)
     E,c = geigh(H,self.i1.S)
     self.orbe = E
     self.orbs = c
     return c
예제 #11
0
 def __init__(self,H,c=None,tol=1e-5,maxiters=100):
     self.H = H
     self.Eold = 0
     if c is None:
         orbe,self.c = geigh(H.i1.T+H.i1.V,H.i1.S)
     else:
         self.c = c
     self.maxiters = maxiters
     self.tol = tol
     
     self.converged = False
     self.iterations = 0
     return
예제 #12
0
    def update(self,D):
        from pyquante2.dft.dft import get_xc
        E0 = self.geo.nuclear_repulsion()
        self.energy = E0
        H = self.i1.T + self.i1.V
        E1 = 2*trace2(H,D)
        self.energy += E1

        J = self.i2.get_j(D)
        Ej = 2*trace2(J,D)

        # The 0.5 before the D comes from making the alpha density from the total density
        Exc,Vxc = get_xc(self.grid,0.5*D,xcname=self.xcname)

        H = H + 2*J + Vxc
        self.energy += Ej+Exc
        
        if self.verbose: print(self.energy,E1,Ej,Exc,E0)
        E,c = geigh(H,self.i1.S)
        self.orbe = E
        self.orbs = c
        return c
예제 #13
0
    def update(self,D):
        from pyquante2.dft.dft import get_xc
        E0 = self.geo.nuclear_repulsion()
        self.energy = E0
        H = self.i1.T + self.i1.V
        E1 = 2*trace2(H,D)
        self.energy += E1

        J = self.i2.get_j(D)
        Ej = 2*trace2(J,D)

        # The 0.5 before the D comes from making the alpha density from the total density
        Exc,Vxc = get_xc(self.grid,0.5*D,xcname=self.xcname)

        H = H + 2*J + Vxc
        self.energy += Ej+Exc
        
        if self.verbose: print(self.energy,E1,Ej,Exc,E0)
        E,c = geigh(H,self.i1.S)
        self.orbe = E
        self.orbs = c
        return c
예제 #14
0
 def eigenv(self, Fa, Fb):
     orbea, orbsa = geigh(Fa, self.i1.S)
     orbeb, orbsb = geigh(Fb, self.i1.S)
     return (orbea, orbsa), (orbeb, orbsb)
예제 #15
0
 def eigenv(self, F):
     """ Eigenvalues and Eigenvectors"""
     orbe, orbs = geigh(F, self.i1.S)
     return orbe, orbs
예제 #16
0
def gvb(geo,
        npair=0,
        basisname='sto3g',
        maxiter=25,
        verbose=False,
        return_orbs=False,
        input_orbs=None):
    """\
    This is a trivial test for the gvb module, because other
    pyquante modules are simpler if you're doing closed shell rhf,
    and should give the same results.

    # -0.46658184546856041 from uhf/sto3g
    >>> gvb(h)     # doctest: +ELLIPSIS
    -0.4665818...

    #  -1.117099582955609 from rhf/sto3g
    >>> gvb(h2)    # doctest: +ELLIPSIS
    -1.117099...

    >>> gvb(lih,maxiter=5)   # doctest: +ELLIPSIS
    -7.86073...

    >>> gvb(li,maxiter=5)    # doctest: +ELLIPSIS
    -7.31552...

    >>> gvb(h2,npair=1)      # doctest: +ELLIPSIS
    -1.13730...
    """
    # Get the basis set and the integrals
    bfs = basisset(geo, basisname)
    i1 = onee_integrals(bfs, geo)
    i2 = twoe_integrals(bfs)
    h = i1.T + i1.V

    # Get a guess for the orbitals
    if input_orbs is not None:
        U = input_orbs
    else:
        E, U = geigh(h, i1.S)

    # Set the parameters based on the molecule
    nopen = geo.nopen()
    ncore = geo.nclosed() - npair
    nocc = ncore + nopen + 2 * npair
    norb = len(bfs)
    virt = range(nocc, norb)
    orbs_per_shell = get_orbs_per_shell(ncore, nopen, npair)
    nsh = len(orbs_per_shell)
    shell = orbital_to_shell_mapping(ncore, nopen, npair)
    Enuke = geo.nuclear_repulsion()

    f, a, b = fab(ncore, nopen, npair)

    if verbose:
        np.set_printoptions(precision=4)
        print("**** PyQuante GVB ****")
        print(geo)
        print("Nuclear repulsion energy: %.3f" % Enuke)
        print("Basis set: %s" % basisname)
        print("  ncore/open/pair: %d,%d,%d" % (ncore, nopen, npair))
        print("  occ/bf/orb: %d,%d,%d" % (nocc, len(bfs), norb))
        for i in range(nsh):
            print("Shell %d" % i)
            print("  occupation = %.2f" % f[i])
            print("  orbitals in shell %s" % orbs_per_shell[i])
            print("  couplings to other shells %s" % zip(a[i, :], b[i, :]))
        print("Starting guess at orbitals:\n%s" % U)
        print("Shell array: %s" % shell)
        print("****")

    Eold = 0
    for it in range(maxiter):
        # Make all of the density matrices:
        Ds = [dmat_gen(U, orbs) for orbs in orbs_per_shell]
        # Compute the required Hamiltonian matrices:
        Js = [i2.get_j(D) for D in Ds]
        Ks = [i2.get_k(D) for D in Ds]

        # Perform the ROTION step and compute the energy
        Eel, Eone, Uocc = ROTION(U[:, :nocc],
                                 h,
                                 Js,
                                 Ks,
                                 f,
                                 a,
                                 b,
                                 nocc,
                                 shell,
                                 verbose=verbose)
        if nsh > 1:
            U[:, :nocc] = Uocc

        # Perform the OCBSE step
        U = OCBSE(U, h, Js, Ks, f, a, b, orbs_per_shell, virt)

        #E = Enuke+Eone+Etwo
        E = Enuke + Eel
        Etwo = Eel - 2 * Eone

        # Update CI coefs
        coeffs = update_gvb_ci_coeffs(Uocc, h, Js, Ks, f, a, b, ncore, nopen,
                                      npair, orbs_per_shell, verbose)
        f, a, b = fab(ncore, nopen, npair, coeffs)

        if verbose:
            print("---- %d :  %10.4f %10.4f %10.4f %10.4f" %
                  ((it + 1), E, Enuke, Eone, Etwo))
        if np.isclose(E, Eold):
            if verbose:
                print("Energy converged")
            break
        Eold = E
    else:
        print("Maximum iterations (%d) reached without convergence" %
              (maxiter))
    if return_orbs:
        return E, U
    return E
예제 #17
0
파일: mcscf.py 프로젝트: padamson/pyquante2
def gvb(geo,npair=0,basisname='sto3g',maxiter=25,verbose=False,
        return_orbs=False, input_orbs=None):
    """\
    This is a trivial test for the gvb module, because other
    pyquante modules are simpler if you're doing closed shell rhf,
    and should give the same results.

    # -0.46658184546856041 from uhf/sto3g
    >>> gvb(h)     # doctest: +ELLIPSIS
    -0.4665818...

    #  -1.117099582955609 from rhf/sto3g
    >>> gvb(h2)    # doctest: +ELLIPSIS
    -1.117099...

    >>> gvb(lih,maxiter=5)   # doctest: +ELLIPSIS
    -7.86073...

    >>> gvb(li,maxiter=5)    # doctest: +ELLIPSIS
    -7.31552...

    >>> gvb(h2,npair=1)      # doctest: +ELLIPSIS
    -1.13730...
    """
    # Get the basis set and the integrals
    bfs = basisset(geo,basisname)
    i1 = onee_integrals(bfs,geo)
    i2 = twoe_integrals(bfs)
    h = i1.T + i1.V

    # Get a guess for the orbitals
    if input_orbs is not None:
        U = input_orbs
    else:
        E,U = geigh(h,i1.S)

    # Set the parameters based on the molecule
    nopen = geo.nopen()
    ncore = geo.nclosed() - npair
    nocc = ncore + nopen + 2*npair
    norb = len(bfs)
    virt = range(nocc,norb)
    orbs_per_shell = get_orbs_per_shell(ncore,nopen,npair)
    nsh = len(orbs_per_shell)
    shell = orbital_to_shell_mapping(ncore,nopen,npair)
    Enuke = geo.nuclear_repulsion()

    f,a,b = fab(ncore,nopen,npair)

    if verbose:
        np.set_printoptions(precision=4)
        print("**** PyQuante GVB ****")
        print(geo)
        print("Nuclear repulsion energy: %.3f" % Enuke)
        print("Basis set: %s" % basisname)
        print("  ncore/open/pair: %d,%d,%d" % (ncore,nopen,npair))
        print("  occ/bf/orb: %d,%d,%d" % (nocc,len(bfs),norb))
        for i in range(nsh):
            print("Shell %d" % i)
            print("  occupation = %.2f" % f[i])
            print("  orbitals in shell %s" % orbs_per_shell[i])
            print("  couplings to other shells %s" % zip(a[i,:],b[i,:]))
        print("Starting guess at orbitals:\n%s"%U)
        print("Shell array: %s" % shell)
        print("****")

    Eold = 0
    for it in range(maxiter):
        # Make all of the density matrices:
        Ds = [dmat_gen(U,orbs) for orbs in orbs_per_shell]
        # Compute the required Hamiltonian matrices:
        Js = [i2.get_j(D) for D in Ds]
        Ks = [i2.get_k(D) for D in Ds]

        # Perform the ROTION step and compute the energy
        Eel,Eone,Uocc = ROTION(U[:,:nocc],h,Js,Ks,f,a,b,nocc,shell,
                               verbose=verbose)
        if nsh > 1:
            U[:,:nocc] = Uocc

        # Perform the OCBSE step
        U = OCBSE(U,h,Js,Ks,f,a,b,orbs_per_shell,virt)

        #E = Enuke+Eone+Etwo
        E = Enuke+Eel
        Etwo = Eel-2*Eone

        # Update CI coefs
        coeffs = update_gvb_ci_coeffs(Uocc,h,Js,Ks,f,a,b,ncore,nopen,npair,
                                      orbs_per_shell,verbose)
        f,a,b = fab(ncore,nopen,npair,coeffs)

        if verbose:
            print ("---- %d :  %10.4f %10.4f %10.4f %10.4f" % ((it+1),E,Enuke,Eone,Etwo))
        if np.isclose(E,Eold):
            if verbose:
                print("Energy converged")
            break
        Eold = E
    else:
        print("Maximum iterations (%d) reached without convergence" % (maxiter))
    if return_orbs:
        return E,U
    return E