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 __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
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
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 __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
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
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
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
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
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)"
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