Exemple #1
0
def test():

    mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5",
                basis="sto-3g",
                unit="bohr",
                verbose=0)
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, "lowdin")

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    obdm_steps = 4
    warmup = 15
    wf = PySCFSlaterUHF(mol, mf)
    configs = initial_guess(mol, nconf)
    energy = EnergyAccumulator(mol)
    obdm = OBDMAccumulator(mol=mol, orb_coeff=lowdin, nsweeps=1)
    obdm_up = OBDMAccumulator(mol=mol, orb_coeff=lowdin, nsweeps=1, spin=0)
    obdm_down = OBDMAccumulator(mol=mol, orb_coeff=lowdin, nsweeps=1, spin=1)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={
            "energy": energy,
            "obdm": obdm,
            "obdm_up": obdm_up,
            "obdm_down": obdm_down,
        },
    )
    df = DataFrame(df)

    obdm_est = {}
    for k in ["obdm", "obdm_up", "obdm_down"]:
        avg_norm = np.array(df.loc[warmup:,
                                   k + "norm"].values.tolist()).mean(axis=0)
        avg_obdm = np.array(df.loc[warmup:,
                                   k + "value"].values.tolist()).mean(axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    print("Average OBDM(orb,orb)", obdm_est["obdm"].diagonal().round(3))
    print("mf obdm", mfobdm.diagonal().round(3))
    assert np.max(np.abs(obdm_est["obdm"] - mfobdm)) < 0.05
    print(obdm_est["obdm_up"].diagonal().round(3))
    print(obdm_est["obdm_down"].diagonal().round(3))
    assert np.mean(
        np.abs(obdm_est["obdm_up"] + obdm_est["obdm_down"] - mfobdm)) < 0.05
Exemple #2
0
def gen_basis(mol, mf, obdm, threshold=1e-2):
    """From an obdm, use IAOs to generate a minimal atomic basis for a given state """
    n = obdm.shape[0]
    obdm *= n
    w, v = np.linalg.eig(obdm)
    keep = np.abs(w) > threshold
    a = lo.orth_ao(mol, 'lowdin')
    basis = np.dot(a, v[:, keep]).real
    iao = lo.iao.iao(mol, basis)
    iao = lo.vec_lowdin(iao, mf.get_ovlp())
    return iao
Exemple #3
0
def find_basis_evaluate(mfchk, hdf_opt, hdf_vmc, hdf_final):
    """Given a wave function in hdf_opt, compute the 1-RDM (stored in hdf_vmc) , generate a minimal atomic basis and compute the energy/OBDM/TBDM and store in hdf_final """
    from pyqmc.obdm import OBDMAccumulator
    from pyqmc.tbdm import TBDMAccumulator
    from pyqmc import EnergyAccumulator

    sys = pyqmc_from_hdf(mfchk)

    mol = sys["mol"]
    a = lo.orth_ao(mol, "lowdin")
    obdm_up = OBDMAccumulator(mol=mol, orb_coeff=a, spin=0)
    obdm_down = OBDMAccumulator(mol=mol, orb_coeff=a, spin=1)
    with h5py.File(hdf_opt, "r") as hdf_in:
        if f"wf" in hdf_in.keys():
            print("reading in wave function")
            grp = hdf_in[f"wf"]
            for k in grp.keys():
                sys["wf"].parameters[k] = np.array(grp[k])

    configs = pyqmc.initial_guess(sys["mol"], 1000)
    pyqmc.vmc(
        sys["wf"],
        configs,
        nsteps=500,
        hdf_file=hdf_vmc,
        accumulators={
            "obdm_up": obdm_up,
            "obdm_down": obdm_down
        },
    )

    with h5py.File(hdf_vmc, "r") as vmc_hdf:
        obdm_up = np.mean(np.array(vmc_hdf["obdm_upvalue"]), axis=0)
        obdm_down = np.mean(np.array(vmc_hdf["obdm_downvalue"]), axis=0)
    basis_up = gen_basis(mol, sys["mf"], obdm_up)
    basis_down = gen_basis(mol, sys["mf"], obdm_down)
    obdm_up_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_up, spin=0)
    obdm_down_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_down, spin=1)
    tbdm = TBDMAccumulator(mol, np.array([basis_up, basis_down]), spin=(0, 1))
    acc = {
        "energy": EnergyAccumulator(mol),
        "obdm_up": obdm_up_acc,
        "obdm_down": obdm_down_acc,
        "tbdm": tbdm,
    }

    configs = pyqmc.initial_guess(sys["mol"], 1000)
    pyqmc.vmc(sys["wf"],
              configs,
              nsteps=500,
              hdf_file=hdf_final,
              accumulators=acc)
Exemple #4
0
def test():

    mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5",
                basis="sto-3g",
                unit="bohr",
                verbose=0)
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, "lowdin")

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    warmup = 15
    wf = Slater(mol, mf)
    configs = initial_guess(mol, nconf)
    obdm_dict = dict(mol=mol, orb_coeff=lowdin, nsweeps=5, warmup=15)
    obdm = OBDMAccumulator(**obdm_dict)
    obdm_up = OBDMAccumulator(**obdm_dict, spin=0)
    obdm_down = OBDMAccumulator(**obdm_dict, spin=1)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={
            "obdm": obdm,
            "obdm_up": obdm_up,
            "obdm_down": obdm_down
        },
    )
    obdm_est = {}
    for k in ["obdm", "obdm_up", "obdm_down"]:
        avg_norm = np.mean(df[k + "norm"][warmup:], axis=0)
        avg_obdm = np.mean(df[k + "value"][warmup:], axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    assert np.mean(
        np.abs(obdm_est["obdm_up"] + obdm_est["obdm_down"] - mfobdm)) < 0.05
Exemple #5
0
def dumpLocal(fname):
   chkfile = fname+'.chk'
   outfile = fname+'_cmo.molden'
   tools.molden.from_chkfile(outfile, chkfile)
   
   mol,mf = scf.chkfile.load_scf(chkfile)
   mo_coeff = mf["mo_coeff"]
   ova=mol.intor_symmetric("cint1e_ovlp_sph")
   nb = mo_coeff.shape[1]
   nalpha = (mol.nelectron+mol.spin)/2
   nbeta  = (mol.nelectron-mol.spin)/2
   print 'nalpha,nbeta,mol.spin,nb:',\
          nalpha,nbeta,mol.spin,nb
   # UHF-alpha/beta
   ma = mo_coeff[0]
   mb = mo_coeff[1]
   
   #=============================
   # Localization
   #=============================
   ma_c = ma[:,:nalpha].copy()
   ma_v = ma[:,nalpha:].copy()
   #--------------------
   # Occupied space: PM
   #--------------------
   import pmloc
   ierr,uc = pmloc.loc(mol,ma_c)
   mc = numpy.dot(ma_c,uc)
   #--------------------
   # Virtual space: PAO
   #--------------------
   from pyscf import lo
   aux = lo.orth_ao(mol,method='meta_lowdin')
   mv = scdm(ma_v,ova,aux)
 
   # P[dm] 
   pa = numpy.dot(ma[:,:nalpha],ma[:,:nalpha].T)
   pb = numpy.dot(mb[:,:nbeta],mb[:,:nbeta].T)
   pT = 0.5*(pa+pb)
   # E-SORT
   enorb = mf["mo_energy"]
   fa = reduce(numpy.dot,(ma,numpy.diag(enorb[0]),ma.T))
   fb = reduce(numpy.dot,(mb,numpy.diag(enorb[1]),mb.T))
   fav = 0.5*(fa+fb)
   mc,occ_c,ec = psort(ova,fav,pT,mc)
   mv,occ_v,ev = psort(ova,fav,pT,mv)
   #---Check---
   tij = reduce(numpy.dot,(mc.T,ova,ma_c))
   sig = scipy.linalg.svd(tij,compute_uv=False)
   print 'nc=',nalpha,numpy.sum(sig**2)
   assert abs(nalpha-numpy.sum(sig**2))<1.e-8
   tij = reduce(numpy.dot,(mv.T,ova,ma_v))
   sig = scipy.linalg.svd(tij,compute_uv=False)
   print 'nv=',nb-nalpha,numpy.sum(sig**2)
   assert abs(nb-nalpha-numpy.sum(sig**2))<1.e-8

   lmo = numpy.hstack([mc,mv])
   enorb = numpy.hstack([ec,ev])
   occ = numpy.hstack([occ_c,occ_v])
   lowdinPop(mol,lmo,ova,enorb,occ)
   dumpLMO(mol,fname,lmo)
   print 'nalpha,nbeta,mol.spin,nb:',\
          nalpha,nbeta,mol.spin,nb
   return 0
from functools import reduce
import numpy
from pyscf import gto, scf, lo

x = .63
mol = gto.M(atom=[['C', (0, 0, 0)],
                  ['H', (x ,  x,  x)],
                  ['H', (-x, -x,  x)],
                  ['H', (-x,  x, -x)],
                  ['H', ( x, -x, -x)]],
            basis='ccpvtz')
mf = scf.RHF(mol).run()

# C matrix stores the AO to localized orbital coefficients
C = lo.orth_ao(mol, 'meta_lowdin')

# C is orthogonal wrt to the AO overlap matrix.  C^T S C  is an identity matrix.
print(abs(reduce(numpy.dot, (C.T, mf.get_ovlp(), C)) -
          numpy.eye(mol.nao_nr())).max())  # should be close to 0

# The following linear equation can also be solved using the matrix
# multiplication reduce(numpy.dot (C.T, mf.get_ovlp(), mf.mo_coeff))
mo = numpy.linalg.solve(C, mf.mo_coeff)

#
# Mulliken population analysis based on meta-lowdin orbitals
#
dm = mf.make_rdm1(mo, mf.mo_occ)
mf.mulliken_pop(mol, dm, numpy.eye(mol.nao_nr()))
Exemple #7
0
def get_localized_orbitals(mf, lo_method, mo=None):
    if mo is None:
        mo = mf.mo_coeff

    if not isinstance(mf, khf.KSCF):
        mol = mf.mol
        s1e = mf.get_ovlp()

        if lo_method.lower() == 'lowdin' or lo_method.lower() == 'meta_lowdin':
            C = lo.orth_ao(mf, 'meta_lowdin', s=s1e)
            C_inv = np.dot(C.conj().T, s1e)
            if isinstance(mf, scf.hf.RHF):
                C_inv_spin = C_inv
            else:
                C_inv_spin = np.array([C_inv] * 2)

        elif lo_method == 'iao':
            s1e = mf.get_ovlp()
            pmol = mf.mol.copy()
            pmol.build(False, False, basis='minao')
            if isinstance(mf, scf.hf.RHF):
                mo_coeff_occ = mf.mo_coeff[:, mf.mo_occ > 0]
                C = lo.iao.iao(mf.mol, mo_coeff_occ)
                # Orthogonalize IAO
                C = lo.vec_lowdin(C, s1e)
                C_inv = np.dot(C.conj().T, s1e)
                C_inv_spin = C_inv
            else:
                mo_coeff_occ_a = mf.mo_coeff[0][:, mf.mo_occ[0] > 0]
                mo_coeff_occ_b = mf.mo_coeff[1][:, mf.mo_occ[1] > 0]
                C_a = lo.iao.iao(mf.mol, mo_coeff_occ_a)
                C_b = lo.iao.iao(mf.mol, mo_coeff_occ_b)
                C_a = lo.vec_lowdin(C_a, s1e)
                C_b = lo.vec_lowdin(C_b, s1e)
                C_inv_a = np.dot(C_a.T, s1e)
                C_inv_b = np.dot(C_b.T, s1e)
                C_inv_spin = np.array([C_inv_a, C_inv_b])

        elif lo_method == 'nao':
            C = lo.orth_ao(mf, 'nao')
            C_inv = np.dot(C.conj().T, s1e)
            if isinstance(mf, scf.hf.RHF):
                C_inv_spin = C_inv
            else:
                C_inv_spin = np.array([C_inv] * 2)

        else:
            raise NotImplementedError("UNDEFINED LOCAL ORBITAL TYPE, EXIT...")

        mo_lo = np.einsum('...jk,...kl->...jl', C_inv_spin, mo)
        return C_inv_spin, mo_lo

    else:
        cell = mf.cell
        s1e = mf.get_ovlp()

        if lo_method.lower() == 'lowdin' or lo_method.lower() == 'meta_lowdin':
            nkpt = len(mf.kpts)
            C_arr = []
            C_inv_arr = []
            for i in range(nkpt):
                C_curr = lo.orth_ao(mf, 'meta_lowdin', s=s1e[i])
                C_inv_arr.append(np.dot(C_curr.conj().T, s1e[i]))
            C_inv_arr = np.array(C_inv_arr)
            if isinstance(mf, scf.hf.RHF):
                C_inv_spin = C_inv_arr
            else:
                C_inv_spin = np.array([C_inv_arr] * 2)
        else:
            raise NotImplementedError("CONSTRUCTING...EXIT")

        mo_lo = np.einsum('...jk,...kl->...jl', C_inv_spin, mo)
        return C_inv_spin, mo_lo
'''
Mulliken population analysis with meta-Lowdin orbitals
'''

from functools import reduce
import numpy
from pyscf import gto, scf, lo

x = .63
mol = gto.M(atom=[['C', (0, 0, 0)], ['H', (x, x, x)], ['H', (-x, -x, x)],
                  ['H', (-x, x, -x)], ['H', (x, -x, -x)]],
            basis='ccpvtz')
mf = scf.RHF(mol).run()

# C matrix stores the AO to localized orbital coefficients
C = lo.orth_ao(mol, 'meta_lowdin')

# C is orthogonal wrt to the AO overlap matrix.  C^T S C  is an identity matrix.
print(
    abs(reduce(numpy.dot, (C.T, mf.get_ovlp(), C)) -
        numpy.eye(mol.nao_nr())).max())  # should be close to 0

# The following linear equation can also be solved using the matrix
# multiplication reduce(numpy.dot (C.T, mf.get_ovlp(), mf.mo_coeff))
mo = numpy.linalg.solve(C, mf.mo_coeff)

#
# Mulliken population analysis based on meta-lowdin orbitals
#
dm = mf.make_rdm1(mo, mf.mo_occ)
mf.mulliken_pop(mol, dm, numpy.eye(mol.nao_nr()))
Exemple #9
0
def genEmbedBasis(mol,
                  mo_coeff,
                  selectionRule,
                  thresh=0.001,
                  lao='meta_lowdin',
                  debug=False,
                  ifplot=True):
    print('\n[embed.genEmbedBasis] for unrestricted determinant')
    ova = mol.intor_symmetric("cint1e_ovlp_sph")
    nb = mo_coeff.shape[1]
    # Check overlap
    diff = reduce(numpy.dot,
                  (mo_coeff[0].T, ova, mo_coeff[0])) - numpy.identity(nb)
    print(' (CtSC-I)[a]', numpy.linalg.norm(diff))
    diff = reduce(numpy.dot,
                  (mo_coeff[1].T, ova, mo_coeff[1])) - numpy.identity(nb)
    print(' (CtSC-I)[b]', numpy.linalg.norm(diff))
    # UHF-alpha/beta
    ma = mo_coeff[0]
    mb = mo_coeff[1]
    nalpha = (mol.nelectron + mol.spin) / 2
    nbeta = (mol.nelectron - mol.spin) / 2
    print(' nalpha/nbeta = ', (nalpha, nbeta))
    # Spin-averaged DM
    ma_occ = ma[:, :nalpha]
    mb_occ = mb[:, :nbeta]
    pTa = numpy.dot(ma_occ, ma_occ.T)
    pTb = numpy.dot(mb_occ, mb_occ.T)
    pT = pTa + pTb

    #------------------------------------
    # OAO basis
    #------------------------------------
    # Due to optimization by segmentation,
    # the lowdin here do not correspond to
    # the idea lowdin OAO.
    if lao == 'bad_lowdin':
        s12 = sqrtm(ova)
        s12inv = lowdin(ova)
    # Better choice: Pbas*|chiANO>
    elif lao == 'meta_lowdin':
        from pyscf import lo
        meta = lo.orth_ao(mol, method='meta_lowdin')
        diff = reduce(numpy.dot, (meta.T, ova, meta)) - numpy.identity(nb)
        s12inv = meta.copy()
        s12 = numpy.linalg.inv(s12inv)
    #
    # Psi = chiAO*C
    #     = (chiAO*Y)*(Yinv*C)
    # DM in ortho basis = Yinv*C*n*C^T*Yinv^T
    # Only in lowdin basis Y^T=Y.
    #
    pTOAO = reduce(numpy.dot, (s12, pT, s12.T))
    #------------------------------------

    # Define impurity
    labels = mol.spheric_labels()
    fragBasis = []
    fragLabels = []
    for idx, item in enumerate(labels):
        ifselect = False
        if selectionRule(item):
            ifselect = True
        if ifselect:
            fragBasis.append(idx)
            fragLabels.append(item)
    print(' Define central fragment:')
    print(' No. of totalBasis:', nb)
    print(' No. of fragBasis :', len(fragBasis))
    print(' Indices of fragBasis:', fragBasis)
    print(' fragLabels:')
    for idx, item in enumerate(fragLabels):
        print('  idx = ', idx, ' fragBas=', item)
    compBasis = list(set(range(nb)) - set(fragBasis))
    nfrag = len(fragBasis)
    ncomp = len(compBasis)
    # Fragment
    pTf = pTOAO[numpy.ix_(fragBasis, fragBasis)]
    ef, u = scipy.linalg.eigh(-pTf)
    ef = -ef
    ne_f = sum(ef)
    print(' Diag_values of pTf:\n', numpy.diag(pTf))
    print(' Eigenvalues of pTf:\n', ef)
    uf = numpy.zeros((nb, nfrag))
    # Retain the locality for impurity
    #uf[fragBasis,:] = u
    uf[fragBasis, :] = numpy.identity(nfrag)
    # Complementary
    if ncomp > 0:
        pTc = pTOAO[numpy.ix_(compBasis, compBasis)]
        ec, v = scipy.linalg.eigh(-pTc)
        ec = -ec
        ne_c = sum(ec)
        print(' Eigenvalues of pTc:\n', ec)
        cindx = []
        aindx = []
        vindx = []
        for i in range(ncomp):
            if abs(ec[i] - 2.0) < thresh:
                cindx.append(i)
            elif abs(ec[i]) < thresh:
                vindx.append(i)
            else:
                aindx.append(i)
        ncStrict = len(numpy.argwhere(abs(ec - 2.0) < 1.e-6))
        nvStrict = len(numpy.argwhere(abs(ec) < 1.e-6))
        naStrict = ncomp - ncStrict - nvStrict
        nc = len(cindx)
        na = len(aindx)
        nv = len(vindx)
        vc = numpy.zeros((nb, nc))
        va = numpy.zeros((nb, na))
        vv = numpy.zeros((nb, nv))
        vc[compBasis, :] = v[:, cindx]
        va[compBasis, :] = v[:, aindx]
        vv[compBasis, :] = v[:, vindx]
        # Set up the proper ordering
        ucoeff = numpy.hstack((uf, va, vc, vv))
        print('-' * 70)
        print(' Final results for classification of basis with thresh=',
              thresh)
        print('-' * 70)
        print(' (nf,na,nc,nv) = ', nfrag, na, nc, nv)
        print(' (ncomp,ncStrict,nvStrict,naStrict) =', ncomp, ncStrict,
              nvStrict, naStrict)
        print(' Eigen_na =\n', ec[aindx])
        if ifplot:
            import matplotlib.pyplot as plt
            plt.plot(abs(ef), marker='o', linewidth=2.0)
            plt.plot(abs(ec), marker='o', linewidth=2.0)
            plt.show()
    else:
        ne_c = 0.0
        ucoeff = uf.copy()
    # Check
    pTu = reduce(numpy.dot, (ucoeff.T, pTOAO, ucoeff))
    print(' Nf =', ne_f, 'Nc =', ne_c, 'Nt =', ne_f + ne_c)
    if debug:
        print(' diagonal of pTu =')
        print(numpy.diag(pTu))
        print('ucoeff\n', ucoeff)
    # Back to AO basis
    basis = numpy.dot(s12inv, ucoeff)
    # Dump
    diff = reduce(numpy.dot, (basis.T, ova, basis)) - numpy.identity(nb)
    print(' CtSC-I=', numpy.linalg.norm(diff))
    with open('embas.molden', 'w') as thefile:
        molden.header(mol, thefile)
        molden.orbital_coeff(mol, thefile, basis)
    with open('cmoA.molden', 'w') as thefile:
        molden.header(mol, thefile)
        molden.orbital_coeff(mol, thefile, ma)
    with open('cmoB.molden', 'w') as thefile:
        molden.header(mol, thefile)
        molden.orbital_coeff(mol, thefile, mb)
    ua = reduce(numpy.dot, (basis.T, ova, ma_occ))
    ub = reduce(numpy.dot, (basis.T, ova, mb_occ))
    if debug: print(' ua\n', ua)
    if debug: print(' ub\n', ub)
    ia = abs(reduce(numpy.dot, (ua.T, ua)))
    ib = abs(reduce(numpy.dot, (ub.T, ub)))
    print(' diffIa=', numpy.linalg.norm(ia - numpy.identity(nalpha)))
    print(' diffIb=', numpy.linalg.norm(ib - numpy.identity(nbeta)))
    return basis, ua, ub
Exemple #10
0
def dumpLocal(fname):
   chkfile = fname+'.chk'
   outfile = fname+'_cmo.molden'
   tools.molden.from_chkfile(outfile, chkfile)
   
   mol,mf = scf.chkfile.load_scf(chkfile)
   mo_coeff = mf["mo_coeff"]
   ova=mol.intor_symmetric("cint1e_ovlp_sph")
   nb = mo_coeff.shape[1]
   nalpha = (mol.nelectron+mol.spin)/2
   nbeta  = (mol.nelectron-mol.spin)/2
   print 'nalpha,nbeta,mol.spin,nb:',\
          nalpha,nbeta,mol.spin,nb
   # UHF-alpha/beta
   ma = mo_coeff[0]
   mb = mo_coeff[1]
   
   #=============================
   # Localization
   #=============================
   ma_c = ma[:,:nalpha].copy()
   ma_v = ma[:,nalpha:].copy()
   #--------------------
   # Occupied space: PM
   #--------------------
   import pmloc
   ierr,uc = pmloc.loc(mol,ma_c)
   mc = numpy.dot(ma_c,uc)
   #--------------------
   # Virtual space: PAO
   #--------------------
   from pyscf import lo
   aux = lo.orth_ao(mol,method='meta_lowdin')
   mv = scdm(ma_v,ova,aux)
 
   # P[dm] 
   pa = numpy.dot(ma[:,:nalpha],ma[:,:nalpha].T)
   pb = numpy.dot(mb[:,:nbeta],mb[:,:nbeta].T)
   pT = 0.5*(pa+pb)
   # E-SORT
   enorb = mf["mo_energy"]
   fa = reduce(numpy.dot,(ma,numpy.diag(enorb[0]),ma.T))
   fb = reduce(numpy.dot,(mb,numpy.diag(enorb[1]),mb.T))
   fav = 0.5*(fa+fb)
   mc,occ_c,ec = psort(ova,fav,pT,mc)
   mv,occ_v,ev = psort(ova,fav,pT,mv)
   #---Check---
   tij = reduce(numpy.dot,(mc.T,ova,ma_c))
   sig = scipy.linalg.svd(tij,compute_uv=False)
   print 'nc=',nalpha,numpy.sum(sig**2)
   assert abs(nalpha-numpy.sum(sig**2))<1.e-8
   tij = reduce(numpy.dot,(mv.T,ova,ma_v))
   sig = scipy.linalg.svd(tij,compute_uv=False)
   print 'nv=',nb-nalpha,numpy.sum(sig**2)
   assert abs(nb-nalpha-numpy.sum(sig**2))<1.e-8

   lmo = numpy.hstack([mc,mv])
   enorb = numpy.hstack([ec,ev])
   occ = numpy.hstack([occ_c,occ_v])
   lowdinPop(mol,lmo,ova,enorb,occ)
   dumpLMO(mol,fname,lmo)
   print 'nalpha,nbeta,mol.spin,nb:',\
          nalpha,nbeta,mol.spin,nb
   return 0
Exemple #11
0
def test():
    from pyscf import gto, scf, lo
    from numpy.linalg import solve
    from pyqmc.slater import PySCFSlaterRHF
    from pyqmc.mc import initial_guess, vmc
    from pyqmc.accumulators import EnergyAccumulator
    from pandas import DataFrame

    ### Generate some basic objects.
    # Simple Li2 run.
    mol = gto.M(atom='Li 0. 0. 0.; Li 0. 0. 1.5',
                basis='sto-3g',
                unit='bohr',
                verbose=0)
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, 'lowdin')

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    #print(mfobdm.diagonal().round(2))

    ### Test one-body sampler.
    #test_sample_onebody(mol,lowdin,mf,nsample=int(1e4))
    #test_sample_onebody(mol,lowdin,mf,nsample=int(4e4))
    #test_sample_onebody(mol,lowdin,mf,nsample=int(1e5))

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    obdm_steps = 2
    warmup = 15
    wf = PySCFSlaterRHF(mol, mf)
    configs = initial_guess(mol, nconf)
    energy = EnergyAccumulator(mol)
    obdm = OBDMAccumulator(mol=mol, orb_coeff=mf.mo_coeff, nstep=obdm_steps)
    df, coords = vmc(wf,
                     configs,
                     nsteps=nsteps,
                     accumulators={
                         'energy': energy,
                         'obdm': obdm
                     })
    df = DataFrame(df)
    df['obdm'] = df[['obdmvalue','obdmnorm']]\
        .apply(lambda x:normalize_obdm(x['obdmvalue'],x['obdmnorm']),axis=1)
    print(df[['obdmvalue', 'obdmnorm',
              'obdm']].applymap(lambda x: x.ravel()[0]))
    avg_norm = np.array(df.loc[warmup:,
                               'obdmnorm'].values.tolist()).mean(axis=0)
    avg_obdm = np.array(df.loc[warmup:, 'obdm'].values.tolist()).mean(axis=0)
    std_obdm = np.array(
        df.loc[warmup:, 'obdm'].values.tolist()).std(axis=0) / nsteps**0.5
    print("Average norm(orb)", avg_norm)
    print("Average OBDM(orb,orb)", avg_obdm.diagonal().round(3))
    print("OBDM error (orb,orb)",
          std_obdm.diagonal().round(
              3))  # Note this needs reblocking to be accurate.
    print("AO occupation", mfobdm[0, 0])
    print('mean field', mf.energy_tot(), 'vmc estimation',
          np.mean(df['energytotal'][warmup:]),
          np.std(df['energytotal'][warmup:]))
Exemple #12
0
'''

import numpy
from pyscf import gto, scf, lo

x = .63
mol = gto.M(atom=[['C', (0, 0, 0)],
                  ['H', (x ,  x,  x)],
                  ['H', (-x, -x,  x)],
                  ['H', (-x,  x, -x)],
                  ['H', ( x, -x, -x)]],
            basis='ccpvtz')
mf = scf.RHF(mol).run()

# C matrix stores the AO to localized orbital coefficients
C = lo.orth_ao(mf, 'nao')

# C is orthogonal wrt to the AO overlap matrix.  C^T S C  is an identity matrix.
print(abs(reduce(numpy.dot, (C.T, mf.get_ovlp(), C)) -
          numpy.eye(mol.nao_nr())).max())  # should be close to 0

# The following linear equation can also be solved using the matrix
# multiplication reduce(numpy.dot (C.T, mf.get_ovlp(), mf.mo_coeff))
mo = numpy.linalg.solve(C, mf.mo_coeff)

#
# Mulliken population analysis based on NAOs
#
dm = mf.make_rdm1(mo, mf.mo_occ)
mf.mulliken_pop(mol, dm, numpy.eye(mol.nao_nr()))
Exemple #13
0
#!/usr/bin/env python
'''
Mulliken population analysis with NAO
'''

import numpy
from pyscf import gto, scf, lo

x = .63
mol = gto.M(atom=[['C', (0, 0, 0)], ['H', (x, x, x)], ['H', (-x, -x, x)],
                  ['H', (-x, x, -x)], ['H', (x, -x, -x)]],
            basis='ccpvtz')
mf = scf.RHF(mol).run()

c = lo.orth_ao(mf, 'nao')
mo = numpy.linalg.solve(c, mf.mo_coeff)
dm = mf.make_rdm1(mo, mf.mo_occ)
mf.mulliken_pop(mol, dm, numpy.eye(mol.nao_nr()))
Exemple #14
0
def dumpLUNO(fname, thresh=0.01):
    chkfile = fname + '.chk'
    outfile = fname + '_cmo.molden'
    tools.molden.from_chkfile(outfile, chkfile)
    #=============================
    # Natural orbitals
    # Lowdin basis X=S{-1/2}
    # psi = chi * C
    #     = chi' * C'
    #     = chi*X*(X{-1}C')
    #=============================
    mol, mf = scf.chkfile.load_scf(chkfile)
    mo_coeff = mf["mo_coeff"]
    ova = mol.intor_symmetric("cint1e_ovlp_sph")
    nb = mo_coeff.shape[1]
    # Check overlap
    diff = reduce(numpy.dot,
                  (mo_coeff[0].T, ova, mo_coeff[0])) - numpy.identity(nb)
    print numpy.linalg.norm(diff)
    diff = reduce(numpy.dot,
                  (mo_coeff[1].T, ova, mo_coeff[1])) - numpy.identity(nb)
    print numpy.linalg.norm(diff)
    # UHF-alpha/beta
    ma = mo_coeff[0]
    mb = mo_coeff[1]
    nalpha = (mol.nelectron + mol.spin) / 2
    nbeta = (mol.nelectron - mol.spin) / 2
    # Spin-averaged DM
    pTa = numpy.dot(ma[:, :nalpha], ma[:, :nalpha].T)
    pTb = numpy.dot(mb[:, :nbeta], mb[:, :nbeta].T)
    pT = 0.5 * (pTa + pTb)
    # Lowdin basis
    s12 = sqrtm(ova)
    s12inv = lowdin(ova)
    pTOAO = reduce(numpy.dot, (s12, pT, s12))
    eig, coeff = scipy.linalg.eigh(-pTOAO)
    eig = -2.0 * eig
    eig[eig < 0.0] = 0.0
    eig[abs(eig) < 1.e-14] = 0.0
    ifplot = False  #True
    if ifplot:
        import matplotlib.pyplot as plt
        plt.plot(range(nb), eig, 'ro')
        plt.show()
    # Back to AO basis
    coeff = numpy.dot(s12inv, coeff)
    diff = reduce(numpy.dot, (coeff.T, ova, coeff)) - numpy.identity(nb)
    print 'CtSC-I', numpy.linalg.norm(diff)
    #
    # Averaged Fock
    #
    enorb = mf["mo_energy"]
    fa = reduce(numpy.dot, (ma, numpy.diag(enorb[0]), ma.T))
    fb = reduce(numpy.dot, (mb, numpy.diag(enorb[1]), mb.T))
    # Non-orthogonal cases: FC=SCE
    # Fao = SC*e*C{-1} = S*C*e*Ct*S
    fav = 0.5 * (fa + fb)
    # Expectation value of natural orbitals <i|F|i>
    fexpt = reduce(numpy.dot, (coeff.T, ova, fav, ova, coeff))
    enorb = numpy.diag(fexpt)
    nocc = eig.copy()
    #
    # Reordering and define active space according to thresh
    #
    idx = 0
    active = []
    for i in range(nb):
        if nocc[i] <= 2.0 - thresh and nocc[i] >= thresh:
            active.append(True)
        else:
            active.append(False)
    print '\nNatural orbitals:'
    for i in range(nb):
        print 'orb:', i, active[i], nocc[i], enorb[i]
    active = numpy.array(active)
    actIndices = list(numpy.argwhere(active == True).flatten())
    cOrbs = coeff[:, :actIndices[0]]
    aOrbs = coeff[:, actIndices]
    vOrbs = coeff[:, actIndices[-1] + 1:]
    nb = cOrbs.shape[0]
    nc = cOrbs.shape[1]
    na = aOrbs.shape[1]
    nv = vOrbs.shape[1]
    print 'core orbs:', cOrbs.shape
    print 'act  orbs:', aOrbs.shape
    print 'vir  orbs:', vOrbs.shape
    assert nc + na + nv == nb
    # dump UNO
    with open(fname + '_uno.molden', 'w') as thefile:
        molden.header(mol, thefile)
        molden.orbital_coeff(mol, thefile, coeff)
    #=====================
    # Population analysis
    #=====================
    from pyscf import lo
    aux = lo.orth_ao(mol, method='meta_lowdin')
    #clmo = ulocal.scdm(cOrbs,ova,aux)
    #almo = ulocal.scdm(aOrbs,ova,aux)
    clmo = cOrbs
    almo = aOrbs
    ierr, uc = pmloc.loc(mol, clmo)
    ierr, ua = pmloc.loc(mol, almo)
    clmo = clmo.dot(uc)
    almo = almo.dot(ua)
    vlmo = ulocal.scdm(vOrbs, ova, aux)
    # P-SORT
    mo_c, n_c, e_c = ulocal.psort(ova, fav, pT, clmo)
    mo_o, n_o, e_o = ulocal.psort(ova, fav, pT, almo)
    mo_v, n_v, e_v = ulocal.psort(ova, fav, pT, vlmo)
    lmo = numpy.hstack((mo_c, mo_o, mo_v)).copy()
    enorb = numpy.hstack([e_c, e_o, e_v])
    occ = numpy.hstack([n_c, n_o, n_v])
    # CHECK
    diff = reduce(numpy.dot, (lmo.T, ova, lmo)) - numpy.identity(nb)
    print 'diff=', numpy.linalg.norm(diff)
    ulocal.lowdinPop(mol, lmo, ova, enorb, occ)
    ulocal.dumpLMO(mol, fname, lmo)
    print 'nalpha,nbeta,mol.spin,nb:',\
           nalpha,nbeta,mol.spin,nb
    return mol, ova, fav, pT, nb, nalpha, nbeta, nc, na, nv, lmo, enorb, occ
Exemple #15
0
def dumpLUNO(fname,thresh=0.01):
   chkfile = fname+'.chk'
   outfile = fname+'_cmo.molden'
   tools.molden.from_chkfile(outfile, chkfile)
   #=============================
   # Natural orbitals
   # Lowdin basis X=S{-1/2}
   # psi = chi * C 
   #     = chi' * C'
   #     = chi*X*(X{-1}C')
   #=============================
   mol,mf = scf.chkfile.load_scf(chkfile)
   mo_coeff = mf["mo_coeff"]
   ova=mol.intor_symmetric("cint1e_ovlp_sph")
   nb = mo_coeff.shape[1]
   # Check overlap
   diff = reduce(numpy.dot,(mo_coeff[0].T,ova,mo_coeff[0])) - numpy.identity(nb)
   print numpy.linalg.norm(diff)
   diff = reduce(numpy.dot,(mo_coeff[1].T,ova,mo_coeff[1])) - numpy.identity(nb)
   print numpy.linalg.norm(diff)
   # UHF-alpha/beta
   ma = mo_coeff[0]
   mb = mo_coeff[1]
   nalpha = (mol.nelectron+mol.spin)/2
   nbeta  = (mol.nelectron-mol.spin)/2
   # Spin-averaged DM
   pTa = numpy.dot(ma[:,:nalpha],ma[:,:nalpha].T)
   pTb = numpy.dot(mb[:,:nbeta],mb[:,:nbeta].T)
   pT = 0.5*(pTa+pTb)
   # Lowdin basis
   s12 = sqrtm(ova)
   s12inv = lowdin(ova)
   pTOAO = reduce(numpy.dot,(s12,pT,s12))
   eig,coeff = scipy.linalg.eigh(-pTOAO)
   eig = -2.0*eig
   eig[eig<0.0]=0.0
   eig[abs(eig)<1.e-14]=0.0
   ifplot = False #True
   if ifplot:
      import matplotlib.pyplot as plt
      plt.plot(range(nb),eig,'ro')
      plt.show()
   # Back to AO basis
   coeff = numpy.dot(s12inv,coeff)
   diff = reduce(numpy.dot,(coeff.T,ova,coeff)) - numpy.identity(nb)
   print 'CtSC-I',numpy.linalg.norm(diff)
   # 
   # Averaged Fock
   #
   enorb = mf["mo_energy"]
   fa = reduce(numpy.dot,(ma,numpy.diag(enorb[0]),ma.T))
   fb = reduce(numpy.dot,(mb,numpy.diag(enorb[1]),mb.T))
   # Non-orthogonal cases: FC=SCE
   # Fao = SC*e*C{-1} = S*C*e*Ct*S
   fav = 0.5*(fa+fb)
   # Expectation value of natural orbitals <i|F|i>
   fexpt = reduce(numpy.dot,(coeff.T,ova,fav,ova,coeff))
   enorb = numpy.diag(fexpt)
   nocc = eig.copy()
   #
   # Reordering and define active space according to thresh
   #
   idx = 0
   active=[]
   for i in range(nb):
      if nocc[i]<=2.0-thresh and nocc[i]>=thresh:
         active.append(True)
      else:
         active.append(False)
   print '\nNatural orbitals:'
   for i in range(nb):
      print 'orb:',i,active[i],nocc[i],enorb[i]
   active = numpy.array(active)
   actIndices = list(numpy.argwhere(active==True).flatten())
   cOrbs = coeff[:,:actIndices[0]]
   aOrbs = coeff[:,actIndices]
   vOrbs = coeff[:,actIndices[-1]+1:]
   nb = cOrbs.shape[0]
   nc = cOrbs.shape[1]
   na = aOrbs.shape[1]
   nv = vOrbs.shape[1]
   print 'core orbs:',cOrbs.shape
   print 'act  orbs:',aOrbs.shape
   print 'vir  orbs:',vOrbs.shape
   assert nc+na+nv == nb
   # dump UNO
   with open(fname+'_uno.molden','w') as thefile:
       molden.header(mol,thefile)
       molden.orbital_coeff(mol,thefile,coeff)
   #=====================
   # Population analysis
   #=====================
   from pyscf import lo
   aux = lo.orth_ao(mol,method='meta_lowdin')
   #clmo = ulocal.scdm(cOrbs,ova,aux)
   #almo = ulocal.scdm(aOrbs,ova,aux)
   clmo = cOrbs
   almo = aOrbs
   ierr,uc = pmloc.loc(mol,clmo)
   ierr,ua = pmloc.loc(mol,almo)
   clmo = clmo.dot(uc)
   almo = almo.dot(ua)
   vlmo = ulocal.scdm(vOrbs,ova,aux)
   # P-SORT
   mo_c,n_c,e_c = ulocal.psort(ova,fav,pT,clmo)
   mo_o,n_o,e_o = ulocal.psort(ova,fav,pT,almo)
   mo_v,n_v,e_v = ulocal.psort(ova,fav,pT,vlmo)
   lmo = numpy.hstack((mo_c,mo_o,mo_v)).copy()
   enorb = numpy.hstack([e_c,e_o,e_v])
   occ = numpy.hstack([n_c,n_o,n_v])
   # CHECK
   diff = reduce(numpy.dot,(lmo.T,ova,lmo)) - numpy.identity(nb)
   print 'diff=',numpy.linalg.norm(diff)
   ulocal.lowdinPop(mol,lmo,ova,enorb,occ)
   ulocal.dumpLMO(mol,fname,lmo)
   print 'nalpha,nbeta,mol.spin,nb:',\
          nalpha,nbeta,mol.spin,nb
   return mol,ova,fav,pT,nb,nalpha,nbeta,nc,na,nv,lmo,enorb,occ
Exemple #16
0
mol.verbose = 4
mol.spin = 0
mol.symmetry = 1
mol.charge = 0
mol.build()

mf = dft.RKS(mol).density_fit()
mf.with_df.auxbasis = 'def2-svp-jkfit'
mf.conv_tol = 1e-8
mf.grids.radi_method = dft.mura_knowles
mf.grids.becke_scheme = dft.stratmann
mf.grids.level = 4
mf.xc = 'pbe0'
mf.kernel()

c = lo.orth_ao(mol, 'nao', scf_method=mf)
mo = numpy.linalg.solve(c, mf.mo_coeff)
dm = mf.make_rdm1(mo, mf.mo_occ)

s = mol.intor('cint1e_ovlp_sph')
s = reduce(numpy.dot, (c.T, s, c))

label = mol.spheric_labels(False)

lib.logger.info(mf, '\nPopulation and charges in NAO basis')
lib.logger.info(mf, '###################################')
pop = einsum('ij,ji->i', dm, s)
chg1 = numpy.zeros(mol.natm)
qq1 = numpy.zeros(mol.natm)
for i, s1 in enumerate(label):
    chg1[s1[0]] += pop[i]
Exemple #17
0
    O 0.0 0.0 1.12
    '''
mol.verbose = 4
mol.spin = 0
mol.symmetry = 0
mol.charge = 0
mol.build()

mf = scf.RHF(mol)
mf.kernel()
dm = mf.make_rdm1()
nao = mol.nao_nr()

s = mol.intor('cint1e_ovlp_sph')
c = lo.orth.restore_ao_character(mol, 'ano')
orth_coeff = lo.orth_ao(mol, 'nao', scf_method=mf, pre_orth_ao=c, s=s)
c_inv = numpy.dot(orth_coeff.T, s)
dm = reduce(numpy.dot, (c_inv, dm, c_inv.T.conj()))
s = numpy.eye(nao)

label = mol.spheric_labels(False)

lib.logger.info(mf, '\nPopulation and charges in NAO basis')
lib.logger.info(mf, '###################################')
pop = einsum('ij,ji->i', dm, s)
chg1 = numpy.zeros(mol.natm)
qq1 = numpy.zeros(mol.natm)
for i, s1 in enumerate(label):
    chg1[s1[0]] += pop[i]
for ia in range(mol.natm):
    symb = mol.atom_symbol(ia)