Пример #1
0
 def __init__(self, molecule, **kwargs):
     from PyQuante.Convergence import DIIS
     from PyQuante.DFunctionals import need_gradients
     self.molecule = molecule
     logging.info("DFT calculation on system %s" % self.molecule.name)
     self.basis_set = BasisSet(molecule, **kwargs)
     self.integrals = Integrals(molecule, self.basis_set, **kwargs)
     self.iterator = SCFIterator()
     self.h = self.integrals.get_h()
     self.S = self.integrals.get_S()
     self.ERI = self.integrals.get_ERI()
     self.Enuke = molecule.get_enuke()
     self.nel = molecule.get_nel()
     self.F = self.h
     self.functional = kwargs.get('functional', settings.DFTFunctional)
     kwargs['do_grad_dens'] = need_gradients[self.functional]
     self.setup_grid(molecule, self.basis_set.get(), **kwargs)
     self.dmat = None
     self.entropy = None
     self.DoAveraging = kwargs.get('DoAveraging', settings.DFTAveraging)
     if self.DoAveraging:
         self.Averager = DIIS(self.S)
     nel = molecule.get_nel()
     nclosed, nopen = molecule.get_closedopen()
     logging.info("Nclosed/open = %d, %d" % (nclosed, nopen))
     self.solver = SolverFactory(nel, nclosed, nopen, self.S, **kwargs)
     return
Пример #2
0
 def __init__(self,molecule,**kwargs):
     from PyQuante.Convergence import DIIS
     from PyQuante.DFunctionals import need_gradients
     self.molecule = molecule
     logging.info("DFT calculation on system %s" % self.molecule.name)
     self.basis_set = BasisSet(molecule,**kwargs)
     self.integrals = Integrals(molecule,self.basis_set,**kwargs)
     self.iterator = SCFIterator()
     self.h = self.integrals.get_h()
     self.S = self.integrals.get_S()
     self.ERI = self.integrals.get_ERI()
     self.Enuke = molecule.get_enuke()
     self.nel = molecule.get_nel()
     self.F = self.h
     self.functional = kwargs.get('functional',settings.DFTFunctional)
     kwargs['do_grad_dens'] = need_gradients[self.functional]
     self.setup_grid(molecule,self.basis_set.get(),**kwargs)
     self.dmat = None
     self.entropy = None
     self.DoAveraging = kwargs.get('DoAveraging',settings.DFTAveraging)
     if self.DoAveraging:
         self.Averager = DIIS(self.S)
     nel = molecule.get_nel()
     nclosed,nopen = molecule.get_closedopen()
     logging.info("Nclosed/open = %d, %d" % (nclosed,nopen))
     self.solver = SolverFactory(nel,nclosed,nopen,self.S,**kwargs)
     return
Пример #3
0
class HFHamiltonian(AbstractHamiltonian):
    method='HF'
    def __init__(self,molecule,**kwargs):
        from PyQuante.Convergence import DIIS
        self.molecule = molecule
        logging.info("HF calculation on system %s" % self.molecule.name)
        self.basis_set = BasisSet(molecule,**kwargs)
        self.integrals = Integrals(molecule,self.basis_set,**kwargs)
        self.iterator = SCFIterator()
        self.h = self.integrals.get_h()
        self.S = self.integrals.get_S()
        self.ERI = self.integrals.get_ERI()
        self.Enuke = molecule.get_enuke()
        self.F = self.h
        self.dmat = None
        self.entropy = None
        self.DoAveraging = kwargs.get('DoAveraging',settings.Averaging)
        if self.DoAveraging:
            self.Averager = DIIS(self.S)
        nel = molecule.get_nel()
        nclosed,nopen = molecule.get_closedopen()
        logging.info("Nclosed/open = %d, %d" % (nclosed,nopen))
        self.solver = SolverFactory(nel,nclosed,nopen,self.S,**kwargs)
        return

    def __repr__(self):
        lstr = ['Hamiltonian constructed for method %s' % self.method,
                repr(self.molecule),
                repr(self.basis_set),
                repr(self.iterator)]
        return '\n'.join(lstr)

    def get_energy(self): return self.energy
    def iterate(self,**kwargs):
        self.iterator.iterate(self,**kwargs)
        if self.iterator.converged:
            logging.info("Final HF energy for system %s is %f"%(self.molecule.name,self.energy))
        return

    def update(self,**kwargs):
        from PyQuante.LA2 import trace2
        from PyQuante.Ints import getJ,getK

        if self.DoAveraging and self.dmat is not None:
            self.F = self.Averager.getF(self.F,self.dmat)
        self.dmat,self.entropy = self.solver.solve(self.F,**kwargs)
        D = self.dmat
        
        self.J = getJ(self.ERI,D)
        self.Ej = 2*trace2(D,self.J)
        self.K = getK(self.ERI,D)
        self.Exc = -trace2(D,self.K)
        self.Eone = 2*trace2(D,self.h)
        self.F = self.h + 2*self.J - self.K
        self.energy = self.Eone + self.Ej + self.Exc + self.Enuke + self.entropy
        return
Пример #4
0
 def __init__(self, molecule, **kwargs):
     from PyQuante.Convergence import DIIS
     self.molecule = molecule
     logging.info("HF calculation on system %s" % self.molecule.name)
     self.basis_set = BasisSet(molecule, **kwargs)
     self.integrals = Integrals(molecule, self.basis_set, **kwargs)
     self.iterator = SCFIterator()
     self.h = self.integrals.get_h()
     self.S = self.integrals.get_S()
     self.ERI = self.integrals.get_ERI()
     self.Enuke = molecule.get_enuke()
     self.F = self.h
     self.dmat = None
     self.entropy = None
     self.DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
     if self.DoAveraging:
         self.Averager = DIIS(self.S)
     nel = molecule.get_nel()
     nclosed, nopen = molecule.get_closedopen()
     logging.info("Nclosed/open = %d, %d" % (nclosed, nopen))
     self.solver = SolverFactory(nel, nclosed, nopen, self.S, **kwargs)
     return
Пример #5
0
 def __init__(self,molecule,**opts):
     from PyQuante.Convergence import DIIS
     self.molecule = molecule
     logging.info("HF calculation on system %s" % self.molecule.name)
     self.basis_set = BasisSet(molecule,**opts)
     self.integrals = Integrals(molecule,self.basis_set,**opts)
     self.iterator = SCFIterator()
     self.h = self.integrals.get_h()
     self.S = self.integrals.get_S()
     self.ERI = self.integrals.get_ERI()
     self.Enuke = molecule.get_enuke()
     self.F = self.h
     self.dmat = None
     self.entropy = None
     self.DoAveraging = opts.get('DoAveraging',True)
     if self.DoAveraging:
         self.Averager = DIIS(self.S)
     nel = molecule.get_nel()
     nclosed,nopen = molecule.get_closedopen()
     logging.info("Nclosed/open = %d, %d" % (nclosed,nopen))
     self.solver = SolverFactory(nel,nclosed,nopen,self.S,**opts)
     return
Пример #6
0
class DFTHamiltonian(AbstractHamiltonian):
    method = 'DFT'

    def __init__(self, molecule, **kwargs):
        from PyQuante.Convergence import DIIS
        from PyQuante.DFunctionals import need_gradients
        self.molecule = molecule
        logging.info("DFT calculation on system %s" % self.molecule.name)
        self.basis_set = BasisSet(molecule, **kwargs)
        self.integrals = Integrals(molecule, self.basis_set, **kwargs)
        self.iterator = SCFIterator()
        self.h = self.integrals.get_h()
        self.S = self.integrals.get_S()
        self.ERI = self.integrals.get_ERI()
        self.Enuke = molecule.get_enuke()
        self.nel = molecule.get_nel()
        self.F = self.h
        self.functional = kwargs.get('functional', settings.DFTFunctional)
        kwargs['do_grad_dens'] = need_gradients[self.functional]
        self.setup_grid(molecule, self.basis_set.get(), **kwargs)
        self.dmat = None
        self.entropy = None
        self.DoAveraging = kwargs.get('DoAveraging', settings.DFTAveraging)
        if self.DoAveraging:
            self.Averager = DIIS(self.S)
        nel = molecule.get_nel()
        nclosed, nopen = molecule.get_closedopen()
        logging.info("Nclosed/open = %d, %d" % (nclosed, nopen))
        self.solver = SolverFactory(nel, nclosed, nopen, self.S, **kwargs)
        return

    def __repr__(self):
        lstr = [
            'Hamiltonian constructed for method %s' % self.method,
            repr(self.molecule),
            repr(self.basis_set),
            repr(self.iterator)
        ]
        return '\n'.join(lstr)

    def get_energy(self):
        return self.energy

    def iterate(self, **kwargs):
        return self.iterator.iterate(self, **kwargs)

    def setup_grid(self, molecule, bfs, **kwargs):
        #from PyQuante.MolecularGrid import MolecularGrid
        from PyQuante.MG2 import MG2 as MolecularGrid
        grid_nrad = kwargs.get('grid_nrad', settings.DFTGridRadii)
        grid_fineness = kwargs.get('grid_fineness', settings.DFTGridFineness)
        self.gr = MolecularGrid(molecule, grid_nrad, grid_fineness, **kwargs)
        self.gr.set_bf_amps(bfs)
        return

    def update(self, **kwargs):
        from PyQuante.LA2 import trace2
        from PyQuante.Ints import getJ
        from PyQuante.dft import getXC

        #self.DoAveraging = kwargs.get('DoAveraging',True)
        #if self.DoAveraging:
        #    self.Averager = DIIS(self.S)

        if self.DoAveraging and self.dmat is not None:
            self.F = self.Averager.getF(self.F, self.dmat)
        self.dmat, self.entropy = self.solver.solve(self.F, **kwargs)
        D = self.dmat

        self.gr.setdens(D)
        self.J = getJ(self.ERI, D)
        self.Ej = 2 * trace2(D, self.J)

        self.Exc, self.XC = getXC(self.gr,
                                  self.nel,
                                  functional=self.functional)

        self.Eone = 2 * trace2(D, self.h)

        self.F = self.h + 2 * self.J + self.XC
        self.energy = self.Eone + self.Ej + self.Exc + self.Enuke + self.entropy
        return
Пример #7
0
class HFHamiltonian(AbstractHamiltonian):
    method = 'HF'

    def __init__(self, molecule, **kwargs):
        from PyQuante.Convergence import DIIS
        self.molecule = molecule
        logging.info("HF calculation on system %s" % self.molecule.name)
        self.basis_set = BasisSet(molecule, **kwargs)
        self.integrals = Integrals(molecule, self.basis_set, **kwargs)
        self.iterator = SCFIterator()
        self.h = self.integrals.get_h()
        self.S = self.integrals.get_S()
        self.ERI = self.integrals.get_ERI()
        self.Enuke = molecule.get_enuke()
        self.F = self.h
        self.dmat = None
        self.entropy = None
        self.DoAveraging = kwargs.get('DoAveraging', settings.Averaging)
        if self.DoAveraging:
            self.Averager = DIIS(self.S)
        nel = molecule.get_nel()
        nclosed, nopen = molecule.get_closedopen()
        logging.info("Nclosed/open = %d, %d" % (nclosed, nopen))
        self.solver = SolverFactory(nel, nclosed, nopen, self.S, **kwargs)
        return

    def __repr__(self):
        lstr = [
            'Hamiltonian constructed for method %s' % self.method,
            repr(self.molecule),
            repr(self.basis_set),
            repr(self.iterator)
        ]
        return '\n'.join(lstr)

    def get_energy(self):
        return self.energy

    def iterate(self, **kwargs):
        self.iterator.iterate(self, **kwargs)
        if self.iterator.converged:
            logging.info("Final HF energy for system %s is %f" %
                         (self.molecule.name, self.energy))
        return

    def update(self, **kwargs):
        from PyQuante.LA2 import trace2
        from PyQuante.Ints import getJ, getK

        if self.DoAveraging and self.dmat is not None:
            self.F = self.Averager.getF(self.F, self.dmat)
        self.dmat, self.entropy = self.solver.solve(self.F, **kwargs)
        D = self.dmat

        self.J = getJ(self.ERI, D)
        self.Ej = 2 * trace2(D, self.J)
        self.K = getK(self.ERI, D)
        self.Exc = -trace2(D, self.K)
        self.Eone = 2 * trace2(D, self.h)
        self.F = self.h + 2 * self.J - self.K
        self.energy = self.Eone + self.Ej + self.Exc + self.Enuke + self.entropy
        return
Пример #8
0
def rhf(mol,
        bfs,
        S,
        Hcore,
        Ints,
        mu=0,
        MaxIter=100,
        eps_SCF=1E-4,
        _diis_=True):

    ##########################################################
    ##					Get the system information
    ##########################################################

    # size
    nbfs = len(bfs)

    # get the nuclear energy
    enuke = mol.get_enuke()

    # determine the number of electrons
    # and occupation numbers
    nelec = mol.get_nel()
    nclosed, nopen = mol.get_closedopen()
    nocc = nclosed

    # orthogonalization matrix
    X = SymOrthCutoff(S)

    if _ee_inter_ == 0:
        print '\t\t ==================================================='
        print '\t\t == Electrons-Electrons interactions desactivated =='
        print '\t\t ==================================================='

    if nopen != 0:
        print '\t\t ================================================================='
        print '\t\t Warning : using restricted HF with open shell is not recommended'
        print "\t\t Use only if you know what you're doing"
        print '\t\t ================================================================='

    # get a first DM
    #D = np.zeros((nbfs,nbfs))
    L, C = scla.eigh(Hcore, b=S)
    D = mkdens(C, 0, nocc)

    # initialize the old energy
    eold = 0.

    # initialize the DIIS
    if _diis_:
        avg = DIIS(S)

    #print '\t SCF Calculations'
    for iiter in range(MaxIter):

        # form the G matrix from the
        # density matrix and  the 2electron integrals
        G = get2JmK(Ints, D)

        # form the Fock matrix
        F = Hcore + _ee_inter_ * G + mu

        # if DIIS
        if _diis_:
            F = avg.getF(F, D)

        # orthogonalize the Fock matrix
        Fp = np.dot(X.T, np.dot(F, X))

        # diagonalize the Fock matrix
        Lp, Cp = scla.eigh(Fp)

        # form the density matrix in the OB
        if nopen == 0:
            Dp = mkdens(Cp, 0, nocc)
        else:
            Dp = mkdens_spinavg(Cp, nclosed, nopen)

        # pass the eigenvector back to the AO
        C = np.dot(X, Cp)

        # form the density matrix in the AO
        if nopen == 0:
            D = mkdens(C, 0, nocc)
        #else:
        #	D = mkdens_spinavg(C,nclosed,nopen)

        # compute the total energy
        e = np.sum(D * (Hcore + F)) + enuke

        print "\t\t Iteration: %d    Energy: %f    EnergyVar: %f" % (
            iiter, e.real, np.abs((e - eold).real))

        # stop if done
        if (np.abs(e - eold) < eps_SCF):
            break
        else:
            eold = e

    if iiter < MaxIter:
        print(
            "\t\t SCF for HF has converged in %d iterations, Final energy %1.3f Ha\n"
            % (iiter, e.real))

    else:
        print("\t\t SCF for HF has failed to converge after %d iterations")

    # compute the density matrix in the
    # eigenbasis of F
    P = np.dot(Cp.T, np.dot(Dp, Cp))
    #print D

    return Lp, C, Cp, F, Fp, D, Dp, P, X
Пример #9
0
class DFTHamiltonian(AbstractHamiltonian):
    method='DFT'
    def __init__(self,molecule,**kwargs):
        from PyQuante.Convergence import DIIS
        from PyQuante.DFunctionals import need_gradients
        self.molecule = molecule
        logging.info("DFT calculation on system %s" % self.molecule.name)
        self.basis_set = BasisSet(molecule,**kwargs)
        self.integrals = Integrals(molecule,self.basis_set,**kwargs)
        self.iterator = SCFIterator()
        self.h = self.integrals.get_h()
        self.S = self.integrals.get_S()
        self.ERI = self.integrals.get_ERI()
        self.Enuke = molecule.get_enuke()
        self.nel = molecule.get_nel()
        self.F = self.h
        self.functional = kwargs.get('functional',settings.DFTFunctional)
        kwargs['do_grad_dens'] = need_gradients[self.functional]
        self.setup_grid(molecule,self.basis_set.get(),**kwargs)
        self.dmat = None
        self.entropy = None
        self.DoAveraging = kwargs.get('DoAveraging',settings.DFTAveraging)
        if self.DoAveraging:
            self.Averager = DIIS(self.S)
        nel = molecule.get_nel()
        nclosed,nopen = molecule.get_closedopen()
        logging.info("Nclosed/open = %d, %d" % (nclosed,nopen))
        self.solver = SolverFactory(nel,nclosed,nopen,self.S,**kwargs)
        return
        
    def __repr__(self):
        lstr = ['Hamiltonian constructed for method %s' % self.method,
                repr(self.molecule),
                repr(self.basis_set),
                repr(self.iterator)]
        return '\n'.join(lstr)

    def get_energy(self): return self.energy
    def iterate(self,**kwargs): return self.iterator.iterate(self,**kwargs)

    def setup_grid(self,molecule,bfs,**kwargs):
        #from PyQuante.MolecularGrid import MolecularGrid
        from PyQuante.MG2 import MG2 as MolecularGrid
        grid_nrad = kwargs.get('grid_nrad',settings.DFTGridRadii)
        grid_fineness = kwargs.get('grid_fineness',settings.DFTGridFineness)
        self.gr = MolecularGrid(molecule,grid_nrad,grid_fineness,**kwargs) 
        self.gr.set_bf_amps(bfs)
        return

    def update(self,**kwargs):
        from PyQuante.LA2 import trace2
        from PyQuante.Ints import getJ
        from PyQuante.dft import getXC

        #self.DoAveraging = kwargs.get('DoAveraging',True)
        #if self.DoAveraging:
        #    self.Averager = DIIS(self.S)

        if self.DoAveraging and self.dmat is not None:
            self.F = self.Averager.getF(self.F,self.dmat)
        self.dmat,self.entropy = self.solver.solve(self.F,**kwargs)
        D = self.dmat
        
        self.gr.setdens(D)
        self.J = getJ(self.ERI,D)
        self.Ej = 2*trace2(D,self.J)

        self.Exc,self.XC = getXC(self.gr,self.nel,
                                 functional=self.functional)

        self.Eone = 2*trace2(D,self.h)

        self.F = self.h+2*self.J+self.XC
        self.energy = self.Eone + self.Ej + self.Exc + self.Enuke + self.entropy
        return
Пример #10
0
from PyQuante.Ints import get2JmK,getbasis,getints
from PyQuante.Convergence import DIIS
from PyQuante.hartree_fock import get_energy

bfs = getbasis(h2,basis="3-21g")
nclosed,nopen = h2.get_closedopen()
nocc = nclosed
nel = h2.get_nel()
S,h,Ints = getints(bfs,h2)

orbe,orbs = geigh(h,S)

enuke = h2.get_enuke()
eold = 0

avg = DIIS(S)

for i in range(20):
    D = mkdens(orbs,0,nocc)
    G = get2JmK(Ints,D)
    F = h+G
    F = avg.getF(F,D)
    orbe,orbs = geigh(F,S)
    energy = get_energy(h,F,D,enuke)
    print i,energy,energy-eold
    if abs(energy-eold)<1e-5:
        break
    eold = energy
print "Converged"
print energy, "(benchmark = -1.122956)"
Пример #11
0
def rhf(mol, bfs, S, Hcore, Ints, MaxIter=100, eps_SCF=1E-4, _diis_=True):

    ##########################################################
    ##					Get the system information
    ##########################################################

    # size
    nbfs = len(bfs)

    # get the nuclear energy
    enuke = mol.get_enuke()

    # determine the number of electrons
    # and occupation numbers
    nelec = mol.get_nel()
    nclosed, nopen = mol.get_closedopen()
    nocc = nclosed

    if nopen != 0:
        print '\t\t ================================================================='
        print '\t\t Warning : using restricted HF with open shell is not recommended'
        print "\t\t Use only if you know what you're doing"
        print '\t\t ================================================================='

    # get a first DM
    #D = np.zeros((nbfs,nbfs))
    L, C = scla.eigh(Hcore, b=S)
    D = mkdens(C, 0, nocc)

    # initialize the old energy
    eold = 0.

    # initialize the DIIS
    if _diis_:
        avg = DIIS(S)

    #print '\t SCF Calculations'
    for iiter in range(MaxIter):

        # form the G matrix from the
        # density matrix and  the 2electron integrals
        G = get2JmK_mpi(Ints, D)

        # form the Fock matrix
        F = Hcore + G

        # if DIIS
        if _diis_:
            F = avg.getF(F, D)

        # diagonalize the Fock matrix
        L, C = scla.eigh(F, b=S)

        # new density mtrix
        D = mkdens(C, 0, nocc)

        # compute the total energy
        e = np.sum(D * (Hcore + F)) + enuke

        print "\t\t Iteration: %d    Energy: %f    EnergyVar: %f" % (
            iiter, e.real, np.abs((e - eold).real))

        # stop if done
        if (np.abs(e - eold) < eps_SCF):
            break
        else:
            eold = e

    if iiter < MaxIter - 1:
        print(
            "\t\t SCF for HF has converged in %d iterations, Final energy %1.3f Ha\n"
            % (iiter, e.real))

    else:
        print("\t\t SCF for HF has failed to converge after %d iterations")
        sys.exit()

    # compute the density matrix in the
    # eigenabsis of the Fock matrix

    # orthogonalization matrix
    X = SymOrthCutoff(S)
    Xm1 = np.linalg.inv(X)

    # density matrix in ortho basis
    Dp = np.dot(Xm1, np.dot(D, Xm1.T))

    # eigenvector in ortho basis
    Cp = np.dot(Xm1, C)

    # density matrix
    P = np.dot(Cp.T, np.dot(Dp, Cp))

    # done
    return L, C, P