Ejemplo n.º 1
0
def test_1():

    ndimer = 5
    r2 = 2 #intra bond length
    rad = 3.7  # radius of circle
    molecule,dist = form_mol(ndimer,rad,r2)


    cas_norb = 10
    cas_nel =  10
    nroots = 5

    #PYSCF inputs
    mol = gto.Mole(atom=molecule,
        symmetry = True,basis = 'sto-3g',spin=0)
    mol.build()
    print("symmertry: ",mol.topgroup)

    #SCF 
    mf = scf.RHF(mol)
    mf.verbose = 4
    mf.conv_tol = 1e-12
    mf.conv_tol_grad = 1e-9
    mf.run(max_cycle=200)


    ## Active space selection
    h,ecore,g,C = get_pi_space(mol,mf,cas_norb,cas_nel,local=True)
    molden.from_mo(mol, 'cas.molden', C)
    if 0:
        from pyscf import fci
        cisolver = fci.direct_spin1.FCI()
        efci, ci = cisolver.kernel(h, g, h.shape[1], cas_nel, ecore=ecore,nroots =nroots,verbose=100)
        #print(" FCI:        %12.8f"%(27.2114*(efci[0]-efci[1])))
        #print(" FCI:        %12.8f"%(efci))
        for i in range(nroots):
            print(" FCI:     %12.8f   %12.8f"%(efci[i],efci[i]-efci[0]))
        exit()


    mc = mulliken_ordering(mol,h.shape[0],C)
    print(mc.shape)
    idx = np.where(mc>.9)[1]  #gives index map from atom to local orbital corresponding to that orbital
    # Reorder 
    h,g = reorder_integrals(idx,h,g)
    print(h)
    C = C[:,idx] # make sure u reorder this too
    molden.from_mo(mol, 'cas.molden', C)

    blocks = [[0,1],[2,3],[4,5],[6,7],[8,9]] 
    init_fspace = ((1, 1),(1, 1),(1, 1),(1, 1),(1, 1))


    # Initialize the CMF solver. 
    oocmf = CmfSolver(h, g, ecore, blocks, init_fspace,C,max_roots=10,cs_solver=0) #cs_solver,0 for our FCI and 1 for pyscf FCI solver.
    oocmf.init() # runs a single step CMF calculation
    oocmf.optimize_orbitals()  # optimize the orbitals using gradient
    oocmf.form_extra_fspace(2)  #form excited fock space configurations

    clustered_ham = oocmf.clustered_ham  # clustered_ham used for TPSCI calculation
    ci_vector = oocmf.ci_vector   # lowest energy TPS using the reference Fock space
    h = oocmf.h
    g = oocmf.g
    C = oocmf.C



    ##
    # Excited State TPSCI for the lowest 5 roots. The guess is generated using a CIS type guess, hence there can be other CT states lower which might need different
    #    initialization
    ##

    # STEP 1: Expand the CIS space and generate roots
    ci_vector_s = ci_vector.copy()
    ci_vector_s.add_single_excitonic_states(clustered_ham.clusters)
    H = build_full_hamiltonian_parallel2(clustered_ham, ci_vector_s)
    e,v = np.linalg.eigh(H)
    idx = e.argsort()
    e = e[idx]
    v = v[:,idx]

    #STEP 2: Store the first n roots into a clustered_state and prune
    all_vecs = []
    for rn in range(nroots):
        vec = ci_vector_s.copy()
        vec.zero()
        vec.set_vector(v[:,rn])
        vec.clip(1e-5)
        print("Root:%4d     Energy:%12.8f   Gap:%12.8f  CI Dim: %4i "%(rn,e[rn].real,e[rn].real-e[0].real,len(vec)))
        #vec.print_configs()
        all_vecs.append(vec)

    #STEP 3: Combine all the vecs for each roots into 1 single ci_vector space.
    # Note the coefficients are meanning less here since its multiple states
    for vi,vec in enumerate(all_vecs):
        ci_vector.add(vec)
    ci_vector.zero()
    ci_vector.print()

    #Exta: Print excited state energies after pruning. Just to make sure we have not lost any state
    H = build_full_hamiltonian_parallel2(clustered_ham, ci_vector, nproc=None)
    e,v = np.linalg.eigh(H)
    idx = e.argsort()
    e = e[idx]
    v = v[:,idx]
    for rn in range(nroots):
        print("Root:%4d     Energy:%12.8f   Gap:%12.8f"%(rn,e[rn].real,e[rn].real-e[0].real))


    #STEP 4: Run the Excited State-TPSCI and analyze results
    time1 = time.time()
    ci_vector, pt_vector, e0, e2  = ex_tp_cipsi(ci_vector, clustered_ham,  
        thresh_cipsi    = 5e-5, 
        thresh_conv     = 1e-8, 
        max_iter        = 30, 
        n_roots         = nroots,
        thresh_asci     = 1e-2,
        nbody_limit     = 4, 
        pt_type         = 'en',
        thresh_search   = 1e-6, 
        shared_mem      = 1e8,
        batch_size      = 1,
        matvec          = 3,
        nproc           = None)
    time2 = time.time()

    for rn in range(nroots):
        print("Root:%4d     Var Energy:%12.8f   Gap:%12.8f  CI Dim: %4i "%(rn,e0[rn].real,e0[rn].real-e0[0].real,len(ci_vector)))
    for rn in range(nroots):
        print("Root:%4d     PT  Energy:%12.8f   Gap:%12.8f  CI Dim: %4i "%(rn,e2[rn],e2[rn]-e2[0],len(ci_vector)))

    print("Time spent in the Ex-TPSCI code%16.8f"%(time2-time1))

    var_val = [ 0.00000000,
                0.02359112,
                0.02397264,
                0.02397629,
                0.02459324,
                0.02459690]

    pt_val = [  0.00000000,
                0.02329525,
                0.02384732,
                0.02385319,
                0.02482514,
                0.02482831]

    for rn in range(nroots):
        assert(abs(e0[rn].real-e0[0].real - var_val[rn]) < 1e-7)
        assert(abs(e2[rn].real-e2[0].real - pt_val[rn]) < 1e-7)

    assert(len(ci_vector[0]) == 28)
def test_1():
    ###     PYSCF INPUT
    r0 = 1.40
    molecule = '''
    H      0.00       0.00       0.00
    H      1.23       0.00       0.00
    H      1.23       0.00       {0}
    H      0.00       0.00       {0}'''.format(r0)

    charge = 0
    spin = 0
    basis_set = '6-31g'

    ###     TPSCI BASIS INPUT
    orb_basis = 'lowdin'
    cas = False
    cas_nstart = 0
    cas_nstop = 8
    cas_nel = 4

    ###     TPSCI CLUSTER INPUT
    blocks = [[0, 1, 2, 3], [4, 5, 6, 7]]
    init_fspace = ((1, 1), (1, 1))

    nelec = tuple([sum(x) for x in zip(*init_fspace)])
    if cas == True:
        assert (cas_nel == sum(nelec))
        nelec = cas_nel

    # Integrals from pyscf
    #Integrals from pyscf
    pmol = PyscfHelper()
    pmol.init(molecule,
              charge,
              spin,
              basis_set,
              orb_basis,
              cas=False,
              cas_nstart=cas_nstart,
              cas_nstop=cas_nstop,
              cas_nel=cas_nel)
    #loc_nstart=loc_start,loc_nstop = loc_stop)

    C = pmol.C
    h = pmol.h
    g = pmol.g
    ecore = pmol.ecore
    print("Ecore:%16.8f" % ecore)
    mol = pmol.mol
    mf = pmol.mf
    mo_energy = mf.mo_energy[cas_nstart:cas_nstop]

    from pyscf import symm
    mo = symm.symmetrize_orb(mol, C)
    osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
    ##symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
    for i in range(len(osym)):
        print("%4d %8s %16.8f" % (i + 1, osym[i], mo_energy[i]))
        from pyscf import molden
        molden.from_mo(mol, 'h8.molden', C)

    # Initialize the CMF solver.
    n_blocks = len(blocks)
    clusters = [Cluster(ci, c) for ci, c in enumerate(blocks)]

    print(" Ecore   :%16.8f" % ecore)
    print(" Clusters:")
    [print(ci) for ci in clusters]

    clustered_ham = ClusteredOperator(clusters, core_energy=ecore)
    print(" Add 1-body terms")
    clustered_ham.add_local_terms()
    clustered_ham.add_1b_terms(h)
    print(" Add 2-body terms")
    clustered_ham.add_2b_terms(g)

    ci_vector = ClusteredState()
    ci_vector.init(clusters, init_fspace)

    Ecmf, converged, rdm_a, rdm_b = cmf(clustered_ham,
                                        ci_vector,
                                        h,
                                        g,
                                        max_iter=20)
    ecmf = Ecmf + ecore

    for ci_idx, ci in enumerate(clusters):
        ci.form_fockspace_eigbasis(h,
                                   g, [init_fspace[ci_idx]],
                                   max_roots=10,
                                   rdm1_a=rdm_a,
                                   rdm1_b=rdm_b,
                                   iprint=1)

        print(" Build new operators for cluster ", ci.idx)
        ci.build_op_matrices(iprint=0)
        ci.build_local_terms(h, g)

    emp2, pt_vector = compute_pt2_correction(ci_vector,
                                             clustered_ham,
                                             Ecmf,
                                             thresh_asci=0,
                                             thresh_search=1e-9,
                                             pt_type='mp',
                                             nbody_limit=4,
                                             matvec=1)

    e1, _ = truncated_pt2(clustered_ham, ci_vector, pt_vector, method='mp2')

    assert (abs(e1 - emp2) < 1e-12)
Ejemplo n.º 3
0
            opt_result = scipy.optimize.minimize(oocmf.energy,
                                                 x,
                                                 jac=oocmf.grad,
                                                 method='BFGS',
                                                 callback=oocmf.callback,
                                                 options=min_options)
            print(opt_result.x)
            Kpq = opt_result.x.reshape(h.shape)

            e_fcmf = oocmf.energy_dps()
            oocmf.rotate(Kpq)
            e_ocmf = oocmf.energy_dps()
            print("Orbital Optimized CMF:%12.8f" % e_ocmf)

            from pyscf import molden
            molden.from_mo(mol, 'clustering_9.hf.molden', C)
            C = oocmf.C
            molden.from_mo(mol, 'clustering_9.cmf.molden', C)

            print(Kpq)

            print("Orbital Frozen    CMF:%12.8f" % e_fcmf)
            print("Orbital Optimized CMF:%12.8f" % e_ocmf)

        h = oocmf.h
        g = oocmf.g

        clustered_ham = oocmf.clustered_ham
        ci_vector = oocmf.ci_vector

        #filename = open('hamiltonian_file_test', 'wb')
Ejemplo n.º 4
0
    do_fci = 0
    do_hci = 1
    do_tci = 0

    if do_fci:
        efci, fci_dim = run_fci_pyscf(h,g,nelec,ecore=ecore)
    if do_hci:
        ehci, hci_dim = run_hci_pyscf(h,g,nelec,ecore=ecore,select_cutoff=5e-4,ci_cutoff=5e-4)

    #cluster using hcore
    idx = e1_order(h,cut_off = 1e-2)
    h,g = reorder_integrals(idx,h,g)
    C = C[:,idx]
    from pyscf import molden
    molden.from_mo(pmol.mol, 'h8.molden', C)
    print(h)
    if do_tci:
        #ci_vector, pt_vector, etci, etci2 = run_tpsci(h,g,blocks,init_fspace,ecore=ecore,
        #    thresh_ci_clip=1e-3,thresh_cipsi=1e-6,max_tucker_iter=20,max_cipsi_iter=20)
        #ci_vector.print_configs()
        #tci_dim = len(ci_vector)
        n_blocks = len(blocks)

        clusters = []

        for ci,c in enumerate(blocks):
            clusters.append(Cluster(ci,c))

        ci_vector = ClusteredState(clusters)
        ci_vector.init(init_fspace)
Ejemplo n.º 5
0
    idx_h0_2s = mol.search_ao_label ('0 H 2s')[0]
    idx_h1_2s = mol.search_ao_label ('1 H 2s')[0]
    dma = np.zeros ((nao, nao))
    dmb = np.zeros ((nao, nao))
    dma[idx_h0_1s,idx_h0_1s] = dmb[idx_h1_1s,idx_h1_1s] = dma[idx_h0_2s,idx_h0_2s] = dmb[idx_h1_2s,idx_h1_2s] = 1
dm0 = [dma, dmb]

# Restricted mean-field base of MC-SCF objects
mf = scf.RHF (mol).run ()

# MC-PDFT objects
if gsbasis:
    gsmo = np.load (gsmofile)
    mc = mcpdft.CASSCF (mf, transl_type + fnal, ncas, nelecas, grids_level = 3)
    mo = mcscf.project_init_guess (mc, gsmo, prev_mol=gsmol)
    molden.from_mo (mol, 'check_projection.molden', mo)
    mc.kernel (mo)
    mc = mc.as_scanner ()
else:  
    mc = mcpdft.CASSCF (mf, transl_type + fnal, ncas, nelecas, grids_level = 3).run ().as_scanner ()
np.save (mofile, mc.mo_coeff)

# Do MCSCF scan forwards
table = np.zeros ((HHrange.size, 9))
table[:,0] = HHrange
for ix, HHdist in enumerate (HHrange):
    geom = 'H 0 0 0; H 0 0 {:.6f}'.format (HHdist)
    table[ix,1] = mc (geom)
    table[ix,2] = mc.e_mcscf
    table[ix,3:] = list (mc.get_energy_decomposition ())
Ejemplo n.º 6
0
    def init(self,molecule,charge,spin,basis_set,orb_basis='scf',cas=False,cas_nstart=None,cas_nstop=None,cas_nel=None,loc_nstart=None,loc_nstop=None,
            scf_conv_tol=1e-14):
    # {{{
        import pyscf
        from pyscf import gto, scf, ao2mo, molden, lo
        pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
        #PYSCF inputs
        print(" ---------------------------------------------------------")
        print("                      Using Pyscf:")
        print(" ---------------------------------------------------------")
        print("                                                          ")

        mol = gto.Mole()
        mol.atom = molecule

        mol.max_memory = 1000 # MB
        mol.symmetry = True
        mol.charge = charge
        mol.spin = spin
        mol.basis = basis_set
        mol.build()
        print("symmertry")
        print(mol.topgroup)

        #SCF 

        #mf = scf.RHF(mol).run(init_guess='atom')
        mf = scf.RHF(mol).run(conv_tol=scf_conv_tol)
        #C = mf.mo_coeff #MO coeffs
        enu = mf.energy_nuc()
        
        print(" SCF Total energy: %12.8f" %mf.e_tot) 
        print(" SCF Elec  energy: %12.8f" %(mf.e_tot-enu))
        print(mf.get_fock())
        print(np.linalg.eig(mf.get_fock())[0])
        
        if mol.symmetry == True:
            from pyscf import symm
            mo = symm.symmetrize_orb(mol, mf.mo_coeff)
            osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
            #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
            for i in range(len(osym)):
                print("%4d %8s %16.8f"%(i+1,osym[i],mf.mo_energy[i]))

        #orbitals and lectrons
        n_orb = mol.nao_nr()
        n_b , n_a = mol.nelec 
        nel = n_a + n_b
        self.n_orb = mol.nao_nr()


        if cas == True:
            cas_norb = cas_nstop - cas_nstart
            from pyscf import mcscf
            assert(cas_nstart != None)
            assert(cas_nstop != None)
            assert(cas_nel != None)
        else:
            cas_nstart = 0
            cas_nstop = n_orb
            cas_nel = nel

        ##AO 2 MO Transformation: orb_basis or scf
        if orb_basis == 'scf':
            print("\nUsing Canonical Hartree Fock orbitals...\n")
            C = cp.deepcopy(mf.mo_coeff)
            print("C shape")
            print(C.shape)

        elif orb_basis == 'lowdin':
            assert(cas == False)
            S = mol.intor('int1e_ovlp_sph')
            print("Using lowdin orthogonalized orbitals")

            C = lowdin(S)
            #end

        elif orb_basis == 'boys':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.Boys(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'boys2':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.Boys(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'PM':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.PM(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'PM2':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.PM(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ER':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :cas_nstart]
            cl_a = lo.PM(mol, mf.mo_coeff[:, cas_nstart:cas_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, cas_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ER2':
            pyscf.lib.num_threads(1)  #with degenerate states and multiple processors there can be issues
            cl_c = mf.mo_coeff[:, :loc_nstart]
            cl_a = lo.ER(mol, mf.mo_coeff[:, loc_nstart:loc_nstop]).kernel(verbose=4)
            cl_v = mf.mo_coeff[:, loc_nstop:]
            C = np.column_stack((cl_c, cl_a, cl_v))

        elif orb_basis == 'ibmo':
            loc_vstop =  loc_nstop - n_a
            print(loc_vstop)

            mo_occ = mf.mo_coeff[:,mf.mo_occ>0]
            mo_vir = mf.mo_coeff[:,mf.mo_occ==0]
            c_core = mo_occ[:,:loc_nstart]
            iao_occ = lo.iao.iao(mol, mo_occ[:,loc_nstart:])
            iao_vir = lo.iao.iao(mol, mo_vir[:,:loc_vstop])
            c_out  = mo_vir[:,loc_vstop:]

            # Orthogonalize IAO
            iao_occ = lo.vec_lowdin(iao_occ, mf.get_ovlp())
            iao_vir = lo.vec_lowdin(iao_vir, mf.get_ovlp())

            #
            # Method 1, using Knizia's alogrithm to localize IAO orbitals
            #
            '''
            Generate IBOS from orthogonal IAOs
            '''
            ibo_occ = lo.ibo.ibo(mol, mo_occ[:,loc_nstart:], iaos = iao_occ)
            ibo_vir = lo.ibo.ibo(mol, mo_vir[:,:loc_vstop], iaos = iao_vir)

            C = np.column_stack((c_core,ibo_occ,ibo_vir,c_out))

        else: 
            print("Error:NO orbital basis defined")

        molden.from_mo(mol, 'orbitals.molden', C)

        if cas == True:
            print(C.shape)
            print(cas_norb)
            print(cas_nel)
            mycas = mcscf.CASSCF(mf, cas_norb, cas_nel)
            h1e_cas, ecore = mycas.get_h1eff(mo_coeff = C)  #core core orbs to form ecore and eff
            h2e_cas = ao2mo.kernel(mol, C[:,cas_nstart:cas_nstop], aosym='s4',compact=False).reshape(4 * ((cas_norb), )) 
            print(h1e_cas)
            print(h1e_cas.shape)
            #return h1e_cas,h2e_cas,ecore,C,mol,mf
            self.h = h1e_cas
            self.g = h2e_cas
            self.ecore = ecore
            self.mf = mf
            self.mol = mol
            self.C = cp.deepcopy(C[:,cas_nstart:cas_nstop])
            J,K = mf.get_jk()
            self.J = self.C.T @ J @ self.C
            self.K = self.C.T @ J @ self.C

            #HF density
            if orb_basis == 'scf':
                #C = C[:,cas_nstart:cas_nstop]
                D = mf.make_rdm1(mo_coeff=C)
                S = mf.get_ovlp()
                sal, svec = np.linalg.eigh(S)
                idx = sal.argsort()[::-1]
                sal = sal[idx]
                svec = svec[:, idx]
                sal = sal**-0.5
                sal = np.diagflat(sal)
                X = svec @ sal @ svec.T
                C_ao2mo = np.linalg.inv(X) @ C
                Cocc = C_ao2mo[:, :n_a]
                D = Cocc @ Cocc.T
                DMO = C_ao2mo.T   @ D @ C_ao2mo
                
                #only for cas space 
                DMO = DMO[cas_nstart:cas_nstop,cas_nstart:cas_nstop]
                self.dm_aa = DMO
                self.dm_bb = DMO
                print("DENSITY")
                print(self.dm_aa.shape)

            if 0:
                h = C.T.dot(mf.get_hcore()).dot(C)
                g = ao2mo.kernel(mol,C,aosym='s4',compact=False).reshape(4*((n_orb),))
                const,heff = get_eff_for_casci(cas_nstart,cas_nstop,h,g)
                print(heff)
                print("const",const)
                print("ecore",ecore)
                
                idx = range(cas_nstart,cas_nstop)
                h = h[:,idx] 
                h = h[idx,:] 
                g = g[:,:,:,idx] 
                g = g[:,:,idx,:] 
                g = g[:,idx,:,:] 
                g = g[idx,:,:,:] 

                self.ecore = const
                self.h = h + heff
                self.g = g 


        elif cas==False:
            h = C.T.dot(mf.get_hcore()).dot(C)
            g = ao2mo.kernel(mol,C,aosym='s4',compact=False).reshape(4*((n_orb),))
            print(h)
            #return h, g, enu, C,mol,mf
            self.h = h
            self.g = g
            self.ecore = enu
            self.mf = mf
            self.mol = mol
            self.C = C
            J,K = mf.get_jk()
            self.J = self.C.T @ J @ self.C
            self.K = self.C.T @ J @ self.C

            #HF density
            if orb_basis == 'scf':
                D = mf.make_rdm1(mo_coeff=None)
                S = mf.get_ovlp()
                sal, svec = np.linalg.eigh(S)
                idx = sal.argsort()[::-1]
                sal = sal[idx]
                svec = svec[:, idx]
                sal = sal**-0.5
                sal = np.diagflat(sal)
                X = svec @ sal @ svec.T
                C_ao2mo = np.linalg.inv(X) @ C
                Cocc = C_ao2mo[:, :n_a]
                D = Cocc @ Cocc.T
                DMO = C_ao2mo.T   @ D @ C_ao2mo
                self.dm_aa = DMO
                self.dm_bb = DMO
                print("DENSITY")
                print(self.dm_aa)
Ejemplo n.º 7
0
h = C.T.dot(mf.get_hcore()).dot(C)
g = ao2mo.kernel(mol,C,aosym='s4',compact=False).reshape(4*((h.shape[0]),))
const,eff = get_eff_for_casci(focc_list,cas_list,h,g)


focc_list = list(set(mo_occ)-set(cas_list))
print(focc_list)
fvir_list = list(set(mo_vir)-set(cas_list))
print(fvir_list)

ecore = enu + const
h,g = reorder_integrals(cas_list,h,g)
h = h + eff
C = C[:,cas_list]
molden.from_mo(mol, 'h8.molden', C)

print("ecore %16.8f"%ecore)


if local:
    idx  = np.argsort(np.diag(h))
    print(idx)
    h,g = reorder_integrals(idx,h,g)
    C = C[:,idx]
    print(h)
    molden.from_mo(mol, 'h8.molden', C)
    idx = e1_order(h,1e-1)
    h,g = reorder_integrals(idx,h,g)
    print(h)
    C = C[:,idx]
Ejemplo n.º 8
0
def init_pyscf(molecule, charge, spin, basis, orbitals):
    # {{{
    #PYSCF inputs
    print(" ---------------------------------------------------------")
    print("                                                          ")
    print("                      Using Pyscf:")
    print("                                                          ")
    print(" ---------------------------------------------------------")
    print("                                                          ")
    mol = gto.Mole()
    mol.atom = molecule

    # this is needed to prevent openblas - openmp clash for some reason
    # todo: take out
    lib.num_threads(1)

    mol.max_memory = 1000  # MB
    mol.charge = charge
    mol.spin = spin
    mol.basis = basis
    mol.build()

    #orbitals and electrons
    n_orb = mol.nao_nr()
    n_b, n_a = mol.nelec
    nel = n_a + n_b

    #SCF
    mf = scf.RHF(mol).run()
    #mf = scf.ROHF(mol).run()
    C = mf.mo_coeff  #MO coeffs
    S = mf.get_ovlp()

    print(" Orbs1:")
    print(C)
    Cl = cp.deepcopy(C)
    if orbitals == "boys":
        print("\nUsing Boys localised orbitals:\n")
        cl_o = lo.Boys(mol, mf.mo_coeff[:, :n_a]).kernel(verbose=4)
        cl_v = lo.Boys(mol, mf.mo_coeff[:, n_a:]).kernel(verbose=4)
        Cl = np.column_stack((cl_o, cl_v))

    elif orbitals == "pipek":
        print("\nUsing Pipek-Mezey localised orbitals:\n")
        cl_o = lo.PM(mol, mf.mo_coeff[:, :n_a]).kernel(verbose=4)
        cl_v = lo.PM(mol, mf.mo_coeff[:, n_a:]).kernel(verbose=4)
        Cl = np.column_stack((cl_o, cl_v))
    elif orbitals == "edmiston":
        print("\nUsing Edmiston-Ruedenberg localised orbitals:\n")
        cl_o = lo.ER(mol, mf.mo_coeff[:, :n_a]).kernel(verbose=4)
        cl_v = lo.ER(mol, mf.mo_coeff[:, n_a:]).kernel(verbose=4)
        Cl = np.column_stack((cl_o, cl_v))
#    elif orbitals == "svd":
#        print("\nUsing SVD localised orbitals:\n")
#        cl_o = cp.deepcopy(mf.mo_coeff[:,:n_a])
#        cl_v = cp.deepcopy(mf.mo_coeff[:,n_a:])
#
#        [U,s,V] = np.linalg.svd(cl_o)
#        cl_o = cl_o.dot(V.T)
#        Cl = np.column_stack((cl_o,cl_v))
    elif orbitals == "canonical":
        print("\nUsing Canonical orbitals:\n")
        pass
    else:
        print("Error: Wrong orbital specification:")
        exit()

    print(" Overlap:")
    print(C.T.dot(S).dot(Cl))

    # sort by cluster
    blocks = [[0, 1, 2, 3], [4, 5, 6, 7]]
    O = Cl[:, :n_a]
    V = Cl[:, n_a:]
    [sorted_order, cluster_sizes] = mulliken_clustering(blocks, mol, O)
    O = O[:, sorted_order]
    [sorted_order, cluster_sizes] = mulliken_clustering(blocks, mol, V)
    V = V[:, sorted_order]
    Cl = np.column_stack((O, V))

    C = cp.deepcopy(Cl)
    # dump orbitals for viewing
    molden.from_mo(mol, 'orbitals_canon.molden', C)
    molden.from_mo(mol, 'orbitals_local.molden', Cl)

    ##READING INTEGRALS FROM PYSCF
    E_nu = gto.Mole.energy_nuc(mol)
    T = mol.intor('int1e_kin_sph')
    V = mol.intor('int1e_nuc_sph')
    hcore = T + V
    S = mol.intor('int1e_ovlp_sph')
    g = mol.intor('int2e_sph')

    print("\nSystem and Method:")
    print(mol.atom)

    print("Basis set                                      :%12s" % (mol.basis))
    print("Number of Orbitals                             :%10i" % (n_orb))
    print("Number of electrons                            :%10i" % (nel))
    print("Nuclear Repulsion                              :%16.10f " % E_nu)
    print("Electronic SCF energy                          :%16.10f " %
          (mf.e_tot - E_nu))
    print("SCF Energy                                     :%16.10f" %
          (mf.e_tot))

    print(" AO->MO")
    g = np.einsum("pqrs,pl->lqrs", g, C)
    g = np.einsum("lqrs,qm->lmrs", g, C)
    g = np.einsum("lmrs,rn->lmns", g, C)
    g = np.einsum("lmns,so->lmno", g, C)

    h = reduce(np.dot, (C.conj().T, hcore, C))

    #    #mf = mf.density_fit(auxbasis='weigend')
    #    #mf._eri = None
    #    mcc = cc.UCCSD(mf)
    #    eris = mcc.ao2mo()
    #    eris.g = g
    #    eris.focka = h
    #    eris.fockb = h
    #
    #    emp2, t1, t2 = mcc.init_amps(eris)
    #    exit()
    #    print(abs(t2).sum() - 4.9318753386922278)
    #    print(emp2 - -0.20401737899811551)
    #    t1, t2 = update_amps(mcc, t1, t2, eris)
    #    print(abs(t1).sum() - 0.046961325647584914)
    #    print(abs(t2).sum() - 5.378260578551683   )
    #
    #
    #    exit()

    return (n_orb, n_a, n_b, h, g, mol, E_nu, mf.e_tot, C, S)
Ejemplo n.º 9
0
def test_1():
    molecule = '''
    C  -4.308669   0.197146   0.000000
    C  -1.839087   0.279751   0.000000
    C  -3.110874  -0.411353   0.000000
    C  -0.634371  -0.341144   0.000000
    C   0.634371   0.341144   0.000000
    C   1.839087  -0.279751   0.000000
    C   3.110874   0.411353   0.000000
    C   4.308669  -0.197146   0.000000
    H  -4.394907   1.280613   0.000000
    H   4.394907  -1.280613   0.000000
    H  -5.234940  -0.367304   0.000000
    H   5.234940   0.367304   0.000000
    H  -3.069439  -1.500574   0.000000
    H   3.069439   1.500574   0.000000
    H  -1.871161   1.369551   0.000000
    H   1.871161  -1.369551   0.000000
    H  -0.607249  -1.431263   0.000000
    H   0.607249   1.431263   0.000000
    '''

    cas_nel = 8
    cas_norb = 8

    local = True
    blocks = [range(0, 2), range(2, 6),
              range(6, 8)]  # 3 clusters with 2,4,2 orbitals each
    blocks = [[0, 5], [2, 3, 4, 6], [1,
                                     7]]  # 3 clusters with 2,4,2 orbitals each
    init_fspace = (
        (1, 1), (2, 2), (1, 1)
    )  # Cluster1: (alpha,beta) Cluster2:(alpha,beta) Cluster3:(alpha,beta)

    #PYSCF inputs
    mol = gto.Mole(atom=molecule, symmetry=True, basis='sto-3g')
    mol.build()
    print("symmertry: ", mol.topgroup)

    #SCF
    mf = scf.RHF(mol)
    mf.verbose = 4
    mf.conv_tol = 1e-12
    mf.conv_tol_grad = 1e-9
    mf.run(max_cycle=200)

    ## Active space selection

    h, ecore, g, C = get_pi_space(mol, mf, cas_norb, cas_nel, local=True)

    #h, g = make_stack_lattice(3,4,1,0.6,2,pbc = True)

    #blocks = [range(4),range(4,8),range(8,12)]
    #init_fspace = ((2,2),(2,2),(2,2))
    #nelec = tuple([sum(x) for x in zip(*init_fspace)])

    #C = np.eye(h.shape[0])

    do_fci = 1
    if do_fci:
        # Run a CAS-CI calculation for comparison
        from pyscf import fci
        cisolver = fci.direct_spin1.FCI()
        ecas, vcas = cisolver.kernel(h,
                                     g,
                                     cas_norb,
                                     nelec=cas_nel,
                                     ecore=ecore,
                                     nroots=1,
                                     verbose=100)
        print("CAS-CI:%10.8f" % (ecas))
        print(" CASCI           %12.8f      Dim:%6d" %
              (ecas, vcas.shape[0] * vcas.shape[1]))
        print(ecore)

    if local:
        ## TPSCI
        mc = mulliken_ordering(mol, h.shape[0], C)
        idx = np.where(
            mc > .9
        )[1]  #gives index map from atom to local orbital corresponding to that orbital

        # Reorder
        h, g = reorder_integrals(idx, h, g)
        print(h)
        C = C[:, idx]  # make sure u reorder this too
        molden.from_mo(mol, 'cas.molden', C)

    n_blocks = len(blocks)
    clusters = [Cluster(ci, c) for ci, c in enumerate(blocks)]

    print(" Ecore   :%16.8f" % ecore)
    print(" Clusters:")
    [print(ci) for ci in clusters]

    clustered_ham = ClusteredOperator(clusters, core_energy=ecore)
    print(" Add 1-body terms")
    clustered_ham.add_local_terms()
    clustered_ham.add_1b_terms(h)
    print(" Add 2-body terms")
    clustered_ham.add_2b_terms(g)

    ci_vector = ClusteredState()
    ci_vector.init(clusters, init_fspace)

    e_curr, converged, rdm_a, rdm_b = cmf(clustered_ham,
                                          ci_vector,
                                          h,
                                          g,
                                          max_iter=20)

    # build cluster basis and operator matrices using CMF optimized density matrices
    for ci_idx, ci in enumerate(clusters):
        fspaces_i = ci.possible_fockspaces()

        print()
        print(" Form basis by diagonalizing local Hamiltonian for cluster: ",
              ci_idx)
        ci.form_fockspace_eigbasis(h,
                                   g,
                                   fspaces_i,
                                   max_roots=50,
                                   rdm1_a=rdm_a,
                                   rdm1_b=rdm_b,
                                   ecore=ecore)

        print(" Build operator matrices for cluster ", ci.idx)
        ci.build_op_matrices(iprint=1)
        ci.build_local_terms(h, g)

    opdm_a, opdm_b, tpdm_aa, tpdm_ab, tpdm_ba, tpdm_bb = build_12rdms_cmf(
        ci_vector, clusters)

    ## Compare energy using density to reference energy

    #compute energy
    opdm = opdm_a + opdm_b
    tpdm = tpdm_aa + tpdm_ab + tpdm_ba + tpdm_bb
    E = np.einsum('pq,pq', h, opdm)
    E += 0.5 * np.einsum('tvuw,tuwv', g, tpdm)

    #reference energy
    e_ref = float(build_hamiltonian_diagonal(clustered_ham, ci_vector))

    ## Compare gradient using matvec to density

    #Generalized Fock
    Gf = np.einsum('pr,rq->pq', h, opdm) + np.einsum('pvuw,quwv->pq', g, tpdm)
    #Gradient
    Wpq = Gf - Gf.T

    #gradient using matvec (expensive)
    h1_vector = matvec.matvec1(clustered_ham,
                               ci_vector,
                               thresh_search=0,
                               nbody_limit=3)
    rdm_a1, rdm_b1 = build_tdm(ci_vector, h1_vector, clustered_ham)
    rdm_a2, rdm_b2 = build_tdm(h1_vector, ci_vector, clustered_ham)
    Gpq = rdm_a1 + rdm_b1 - rdm_a2 - rdm_b2

    assert (abs(E - e_ref) < 1e-8)
    assert (np.allclose(Gpq, Wpq))
Ejemplo n.º 10
0
def init(molecule,
         charge,
         spin,
         basis,
         n_frzn_occ=0,
         n_act=None,
         mo_order=None):
    # {{{
    #PYSCF inputs
    print(" ---------------------------------------------------------")
    print("                                                          ")
    print("                      Using Pyscf:")
    print("                                                          ")
    print(" ---------------------------------------------------------")
    print("                                                          ")
    mol = gto.Mole()
    mol.atom = molecule

    # this is needed to prevent openblas - openmp clash for some reason
    # todo: take out
    lib.num_threads(1)

    mol.max_memory = 1000  # MB
    mol.charge = charge
    mol.spin = spin
    mol.basis = basis
    mol.build()

    #orbitals and electrons
    n_orb = mol.nao_nr()
    n_b, n_a = mol.nelec
    nel = n_a + n_b

    if n_act == None:
        n_act = n_orb
    #SCF
    mf = scf.RHF(mol).run()
    #mf = scf.ROHF(mol).run()

    if mo_order != None:
        print(len(mo_order), mf.mo_coeff.shape[1])
        assert (len(mo_order) == mf.mo_coeff.shape[1])
        mf.mo_coeff = mf.mo_coeff[:, mo_order]

    C = mf.mo_coeff  #MO coeffs
    S = mf.get_ovlp()

    # dump orbitals for viewing
    molden.from_mo(mol, 'orbitals_canon.molden', C)

    ##READING INTEGRALS FROM PYSCF
    E_nuc = gto.Mole.energy_nuc(mol)
    T = mol.intor('int1e_kin_sph')
    V = mol.intor('int1e_nuc_sph')
    hcore = T + V
    S = mol.intor('int1e_ovlp_sph')
    g = mol.intor('int2e_sph')

    print("\nSystem and Method:")
    print(mol.atom)

    print("Basis set                                      :%12s" % (mol.basis))
    print("Number of Orbitals                             :%10i" % (n_orb))
    print("Number of electrons                            :%10i" % (nel))
    print("Nuclear Repulsion                              :%16.10f " % E_nuc)
    print("Electronic SCF energy                          :%16.10f " %
          (mf.e_tot - E_nuc))
    print("SCF Energy                                     :%16.10f" %
          (mf.e_tot))

    print(" AO->MO")
    g = np.einsum("pqrs,pl->lqrs", g, C)
    g = np.einsum("lqrs,qm->lmrs", g, C)
    g = np.einsum("lmrs,rn->lmns", g, C)
    g = np.einsum("lmns,so->lmno", g, C)

    assert (n_frzn_occ <= n_b)
    n_frzn_vir = n_orb - n_act - n_frzn_occ
    assert (n_frzn_vir >= 0)

    n_a -= n_frzn_occ
    n_b -= n_frzn_occ
    n_orb -= n_frzn_occ

    print(" NElectrons: %4i %4i" % (n_a, n_b))
    Cact = C[:, n_frzn_occ:n_frzn_occ + n_act]
    Cocc = C[:, 0:n_frzn_occ]

    dm = Cocc @ Cocc.T
    j, k = scf.hf.get_jk(mol, dm)

    t = hcore + 2 * j - k
    h = reduce(np.dot, (Cact.conj().T, hcore + 2 * j - k, Cact))
    ecore = np.trace(2 * dm @ (hcore + j - .5 * k))
    print(" ecore: %12.8f" % ecore)

    E_nuc += ecore

    def view(h5file, dataname='eri_mo'):
        f5 = h5py.File(h5file)
        print('dataset %s, shape %s' %
              (str(f5.keys()), str(f5[dataname].shape)))
        f5.close()

    eri_act = ao2mo.outcore.general_iofree(mol, (Cact, Cact, Cact, Cact),
                                           intor='int2e',
                                           aosym='s4',
                                           compact=True)
    #view('ints_occ.h5')
    #view('ints_act.h5')
    eri_act = ao2mo.restore('s1', eri_act, Cact.shape[1])
    print(" ERIs in the active-space:")
    print(eri_act.shape, " %12.8f Mb" % (eri_act.nbytes * 1e-6))

    if False:
        #compute slater determinant energy
        e1 = 0
        e2 = 0
        config_a = range(n_a)
        config_b = range(n_b)
        print(config_a, config_b)
        for i in config_a:
            e1 += h[i, i]
        for i in config_b:
            e1 += h[i, i]
        for i in config_a:
            for j in config_a:
                if i >= j:
                    continue
                e2 += eri_act[i, i, j, j]
                e2 -= eri_act[i, j, j, i]
        for i in config_b:
            for j in config_b:
                if i >= j:
                    continue
                e2 += eri_act[i, i, j, j]
                e2 -= eri_act[i, j, j, i]
        for i in config_a:
            for j in config_b:
                e2 += eri_act[i, i, j, j]
        e = e1 + e2
        print("*HF Energy: %12.8f" % (e + E_nuc))

    fci = 0
    #pyscf FCI
    if fci:
        print()
        print(" ----------------------")
        print(" PYSCF")
        mc = mcscf.CASCI(mf, n_act, (n_a, n_b), ncore=n_frzn_occ)
        #mc.fcisolver = pyscf.fci.solver(mf, singlet=True)
        #mc.fcisolver = pyscf.fci.direct_spin1.FCISolver(mol)
        efci, ci = mc.kernel()
        print(" PYSCF: FCI energy: %12.8f" % (efci))
        print()

    Cact = C[:, n_frzn_occ:n_frzn_occ + n_act]
    return (n_act, n_a, n_b, h, eri_act, mol, E_nuc, mf.e_tot, Cact, S)
Ejemplo n.º 11
0
# Reorder the orbitals for TPSCI. (optional, if u know exact cluster u are looking for)
# U can use mulliken order to reorder ur orbitals in same order as the C atoms.
# For this example, we can just use the simpler reordering since its a 1D system

#mc = mulliken_ordering(mol,h.shape[0],C)
#idx = np.where(mc>.9)[1]  #gives index map from atom to local orbital corresponding to that orbital
idx = e1_order(
    h, 1e-1
)  #this function works for 1d systems only. its better to know the atom ordering of the atoms

# Reorder
h, g = reorder_integrals(idx, h, g)
print(h)
C = C[:, idx]  # make sure u reorder this too
molden.from_mo(mol, 'cas.molden', C)

# define the orbital blocks and the fock space you wish to initialize.
blocks = [range(0, 2), range(2, 6),
          range(6, 8)]  # 3 clusters with 2,4,2 orbitals each
init_fspace = (
    (1, 1), (2, 2), (1, 1)
)  # Cluster1: (alpha,beta) Cluster2:(alpha,beta) Cluster3:(alpha,beta)

# Initialize the CMF solver.
oocmf = CmfSolver(h, g, ecore, blocks, init_fspace, C, max_roots=100)
oocmf.init()  # runs a single step CMF calculation

clustered_ham = oocmf.clustered_ham  # clustered_ham used for TPSCI calculation
ci_vector = oocmf.ci_vector  # lowest energy TPS using the given Fock space
Ejemplo n.º 12
0
def run():
    ###     PYSCF INPUT
    r0 = 1.50
    molecule = '''
    Cr
    Cr   1   {}
    '''.format(r0)
    charge = 0
    spin = 0
    basis_set = 'def2-svp'

    ###     TPSCI BASIS INPUT
    orb_basis = 'scf'
    cas = True
    cas_nstart = 12
    cas_nstop = 42
    loc_start = 1
    loc_stop = 6
    cas_nel = 24

    def ordering_diatomics_cr(mol, C):
        # {{{
        ##DZ basis diatomics reordering with frozen 1s

        orb_type = ['s', 'pz', 'dz', 'px', 'dxz', 'py', 'dyz', 'dx2-y2', 'dxy']
        ref = np.zeros(C.shape[1])

        ## Find dimension of each space
        dim_orb = []
        for orb in orb_type:
            print("Orb type", orb)
            idx = 0
            for label in mol.ao_labels():
                if orb in label:
                    #print(label)
                    idx += 1

            ##frozen 1s orbitals
            if orb == 's':
                idx -= 6
            elif orb == 'px':
                idx -= 2
            elif orb == 'py':
                idx -= 2
            elif orb == 'pz':
                idx -= 2
            dim_orb.append(idx)
            print(idx)

        new_idx = []
        ## Find orbitals corresponding to each orb space
        for i, orb in enumerate(orb_type):
            print("Orbital type:", orb)
            from pyscf import mo_mapping
            s_pop = mo_mapping.mo_comps(orb, mol, C)
            print(s_pop)
            ref += s_pop
            cas_list = s_pop.argsort()[-dim_orb[i]:]
            print('cas_list', np.array(cas_list))
            new_idx.extend(cas_list)
            #print(orb,' population for active space orbitals', s_pop[cas_list])

        ao_labels = mol.ao_labels()
        #idx = mol.search_ao_label(['N.*s'])
        #for i in idx:
        #    print(i, ao_labels[i])
        print(ref)
        print(new_idx)
        for label in mol.ao_labels():
            print(label)

        return new_idx

    # }}}

    # basis is SVP read comments by alex thom paper DOI:10.1021/acs.jctc.9b01023
    from pyscf import gto
    basis_set = {
        'Cr':
        gto.parse('''
    BASIS "ao basis" PRINT
    #BASIS SET: (14s,8p,5d) -> [5s,2p,2d]
    Cr    S
      51528.086349               0.14405823106E-02
       7737.2103487              0.11036202287E-01
       1760.3748470              0.54676651806E-01
        496.87706544             0.18965038103
        161.46520598             0.38295412850
         55.466352268            0.29090050668
    Cr    S
        107.54732999            -0.10932281100
         12.408671897            0.64472599471
          5.0423628826           0.46262712560
    Cr    S
          8.5461640165          -0.22711013286
          1.3900441221           0.73301527591
          0.56066602876          0.44225565433
    Cr    S
          0.71483705972E-01      1.0000000000
    Cr    S
          0.28250687604E-01      1.0000000000
    Cr    P
        640.48536096             0.96126715203E-02
        150.69711194             0.70889834655E-01
         47.503755296            0.27065258990
         16.934120165            0.52437343414
          6.2409680590           0.34107994714
    Cr    P
          3.0885463206           0.33973986903
          1.1791047769           0.57272062927
          0.43369774432          0.24582728206
    Cr    D
         27.559479426            0.30612488044E-01
          7.4687020327           0.15593270944
          2.4345903574           0.36984421276
          0.78244754808          0.47071118077
    Cr    D
          0.21995774311          0.33941649889
    END''')
    }

    ###     TPSCI CLUSTER INPUT
    init_fspace = ((1, 1), (3, 3), (3, 3), (3, 3), (1, 1), (1, 1))
    blocks = [
        range(0, 4),
        range(4, 10),
        range(10, 16),
        range(16, 22),
        range(22, 26),
        range(26, 30)
    ]

    # Integrals from pyscf
    #Integrals from pyscf
    pmol = PyscfHelper()
    pmol.init(molecule,
              charge,
              spin,
              basis_set,
              orb_basis,
              cas_nstart=cas_nstart,
              cas_nstop=cas_nstop,
              cas_nel=cas_nel,
              cas=True,
              loc_nstart=loc_start,
              loc_nstop=loc_stop)

    h = pmol.h
    g = pmol.g
    ecore = pmol.ecore
    print("Ecore:%16.8f" % ecore)
    C = pmol.C
    K = pmol.K
    mol = pmol.mol
    mo_energy = pmol.mf.mo_energy
    dm_aa = pmol.dm_aa
    dm_bb = pmol.dm_bb

    do_tci = 1

    #cluster using hcore

    idx = ordering_diatomics_cr(mol, C)
    h, g = reorder_integrals(idx, h, g)
    C = C[:, idx]
    mo_energy = mo_energy[idx]
    dm_aa = dm_aa[:, idx]
    dm_aa = dm_aa[idx, :]
    dm_bb = dm_bb[:, idx]
    dm_bb = dm_bb[idx, :]

    print(dm_aa)

    from pyscf import molden
    molden.from_mo(pmol.mol, 'h8.molden', C)
    print(h)
    mol = pmol.mol
    if mol.symmetry == True:
        from pyscf import symm
        mo = symm.symmetrize_orb(mol, C)
        osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
        #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
        for i in range(len(osym)):
            print("%4d %8s %16.8f" % (i + 1, osym[i], mo_energy[i]))

    clusters, clustered_ham, ci_vector = system_setup(h,
                                                      g,
                                                      ecore,
                                                      blocks,
                                                      init_fspace,
                                                      cmf_maxiter=20,
                                                      cmf_dm_guess=(dm_aa,
                                                                    dm_bb),
                                                      cmf_diis=True,
                                                      max_roots=100,
                                                      delta_elec=3)

    ndata = 0
    for ci in clusters:
        for o in ci.ops:
            for f in ci.ops[o]:
                ndata += ci.ops[o][f].size * ci.ops[o][f].itemsize
    print(" Amount of data stored in TDMs: %12.2f Gb" % (ndata * 1e-9))

    init_fspace = ((1, 1), (3, 3), (3, 3), (3, 3), (1, 1), (1, 1))

    ci_vector, pt_vector, etci, etci2, t_conv = bc_cipsi_tucker(
        ci_vector.copy(),
        clustered_ham,
        pt_type='mp',
        thresh_cipsi=1e-3,
        thresh_ci_clip=1e-6,
        max_tucker_iter=4,
        nbody_limit=4,
        thresh_search=1e-3,
        thresh_asci=1e-2,
        tucker_state_clip=100,  #don't use any pt for tucker 
        tucker_conv_target=0,  #converge variational energy
        nproc=None)

    ci_vector, pt_vector, etci, etci2, t_conv = bc_cipsi_tucker(
        ci_vector.copy(),
        clustered_ham,
        pt_type='mp',
        thresh_cipsi=1e-5,
        thresh_ci_clip=1e-7,
        max_tucker_iter=2,
        nbody_limit=4,
        thresh_search=1e-4,
        thresh_asci=1e-2,
        tucker_state_clip=100,  #don't use any pt for tucker 
        tucker_conv_target=0,  #converge variational energy
        nproc=None)

    ci_vector, pt_vector, etci, etci2, t_conv = bc_cipsi_tucker(
        ci_vector.copy(),
        clustered_ham,
        pt_type='mp',
        thresh_cipsi=1e-6,
        thresh_ci_clip=1e-8,
        max_tucker_iter=2,
        nbody_limit=4,
        thresh_search=1e-4,
        thresh_asci=1e-2,
        tucker_state_clip=100,  #don't use any pt for tucker 
        tucker_conv_target=0,  #converge variational energy
        nproc=None)

    ci_vector, pt_vector, etci, etci2, t_conv = bc_cipsi_tucker(
        ci_vector.copy(),
        clustered_ham,
        pt_type='mp',
        thresh_cipsi=1e-7,
        thresh_ci_clip=1e-9,
        max_tucker_iter=4,
        nbody_limit=4,
        thresh_search=1e-4,
        thresh_asci=1e-2,
        tucker_state_clip=100,  #don't use any pt for tucker 
        tucker_conv_target=0,  #converge variational energy
        nproc=None)

    tci_dim = len(ci_vector)
    ci_vector.print()
    ecore = clustered_ham.core_energy

    etci += ecore
    etci2 += ecore

    print(" TCI:        %12.9f Dim:%6d" % (etci, tci_dim))
Ejemplo n.º 13
0
# UKS comparison (initial guess must break symmetry!)
pks = scf.UKS(mol)
pks.xc = fnal
pks.kernel(dm0)
pks = pks.as_scanner()
hks = scf.UKS(mol)
hks.xc = kshfnal
hks.kernel(dm0)
hks = hks.as_scanner()

# MC-PDFT objects
if gsbasis:
    gsmo = np.load(gsmofile)
    mc = mcpdft.CASSCF(mf, transl_type + fnal, ncas, nelecas, grids_level=3)
    mo = mcscf.project_init_guess(mc, gsmo, prev_mol=gsmol)
    molden.from_mo(mol, 'check_projection.molden', mo)
    mc.kernel(mo)
    mc = mc.as_scanner()
else:
    mc = mcpdft.CASSCF(mf, transl_type + fnal, ncas, nelecas,
                       grids_level=3).run().as_scanner()
mc0 = mcpdft.CASSCF(mf, otfnal0, ncas, nelecas,
                    grids_level=3).run().as_scanner()
mc1 = mcpdft.CASSCF(mf, otfnal1, ncas, nelecas,
                    grids_level=3).run().as_scanner()
mc2 = mcpdft.CASSCF(mf, otfnal2, ncas, nelecas,
                    grids_level=3).run().as_scanner()
molden.from_mcscf(mc0, moldenfile)
np.save(mofile, mc.mo_coeff)

# Do MCSCF scan forwards
Ejemplo n.º 14
0
def generate_hamiltonian():
    ###     PYSCF INPUT
    r0 = 1.50
    molecule = '''
    Cr
    Cr   1   {}
    '''.format(r0)
    charge = 0
    spin  = 0
    basis_set = 'def2-svp'

    ###     TPSCI BASIS INPUT
    orb_basis = 'scf'
    cas = True
    cas_nstart = 12
    cas_nstop =  42
    loc_start = 1
    loc_stop = 6
    cas_nel = 24

    def ordering_diatomics_cr(mol,C):
    # {{{
        ##DZ basis diatomics reordering with frozen 1s

        orb_type = ['s','pz','dz','px','dxz','py','dyz','dx2-y2','dxy']
        ref = np.zeros(C.shape[1])

        ## Find dimension of each space
        dim_orb = []
        for orb in orb_type:
            print("Orb type",orb)
            idx = 0
            for label in mol.ao_labels():
                if orb in label:
                    #print(label)
                    idx += 1

            ##frozen 1s orbitals
            if orb == 's':
                idx -= 6
            elif orb == 'px':
                idx -=2
            elif orb == 'py':
                idx -=2
            elif orb == 'pz':
                idx -=2
            dim_orb.append(idx)
            print(idx)


        new_idx = []
        ## Find orbitals corresponding to each orb space
        for i,orb in enumerate(orb_type):
            print("Orbital type:",orb)
            from pyscf import mo_mapping
            s_pop = mo_mapping.mo_comps(orb, mol, C)
            print(s_pop)
            ref += s_pop
            cas_list = s_pop.argsort()[-dim_orb[i]:]
            print('cas_list', np.array(cas_list))
            new_idx.extend(cas_list)
            #print(orb,' population for active space orbitals', s_pop[cas_list])

        ao_labels = mol.ao_labels()
        #idx = mol.search_ao_label(['N.*s'])
        #for i in idx:
        #    print(i, ao_labels[i])
        print(ref)
        print(new_idx)
        for label in mol.ao_labels():
            print(label)

        return new_idx
    # }}}

    # basis is SVP read comments by alex thom paper DOI:10.1021/acs.jctc.9b01023
    from pyscf import gto
    basis_set={'Cr': gto.parse('''
    BASIS "ao basis" PRINT
    #BASIS SET: (14s,8p,5d) -> [5s,2p,2d]
    Cr    S
      51528.086349               0.14405823106E-02
       7737.2103487              0.11036202287E-01
       1760.3748470              0.54676651806E-01
        496.87706544             0.18965038103
        161.46520598             0.38295412850
         55.466352268            0.29090050668
    Cr    S
        107.54732999            -0.10932281100
         12.408671897            0.64472599471
          5.0423628826           0.46262712560
    Cr    S
          8.5461640165          -0.22711013286
          1.3900441221           0.73301527591
          0.56066602876          0.44225565433
    Cr    S
          0.71483705972E-01      1.0000000000
    Cr    S
          0.28250687604E-01      1.0000000000
    Cr    P
        640.48536096             0.96126715203E-02
        150.69711194             0.70889834655E-01
         47.503755296            0.27065258990
         16.934120165            0.52437343414
          6.2409680590           0.34107994714
    Cr    P
          3.0885463206           0.33973986903
          1.1791047769           0.57272062927
          0.43369774432          0.24582728206
    Cr    D
         27.559479426            0.30612488044E-01
          7.4687020327           0.15593270944
          2.4345903574           0.36984421276
          0.78244754808          0.47071118077
    Cr    D
          0.21995774311          0.33941649889
    END''')}


    ###     TPSCI CLUSTER INPUT
    init_fspace = ((1, 1),(3, 3),(3, 3),(3, 3), (1, 1), (1, 1))
    blocks = [range(0,4),range(4,10),range(10,16),range(16,22),range(22,26),range(26,30)]

    # Integrals from pyscf
    #Integrals from pyscf
    pmol = PyscfHelper()
    pmol.init(molecule,charge,spin,basis_set,orb_basis,
                    cas_nstart=cas_nstart,cas_nstop=cas_nstop,cas_nel=cas_nel,cas=True,
                    loc_nstart=loc_start,loc_nstop = loc_stop)

    h = pmol.h
    g = pmol.g
    ecore = pmol.ecore
    print("Ecore:%16.8f"%ecore)
    C = pmol.C
    K = pmol.K
    mol = pmol.mol
    mo_energy = pmol.mf.mo_energy
    dm_aa = pmol.dm_aa
    dm_bb = pmol.dm_bb

    do_fci = 0
    do_hci = 0
    do_tci = 1

    if do_fci:
        efci, fci_dim = run_fci_pyscf(h,g,nelec,ecore=ecore)
    if do_hci:
        ehci, hci_dim = run_hci_pyscf(h,g,nelec,ecore=ecore,select_cutoff=5e-4,ci_cutoff=5e-4)

    #cluster using hcore

    idx = ordering_diatomics_cr(mol,C)
    h,g = reorder_integrals(idx,h,g)
    C = C[:,idx]
    mo_energy = mo_energy[idx]
    dm_aa = dm_aa[:,idx]
    dm_aa = dm_aa[idx,:]
    dm_bb = dm_bb[:,idx]
    dm_bb = dm_bb[idx,:]

    print(dm_aa)


    from pyscf import molden
    molden.from_mo(pmol.mol, 'h8.molden', C)
    print(h)
    mol = pmol.mol
    if mol.symmetry == True:
        from pyscf import symm
        mo = symm.symmetrize_orb(mol, C)
        osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo)
        #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07)
        for i in range(len(osym)):
            print("%4d %8s %16.8f"%(i+1,osym[i],mo_energy[i]))




    clusters = []

    for ci,c in enumerate(blocks):
        clusters.append(Cluster(ci,c))

    print(" Clusters:")
    [print(ci) for ci in clusters]

    clustered_ham = ClusteredOperator(clusters, core_energy=ecore)
    print(" Add 1-body terms")
    clustered_ham.add_local_terms()
    clustered_ham.add_1b_terms(h)
    print(" Add 2-body terms")
    clustered_ham.add_2b_terms(g)

    # intial state
    ci_vector = ClusteredState(clusters)
    ci_vector.init(init_fspace)
    ci_vector.print()

    # do cmf
    do_cmf = 1
    if do_cmf:
        # Get CMF reference
        e_cmf, cmf_conv, rdm_a, rdm_b = cmf(clustered_ham, ci_vector, h, g, max_iter=10, dm_guess=(dm_aa, dm_bb), diis=True)

    print(" Final CMF Total Energy %12.8f" %(e_cmf + ecore))

    # build cluster basis and operator matrices using CMF optimized density matrices
    for ci_idx, ci in enumerate(clusters):
        print(ci)
        fspaces_i = init_fspace[ci_idx]
        delta_e = 2
        fspaces_i = ci.possible_fockspaces( delta_elec=(fspaces_i[0], fspaces_i[1], delta_e) )


        print()
        print(" Form basis by diagonalizing local Hamiltonian for cluster: ",ci_idx)

        ci.form_fockspace_eigbasis(h, g, fspaces_i, max_roots=100, rdm1_a=rdm_a, rdm1_b=rdm_b)


        print(" Build mats for cluster ",ci.idx)
        ci.build_op_matrices()
        ci.build_local_terms(h,g)


    hamiltonian_file = open('hamiltonian_file', 'wb')
    pickle.dump(clustered_ham, hamiltonian_file)

    print(" Done.")