def localize(mol, mf, method): if (method == "lowdin"): return fractional_matrix_power(mf.get_ovlp(mol), -0.5).T elif (method == "pm"): return pipek.PM(mol).kernel(mf.mo_coeff) elif (method == "pmLowdin"): lowdin = fractional_matrix_power(mf.get_ovlp(mol), -0.5).T return pipek.PM(mol).kernel(lowdin) elif (method == "boys"): return boys.Boys(mol).kernel(mf.mo_coeff)
def PipekMezey(mol, orbocc, iaos=None, s=None, exponent=EXPONENT): ''' Note this localization is slightly different to Knizia's implementation. The localization here reserves orthogonormality during optimization. Orbitals are projected to IAO basis first and the Mulliken pop is calculated based on IAO basis (in function atomic_pops). A series of unitary matrices are generated and applied on the input orbitals. The intemdiate orbitals in the optimization and the finally localized orbitals are all orthogonormal. Examples: >>> from pyscf import gto, scf >>> from pyscf.lo import ibo >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', >>> basis='unc-sto3g') >>> mf = scf.RHF(mol).run() >>> pm = ibo.PM(mol, mf.mo_coeff[:,mf.mo_occ>0]) >>> loc_orb = pm.kernel() ''' if hasattr(mol, 'pbc_intor'): # whether mol object is a cell if isinstance(orbocc, numpy.ndarray) and orbocc.ndim == 2: s = mol.pbc_intor('int1e_ovlp', hermi=1) else: raise NotImplementedError('k-points crystal orbitals') else: s = mol.intor_symmetric('int1e_ovlp') if iaos is None: iaos = iao.iao(mol, orbocc) # Different to Knizia's code, the reference IAOs are not neccessary # orthogonal. #iaos = orth.vec_lowdin(iaos, s) cs = numpy.dot(iaos.T.conj(), s) s_iao = numpy.dot(cs, iaos) iao_inv = numpy.linalg.solve(s_iao, cs) iao_mol = iao.reference_mol(mol) # Define the mulliken population of each atom based on IAO basis. # proj[i].trace is the mulliken population of atom i. def atomic_pops(mol, mo_coeff, method=None): nmo = mo_coeff.shape[1] proj = numpy.empty((mol.natm, nmo, nmo)) orb_in_iao = reduce(numpy.dot, (iao_inv, mo_coeff)) for i, (b0, b1, p0, p1) in enumerate(iao_mol.offset_nr_by_atom()): csc = reduce(numpy.dot, (orb_in_iao[p0:p1].T, s_iao[p0:p1], orb_in_iao)) proj[i] = (csc + csc.T) * .5 return proj pm = pipek.PM(mol, orbocc) pm.atomic_pops = atomic_pops pm.exponent = exponent return pm
def localizeAllElectron(mf, method="lowdin"): if (method == "lowdin"): return fractional_matrix_power(mf.get_ovlp(), -0.5).T elif (method == "pm"): return pipek.PM(mf.mol).kernel(mf.mo_coeff) elif (method == "boys"): return boys.Boys(mf.mol).kernel(mf.mo_coeff) elif (method == "er"): return edmiston.ER(mf.mol).kernel(mf.mo_coeff) elif (method == "iao"): return iao.iao(mf.mol, mf.mo_coeff) elif (method == "ibo"): a = iao.iao(mf.mol, mf.mo_coeff) a = lo.vec_lowdin(a, mf.get_ovlp()) return ibo.ibo(mf.mol, mf.mo_coeff, iaos=a)
def PipekMezey(mol, orbocc, iaos, s, exponent): ''' Note this localization is slightly different to Knizia's implementation. The localization here reserves orthogonormality during optimization. Orbitals are projected to IAO basis first and the Mulliken pop is calculated based on IAO basis (in function atomic_pops). A series of unitary matrices are generated and applied on the input orbitals. The intemdiate orbitals in the optimization and the finally localized orbitals are all orthogonormal. Examples: >>> from pyscf import gto, scf >>> from pyscf.lo import ibo >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', >>> basis='unc-sto3g') >>> mf = scf.RHF(mol).run() >>> pm = ibo.PM(mol, mf.mo_coeff[:,mf.mo_occ>0]) >>> loc_orb = pm.kernel() ''' # Note: PM with Lowdin-orth IAOs is implemented in pipek.PM class # TODO: Merge the implemenation here to pipek.PM MINAO = getattr(__config__, 'lo_iao_minao', 'minao') cs = numpy.dot(iaos.T.conj(), s) s_iao = numpy.dot(cs, iaos) iao_inv = numpy.linalg.solve(s_iao, cs) iao_mol = iao.reference_mol(mol, minao=MINAO) # Define the mulliken population of each atom based on IAO basis. # proj[i].trace is the mulliken population of atom i. def atomic_pops(mol, mo_coeff, method=None): nmo = mo_coeff.shape[1] proj = numpy.empty((mol.natm, nmo, nmo)) orb_in_iao = reduce(numpy.dot, (iao_inv, mo_coeff)) for i, (b0, b1, p0, p1) in enumerate(iao_mol.offset_nr_by_atom()): csc = reduce(numpy.dot, (orb_in_iao[p0:p1].T, s_iao[p0:p1], orb_in_iao)) proj[i] = (csc + csc.T) * .5 return proj pm = pipek.PM(mol, orbocc) pm.atomic_pops = atomic_pops pm.exponent = exponent return pm
n = 10 order = 2 sqrt2 = 2**0.5 atomstring = "" for i in range(n): atomstring += "H 0 0 %g\n" % (i * r) mol = gto.M(atom=atomstring, basis='ccpvdz', verbose=4, symmetry=0, spin=0) mf = scf.RHF(mol) print mf.kernel() mocoeff = mf.mo_coeff lowdin = fractional_matrix_power(mf.get_ovlp(mol), -0.5).T pm = pipek.PM(mol).kernel(lowdin) lmo = np.full((50, 50), 0.) orth = ortho_group.rvs(dim=5) for i in range(10): lmo[::, 5 * i:5 * (i + 1)] = pm[::, 5 * i:5 * (i + 1)].dot(orth) norb = mf.mo_coeff.shape[0] h1 = lmo.T.dot(mf.get_hcore()).dot(lmo) eri = ao2mo.kernel(mol, lmo) tools.fcidump.from_integrals('FCIDUMP', h1, eri, norb, n, mf.energy_nuc()) print mf.mo_coeff print "local" print lmo #print the atom with which the lmo is associated
atomstring = "" for i in range(n): atomstring += "H 0 0 %g\n" % (i * r) mol = gto.M(atom=atomstring, basis='sto-6g', verbose=4, symmetry=0, spin=0) myhf = scf.RHF(mol) if (UHF): myhf = scf.UHF(mol) print myhf.kernel() if UHF: mocoeff = myhf.mo_coeff[0] else: mocoeff = myhf.mo_coeff lmo = pipek.PM(mol).kernel(mocoeff) #print the atom with which the lmo is associated orbitalOrder = [] for i in range(lmo.shape[1]): orbitalOrder.append(numpy.argmax(numpy.absolute(lmo[:, i]))) print orbitalOrder norbs = len(orbitalOrder) #f = open("correlators.txt", 'w') #print sorted(orbitalOrder) reorder = [] for i in range(norbs): reorder.append(orbitalOrder.index(i))
from pyscf import gto, scf, ao2mo, mcscf, tools, fci from pyscf.shciscf import shci, settings from pyscf.lo import pipek r = 0.529177 atomstring = "" for i in range(20): atomstring += "H 0 0 %g\n" % (i * r) mol = gto.M(atom=atomstring, basis='sto-6g', verbose=2, symmetry=0, spin=0) myhf = scf.RHF(mol) myhf.kernel() print myhf.e_tot #localized orbitals lmo = pipek.PM(mol).kernel(myhf.mo_coeff) #print the atom with which the lmo is associated for i in range(lmo.shape[1]): print numpy.argmax(numpy.absolute(lmo[:, i])), print #this gives the mo coeffficients in terms of lmo S = myhf.get_ovlp(mol) uc = reduce(numpy.dot, (myhf.mo_coeff.T, S, lmo)).T #write the UC(lmo, mo) to disk norbs = myhf.mo_coeff.shape[0] fileHF = open("hf.txt", 'w') for i in range(norbs): for j in range(norbs):