def __init__(self, fciqmc_dir=None, mol_kwargs=None, fname='nevpt2_store.pkl', casorbs=None, norb=None, nelecas=None, save_dms=False, threshs=(1e-14, ), analyze=False): self.save_dms = save_dms self.casorbs = casorbs if isinstance(mol_kwargs, dict): self.mol_kwargs = mol_kwargs mol = self.mol() hf = scf.RHF(mol) hf.conv_tol = 1e-10 hf.kernel() if analyze: hf.analyze() self.hf_canon_mo = hf.mo_coeff self.hf_mo_energy = hf.mo_energy self.norb, self.nelecas = norb, nelecas if casorbs is not None: self.norb = len(casorbs) casci = mcscf.CASCI(hf, self.norb, self.nelecas) if casorbs is not None: casci.mo_coeff = casci.sort_mo(casorbs) self.hf_canon_mo = casci.mo_coeff if fciqmc_dir is not None: print '### Initial invokation for subsequent FCIQMC RDM sampling' output_fcidump(casci, mol, fciqmc_dir) self.save(fname) else: print '### Exact CASCI+NEVPT2 invokation' output_fcidump(casci, mol) casci.kernel() self.casci_canon_mo = casci.mo_coeff self.casci_mo_energy = casci.mo_energy nevpt2 = mrpt.NEVPT(casci) nevpt2.threshs = threshs nevpt2.kernel(self.save_dms) self.save(fname) elif isinstance(fname, str) and os.path.exists(fname): self.load(fname) mol = self.mol() hf = scf.RHF(mol) casci = mcscf.CASCI(hf, self.norb, self.nelecas) casci.mo_coeff = self.casci_canon_mo if self.casci_canon_mo is not None else self.hf_canon_mo casci.mo_energy = self.casci_mo_energy if self.casci_canon_mo is not None else self.hf_mo_energy if fciqmc_dir is not None: print '### Stochastic NEVPT2 invokation with FCIQMC RDMs' casci.fcisolver = fciqmcscf.FCIQMCCI(mol) casci.fcisolver.dirname = fciqmc_dir else: print '### Exact NEVPT2 invokation from previous CASCI' nevpt2 = mrpt.NEVPT(casci) nevpt2.threshs = threshs nevpt2.canonicalized = self.casci_canon_mo is not None nevpt2.kernel(self.save_dms) else: raise Exception('Neither a mol dict nor a valid path was provided')
def make_nevpt_object(self, dirname=None): # dirname None implies exact solve, i.e. no NECI invokation to supply RDMs mol = self.get_mol_obj() m = scf.RHF(mol) m.conv_tol = 1e-10 if dirname is not None: try: casci = mcscf.CASCI(m, self.ncas, self.nelecas) pyscf_serializer.selective_deserialize( casci, pfile='{}/casci.pkl'.format(dirname)) casci.fcisolver = fciqmcscf.FCIQMCCI(mol) casci.fcisolver.dirname = dirname except IOError: m.kernel() m.analyze(with_meta_lowdin=0) casci = mcscf.CASCI(m, self.ncas, self.nelecas) casci.fcisolver = fciqmcscf.FCIQMCCI(mol) casci.fcisolver.only_ints = True try: casci.kernel() except TypeError: pass pyscf_serializer.selective_serialize( casci, ['mo_coeff', '_scf.mo_occ', '_scf.mo_coeff'], pfile='{}/casci.pkl'.format(dirname)) if not os.path.abspath(dirname) == os.path.abspath('.'): shutil.move('FCIDUMP', dirname) return else: m.kernel() casci = mcscf.CASCI(m, self.ncas, self.nelecas) casci.kernel() return mrpt.NEVPT(casci)
def run(b, dm, mo, ci=None): mol = gto.M( verbose = 5, output = 'cr2-%2.1f.out' % b, atom = 'Cr 0 0 0; Cr 0 0 %f' % b, basis = 'cc-pVTZ', symmetry = 1, ) m = scf.RHF(mol) m.conv_tol = 1e-9 ehf.append(m.scf(dm)) mc = mcscf.CASSCF(m, 12, 12) if mo is None: # the initial guess for b = 1.5 caslst = [19,20,21,22,23,24,25,28,29,31,32,33] mo = mcscf.addons.sort_mo(mc, m.mo_coeff, caslst, 1) else: mo = mcscf.project_init_guess(mc, mo) emc.append(mc.kernel(mo)[0]) mc.analyze() ept.append(mrpt.NEVPT(mc).kernel()) return m.make_rdm1(), mc.mo_coeff, mc.ci
cect = numpy.dot(HF_MOcoeff, numpy.dot(e_d, HF_MOcoeff.T)) f = numpy.dot(ova, numpy.dot(cect, ova)) en = numpy.diag(numpy.dot(coeff.T, numpy.dot(f, coeff))) fname = 'generated_AS_beforeCAS' from pyscf.tools import molden with open(fname + '.molden', 'w') as thefile: molden.header(mol, thefile) molden.orbital_coeff(mol, thefile, coeff, ene=en, occ=mf.mo_occ) #========================================================== mycas = mcscf.CASSCF(mf, norb, [nalpha, nbeta]) AS = range(N_Core, N_Core + N_Act) mycas.chkfile = 'cas_FeCp2.chk' # it is useful to keep the chk file for CASSCF in case you want to run some subsequent CASCI and NEVPT2 calculations mycas.fcisolver.nroots = 1 mycas.fix_spin_( ss=0 ) # in newer PYSCF it is better to specify ss which is usually your mol.spin activeMO = mcscf.sort_mo(mycas, coeff, AS, base=0) mycas.verbose = 5 mycas.max_cycle_macro = 150 mycas.kernel(activeMO) mc = mcscf.CASCI(mf, norb, [nalpha, nbeta]) mc.__dict__.update(scf.chkfile.load('cas_FeCp2.chk', 'mcscf')) mc.fcisolver.nroots = 1 mc.fix_spin_(ss=0) mc.verbose = 6 mc.kernel() ci_nevpt_e1 = mrpt.NEVPT(mc, root=0).kernel()
def read_charges(casci_object, n_excited_states): chgs = [] for i in range(1 + n_excited_states): ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas casdm1 = mc.fcisolver.make_rdm1(mc.ci[i], ncas, nelecas) mo_coeff = mc.mo_coeff mocore = mo_coeff[:, :ncore] mocas = mo_coeff[:, ncore:nocc] dm1 = (numpy.dot(mocore, mocore.T) * 2 + reduce(numpy.dot, (mocas, casdm1, mocas.T))) ovlp_ao = mc._scf.get_ovlp() pop, chg = mc._scf.mulliken_meta(mc.mol, dm1, s=ovlp_ao) chgs.append(chg) return chgs charges = read_charges(mc, 5) analyze_charges(charges, 5) # compute NEVPT2 corrections ci_nevpt_e1 = mrpt.NEVPT(mc, root=0).kernel() ci_nevpt_e2 = mrpt.NEVPT(mc, root=1).kernel() ci_nevpt_e3 = mrpt.NEVPT(mc, root=2).kernel() ci_nevpt_e4 = mrpt.NEVPT(mc, root=3).kernel() ci_nevpt_e5 = mrpt.NEVPT(mc, root=4).kernel() ci_nevpt_e6 = mrpt.NEVPT(mc, root=5).kernel()
'A1u': 4, 'E1uy': 2, 'E1ux': 2, 'E2gx': 0, 'E2gy': 0, 'E2uy': 0, 'E2ux': 0 } ehf = mf.kernel() # # Save orbitals from state-average CASSCF calculation. # mc = mcscf.CASSCF(mf, 8, 8).state_average_(weights=(0.5, 0.5)) mc.kernel() orbital = mc.mo_coeff # # Create a multi-root CASCI calcultion to get excited state wavefunctions. # mc = mcscf.CASCI(mf, 8, 8) mc.fcisolver.nroots = 4 mc.kernel(orbital) # # Finally compute NEVPT energy for required state # e_corr = mrpt.NEVPT(mc, root=1).kernel() e_tot = mc.e_tot[1] + e_corr print('Total energy of first excited state', e_tot)
def test_nevpt2_without_4pdm(self): e = mrpt.NEVPT(mc).compress_approx(maxM=5000).kernel() self.assertAlmostEqual(e, -0.14058324516302972, 6)
# symmetry='d2h', ) m = scf.RHF(mol) m.kernel() # # FCI-based CASCI + NEVPT2. Two roots are computed. mc.ci holds the two CI # wave functions. Root ID needs to be specified for the state-specific NEVPT2 # calculation. By default the lowest root is computed. # mc = mcscf.CASCI(m, 4, 4) mc.fcisolver.nroots = 2 mc.kernel() ci_nevpt_e1 = mrpt.NEVPT(mc, root=0).kernel() ci_nevpt_e2 = mrpt.NEVPT(mc, root=1).kernel() # # By default, the orbitals are canonicalized after calling CASCI solver. Save # the canonical MC orbitals for later use. Althoug it's not necessary for this # example, we put here to demonstrate how to carry out CASCI calculation on # given orbitals (or as initial guess for CASSCF method) other than the # default HF canonical orbitals. More examples of initial guess refers to # pyscf/mcscf/33-make_init_guess. # mc_orb = mc.mo_coeff ################################################## # # DMRG-NEVPT2 slow version
# # 2. Frozen solvation of ground state for excited states # # Assigning certain density matrix to sol.dm can force the solvent object to # compute the solvation correction with the given density matrix. # sol._dm_guess is the system density matrix of the last iteration from # previous calculation. Setting "sol.dm = sol._dm_guess" freezes the # ground state solvent effects in the excitated calculation. # sol.dm = sol._dm_guess mc = cosmo.cosmo_(mcscf.CASCI(mf, 5, 6), sol) mc.fcisolver.nroots = 2 mc.kernel(mo) e_state0 = mc.e_tot[0] + mrpt.NEVPT(mc, root=0).kernel() e_state1 = mc.e_tot[1] + mrpt.NEVPT(mc, root=1).kernel() print('Excitation E = %.9g' % (e_state1-e_state0)) ################################################## # # Emission # ################################################## # # 1. Equilibrium solvation for excited state. # # "sol.dm = None" relaxes the solvent to equilibruim wrt excited state
for r in np.arange(1.4, 1.45, 0.1): output = 'c2_%.1f.out' % r os.system("echo '\n' > %s" % output) print('scan %.1f' % r) with open(output, 'a', encoding='utf-8') as f: with contextlib.redirect_stdout(f): xyz = '''C 0.0 0.0 0.0; C 0.0 0.0 %f''' % r mol = gto.M(atom=xyz, basis='cc-pvtz') mf = scf.RHF(mol) mf.kernel() mc = mcscf.CASSCF(mf, 8, (4, 4)) mc.fix_spin_(ss=0) mc.fcisolver.nroots = 3 mc = mc.state_specific_(0) mc.run() dump_mat.dump_mo(mol, mc.mo_coeff[:, :12]) cidump.dump(mc) #mc2 = mcscf.CASCI(mf, 8, (4,4)) #mc2.fix_spin_(ss=0) #mc2.fcisolver.nroots = 3 #mc2.kernel(mc.mo_coeff) #cidump.dump(mc2) e_corr = mrpt.NEVPT(mc).kernel() e_tot = mc.e_tot + e_corr print('Total energy of ground state', e_tot)
basis = '3-21g', verbose=6, spin = 0) myhf = scf.RHF(mol) myhf.kernel() myhf.analyze() # 6 orbitals, 8 electrons mycas = mcscf.CASCI(myhf, 6, 6) print mycas.mo_energy mycas.mo_energy = None mycas.kernel() mycas.mo_energy = None from pyscf import mrpt mrpt.NEVPT(mycas).kernel() assert 0 cas_list = [5,6,7,8,9,11] mo = mycas.sort_mo(cas_list) mycas.mo_coeff = mo e1 = mycas.kernel() e2 = mycas.kernel(mo) print e1[0], e2[0], myhf.e_tot assert 0 # Natural occupancy in CAS space, Mulliken population etc. mycas.verbose = 4 mycas.analyze()
['H', (1.435682, 2.309097, 0.0)], ['H', (1.435682, -0.163698, 0.0)], ['H', (-0.705820, -1.400095, 0.0)], ['H', (-2.847323, -0.163698, 0.0)], ['H', (-2.847323, 2.309097, 0.0)]], basis=basisName, output=outputName, max_memory=16000) # Hartree-Fock calculation mf = scf.RHF(mol) mf.kernel() mf.analyze() # Get active space for CASSCF calculation n_orb_active_space, nelec_act_space, new_all_orbs = avas.kernel(mf, 'C 2pz') # CASSCF mc = dmrgscf.DMRGSCF(mf, n_orb_active_space, nelec_act_space) mc.state_specific_(state=1) mc.fcisolver.maxM = 500 mc.kernel(new_all_orbs) mc_orbs = mc.mo_coeff # CASCI mc = mcscf.CASCI(mf, n_orb_active_space, nelec_act_space) mc.fcisolver = dmrgscf.DMRGCI(mol) mc.fcisolver.maxM = 1200 mc.fcisolver.nroots = 2 mc.kernel(mc_orbs) # NEVPT2 correction mps_nevpt_e2 = mrpt.NEVPT(mc, root=1).compress_approx(maxM=1200).kernel() mc.analyze() os.system('date > endTime')
mc.conv_tol = 1e-6 mc.state_average_([.2]*3) mc.kernel(mos) mc_orbs = mc.mo_coeff # # Pass 2 # A separated DMRG-CASCI calculation based on DMRG-CASSCF orbitals obtained and # DMRG solver with large bond dimension to improve the multi configurational # wave function. # mc = mcscf.CASCI(mf, norb_act, ne_act) mc.fcisolver = dmrgscf.DMRGCI(mol) mc.fcisolver.maxM = 1500 mc.fcisolver.extraline = ['num_thrds %d'%lib.num_threads(), 'warmup local_2site'] mc.fcisolver.memory = 100 # GB mc.fcisolver.nroots = 3 mc.kernel(mc_orbs) # # This step computes DMRG-NEVPT2 energy state-specificly. It is recommended to # use large bond dimension (larger than the last DMRG-CASCI calculation) to # guarantee the accuracy. # print mrpt.NEVPT(mc, root=0).compress_approx(maxM=2000).kernel() print mrpt.NEVPT(mc, root=1).compress_approx(maxM=2000).kernel() print mrpt.NEVPT(mc, root=2).compress_approx(maxM=2000).kernel()
mc.fcisolver = DMRGCI(mol, maxM=500, tol=1e-8) # # Tune DMRG parameters. It's not necessary in most scenario. # #mc.fcisolver.outputlevel = 3 #mc.fcisolver.scheduleSweeps = [0, 4, 8, 12, 16, 20, 24, 28, 30, 34] #mc.fcisolver.scheduleMaxMs = [200, 400, 800, 1200, 2000, 4000, 3000, 2000, 1000, 500] #mc.fcisolver.scheduleTols = [0.0001, 0.0001, 0.0001, 0.0001, 1e-5, 1e-6, 1e-7, 1e-7, 1e-7, 1e-7 ] #mc.fcisolver.scheduleNoises = [0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0, 0.0, 0.0, 0.0] #mc.fcisolver.twodot_to_onedot = 38 #mc.fcisolver.maxIter = 50 mc.casci(mo) # # DMRG-NEVPT2 # mrpt.NEVPT(mc).kernel() # # There is also a fast DMRG-NEVPT2 implementation. See also the example # pyscf/examples/dmrg/02-dmrg_nevpt2.py # mrpt.NEVPT(mc).compress_approx().kernel() ################################################## # # Don't forget to clean up the scratch. DMRG calculation can produce large # amount of temporary files. # ##################################################
mc.fix_spin(ss=final_spin) mc.kernel(mo) # Save info cas_orbs = mc.mo_coeff mc = mcscf.CASCI(mf, len(mos), ele) mc.fcisolver.nroots = 2 mc.fix_spin(ss=final_spin) ener = mc.kernel(cas_orbs) print(color.BOLD + 'Root [0]:' + color.END, color.RED, ener[0][0], color.END, color.BOLD + 'Root [1]:' + color.END, color.RED, ener[0][1], color.END) print(color.BOLD + "NEVPT2 calculations..." + color.END) NEVPT2_H = mrpt.NEVPT(mc, root=1).kernel() print(color.BOLD + 'NEVPT2 ROOT[1]:' + color.END, color.RED, NEVPT2_H, color.END) NEVPT2_L = mrpt.NEVPT(mc, root=0).kernel() print(color.BOLD + 'NEVPT2 ROOT[0]:' + color.END, color.RED, NEVPT2_L, color.END) print(color.BOLD + "Excited state calculations..." + color.END) CAS_ex = (ener[0][1] - ener[0][0]) * 27.2114 NEVPT_corr = (NEVPT2_H - NEVPT2_L) * 27.2114 print("") print(color.BOLD + 'CASCF excitation (eV):' + color.END, color.RED, '{0:.4f}'.format(CAS_ex), color.END, color.BOLD + 'NEVPT2 excitation (eV):' + color.END, color.RED,
def do_scf(inp): '''Do the requested SCF.''' from pyscf import gto, scf, dft, cc, fci, ci, ao2mo, mcscf, mrpt, lib, mp, tdscf from pyscf.cc import ccsd_t, uccsd_t import numpy as np from .fcidump import fcidump # sort out the method mol = inp.mol method = inp.scf.method.lower() # UHF if method == 'uhf': ehf, mSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) if inp.scf.exci is not None: inp.timer.start('TDHF') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDHF') # RHF elif method in ('rhf', 'hf'): ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) if inp.scf.exci is not None: inp.timer.start('TDHF') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDHF') # CCSD and CCSD(T) elif method in ('ccsd', 'ccsd(t)', 'uccsd', 'uccsd(t)', 'eomccsd'): if 'u' in method: ehf, tSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) else: ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('ccsd') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze if 'u' in method: mSCF = cc.UCCSD(tSCF, frozen=frozen) else: mSCF = cc.CCSD(tSCF, frozen=frozen) mSCF.max_cycle = inp.scf.maxiter eccsd, t1, t2 = mSCF.kernel() print_energy('CCSD', ehf + eccsd) inp.timer.end('ccsd') if method == 'eomccsd': inp.timer.start('eomccsd') ee = mSCF.eomee_ccsd_singlet(nroots=4)[0] inp.timer.end('eomccsd') for i in range(len(ee)): print_energy('EOM-CCSD {0} (eV)'.format(i+1), ee[i] * 27.2114) if method in ('ccsd(t)', 'uccsd(t)'): inp.timer.start('ccsd(t)') eris = mSCF.ao2mo() if method == 'ccsd(t)': e3 = ccsd_t.kernel(mSCF, eris) else: e3 = uccsd_t.kernel(mSCF, eris) print_energy('CCSD(T)', ehf + eccsd + e3) inp.timer.end('ccsd(t)') # MP2 elif method == 'mp2': ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('mp2') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze mSCF = mp.MP2(tSCF, frozen=frozen) emp2, t2 = mSCF.kernel() print_energy('MP2', ehf+emp2) inp.timer.end('mp2') # CISD elif method == 'cisd' or method == 'cisd(q)': ehf, tSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('cisd') frozen = 0 if inp.scf.freeze is not None: frozen = inp.scf.freeze mSCF = ci.CISD(tSCF, frozen=frozen) ecisd = mSCF.kernel()[0] print_energy('CISD', ehf + ecisd) inp.timer.end('cisd') # perform Davison quadruples correction c0 = np.max(np.abs(mSCF.ci)) c02 = c0**2 ne = mSCF.mol.nelectron eq = ( 1.0 - c02 ) * ecisd print_energy('CISD(Q) Davidson', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / c02 * ecisd print_energy('CISD(Q) Renomalized-Davidson', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / ( 2.0 * c02 - 1.0 ) * ecisd print_energy('CISD(Q) Davison-Silver', ehf + ecisd + eq) eq = (( 2.0 * c02 ) / ((2.0*c02-1.0)*(1.0 + np.sqrt(1.0 + (8.0*c02*(1.0-c02)) / ( ne * (2.0*c02-1.0)**2 )))) - 1.0 ) * ecisd print_energy('CISD(Q) PC', ehf + ecisd + eq) eq = ( 1.0 - c02 ) / c02 * ((ne-2)*(ne-3.0)) / (ne*(ne-1.0)) * ecisd print_energy('CISD(Q) MC', ehf + ecisd + eq) if ne > 2: eq = ( 2.0 - c02 ) / (2.0 * (ne-1.0)/(ne-2.0) * c02 - 1.0) else: eq = 0.0 print_energy('CISD(Q) DD', ehf + ecisd + eq) # UKS elif method in ('uks' or 'udft'): inp.timer.start('uks') inp.timer.start('grids') grids = dft.gen_grid.Grids(mol) grids.level = inp.scf.grid grids.build() inp.timer.end('grids') mSCF = dft.UKS(mol) mSCF.grids = grids mSCF.xc = inp.scf.xc mSCF.conv_tol = inp.scf.conv mSCF.conv_tol_grad = inp.scf.grad mSCF.max_cycle = inp.scf.maxiter mSCF.init_guess = inp.scf.guess mSCF.small_rho_cutoff = 1e-20 eks = mSCF.kernel() print_energy('UKS', eks) inp.timer.end('uks') if inp.scf.exci is not None: inp.timer.start('TDDFT') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDDFT') # RKS elif method in ('rks', 'ks', 'rdft', 'dft'): inp.timer.start('ks') inp.timer.start('grids') grids = dft.gen_grid.Grids(mol) grids.level = inp.scf.grid grids.build() inp.timer.end('grids') if mol.nelectron%2 == 0: mSCF = dft.RKS(mol) else: mSCF = dft.ROKS(mol) mSCF.grids = grids mSCF.xc = inp.scf.xc mSCF.conv_tol = inp.scf.conv mSCF.conv_tol_grad = inp.scf.grad mSCF.max_cycle = inp.scf.maxiter mSCF.init_guess = inp.scf.guess mSCF.small_rho_cutoff = 1e-20 mSCF.damp = inp.scf.damp mSCF.level_shift = inp.scf.shift eks = mSCF.kernel() print_energy('RKS', eks) inp.timer.end('ks') if inp.scf.exci is not None: inp.timer.start('TDDFT') mtd = do_TDDFT(inp, mSCF) inp.timer.end('TDDFT') # Unrestricted FCI elif method == 'ufci': ehf, mSCF = do_hf(inp, unrestricted=True) print_energy('UHF', ehf) inp.timer.start('fci') cis = fci.direct_uhf.FCISolver(mol) norb = mSCF.mo_energy[0].size nea = (mol.nelectron+mol.spin) // 2 neb = (mol.nelectron-mol.spin) // 2 nelec = (nea, neb) mo_a = mSCF.mo_coeff[0] mo_b = mSCF.mo_coeff[1] h1e_a = reduce(np.dot, (mo_a.T, mSCF.get_hcore(), mo_a)) h1e_b = reduce(np.dot, (mo_b.T, mSCF.get_hcore(), mo_b)) g2e_aa = ao2mo.incore.general(mSCF._eri, (mo_a,)*4, compact=False) g2e_aa = g2e_aa.reshape(norb,norb,norb,norb) g2e_ab = ao2mo.incore.general(mSCF._eri, (mo_a,mo_a,mo_b,mo_b), compact=False) g2e_ab = g2e_ab.reshape(norb,norb,norb,norb) g2e_bb = ao2mo.incore.general(mSCF._eri, (mo_b,)*4, compact=False) g2e_bb = g2e_bb.reshape(norb,norb,norb,norb) h1e = (h1e_a, h1e_b) eri = (g2e_aa, g2e_ab, g2e_bb) eci = fci.direct_uhf.kernel(h1e, eri, norb, nelec)[0] print_energy('FCI', eci) inp.timer.end('fci') # FCI elif method in ('fci'): ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('fci') if inp.scf.freeze is None: mCI = fci.FCI(mSCF) if inp.scf.roots is not None: mCI.nroots = inp.scf.roots mCI.kernel()[0] eci = mCI.eci else: nel = mol.nelectron - inp.scf.freeze * 2 ncas = mol.nao_nr() - inp.scf.freeze if mol.spin == 0: nelecas = nel mCI = mcscf.CASCI(mSCF, ncas, nelecas) mCI.fcisolver = fci.solver(mol) else: if mol.spin%2 == 0: nelecas = (nel//2+mol.spin//2, nel//2-mol.spin//2) else: nelecas = (nel//2+mol.spin//2+1, nel//2-mol.spin//2) mCI = mcscf.CASCI(mSCF, ncas, nelecas) mCI.fcisolver = fci.direct_spin1.FCISolver(mol) eci = mCI.kernel()[0] dm = mCI.make_rdm1() dip = mSCF.dip_moment(dm=dm) if inp.scf.roots is None: print_energy('FCI', eci) else: for i in range(inp.scf.roots): print_energy('FCI {0}'.format(i), eci[i]) inp.timer.end('fci') # CASCI elif method == 'casci': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) inp.timer.start('casci') mCI = mcscf.CASCI(mSCF, ncasorb, nelecas) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASCI', eci) inp.timer.end('casci') # CASSCF elif method == 'casscf' or method == 'ucasscf': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp lunrestricted = (method == 'ucasscf') ehf, mSCF = do_hf(inp, unrestricted=lunrestricted) print_energy('HF', ehf) # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) inp.timer.start('casscf') mCI = mcscf.CASSCF(mSCF, ncasorb, nelecas) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASSCF', eci) inp.timer.end('casscf') # NEVPT2 elif method == 'nevpt2' or method == 'unevpt2': if inp.scf.cas is None and inp.scf.casorb is None: print ('ERROR: Must specify CAS space or CASORB') return inp ehf, mSCF = do_hf(inp) print_energy('RHF', ehf) inp.timer.start('casscf') # get cas space if inp.scf.cas is not None: if mol.spin == 0: nelecas = inp.scf.cas[0] else: nelecas = (inp.scf.cas[0]//2 + mol.spin//2, inp.scf.cas[0]//2 - mol.spin//2) ncasorb = inp.scf.cas[1] elif inp.scf.casorb is not None: ncasorb = len(inp.scf.casorb) nelecas = int(np.sum(mSCF.mo_occ[inp.scf.casorb])) if inp.scf.casspin is not None: nelecas = (nelecas//2 + inp.scf.casspin//2, nelecas//2 - inp.scf.casspin//2) mCI = mcscf.CASSCF(mSCF, ncasorb, nelecas, frozen=inp.scf.freeze) if inp.scf.casorb is not None: mo = mcscf.addons.sort_mo(mCI, np.copy(mSCF.mo_coeff), inp.scf.casorb, 0) else: mo = np.copy(mSCF.mo_coeff) eci = mCI.kernel(mo)[0] print_energy('CASSCF', eci) inp.timer.end('casscf') inp.timer.start('nevpt2') mpt2 = mrpt.NEVPT(mCI) ept2 = mpt2.kernel() + eci print_energy('NEVPT2', ept2) inp.timer.end('nevpt2') else: print ('ERROR: Unrecognized SCF method!') raise SystemExit # dump fcidump file if needed if inp.fcidump: if inp.filename[-4:].lower() == '.inp': fcifile = inp.filename[:-4] + '.fcidump' else: fcifile = inp.filename + '.fcidump' fcidump(mSCF, filename=fcifile, tol=1e-6) # plot MOs if needed if inp.mo2cube: from .mo_2_cube import save_MOs save_MOs(inp, mSCF, mSCF.mo_coeff) # save molden file if needed if inp.molden: from pyscf.tools import molden molden_file = inp.filename[:-4] + '.molden' molden.from_mo(inp.mol, molden_file, mSCF.mo_coeff, ene=mSCF.mo_energy) # save and return inp.mf = mSCF return inp
mc = dmrgscf.dmrgci.DMRGSCF(m, 8, 8) mc.state_average_([.5,.5]) e_0 = mc.kernel()[0] # # Run DMRGCI for 2 excited states # mc = mcscf.CASCI(m, 8, 8) mc.fcisolver = dmrgscf.dmrgci.DMRGCI(mol, maxM=200) mc.fcisolver.nroots = 2 e_0 = mc.kernel()[0] # # Computing NEVPT2 based on state-specific DMRG-CASCI calculation # dmrg_nevpt_e1 = mrpt.NEVPT(mc, root=0).kernel() dmrg_nevpt_e2 = mrpt.NEVPT(mc, root=1).kernel() print('DE = %.9g' % (e_0[1]+dmrg_nevpt_e2) - (e_0[0]+dmrg_nevpt_e1)) ################################################## # # State-specific # ################################################## # # Optimize orbitals for first excited state # mc = dmrgscf.dmrgci.DMRGSCF(m, 8, 8)
def nevpt2(mc, root=0): nev = mrpt.NEVPT(mc, root=root) nev.kernel()
def test_nevpt2_with_4pdm(self): e = mrpt.NEVPT(mc).kernel() self.assertAlmostEqual(e, -0.14058373193902649, 6)
# # Load SA-MCSCF # nelecas, ncas = (4, 4) n_states = 3 weights = np.ones(n_states) / n_states mc0 = mcscf.CASSCF(mf, ncas, nelecas).state_average_(weights) mc0.fix_spin(ss=0) mc0.chkfile = "_chk/pp_dz_cas_4e_4o.chk" mc0.__dict__.update(chkfile.load(mc0.chkfile, "mcscf")) # # NEVPT2 # mc = mcscf.CASCI(mf, ncas, nelecas) mc.fcisolver.nroots = n_states mc.fix_spin(ss=0) mc.kernel(mc0.mo_coeff) np.savetxt(f"_energies/SA-{n_states}-CASSCF({nelecas},{ncas}).txt", mc.e_tot) lib.num_threads(1) print(f"NUM THREADS NOW = {lib.num_threads()}") e_corr = mrpt.NEVPT(mc, root=target_state).kernel() e_tot = mc.e_tot[target_state] + e_corr np.savetxt(f"_energies/NEVPT2-{target_state}.txt", np.array([e_tot])) lib.num_threads(24) print(f"NUM THREADS NOW = {lib.num_threads()}")
idx = [ i for i, s in enumerate(mol.spheric_labels(1)) if 'Fe 3d' in s or 'Fe 4d' in s or 'Fe 4s' in s or 'N 2pz' in s ] mo = dmet_cas(mc, mf.make_rdm1(), idx) mc.fcisolver.wfnsym = 'Ag' mc.kernel(mo) #mc.analyze() e_q = mc.e_tot # -2244.90267106288 cas_q = mc.mo_coeff[:, mc.ncore:mc.ncore + mc.ncas] # # call DMRG-NEVPT2 (about 2 days, 100 GB memory) # ept2_q = mrpt.NEVPT(mc).kernel() ################################################## # # Triplet # ################################################## mol.spin = 2 mol.build(0, 0) mf = scf.ROHF(mol) mf = scf.fast_newton(mf) # # CAS(16e, 20o)