def fci(self, nelecs=None): print('\n[iface.fci]') from pyscf import mcscf, fci ehf = self.mf.energy_tot(self.mf.make_rdm1()) if nelecs is None: na = (self.mol.nelectron + self.mol.spin) // 2 nb = (self.mol.nelectron - self.mol.spin) // 2 else: na, nb = nelecs if na == nb: fcisol = fci.FCI(self.mol, self.mo_coeff) else: fcisol = fci.FCI(self.mol, self.mo_coeff, singlet=False) #fcisol.nroots = 10 fcisol.max_cycle = 300 fcisol.max_space = 300 #fcisol.conv_tol = 1.e-16 fci.addons.fix_spin_(fcisol, 0.1) efci, civec = fcisol.kernel(nelec=[na, nb]) ecor = efci - ehf enuc = self.mol.energy_nuc() print("\nSummary of FCI:") print("nalpha,nbeta =", na, nb) print("E_scf(wo/wNUC) =", ehf - enuc, ehf) print("E_fci(wo/wNUC) =", efci, efci + enuc) print("E_cor =", ecor) #print "Coeff:",mc.ci #print "Weights:",mc.ci**2 return efci
def test_fix_spin_high_cost(self): def check(mci): mci = fci.addons.fix_spin_(mci, .2, 0) mci.kernel(nelec=(8, 8)) self.assertAlmostEqual( mci.spin_square(mci.ci, mol.nao_nr(), 16)[0], 0, 7) mol = gto.M(atom='O 0 0 0; O 0 0 1.2', spin=2, basis='sto3g', symmetry=1, verbose=0) mf = scf.RHF(mol).run() mci = fci.FCI(mol, mf.mo_coeff, False) mci.wfnsym = 'A1g' check(mci) mci.wfnsym = 'A2g' check(mci) mci = fci.FCI(mol, mf.mo_coeff, True) mci.wfnsym = 'A1g' check(mci) mci.wfnsym = 'A2g' check(mci) mol = gto.M(atom='O 0 0 0; O 0 0 1.2', spin=2, basis='sto3g', verbose=0) mf = scf.RHF(mol).run() mci = fci.FCI(mol, mf.mo_coeff, False) check(mci) mci = fci.FCI(mol, mf.mo_coeff, True) check(mci)
def test__init__file(self): c1 = fci.FCI(mol, m.mo_coeff, singlet=True) self.assertAlmostEqual(c1.kernel()[0], -2.8227809167209683, 9) c1 = fci.FCI(m, singlet=True) self.assertAlmostEqual(c1.kernel()[0], -2.8227809167209683, 9) c1 = fci.FCI(mol.UHF().run()) self.assertAlmostEqual(c1.kernel()[0], -2.8227809167209683, 9)
def setUpModule(): global mol, mf, mc, sa, mol_N2, mf_N2, mc_N2 mol = gto.Mole() mol.verbose = lib.logger.DEBUG mol.output = '/dev/null' mol.atom = [ ['H', (5., -1., 1.)], ['H', (0., -5., -2.)], ['H', (4., -0.5, -3.)], ['H', (0., -4.5, -1.)], ['H', (3., -0.5, -0.)], ['H', (0., -3., -1.)], ['H', (2., -2.5, 0.)], ['H', (1., 1., 3.)], ] mol.basis = 'sto-3g' mol.build() b = 1.4 mol_N2 = gto.Mole() mol_N2.build(verbose=lib.logger.DEBUG, output='/dev/null', atom=[ ['N', (0.000000, 0.000000, -b / 2)], ['N', (0.000000, 0.000000, b / 2)], ], basis={ 'N': 'ccpvdz', }, symmetry=1) mf_N2 = scf.RHF(mol_N2).run() solver1 = fci.FCI(mol_N2) solver1.spin = 0 solver1.nroots = 2 solver2 = fci.FCI(mol_N2, singlet=False) solver2.spin = 2 mc_N2 = CASSCF(mf_N2, 4, 4) mc_N2 = addons.state_average_mix_(mc_N2, [solver1, solver2], (0.25, 0.25, 0.5)).newton() mc_N2.kernel() mf = scf.RHF(mol) mf.max_cycle = 3 mf.kernel() mc = newton_casscf.CASSCF(mf, 4, 4) mc.fcisolver = fci.direct_spin1.FCI(mol) mc.kernel() sa = CASSCF(mf, 4, 4) sa.fcisolver = fci.direct_spin1.FCI(mol) sa = sa.state_average([0.5, 0.5]).newton() sa.kernel()
def test_state_average_mix(self): solver1 = fci.FCI(mol) solver1.spin = 0 solver1.nroots = 2 solver2 = fci.FCI(mol, singlet=False) solver2.spin = 2 mc = mcscf.CASSCF(mfr, 4, 4) mc = mcscf.addons.state_average_mix_(mc, [solver1, solver2], (0.25, 0.25, 0.5)) e = mc.kernel()[0] self.assertAlmostEqual(e, -108.80340952016508, 7) dm1 = mc.analyze() self.assertAlmostEqual(lib.finger(dm1[0]), 0.52172669549357464, 4) self.assertAlmostEqual(lib.finger(dm1[1]), 0.53366776017869022, 4) self.assertAlmostEqual(lib.finger(dm1[0] + dm1[1]), 1.0553944556722636, 4)
def test_davidson_large_dx(self): mol = gto.M(atom=''' O 0 0 0 H 1.92 1.38 0 H -1.92 1.38 0''', verbose=0) ci = fci.FCI(mol.RHF().run()).run() self.assertAlmostEqual(ci.e_tot, -74.74294263255416, 9)
def test_symm_spin1(self): fs = fci.FCI(mol, m.mo_coeff, singlet=False) fs.wfnsym = 'B1' fs.nroots = 2 e, c = fs.kernel() self.assertAlmostEqual(e[0], -19.303845373762+mol.energy_nuc(), 9) self.assertAlmostEqual(e[1], -19.286003160337+mol.energy_nuc(), 9) self.assertAlmostEqual(fci.spin_op.spin_square0(c[0], norb, nelec)[0], 2, 9) self.assertAlmostEqual(fci.spin_op.spin_square0(c[1], norb, nelec)[0], 0, 9)
def solve(frag, guess_1RDM, chempot_imp): # Augment OEI with the chemical potential OEI = frag.impham_OEI_C - chempot_imp # Get the RHF solution mol = gto.Mole() mol.spin = int(round(2 * frag.target_MS)) mol.verbose = 0 if frag.mol_output is None else 4 mol.output = frag.mol_output mol.build() mol.atom.append(('H', (0, 0, 0))) mol.nelectron = frag.nelec_imp #mol.incore_anyway = True #mf.get_hcore = lambda *args: OEI #mf.get_ovlp = lambda *args: np.eye(frag.norbs_imp) #mf._eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp) h1e = OEI eri = ao2mo.restore(8, frag.impham_TEI, frag.norbs_imp) ed = fci.FCI(mol, singlet=(frag.target_S == 0)) if frag.target_S != 0: s2_eval = frag.target_S * (frag.target_S + 1) fix_spin_(ed, ss=s2_eval) # Guess vector ci = None if len(frag.imp_cache) == 1: ci = frag.imp_cache[0] print("Taking initial ci vector from cache") t_start = time.time() ed.conv_tol = 1e-12 E_FCI, ci = ed.kernel(h1e, eri, frag.norbs_imp, frag.nelec_imp, ci0=ci) assert (ed.converged) frag.imp_cache = [ci] t_end = time.time() print( 'Impurity FCI energy (incl chempot): {}; spin multiplicity: {}; time to solve: {}' .format(frag.impham_CONST + E_FCI, ed.spin_square(ci, frag.norbs_imp, frag.nelec_imp)[1], t_end - t_start)) # oneRDM and twoCDM oneRDM_imp, twoRDM_imp = ed.make_rdm12(ci, frag.norbs_imp, frag.nelec_imp) oneRDMs_imp = ed.make_rdm1s(ci, frag.norbs_imp, frag.nelec_imp) twoCDM_imp = get_2CDM_from_2RDM(twoRDM_imp, oneRDMs_imp) # General impurity data frag.oneRDM_loc = symmetrize_tensor( frag.oneRDMfroz_loc + represent_operator_in_basis(oneRDM_imp, frag.imp2loc)) frag.twoCDM_imp = symmetrize_tensor(twoCDM_imp) frag.E_imp = frag.impham_CONST + E_FCI + np.einsum('ab,ab->', chempot_imp, oneRDM_imp) return None
def test_fix_spin(self): mci = fci.FCI(mol, m.mo_coeff, False) mci = fci.addons.fix_spin_(mci, .2, 0) mci.kernel(nelec=(3,3)) self.assertAlmostEqual(mci.spin_square(mci.ci, mol.nao_nr(), (3,3))[0], 0, 7) mci = fci.addons.fix_spin_(mci, .2, ss=2) # Change initial guess to triplet state ci0 = fci.addons.initguess_triplet(norb, (3,3), '0b10011') mci.kernel(nelec=(3,3), ci0=ci0) self.assertAlmostEqual(mci.spin_square(mci.ci, mol.nao_nr(), (3,3))[0], 2, 7)
def test_symm_spin0(self): fs = fci.FCI(mol, m.mo_coeff, singlet=True) fs.wfnsym = 'B1' fs.nroots = 3 e, c = fs.kernel() self.assertAlmostEqual(e[0], -19.286003160337+mol.energy_nuc(), 9) self.assertAlmostEqual(e[1], -18.812177419921+mol.energy_nuc(), 9) self.assertAlmostEqual(e[2], -18.786684534678+mol.energy_nuc(), 9) self.assertAlmostEqual(fci.spin_op.spin_square0(c[0], norb, nelec)[0], 0, 9) self.assertAlmostEqual(fci.spin_op.spin_square0(c[1], norb, nelec)[0], 6, 9) self.assertAlmostEqual(fci.spin_op.spin_square0(c[2], norb, nelec)[0], 0, 9)
def test_davidson(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [['H', (0, 0, i)] for i in range(8)] mol.basis = {'H': 'sto-3g'} mol.build() mf = scf.RHF(mol) mf.scf() myfci = fci.FCI(mol, mf.mo_coeff) myfci.max_memory = .001 myfci.max_cycle = 100 e = myfci.kernel()[0] self.assertAlmostEqual(e, -11.579978414933732 + mol.energy_nuc(), 9)
def create_PYSCF_fcidump(): myhf = scf.RHF(mol) E = myhf.kernel() c = myhf.mo_coeff h1e = reduce(np.dot, (c.T, myhf.get_hcore(), c)) eri = ao2mo.kernel(mol, c) pt.fcidump.from_integrals('fcidump.txt', h1e, eri, c.shape[1], mol.nelectron, ms=0) cisolver = fci.FCI(mol, myhf.mo_coeff) print('E(HF) = %.12f, E(FCI) = %.12f' % (E, (cisolver.kernel()[0] + mol.energy_nuc())))
def __init__(self, mol, mf, states=None, weights=None, cas=None): self.mol = mol self.mo_coeff = mf.mo_coeff self.cas = cas if cas is None: self.ff = fci.FCI(mol, mf.mo_coeff) self.ncore = 0 self.norb = mol.nao else: self.ff = mcscf.CASCI(mf, cas[0], cas[1]) self.ncore = self.ff.ncore self.norb = cas[0] self.weights = weights self.ci = None self.states = states
def setUp(self): geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = '6-31g' multiplicity = 1 charge = 0 self.molecule = PyscfMolecularData(geometry, basis, multiplicity, charge) mol = prepare_pyscf_molecule(self.molecule) mol.verbose = 0 self.molecule._pyscf_data['mol'] = mol self.molecule._pyscf_data['scf'] = mf = scf.RHF(mol).run() self.molecule._pyscf_data['mp2'] = mp.MP2(mf).run() self.molecule._pyscf_data['cisd'] = ci.CISD(mf).run() self.molecule._pyscf_data['ccsd'] = cc.CCSD(mf).run() self.molecule._pyscf_data['fci'] = fci.FCI(mf).run()
def test_state_average_mix_fci_dmrg(self): fcisolver1 = fci.direct_spin0_symm.FCISolver(mol) class FCI_as_DMRG(fci.direct_spin0_symm.FCISolver): def __getattribute__(self, attr): """Prevent 'private' attribute access""" if attr in ('make_rdm1s', 'spin_square', 'contract_2e', 'absorb_h1e'): raise AttributeError else: return object.__getattribute__(self, attr) def kernel(self, *args, **kwargs): return fcisolver1.kernel(*args, **kwargs) def approx_kernel(self, *args, **kwargs): return fcisolver1.kernel(*args, **kwargs) @property def orbsym(self): return fcisolver1.orbsym @orbsym.setter def orbsym(self, x): fcisolver1.orbsym = x spin_square = None large_ci = None transform_ci_for_orbital_rotation = None solver1 = FCI_as_DMRG(mol) solver1.spin = fcisolver1.spin = 0 solver1.nroots = fcisolver1.nroots = 2 solver2 = fci.FCI(mol, singlet=False) solver2.spin = 2 mc = mcscf.CASSCF(mfr, 4, 4) mc = mcscf.addons.state_average_mix_(mc, [solver1, solver2], (0.25, 0.25, 0.5)) mc.kernel() e = mc.e_states self.assertAlmostEqual(numpy.dot(e, [.25, .25, .5]), -108.80340952016508, 7) dm1 = mc.analyze() self.assertAlmostEqual(lib.fp(dm1[0]), 1.0553944556722636, 4) self.assertEqual(dm1[1], None) mc.cas_natorb()
def test_pyscf(): mol, myhf = get_hf() tools.molden.from_scf(myhf, "molden_file.molden") s = pyopencap.System(sys_dict) pc = pyopencap.CAP(s, cap_dict, 3) fs = fci.FCI(mol, myhf.mo_coeff) fs.nroots = 3 e, c = fs.kernel() for i in range(0, len(fs.ci)): for j in range(0, len(fs.ci)): dm1 = fs.trans_rdm1(fs.ci[i], fs.ci[j], myhf.mo_coeff.shape[1], mol.nelec) dm1_ao = np.einsum('pi,ij,qj->pq', myhf.mo_coeff, dm1, myhf.mo_coeff.conj()) pc.add_tdm(dm1_ao, i, j, "pyscf") pc.compute_projected_cap() os.remove("molden_file.molden")
def run_FCI(molecule: MolecularData, roots: int): pyscf_mol = molecule._pyscf_data['mol'] pyscf_scf = molecule._pyscf_data['scf'] pyscf_mol.symmetry = True pyscf_mol.build() # label orbital symmetries orbsym = scf.hf_symm.get_orbsym(pyscf_mol, pyscf_scf.mo_coeff) pyscf_mol.symmetry = False # generate FCI solver fci_solver = fci.addons.fix_spin_(fci.FCI(pyscf_mol, pyscf_scf.mo_coeff), shift=0.0, ss=1.0) fci_solver.nroots = roots # execute FCI solver f, d = fci_solver.kernel() fci_e = [] print(' FCI:') # iterate over eigenstates for i, x in enumerate(d): energy = f[i] mult = fci.spin_op.spin_square0(x, molecule.n_orbitals, molecule.n_electrons)[1] eigen_symm = fci.addons.guess_wfnsym(x, molecule.n_orbitals, molecule.n_electrons, orbsym) eigen_symm = symm.irrep_id2name('Coov', eigen_symm) fci_e.append((energy, mult)) print('state {}, E = {}, 2S+1 = {}, IrRep = {} '.format( i, round(energy, 5), round(mult), eigen_symm)) return fci_e
from pyscf import scf, mp, ci, cc, fci geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = '6-31g' multiplicity = 1 charge = 0 molecule = PyscfMolecularData(geometry, basis, multiplicity, charge) mol = prepare_pyscf_molecule(molecule) mol.verbose = 0 molecule._pyscf_data['mol'] = mol molecule._pyscf_data['scf'] = mf = scf.RHF(mol).run() molecule._pyscf_data['mp2'] = mp.MP2(mf).run() molecule._pyscf_data['cisd'] = ci.CISD(mf).run() molecule._pyscf_data['ccsd'] = cc.CCSD(mf).run() molecule._pyscf_data['fci'] = fci.FCI(mf).run() def test_accessing_rdm(): mo = molecule.canonical_orbitals overlap = molecule.overlap_integrals h1 = molecule.one_body_integrals h2 = molecule.two_body_integrals mf = molecule._pyscf_data['scf'] e_core = mf.energy_nuc() rdm1 = molecule.cisd_one_rdm rdm2 = molecule.cisd_two_rdm e_ref = molecule._pyscf_data['cisd'].e_tot e_tot = (numpy.einsum('pq,pq', h1, rdm1) + numpy.einsum('pqrs,pqrs', h2, rdm2) * .5 + e_core)
energies["HF"].append(Ehf) # Il conto di campo medio è la prima approsimazione che si può fare nello studio # della nostra molecola. Da questo possiamo partire per studiare le correlazioni # tra gli elettroni a diversi livelli ## FCI # Quando il sistema ha pochi elettroni, possiamo permetterci di diagonalizzare esattamente # l' Hamiltoniano del sistema nella base degli orbitali scelta. # Questo metodo prende il nome di Full Configuration Interaction (FCI) #### NB queste righe vanno commentate se la base diventa troppo grande fci_h3 = fci.FCI( mf ) #<- nei metodi correlati passiamo come argomento un conto di campo medio, HF e_fci = fci_h3.kernel()[0] energies["FCI"].append(e_fci) # Sfortunatamente, questo metodo diventa particolarmente oneroso quando incrementiamo # la taglia della base o il numero di elettroni, dobbiamo queindi ricorrere a delle # approssimazioni ## MP2 # Possiamo ad esempio aggiungere perturbativamente le interazioni tra gli elettroni. Questa tecnica # prende il nome di Møller-Plesset. Nel nostro caso consideriamo una perturbazione al secondo ordine mp2 = mp.MP2(mf) e_mp2 = mp2.kernel()[0]
'ghost': ghost_bas }, symmetry='d2h') mol.build() myhf = scf.RHF(mol) myhf.kernel() # create system using molden file molden_dict = {"basis_file": "molden_in.molden", "molecule": "molden"} tools.molden.from_scf(myhf, "molden_in.molden") s = pyopencap.System(molden_dict) pyscf_smat = scf.hf.get_ovlp(mol) s.check_overlap_mat(pyscf_smat, "pyscf") # run full ci fs = fci.FCI(mol, myhf.mo_coeff) fs.nroots = nstates e, c = fs.kernel() # fill density matrices h0 = np.zeros((nstates, nstates)) for i in range(0, len(e)): h0[i][i] = e[i] # compute CAP pc = pyopencap.CAP(s, cap_dict, nstates) for i in range(0, len(fs.ci)): for j in range(0, len(fs.ci)): dm1 = fs.trans_rdm1(fs.ci[i], fs.ci[j], myhf.mo_coeff.shape[1], mol.nelec) dm1_ao = np.einsum('pi,ij,qj->pq', myhf.mo_coeff, dm1,
def run_pyscf(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=False, verbose=False): """ This function runs a pyscf calculation. Args: molecule: An instance of the MolecularData or PyscfMolecularData class. run_scf: Optional boolean to run SCF calculation. run_mp2: Optional boolean to run MP2 calculation. run_cisd: Optional boolean to run CISD calculation. run_ccsd: Optional boolean to run CCSD calculation. run_fci: Optional boolean to FCI calculation. verbose: Boolean whether to print calculation results to screen. Returns: molecule: The updated PyscfMolecularData object. Note the attributes of the input molecule are also updated in this function. """ # Prepare pyscf molecule. pyscf_molecule = prepare_pyscf_molecule(molecule) molecule.n_orbitals = int(pyscf_molecule.nao_nr()) molecule.n_qubits = 2 * molecule.n_orbitals molecule.nuclear_repulsion = float(pyscf_molecule.energy_nuc()) # Run SCF. pyscf_scf = compute_scf(pyscf_molecule) pyscf_scf.verbose = 0 # Custom properties pyscf_scf.chkfile = 'chkfiles/rohf.chk' pyscf_scf.init_guess = 'chkfile' #pyscf_scf.max_cycle = 1000 pyscf_scf.max_cycle = 0 # Use chkfile pyscf_scf.verbose = 4 pyscf_scf.run() pyscf_scf.analyze() molecule.hf_energy = float(pyscf_scf.e_tot) if verbose: print('Hartree-Fock energy for {} ({} electrons) is {}.'.format( molecule.name, molecule.n_electrons, molecule.hf_energy)) # Hold pyscf data in molecule. They are required to compute density # matrices and other quantities. molecule._pyscf_data = pyscf_data = {} pyscf_data['mol'] = pyscf_molecule pyscf_data['scf'] = pyscf_scf # Populate fields. molecule.canonical_orbitals = pyscf_scf.mo_coeff.astype(float) molecule.orbital_energies = pyscf_scf.mo_energy.astype(float) # Get integrals. # Try to load integrals from file if they exist try: print("Attempting to load integrals...") one_body_integrals = np.load("1e-integrals.npy") two_body_integrals = np.load("2e-integrals.npy") except FileNotFoundError: print("Integrals not found. Recalculating...") one_body_integrals, two_body_integrals = compute_integrals( pyscf_molecule, pyscf_scf) np.save("1e-integrals.npy", one_body_integrals) np.save("2e-integrals.npy", two_body_integrals) print("Integrals loaded") molecule.one_body_integrals = one_body_integrals molecule.two_body_integrals = two_body_integrals molecule.overlap_integrals = pyscf_scf.get_ovlp() # Run MP2. if run_mp2: if molecule.multiplicity != 1: print("WARNING: RO-MP2 is not available in PySCF.") else: pyscf_mp2 = mp.MP2(pyscf_scf) pyscf_mp2.verbose = 0 pyscf_mp2.run() # molecule.mp2_energy = pyscf_mp2.e_tot # pyscf-1.4.4 or higher molecule.mp2_energy = pyscf_scf.e_tot + pyscf_mp2.e_corr pyscf_data['mp2'] = pyscf_mp2 if verbose: print('MP2 energy for {} ({} electrons) is {}.'.format( molecule.name, molecule.n_electrons, molecule.mp2_energy)) # Run CISD. if run_cisd: pyscf_cisd = ci.CISD(pyscf_scf) pyscf_cisd.verbose = 0 pyscf_cisd.run() molecule.cisd_energy = pyscf_cisd.e_tot pyscf_data['cisd'] = pyscf_cisd if verbose: print('CISD energy for {} ({} electrons) is {}.'.format( molecule.name, molecule.n_electrons, molecule.cisd_energy)) # Run CCSD. if run_ccsd: pyscf_ccsd = cc.CCSD(pyscf_scf) pyscf_ccsd.verbose = 0 pyscf_ccsd.run() molecule.ccsd_energy = pyscf_ccsd.e_tot pyscf_data['ccsd'] = pyscf_ccsd if verbose: print('CCSD energy for {} ({} electrons) is {}.'.format( molecule.name, molecule.n_electrons, molecule.ccsd_energy)) # Run FCI. if run_fci: pyscf_fci = fci.FCI(pyscf_molecule, pyscf_scf.mo_coeff) pyscf_fci.verbose = 0 molecule.fci_energy = pyscf_fci.kernel()[0] pyscf_data['fci'] = pyscf_fci if verbose: print('FCI energy for {} ({} electrons) is {}.'.format( molecule.name, molecule.n_electrons, molecule.fci_energy)) # Return updated molecule instance. print("Ending pyscf...") pyscf_molecular_data = PyscfMolecularData.__new__(PyscfMolecularData) pyscf_molecular_data.__dict__.update(molecule.__dict__) print("Saving...") #pyscf_molecular_data.save() print("Saved") return pyscf_molecular_data
def main(filename): #uses the parameters specified in the inp object to optimize the geometry of the given molecule and outputs a file with the updated geometry #TO PARAMATERIZE min_grad = (1 * 10 ^ (-6)) # initialize and print header pstr("", delim="*", addline=False) pstr(" FREEZE-AND-THAW GEOMETRY CALCULATION ", delim="*", fill=False, addline=False) pstr("", delim="*", addline=False) # print input options to stdout pstr("Input File") [ print(i[:-1]) for i in open(filename).readlines() if ((i[0] not in ['#', '!']) and (i[0:2] not in ['::', '//'])) ] pstr("End Input", addline=False) # read input file inp = read_input(filename) inp.timer = simple_timer.timer() nsub = inp.nsubsys inp.DIIS = None inp.ndiags = [0 for i in range(nsub)] # use supermolecular grid for all subsystem grids inp.grids = gen_grids(inp) sna = inp.smol.nao_nr() na = [inp.mol[i].nao_nr() for i in range(nsub)] # initialize 1e matrices from supermolecular system inp.timer.start("OVERLAP INTEGRALS") pstr("Getting subsystem overlap integrals", delim=" ") inp.sSCF = get_scf(inp, inp.smol) Hcore = inp.sSCF.get_hcore() Smat = inp.sSCF.get_ovlp() Fock = np.zeros((sna, sna)) Dmat = [None for i in range(nsub)] inp.timer.end("OVERLAP INTEGRALS") # get initial density for each subsystem inp.timer.start("INITIAL SUBSYSTEMS") inp.mSCF = [None for i in range(nsub)] # SCF objects pstr('Initial subsystem densities', delim=' ') for i in range(nsub): inp.mSCF[i] = get_scf(inp, inp.mol[i]) # read density from file if inp.read and os.path.isfile(inp.read + '.dm{0}'.format(i)): print("Reading initial densities from file: {0}".format( inp.read + '.dm{0}'.format(i))) Dmat[i] = pickle.load(open(inp.read + '.dm{0}'.format(i), 'rb')) # guess density else: print("Guessing initial subsystem densities") Dmat[i] = inp.mSCF[i].init_guess_by_atom() #Dmat[i] = inp.mSCF[i].init_guess_by_minao() inp.sub2sup = get_sub2sup(inp, inp.mSCF) inp.timer.end("INITIAL SUBSYSTEMS") # start with supermolecule calculation if inp.embed.localize: pstr("Supermolecular DFT") inp.sSCF = do_supermol_scf(inp, Dmat, Smat) from localize import localize pstr("Localizing Orbitals", delim="=") Dmat = localize(inp, inp.sSCF, inp.mSCF, Dmat, Smat) # do freeze-and-thaw cycles inp.timer.start("FREEZE AND THAW") if inp.embed.cycles == 1: smethod = "SCF" else: smethod = "Freeze-and-Thaw" if inp.embed.cycles > 0: pstr("Starting " + smethod) inp.error = 1. inp.ift = 0 while ((inp.error > inp.embed.conv) and (inp.ift < inp.embed.cycles)): inp.ift += 1 inp.prev_error = copy(inp.error) inp.error = 0. # cycle over active subsystems for a in range(nsub): if inp.embed.freezeb and a > 0: continue # perform embedding of this subsystem inp.timer.start("TOT. EMBED. OF {0}".format(a + 1)) Fock, inp.mSCF[a], Dnew, eproj, err = do_embedding( a, inp, inp.mSCF, Hcore, Dmat, Smat, Fock, cycles=inp.embed.subcycles, conv=inp.embed.conv, llast=False) er = sp.linalg.norm(Dnew - Dmat[a]) Dmat[a] = np.copy(Dnew) print(' iter: {0:>3d}:{1:<2d} |ddm|: {2:12.6e} ' 'Tr[DP] {3:13.6e}'.format(inp.ift, a + 1, er, eproj)) inp.error += er inp.timer.end("TOT. EMBED. OF {0}".format(a + 1)) print("FOCK") print(Fock) # print whether freeze-and-thaw has converged if ((inp.embed.cycles > 1 and inp.error < inp.embed.conv) or (inp.embed.cycles == 1 and err < inp.embed.conv)): pstr(smethod + " converged!", delim=" ", addline=False) elif inp.embed.cycles == 0: pass else: pstr(smethod + " NOT converged!", delim=" ", addline=False) #DFT in DFT Breakdown superMol = concatenate_mols(inp.mol[0], inp.mol[1]) # do final embedded cycle at high level of theory if inp.embed.cycles > -1: inp.timer.start("TOT. EMBED. OF 1") maxiter = inp.embed.subcycles conv = inp.embed.conv if inp.embed.method != inp.method: pstr("Subsystem 1 at higher mean-field method", delim="=") maxiter = inp.maxiter conv = inp.conv Fock, mSCF_A, DA, eproj, err = do_embedding(0, inp, inp.mSCF, Hcore, Dmat, Smat, Fock, cycles=maxiter, conv=conv, llast=True) er = sp.linalg.norm(DA - Dmat[0]) print(' iter: {0:>3d}:{1:<2d} |ddm|: {2:12.6e} ' 'Tr[DP] {3:13.6e}'.format(inp.ift + 1, 1, er, eproj)) inp.timer.end("TOT. EMBED. OF 1") if inp.embed.method != inp.method: inp.eHI = mSCF_A.e_tot else: inp.eHI = None inp.timer.end("FREEZE AND THAW") # if WFT-in-(DFT/HF), do WFT theory calculation here if inp.method == 'ccsd' or inp.method == 'ccsd(t)': inp.timer.start("CCSD") pstr("Doing CCSD Calculation on Subsystem 1") mCCSD = cc.CCSD(mSCF_A) ecc, t1, t2 = mCCSD.kernel() inp.eHI = mSCF_A.e_tot + ecc inp.timer.end("CCSD") print("Hartree-Fock Energy: {0:19.14f}".format(mSCF_A.e_tot)) print("CCSD Correlation: {0:19.14f}".format(ecc)) print("CCSD Energy: {0:19.14f}".format(mSCF_A.e_tot + ecc)) if inp.method == 'ccsd(t)': from pyscf.cc import ccsd_t, ccsd_t_lambda_slow, ccsd_t_rdm_slow inp.timer.start("CCSD(T)") pstr("Doing CCSD(T) Calculation on Subsystem 1") ecc += ccsd_t.kernel(mCCSD, mCCSD.ao2mo()) inp.eHI = mSCF_A.e_tot + ecc inp.timer.end("CCSD(T)") print("Hartree-Fock Energy: {0:19.14f}".format(mSCF_A.e_tot)) print("CCSD(T) Correlation: {0:19.14f}".format(ecc)) print("CCSD(T) Energy: {0:19.14f}".format(mSCF_A.e_tot + ecc)) if inp.method == 'fci': from pyscf import fci inp.timer.start("FCI") pstr("Doing FCI Calculation on Subsystem 1") #Found here: https://github.com/sunqm/pyscf/blob/master/examples/fci/00-simple_fci.py cisolver = fci.FCI(inp.mol[0], mSCF_A.mo_coeff) efci = cisolver.kernel()[0] inp.eHI = efci inp.timer.end("FCI") print("Hartree-Fock Energy: {0:19.14f}".format(mSCF_A.e_tot)) print("FCI Correlation: {0:19.14f}".format(efci - mSCF_A.e_tot)) print("FCI Energy: {0:19.14f}".format(efci)) # get interaction energy inp.timer.start("INTERACTION ENERGIES") ldosup = not inp.embed.localize if ldosup: pstr("Supermolecular DFT") Etot, EA = get_interaction_energy(inp, Dmat, Smat, ldosup=ldosup) inp.timer.end("INTERACTION ENERGIES") if inp.gencube == "final": inp.timer.start("Generate Cube file") molA_cubename = filename.split(".")[0] + "_A.cube" molB_cubename = filename.split(".")[0] + "_B.cube" cubegen.density(inp.mol[0], molA_cubename, Dmat[0]) cubegen.density(inp.mol[1], molB_cubename, Dmat[1]) inp.timer.end("Generate Cube file") pstr("Embedding Energies", delim="=") Eint = Etot - EA Ediff = inp.Esup - Etot print("Subsystem DFT {0:19.14f}".format(EA)) print("Interaction {0:19.14f}".format(Eint)) print("DFT-in-DFT {0:19.14f}".format(Etot)) print("Supermolecular DFT {0:19.14f}".format(inp.Esup)) print("Difference {0:19.14f}".format(Ediff)) print("Corrected DFT-in-DFT {0:19.14f}".format(Etot + Ediff)) if inp.eHI is not None: print("WF-in-DFT {0:19.14f}".format(inp.eHI + Eint)) print("Corrected WF-in-DFT {0:19.14f}".format(inp.eHI + Eint + Ediff)) # close and print timings inp.timer.close() # print end of file pstr("", delim="*") pstr("END OF CYCLE", delim="*", fill=False, addline=False) pstr("", delim="*", addline=False) G_tot = grad.rks.Gradient(inp.sSCF) G_tot_mat = G_tot.grad() print(G_tot_mat)
def FCI(self): ''' FCI solver from PySCF ''' Nimp = self.Nimp FOCKcopy = self.FOCK.copy() - self.chempot self.mol.nelectron = self.Nel self.mf.__init__(self.mol) self.mf.get_hcore = lambda *args: FOCKcopy self.mf.get_ovlp = lambda *args: np.eye(self.Norb) self.mf._eri = ao2mo.restore(8, self.TEI, self.Norb) self.mf.scf(self.DMguess) DMloc = np.dot(np.dot(self.mf.mo_coeff, np.diag(self.mf.mo_occ)), self.mf.mo_coeff.T) if (self.mf.converged == False): self.mf.newton().kernel(dm0=DMloc) DMloc = np.dot(np.dot(self.mf.mo_coeff, np.diag(self.mf.mo_occ)), self.mf.mo_coeff.T) # Create and solve the fci object if self.e_shift == None: self.fs = fci.FCI(self.mf, self.mf.mo_coeff) else: self.fs = fci.addons.fix_spin_(fci.FCI(self.mf, self.mf.mo_coeff), self.e_shift) self.fs.verbose = self.verbose self.fs.fs_conv_tol = self.fs_conv_tol self.fs.conv_tol_residual = self.fs_conv_tol_residual self.fs.nroots = self.nroots if self.ci is not None: ci0 = self.ci else: ci0 = None EFCI, fcivec = self.fs.kernel(ci0=ci0) self.ci = fcivec # Compute energy and RDM1 if self.nroots == 1: if self.fs.converged == False: print(' WARNING: The solver is not converged') self.SS = self.fs.spin_square(fcivec, self.Norb, self.mol.nelec)[0] RDM1_mo , RDM2_mo = self.fs.make_rdm12(fcivec, self.Norb, self.mol.nelec) # Transform RDM1 , RDM2 to local basis RDM1 = lib.einsum('ap,pq->aq', self.mf.mo_coeff, RDM1_mo) RDM1 = lib.einsum('bq,aq->ab', self.mf.mo_coeff, RDM1) RDM2 = lib.einsum('ap,pqrs->aqrs', self.mf.mo_coeff, RDM2_mo) RDM2 = lib.einsum('bq,aqrs->abrs', self.mf.mo_coeff, RDM2) RDM2 = lib.einsum('cr,abrs->abcs', self.mf.mo_coeff, RDM2) RDM2 = lib.einsum('ds,abcs->abcd', self.mf.mo_coeff, RDM2) ImpurityEnergy = 0.50 * lib.einsum('ij,ij->', RDM1[:Nimp,:], self.FOCK[:Nimp,:] + self.OEI[:Nimp,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', RDM2[:Nimp,:,:,:], self.TEI[:Nimp,:,:,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', RDM2[:,:Nimp,:,:], self.TEI[:,:Nimp,:,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', RDM2[:,:,:Nimp,:], self.TEI[:,:,:Nimp,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', RDM2[:,:,:,:Nimp], self.TEI[:,:,:,:Nimp]) e_cell = self.kmf_ecore + ImpurityEnergy else: if self.fs.converged.any() == False: print(' WARNING: The solver is not converged') tot_SS = 0 RDM1 = [] e_cell = [] for i, vec in enumerate(fcivec): SS = self.fs.spin_square(vec, self.Norb, self.mol.nelec)[0] rdm1_mo , rdm2_mo = self.fs.make_rdm12(vec, self.Norb, self.mol.nelec) # Transform rdm1 , rdm2 to local basis rdm1 = lib.einsum('ap,pq->aq', self.mf.mo_coeff, rdm1_mo) rdm1 = lib.einsum('bq,aq->ab', self.mf.mo_coeff, rdm1) rdm2 = lib.einsum('ap,pqrs->aqrs', self.mf.mo_coeff, rdm2_mo) rdm2 = lib.einsum('bq,aqrs->abrs', self.mf.mo_coeff, rdm2) rdm2 = lib.einsum('cr,abrs->abcs', self.mf.mo_coeff, rdm2) rdm2 = lib.einsum('ds,abcs->abcd', self.mf.mo_coeff, rdm2) Imp_Energy_state = 0.50 * lib.einsum('ij,ij->', rdm1[:Nimp,:], self.FOCK[:Nimp,:] + self.OEI[:Nimp,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', rdm2[:Nimp,:,:,:], self.TEI[:Nimp,:,:,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', rdm2[:,:Nimp,:,:], self.TEI[:,:Nimp,:,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', rdm2[:,:,:Nimp,:], self.TEI[:,:,:Nimp,:]) \ + 0.125 * lib.einsum('ijkl,ijkl->', rdm2[:,:,:,:Nimp], self.TEI[:,:,:,:Nimp]) Imp_e = self.kmf_ecore + Imp_Energy_state print(' Root %d: E(Solver) = %12.8f E(Imp) = %12.8f <S^2> = %12.8f' % (i, e[i], Imp_e, SS)) tot_SS += SS RDM1.append(rdm1) e_cell.append(Imp_e) RDM1 = lib.einsum('i,ijk->jk',self.state_percent, RDM1) e_cell = lib.einsum('i,i->',self.state_percent, e_cell) self.SS = tot_SS/self.nroots return (e_cell, EFCI, RDM1)
Applying creation or annihilation operators on FCI wavefunction a |0> Compute density matrices by gamma_{ij} = <0| i^+ j |0> Gamma_{ij,kl} = <0| i^+ j^+ l k |0> ''' import numpy from pyscf import gto, scf, fci verbose = True # RHF calc of HLi for comparison mol = gto.M(atom='H 0 0 0; Li 0 0 1.1', basis='sto3g') m = scf.RHF(mol).run() fs = fci.FCI(mol, m.mo_coeff) e, c = fs.kernel() norb = m.mo_energy.size neleca = nelecb = mol.nelectron // 2 if (verbose): print("norb = ", norb, " neleca = ", neleca) # # Spin-free 1-particle density matrix # <Psi| a_{i\alpha}^\dagger a_{j\alpha} + a_{i\beta}^\dagger a_{j\beta} |Psi> # if (verbose): print("1 particle density matrix") dm1 = numpy.zeros((norb, norb))
#!/usr/bin/env python # # Author: Qiming Sun <*****@*****.**> # ''' Transform FCI wave functions according to the underlying one-particle basis transformations. ''' from functools import reduce import numpy from pyscf import gto, scf, fci myhf1 = gto.M(atom='H 0 0 0; F 0 0 1.1', basis='6-31g', verbose=0).apply(scf.RHF).run() e1, ci1 = fci.FCI(myhf1.mol, myhf1.mo_coeff).kernel() print('FCI energy of mol1', e1) myhf2 = gto.M(atom='H 0 0 0; F 0 0 1.2', basis='6-31g', verbose=0).apply(scf.RHF).run() s12 = gto.intor_cross('cint1e_ovlp_sph', myhf1.mol, myhf2.mol) s12 = reduce(numpy.dot, (myhf1.mo_coeff.T, s12, myhf2.mo_coeff)) norb = myhf2.mo_energy.size nelec = myhf2.mol.nelectron ci2 = fci.addons.transform_ci_for_orbital_rotation(ci1, norb, nelec, s12) print('alpha-string, beta-string, CI coefficients') for c, stra, strb in fci.addons.large_ci(ci2, norb, nelec): print(stra, strb, c)
def test__init__file(self): c1 = fci.FCI(mol, m.mo_coeff) self.assertAlmostEqual(c1.kernel()[0], -2.8227809167209683, 9)
cisolver = fci.FCI(mol, myhf.mo_coeff) print('E(HF) = %.12f, E(FCI) = %.12f' % (E, (cisolver.kernel()[0] + mol.energy_nuc()))) def amplitude(det, excitation): return 0.1 ############# # INITIALIZE ############# myhf = scf.RHF(mol) E = myhf.kernel() c = myhf.mo_coeff cisolver = fci.FCI(mol, c) print('PYSCF E(FCI) = %.12f' % (cisolver.kernel()[0] + mol.energy_nuc())) h1e = reduce(np.dot, (c.T, myhf.get_hcore(), c)) eri = ao2mo.kernel(mol, c) cdets = 25 tdets = 50 threshold = 1e-13 #threshold for hii and hij #use eri[idx2(i,j),idx2(k,l)] to get (ij|kl) chemists' notation 2e- ints #make full 4-index eris in MO basis (only for testing idx2) #eri_mo = ao2mo.restore(1, eri, nao) #eri in AO basis #eri_ao = mol.intor('cint2e_sph') #eri_ao = eri_ao.reshape([nao,nao,nao,nao])
of alpha electrons; the second is the number of beta electrons. If spin-contamination is observed on FCI wavefunction, we can use the decoration function :func:`fci.addons.fix_spin_` to level shift the energy of states which do not have the target spin. ''' import numpy from pyscf import gto, scf, fci mol = gto.M(atom='Ne 0 0 0', basis='631g', spin=2) m = scf.RHF(mol) m.kernel() norb = m.mo_energy.size fs = fci.FCI(mol, m.mo_coeff) e, c = fs.kernel() print('E = %.12f 2S+1 = %.7f' % (e, fs.spin_square(c, norb, (6, 4))[1])) e, c = fs.kernel(nelec=(5, 5)) print('E = %.12f 2S+1 = %.7f' % (e, fs.spin_square(c, norb, (5, 5))[1])) fs = fci.addons.fix_spin_(fci.FCI(mol, m.mo_coeff), shift=.5) e, c = fs.kernel() print('E = %.12f 2S+1 = %.7f' % (e, fs.spin_square(c, norb, (6, 4))[1])) # # Example 2: Oxygen molecule singlet state # nelec = (8, 8)
#!/usr/bin/env python # # Author: Qiming Sun <*****@*****.**> # ''' A simple example to run FCI ''' from pyscf import gto, scf, fci mol = gto.Mole() mol.build( atom='H 0 0 0; F 0 0 1.1', # in Angstrom basis='6-31g', symmetry=True, ) myhf = scf.RHF(mol) myhf.kernel() # # Function fci.FCI creates an FCI solver based on the given orbitals and the # num. electrons and spin of the given mol object # cisolver = fci.FCI(mol, myhf.mo_coeff) print('E(FCI) = %.12f' % (cisolver.kernel()[0] + mol.energy_nuc()))
def solve( CONST, OEI, FOCK, TEI, Norb, Nel, Nimp, DMguessRHF, chempot_imp): # Augment the FOCK operator with the chemical potential FOCKcopy = FOCK.copy() if (chempot_imp != 0.0): for orb in range(Nimp): FOCKcopy[ orb, orb ] -= chempot_imp # Get the RHF solution mol = gto.Mole() mol.build( verbose=0 ) mol.atom.append(('C', (0, 0, 0))) mol.nelectron = Nel mol.incore_anyway = True mf = scf.RHF( mol ) mf.get_hcore = lambda *args: FOCKcopy mf.get_ovlp = lambda *args: np.eye( Norb ) mf._eri = ao2mo.restore(8, TEI, Norb) mf.scf( DMguessRHF ) DMloc = np.dot(np.dot( mf.mo_coeff, np.diag( mf.mo_occ )), mf.mo_coeff.T ) if ( mf.converged == False ): mf = mf.newton() DMloc = np.dot(np.dot( mf.mo_coeff, np.diag( mf.mo_occ )), mf.mo_coeff.T ) # Check the RHF solution assert( Nel % 2 == 0 ) numPairs = Nel / 2 FOCKloc = FOCKcopy + np.einsum('ijkl,ij->kl', TEI, DMloc) - 0.5 * np.einsum('ijkl,ik->jl', TEI, DMloc) eigvals, eigvecs = np.linalg.eigh( FOCKloc ) idx = eigvals.argsort() eigvals = eigvals[ idx ] eigvecs = eigvecs[ :, idx ] # print "psi4cc::solve : RHF h**o-lumo gap =", eigvals[numPairs] - eigvals[numPairs-1] DMloc2 = 2 * np.dot( eigvecs[ :, :numPairs ], eigvecs[ :, :numPairs ].T ) # print "Two-norm difference of 1-RDM(RHF) and 1-RDM(FOCK(RHF)) =", np.linalg.norm(DMloc - DMloc2) # Get the fci solution from pyscf fcisolver = fci.FCI( mf ) fcisolver.verbose = 1 E, fcivec = fcisolver.kernel() # Compute the impurity energy pyscfRDM1 = fcisolver.make_rdm1(fcivec, Norb, Nel) # MO space pyscfRDM2 = fcisolver.make_rdm2(fcivec, Norb, Nel) # MO space pyscfRDM1 = 0.5 * ( pyscfRDM1 + pyscfRDM1.T ) # Symmetrize # Change the pyscfRDM1/2 from MO space to localized space pyscfRDM1 = np.dot(mf.mo_coeff, np.dot(pyscfRDM1, mf.mo_coeff.T )) pyscfRDM2 = np.einsum('ai,ijkl->ajkl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('bj,ajkl->abkl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('ck,abkl->abcl', mf.mo_coeff, pyscfRDM2) pyscfRDM2 = np.einsum('dl,abcl->abcd', mf.mo_coeff, pyscfRDM2) # To calculate the impurity energy, rescale the JK matrix with a factor 0.5 to avoid double counting: 0.5 * ( OEI + FOCK ) = OEI + 0.5 * JK ImpurityEnergy = CONST \ + 0.25 * np.einsum('ij,ij->', pyscfRDM1[:Nimp,:], FOCK[:Nimp,:] + OEI[:Nimp,:]) \ + 0.25 * np.einsum('ij,ij->', pyscfRDM1[:,:Nimp], FOCK[:,:Nimp] + OEI[:,:Nimp]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:Nimp,:,:,:], TEI[:Nimp,:,:,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:Nimp,:,:], TEI[:,:Nimp,:,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:,:Nimp,:], TEI[:,:,:Nimp,:]) \ + 0.125 * np.einsum('ijkl,ijkl->', pyscfRDM2[:,:,:,:Nimp], TEI[:,:,:,:Nimp]) return ( ImpurityEnergy, pyscfRDM1 )