Esempio n. 1
0
	def __init__(self, mf, method = 'overlap'):
		'''
		Prepare the orthonormal/localized set of orbitals for DMET
		Args:
			mf		: a mean-field wf
			method	: overlap/boys/lowdin/meta_lowdin. if method == lattice: U = 1
					
		Return:
			U		: Tranformation matrix to the orthonormal basis
		'''	
		
		self.mol = mf.mol 	
		self.mf = mf
		self.Nelecs = mf.mol.nelectron		
		self.Norbs = mf.mol.nao_nr()
		self.U = None		
		self.orthoOEI = None 		
		self.orthoTEI = None
		self.S = mf.get_ovlp()	
		
		if method == 'overlap':
			self.U = scipy.linalg.fractional_matrix_power(self.S, -0.5)
		elif method == 'boys':
			self.U = self.mf.mo_coeff
			loc = localizer.localizer( self.mol, self.U, method, use_full_hessian = True )
			loc.verbose = 0			
			self.U = loc.optimize( threshold = 1.e-8 )
		elif method == 'lowdin':
			ovlp = self.mol.intor('cint1e_ovlp_sph')
			ovlp_eigs, ovlp_vecs = np.linalg.eigh( ovlp )
			assert ( np.linalg.norm( np.dot( np.dot( ovlp_vecs, np.diag( ovlp_eigs ) ), ovlp_vecs.T ) - ovlp ) < 1e-10 )
			self.U = np.dot( np.dot( ovlp_vecs, np.diag( np.power( ovlp_eigs, -0.5 ) ) ), ovlp_vecs.T )
		elif method == 'meta_lowdin':
			nao.AOSHELL[4] = ['1s0p0d0f', '2s1p0d0f'] #redefine the valence shell for Be	
			self.U = orth.orth_ao( self.mol, 'meta_lowdin' )
		elif method == 'lattice':
			self.orthoOEI = self.mf.get_hcore()
			self.orthoTEI = ao2mo.incore.full(ao2mo.restore(8, self.mf._eri, self.Norbs), self.S, compact=False).reshape(self.Norbs, self.Norbs, self.Norbs, self.Norbs)
			self.orthoFOCK = self.orthoOEI + self.mf.get_veff()
		
		if method != 'lattice':
			#Tranform One-Electron Integral to orthonormal basis
			OEI = self.mf.get_hcore()
			self.orthoOEI = reduce(np.dot, (self.U.T, OEI, self.U))

			#Tranform Two-Electron Integral to orthonormal basis	
			Norbs = self.Norbs		
			g_format = self.mol.intor('cint2e_sph')
			TEI = np.zeros([Norbs, Norbs, Norbs, Norbs]) 
			for cn1 in range(Norbs):
				for cn2 in range(Norbs):
					for cn3 in range(Norbs):
						for cn4 in range(Norbs):
							TEI[cn1][cn2][cn3][cn4] = g_format[cn1*Norbs + cn2][cn3*Norbs + cn4]		
			self.orthoTEI = ao2mo.incore.full(ao2mo.restore(8, TEI, Norbs), self.U, compact=False).reshape(Norbs, Norbs, Norbs, Norbs)	

			#Tranform Fock to orthonormal basis
			vhf = self.mf.get_veff()
			FOCK = OEI + vhf  
			self.orthoFOCK = reduce(np.dot, (self.U.T, FOCK, self.U))
Esempio n. 2
0
def build_iAO_basis(mol,Cf,Cf_core,Cf_vale,nfreeze):
    import numpy as np
    import scipy.linalg as sla
    S_f  = mol.intor_symmetric('cint1e_ovlp_sph')
    nup  = mol.nelectron//2
    iao, Cf_core = build_iao(S_f,Cf[:,:nup],Cf_vale,P_core=Cf_core,nfreeze=nfreeze)
    loc          = localizer.localizer(mol,iao,'boys')
    loc.verbose  = 5
    iao_loc      = loc.optimize (threshold=1.0e-5)
#    loc = lo.Boys(mol, iao).kernel()
#    iao_loc = loc
    del loc
    # need to find occupied orbitals orthogonal to core
    if(Cf_core is not None):
       Cf_x = project(Cf[:,:nup],S_f,Cf_core,'out')
       return iao_loc,Cf_core,Cf_x
    else:
       Cf_x = Cf[:,:nup]
       return iao_loc,None,Cf_x
#
# We now dump out UHF natual orbitals and localized orbitals to help identify
# active space.
#
# dump UHF natrual orbital
#
tools.molden.from_mo(mol, fname+'_uno.molden', coeff)

#=============================
# localized orbitals
#=============================
iflocal  = False
if iflocal:
    # We implemented different localization later
    from pyscf.tools import localizer
    loc = localizer.localizer(mol,ma[:,:mol.nelectron/2],'boys')
    loc.verbose = 10
    new_coeff = loc.optimize()
    loc = localizer.localizer(mol,ma[:,mol.nelectron/2:],'boys')
    new_coeff2 = loc.optimize()
    lmo = numpy.hstack([new_coeff,new_coeff2])
    tools.molden.from_mo(mol, fname+'lmo.molden', lmo)

#
# Test orthogonality because occasionally localization procedure may break the
# orbital orthogonality (when AO functions are close to linear dependent).
#
cOrbsOAO = numpy.dot(s12,cOrbs)
aOrbsOAO = numpy.dot(s12,aOrbs)
vOrbsOAO = numpy.dot(s12,vOrbs)
print('Ortho-cOAO',numpy.linalg.norm(numpy.dot(cOrbsOAO.T,cOrbsOAO)-numpy.identity(nc)))
Esempio n. 4
0
#
# We now dump out UHF natual orbitals and localized orbitals to help identify
# active space.
#
# dump UHF natrual orbital
#
tools.molden.from_mo(mol, fname + '_uno.molden', coeff)

#=============================
# localized orbitals
#=============================
iflocal = False
if iflocal:
    # We implemented different localization later
    from pyscf.tools import localizer
    loc = localizer.localizer(mol, ma[:, :mol.nelectron / 2], 'boys')
    loc.verbose = 10
    new_coeff = loc.optimize()
    loc = localizer.localizer(mol, ma[:, mol.nelectron / 2:], 'boys')
    new_coeff2 = loc.optimize()
    lmo = numpy.hstack([new_coeff, new_coeff2])
    tools.molden.from_mo(mol, fname + 'lmo.molden', lmo)

#
# Test orthogonality because occasionally localization procedure may break the
# orbital orthogonality (when AO functions are close to linear dependent).
#
cOrbsOAO = numpy.dot(s12, cOrbs)
aOrbsOAO = numpy.dot(s12, aOrbs)
vOrbsOAO = numpy.dot(s12, vOrbs)
print('Ortho-cOAO',
Esempio n. 5
0
     C    1.211265339156    -0.699329968382     0.000000000000
     H   -2.157597486829     1.245660462400     0.000000000000
     C   -1.211265339156     0.699329968382     0.000000000000
     H   -2.157597486829    -1.245660462400     0.000000000000
     C   -1.211265339156    -0.699329968382     0.000000000000
  '''
mol.basis = '6-31g'
mol.symmetry = 0
mol.charge = 0
mol.spin = 0
mol.build()
mf = scf.RHF(mol)
mf.verbose = 0
mf.scf()

filename_mo = 'benzene-631g-mo.molden'
filename_boys = 'benzene-631g-boys.molden'

with open(filename_mo, 'w') as thefile:
    molden.header(mol, thefile)
    molden.orbital_coeff(mol, thefile, mf.mo_coeff)
print("Molecular orbitals saved in", filename_mo)

# Localize the pi-type orbitals. Counting starts from 0! 12 orbitals as 6-31G is DZ.
tolocalize = np.array([17, 20, 21, 22, 23, 30, 36, 41, 42, 47, 48, 49]) - 1
loc = localizer.localizer(mol, mf.mo_coeff[:, tolocalize], 'boys')
loc.verbose = param.VERBOSE_DEBUG
new_coeff = loc.optimize()
loc.dump_molden(filename_boys, new_coeff)
print("Boys localized pi-orbitals saved in", filename_boys)
Esempio n. 6
0
    def __init__(self,
                 the_mf,
                 active_orbs,
                 localizationtype,
                 ao_rotation=None,
                 use_full_hessian=True,
                 localization_threshold=1e-6):

        assert ((localizationtype == 'meta_lowdin')
                or (localizationtype == 'boys')
                or (localizationtype == 'lowdin')
                or (localizationtype == 'iao'))

        # Information on the full HF problem
        self.mol = the_mf.mol
        self.fullEhf = the_mf.hf_energy
        self.fullDMao = np.dot(np.dot(the_mf.mo_coeff, np.diag(the_mf.mo_occ)),
                               the_mf.mo_coeff.T)
        self.fullJKao = scf.hf.get_veff(
            self.mol, self.fullDMao, 0, 0,
            1)  #Last 3 numbers: dm_last, vhf_last, hermi
        self.fullFOCKao = self.mol.intor('cint1e_kin_sph') + self.mol.intor(
            'cint1e_nuc_sph') + self.fullJKao

        # Active space information
        self._which = localizationtype
        self.active = np.zeros([self.mol.nao_nr()], dtype=int)
        self.active[active_orbs] = 1
        self.Norbs = np.sum(self.active)  # Number of active space orbitals
        self.Nelec = int(
            np.rint(self.mol.nelectron -
                    np.sum(the_mf.mo_occ[self.active == 0]))
        )  # Total number of electrons minus frozen part

        # Localize the orbitals
        if ((self._which == 'meta_lowdin') or (self._which == 'boys')):
            if (self._which == 'meta_lowdin'):
                assert (self.Norbs == self.mol.nao_nr()
                        )  # Full active space required
            if (self._which == 'boys'):
                self.ao2loc = the_mf.mo_coeff[:, self.active == 1]
            if (self.Norbs == self.mol.nao_nr()
                ):  # If you want the full active, do meta-Lowdin
                nao.AOSHELL[4] = ['1s0p0d0f', '2s1p0d0f'
                                  ]  # redefine the valence shell for Be
                self.ao2loc = orth.orth_ao(self.mol, 'meta_lowdin')
                if (ao_rotation != None):
                    self.ao2loc = np.dot(self.ao2loc, ao_rotation.T)
            if (self._which == 'boys'):
                old_verbose = self.mol.verbose
                self.mol.verbose = 5
                loc = localizer.localizer(self.mol, self.ao2loc, self._which,
                                          use_full_hessian)
                self.mol.verbose = old_verbose
                self.ao2loc = loc.optimize(threshold=localization_threshold)
            self.TI_OK = False  # Check yourself if OK, then overwrite
        if (self._which == 'lowdin'):
            assert (self.Norbs == self.mol.nao_nr()
                    )  # Full active space required
            ovlp = self.mol.intor('cint1e_ovlp_sph')
            ovlp_eigs, ovlp_vecs = np.linalg.eigh(ovlp)
            assert (np.linalg.norm(
                np.dot(np.dot(ovlp_vecs, np.diag(ovlp_eigs)), ovlp_vecs.T) -
                ovlp) < 1e-10)
            self.ao2loc = np.dot(
                np.dot(ovlp_vecs, np.diag(np.power(ovlp_eigs, -0.5))),
                ovlp_vecs.T)
            self.TI_OK = False  # Check yourself if OK, then overwrite
        if (self._which == 'iao'):
            assert (self.Norbs == self.mol.nao_nr()
                    )  # Full active space assumed
            self.ao2loc = iao_helper.localize_iao(self.mol, the_mf)
            if (ao_rotation != None):
                self.ao2loc = np.dot(self.ao2loc, ao_rotation.T)
            self.TI_OK = False  # Check yourself if OK, then overwrite
            #self.molden( 'dump.molden' ) # Debugging mode
        assert (self.loc_ortho() < 1e-8)

        # Effective Hamiltonian due to frozen part
        self.frozenDMmo = np.array(the_mf.mo_occ, copy=True)
        self.frozenDMmo[self.active ==
                        1] = 0  # Only the frozen MO occupancies nonzero
        self.frozenDMao = np.dot(
            np.dot(the_mf.mo_coeff, np.diag(self.frozenDMmo)),
            the_mf.mo_coeff.T)
        self.frozenJKao = scf.hf.get_veff(
            self.mol, self.frozenDMao, 0, 0,
            1)  #Last 3 numbers: dm_last, vhf_last, hermi
        self.frozenOEIao = self.fullFOCKao - self.fullJKao + self.frozenJKao

        # Active space OEI and ERI
        self.activeCONST = self.mol.energy_nuc() + np.einsum(
            'ij,ij->', self.frozenOEIao - 0.5 * self.frozenJKao,
            self.frozenDMao)
        self.activeOEI = np.dot(np.dot(self.ao2loc.T, self.frozenOEIao),
                                self.ao2loc)
        self.activeFOCK = np.dot(np.dot(self.ao2loc.T, self.fullFOCKao),
                                 self.ao2loc)
        if (self.Norbs <= 150):
            self.ERIinMEM = True
            self.activeERI = ao2mo.outcore.full_iofree(
                self.mol, self.ao2loc,
                compact=False).reshape(self.Norbs, self.Norbs, self.Norbs,
                                       self.Norbs)
        else:
            self.ERIinMEM = False
            self.activeERI = None
Esempio n. 7
0
     C    1.211265339156    -0.699329968382     0.000000000000
     H   -2.157597486829     1.245660462400     0.000000000000
     C   -1.211265339156     0.699329968382     0.000000000000
     H   -2.157597486829    -1.245660462400     0.000000000000
     C   -1.211265339156    -0.699329968382     0.000000000000
  '''
mol.basis = '6-31g'
mol.symmetry = 0
mol.charge = 0
mol.spin = 0
mol.build()
mf = scf.RHF( mol )
mf.verbose = 0
mf.scf()

filename_mo   = 'benzene-631g-mo.molden'
filename_boys = 'benzene-631g-boys.molden'

with open( filename_mo, 'w' ) as thefile:
    molden.header( mol, thefile )
    molden.orbital_coeff( mol, thefile, mf.mo_coeff )
print("Molecular orbitals saved in", filename_mo)

# Localize the pi-type orbitals. Counting starts from 0! 12 orbitals as 6-31G is DZ.
tolocalize = np.array([17, 20, 21, 22, 23, 30, 36, 41, 42, 47, 48, 49]) - 1
loc  = localizer.localizer( mol, mf.mo_coeff[:,tolocalize], 'boys' )
loc.verbose = param.VERBOSE_DEBUG
new_coeff = loc.optimize()
loc.dump_molden( filename_boys, new_coeff )
print("Boys localized pi-orbitals saved in", filename_boys)
Esempio n. 8
0
    def __init__( self, the_mf, active_orbs, localizationtype, ao_rotation=None, use_full_hessian=True, localization_threshold=1e-6 ):

        assert (( localizationtype == 'meta_lowdin' ) or ( localizationtype == 'boys' ) or ( localizationtype == 'lowdin' ) or ( localizationtype == 'iao' ))
        
        # Information on the full HF problem
        self.mol        = the_mf.mol
        self.fullEhf    = the_mf.hf_energy
        self.fullDMao   = np.dot(np.dot( the_mf.mo_coeff, np.diag( the_mf.mo_occ )), the_mf.mo_coeff.T )
        self.fullJKao   = scf.hf.get_veff( self.mol, self.fullDMao, 0, 0, 1 ) #Last 3 numbers: dm_last, vhf_last, hermi
        self.fullFOCKao = self.mol.intor('cint1e_kin_sph') + self.mol.intor('cint1e_nuc_sph') + self.fullJKao
        
        # Active space information
        self._which   = localizationtype
        self.active   = np.zeros( [ self.mol.nao_nr() ], dtype=int )
        self.active[ active_orbs ] = 1
        self.Norbs    = np.sum( self.active ) # Number of active space orbitals
        self.Nelec    = int(np.rint( self.mol.nelectron - np.sum( the_mf.mo_occ[ self.active==0 ] ))) # Total number of electrons minus frozen part
        
        # Localize the orbitals
        if (( self._which == 'meta_lowdin' ) or ( self._which == 'boys' )):
            if ( self._which == 'meta_lowdin' ):
                assert( self.Norbs == self.mol.nao_nr() ) # Full active space required
            if ( self._which == 'boys' ):
                self.ao2loc = the_mf.mo_coeff[ : , self.active==1 ]
            if ( self.Norbs == self.mol.nao_nr() ): # If you want the full active, do meta-Lowdin
                nao.AOSHELL[4] = ['1s0p0d0f', '2s1p0d0f'] # redefine the valence shell for Be
                self.ao2loc = orth.orth_ao( self.mol, 'meta_lowdin' )
                if ( ao_rotation != None ):
                    self.ao2loc = np.dot( self.ao2loc, ao_rotation.T )
            if ( self._which == 'boys' ):
                old_verbose = self.mol.verbose
                self.mol.verbose = 5
                loc = localizer.localizer( self.mol, self.ao2loc, self._which, use_full_hessian )
                self.mol.verbose = old_verbose
                self.ao2loc = loc.optimize( threshold=localization_threshold )
            self.TI_OK = False # Check yourself if OK, then overwrite
        if ( self._which == 'lowdin' ):
            assert( self.Norbs == self.mol.nao_nr() ) # Full active space required
            ovlp = self.mol.intor('cint1e_ovlp_sph')
            ovlp_eigs, ovlp_vecs = np.linalg.eigh( ovlp )
            assert ( np.linalg.norm( np.dot( np.dot( ovlp_vecs, np.diag( ovlp_eigs ) ), ovlp_vecs.T ) - ovlp ) < 1e-10 )
            self.ao2loc = np.dot( np.dot( ovlp_vecs, np.diag( np.power( ovlp_eigs, -0.5 ) ) ), ovlp_vecs.T )
            self.TI_OK  = False # Check yourself if OK, then overwrite
        if ( self._which == 'iao' ):
            assert( self.Norbs == self.mol.nao_nr() ) # Full active space assumed
            self.ao2loc = iao_helper.localize_iao( self.mol, the_mf )
            if ( ao_rotation != None ):
                self.ao2loc = np.dot( self.ao2loc, ao_rotation.T )
            self.TI_OK = False # Check yourself if OK, then overwrite
            #self.molden( 'dump.molden' ) # Debugging mode
        assert( self.loc_ortho() < 1e-8 )
        
        # Effective Hamiltonian due to frozen part
        self.frozenDMmo  = np.array( the_mf.mo_occ, copy=True )
        self.frozenDMmo[ self.active==1 ] = 0 # Only the frozen MO occupancies nonzero
        self.frozenDMao  = np.dot(np.dot( the_mf.mo_coeff, np.diag( self.frozenDMmo )), the_mf.mo_coeff.T )
        self.frozenJKao  = scf.hf.get_veff( self.mol, self.frozenDMao, 0, 0, 1 ) #Last 3 numbers: dm_last, vhf_last, hermi
        self.frozenOEIao = self.fullFOCKao - self.fullJKao + self.frozenJKao
        
        # Active space OEI and ERI
        self.activeCONST = self.mol.energy_nuc() + np.einsum( 'ij,ij->', self.frozenOEIao - 0.5*self.frozenJKao, self.frozenDMao )
        self.activeOEI   = np.dot( np.dot( self.ao2loc.T, self.frozenOEIao ), self.ao2loc )
        self.activeFOCK  = np.dot( np.dot( self.ao2loc.T, self.fullFOCKao  ), self.ao2loc )
        if ( self.Norbs <= 150 ):
            self.ERIinMEM  = True
            self.activeERI = ao2mo.outcore.full_iofree( self.mol, self.ao2loc, compact=False ).reshape(self.Norbs, self.Norbs, self.Norbs, self.Norbs)
        else:
            self.ERIinMEM  = False
            self.activeERI = None
Esempio n. 9
0
from pyscf import gto, scf, lo
from pyscf.tools import localizer

mol = gto.Mole()
mol.atom = '''
     He   0.    0.     0.2
     H    0.   -0.5   -0.4
     H    0.    0.5   -0.4
  '''
mol.basis = 'sto-3g'
mol.build()
mf = scf.RHF(mol).run()

print mf.mo_coeff

loc = localizer.localizer(mol, mf.mo_coeff, 'boys')
loc.verbose = 5
print("loc object")
print(loc.coeff)
new_coeff = loc.optimize(threshold=1e-5)
#loc = lo.Boys(mol, mf.mo_coeff).kernel()
print(new_coeff)
#print("localized = ")
#print( loc)
Esempio n. 10
0
     C    1.211265339156    -0.699329968382     0.000000000000
     H   -2.157597486829     1.245660462400     0.000000000000
     C   -1.211265339156     0.699329968382     0.000000000000
     H   -2.157597486829    -1.245660462400     0.000000000000
     C   -1.211265339156    -0.699329968382     0.000000000000
  '''
mol.basis = '6-31g'
mol.symmetry = 0
mol.charge = 0
mol.spin = 0
mol.build()
mf = scf.RHF( mol )
mf.verbose = 0
mf.scf()

filename_mo       = 'benzene-631g-mo.molden'
filename_edmiston = 'benzene-631g-edmiston.molden'

with open( filename_mo, 'w' ) as thefile:
    molden.header( mol, thefile )
    molden.orbital_coeff( mol, thefile, mf.mo_coeff )
print("Molecular orbitals saved in", filename_mo)

# Localize the pi-type orbitals. Counting starts from 0! 12 orbitals as 6-31G is DZ.
tolocalize = np.array([17, 20, 21, 22, 23, 30, 36, 41, 42, 47, 48, 49]) - 1
loc  = localizer.localizer( mol, mf.mo_coeff[:,tolocalize], 'edmiston' )
loc.verbose = param.VERBOSE_DEBUG
new_coeff = loc.optimize()
loc.dump_molden( filename_edmiston, new_coeff )
print("Edmiston-Ruedenberg localized pi-orbitals saved in", filename_edmiston)