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)
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')
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)
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 ())
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)
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]
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)
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))
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)
# 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
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))
# 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
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.")