def make_h3_2_5() -> Tuple[RestrictedHartreeFockObjective, of.MolecularData, np.ndarray, np.ndarray, np.ndarray]: # load the molecule from moelcular data h3_2_5_path = os.path.join( hfvqe.__path__[0], 'molecular_data/hydrogen_chains/h_3_p_sto-3g/bond_distance_2.5') molfile = os.path.join(h3_2_5_path, 'H3_plus_sto-3g_singlet_linear_r-2.5.hdf5') molecule = of.MolecularData(filename=molfile) molecule.load() S = np.load(os.path.join(h3_2_5_path, 'overlap.npy')) Hcore = np.load(os.path.join(h3_2_5_path, 'h_core.npy')) TEI = np.load(os.path.join(h3_2_5_path, 'tei.npy')) _, X = sp.linalg.eigh(Hcore, S) obi = of.general_basis_change(Hcore, X, (1, 0)) tbi = np.einsum('psqr', of.general_basis_change(TEI, X, (1, 0, 1, 0))) molecular_hamiltonian = generate_hamiltonian(obi, tbi, molecule.nuclear_repulsion) rhf_objective = RestrictedHartreeFockObjective(molecular_hamiltonian, molecule.n_electrons) scipy_result = rhf_minimization(rhf_objective) return rhf_objective, molecule, scipy_result.x, obi, tbi
def make_h3_2_5(molecular_data_directory=None) \ -> Tuple[RestrictedHartreeFockObjective, of.MolecularData, np.ndarray, np.ndarray, np.ndarray]: if molecular_data_directory is None: molecular_data_directory = _MOLECULAR_DATA_DIRECTORY h3_2_5_path = f'{molecular_data_directory}/hydrogen_chains/h_3_p_sto-3g/bond_distance_2.5' molfile = f'{h3_2_5_path}/H3_plus_sto-3g_singlet_linear_r-2.5.hdf5' molecule = of.MolecularData(filename=molfile) molecule.load() S = np.load(os.path.join(h3_2_5_path, 'overlap.npy')) Hcore = np.load(os.path.join(h3_2_5_path, 'h_core.npy')) TEI = np.load(os.path.join(h3_2_5_path, 'tei.npy')) _, X = sp.linalg.eigh(Hcore, S) obi = of.general_basis_change(Hcore, X, (1, 0)) tbi = np.einsum('psqr', of.general_basis_change(TEI, X, (1, 0, 1, 0))) molecular_hamiltonian = generate_hamiltonian(obi, tbi, molecule.nuclear_repulsion) rhf_objective = RestrictedHartreeFockObjective(molecular_hamiltonian, molecule.n_electrons) scipy_result = rhf_minimization(rhf_objective) return rhf_objective, molecule, scipy_result.x, obi, tbi
def h_n_linear_molecule(bond_distance: float, n_hydrogens: int, basis: str = 'sto-3g'): # coverage: ignore if n_hydrogens < 1 or n_hydrogens % 2 != 0: raise ValueError('Must specify a positive, even number of hydrogens.') molecule = of.MolecularData( geometry=_h_n_linear_geometry(bond_distance, n_hydrogens), charge=0, basis=basis, multiplicity=1, description=f"linear_r-{bond_distance}", ) if NO_OFPSI4: raise NOOFPsi4Error("openfermion-psi4 is not installed") molecule = run_psi4(molecule, run_fci=False, run_mp2=False, run_cisd=False, run_ccsd=False, delete_input=False, delete_output=False) return molecule
def make_hn( hcount, distance ) -> Tuple[RestrictedHartreeFockObjective, of.MolecularData, np.ndarray, np.ndarray, np.ndarray]: shcount = str(hcount) sdistance = str(distance) cwd = os.path.dirname(os.path.realpath(__file__)) hn_path = str( Path(cwd + "/molecular_data/hydrogen_chains/h_" + shcount + "_sto-3g/bond_distance_" + sdistance + "/")) hdf5name = str("H" + shcount + "_sto-3g_singlet_linear_r-" + sdistance + ".hdf5") molfile = os.path.join(hn_path, hdf5name) molecule = of.MolecularData(filename=molfile) molecule.load() S = np.load(os.path.join(hn_path, 'overlap.npy')) Hcore = np.load(os.path.join(hn_path, 'h_core.npy')) TEI = np.load(os.path.join(hn_path, 'tei.npy')) _, X = sp.linalg.eigh(Hcore, S) obi = of.general_basis_change(Hcore, X, (1, 0)) tbi = np.einsum('psqr', of.general_basis_change(TEI, X, (1, 0, 1, 0))) molecular_hamiltonian = generate_hamiltonian(obi, tbi, molecule.nuclear_repulsion) rhf_objective = RestrictedHartreeFockObjective(molecular_hamiltonian, molecule.n_electrons) scipy_result = rhf_minimization(rhf_objective) return rhf_objective, molecule, scipy_result.x, obi, tbi
def load_molecular_hamiltonian( geometry, basis, multiplicity, description, n_active_electrons, n_active_orbitals): molecule = openfermion.MolecularData( geometry, basis, multiplicity, description=description) molecule.load() n_core_orbitals = (molecule.n_electrons - n_active_electrons) // 2 occupied_indices = list(range(n_core_orbitals)) active_indices = list(range(n_core_orbitals, n_core_orbitals + n_active_orbitals)) return molecule.get_molecular_hamiltonian( occupied_indices=occupied_indices, active_indices=active_indices)
def main(): from itertools import product import pyscf import openfermion as of from openfermion.chem.molecular_data import spinorb_from_spatial from openfermionpyscf import run_pyscf from pyscf.cc.addons import spatial2spin import numpy as np basis = 'cc-pvdz' mol = pyscf.M(atom='H 0 0 0; B 0 0 {}'.format(1.6), basis=basis) mf = mol.RHF().run() mycc = mf.CCSD().run() print('CCSD correlation energy', mycc.e_corr) molecule = of.MolecularData(geometry=[['H', (0, 0, 0)], ['B', (0, 0, 1.6)]], basis=basis, charge=0, multiplicity=1) molecule = run_pyscf(molecule, run_ccsd=True) oei, tei = molecule.get_integrals() norbs = int(mf.mo_coeff.shape[1]) occ = mf.mo_occ nele = int(sum(occ)) nocc = nele // 2 assert np.allclose(np.transpose(mycc.t2, [1, 0, 3, 2]), mycc.t2) soei, stei = spinorb_from_spatial(oei, tei) astei = np.einsum('ijkl', stei) - np.einsum('ijlk', stei) # put in physics notation. OpenFermion stores <12|2'1'> gtei = astei.transpose(0, 1, 3, 2) eps = np.kron(molecule.orbital_energies, np.ones(2)) n = np.newaxis o = slice(None, 2 * nocc) v = slice(2 * nocc, None) e_abij = 1 / (-eps[v, n, n, n] - eps[n, v, n, n] + eps[n, n, o, n] + eps[n, n, n, o]) e_ai = 1 / (-eps[v, n] + eps[n, o]) fock = soei + np.einsum('piiq->pq', astei[:, o, o, :]) hf_energy = 0.5 * np.einsum('ii', (fock + soei)[o, o]) hf_energy_test = 1.0 * einsum('ii', fock[o, o]) - 0.5 * einsum( 'ijij', gtei[o, o, o, o]) print(hf_energy_test, hf_energy) assert np.isclose(hf_energy + molecule.nuclear_repulsion, molecule.hf_energy) g = gtei nsvirt = 2 * (norbs - nocc) nsocc = 2 * nocc t1f, t2f = kernel(np.zeros((nsvirt, nsocc)), np.zeros((nsvirt, nsvirt, nsocc, nsocc)), fock, g, o, v, e_ai, e_abij) print(ccsd_energy(t1f, t2f, fock, g, o, v) - hf_energy) t1f, t2f = kernel(np.zeros((nsvirt, nsocc)), np.zeros((nsvirt, nsvirt, nsocc, nsocc)), fock, g, o, v, e_ai, e_abij, diis_size=8, diis_start_cycle=4) print(ccsd_energy(t1f, t2f, fock, g, o, v) - hf_energy)
def main(): """ Example for solving CC3 amplitude equations """ import pyscf import openfermion as of from openfermion.chem.molecular_data import spinorb_from_spatial from openfermionpyscf import run_pyscf from pyscf.cc.addons import spatial2spin from pyscf import cc import numpy as np np.set_printoptions(linewidth=500) # run pyscf for some reason basis = '6-31g' mol = pyscf.M( atom='H 0 0 0; F 0 0 {}'.format(1.6), basis=basis) mf = mol.RHF() mf.verbose = 0 mf.run() # build molecule and run pyscf again for some reason molecule = of.MolecularData(geometry=[['H', (0, 0, 0)], ['F', (0, 0, 1.6)]], basis=basis, charge=0, multiplicity=1) molecule = run_pyscf(molecule,run_ccsd=False) # 1-, 2-electron integrals oei, tei = molecule.get_integrals() # Number of orbitals, number of electrons. apparently only works for closed shells occ = mf.mo_occ nele = int(sum(occ)) nocc = nele // 2 norbs = oei.shape[0] nsvirt = 2 * (norbs - nocc) nsocc = 2 * nocc soei, stei = spinorb_from_spatial(oei, tei) astei = np.einsum('ijkl', stei) - np.einsum('ijlk', stei) gtei = astei.transpose(0, 1, 3, 2) eps = np.kron(molecule.orbital_energies, np.ones(2)) n = np.newaxis o = slice(None, nsocc) v = slice(nsocc, None) e_abcijk = 1 / (- eps[v, n, n, n, n, n] - eps[n, v, n, n, n, n] - eps[n, n, v, n, n, n] + eps[n, n, n, o, n, n] + eps[n, n, n, n, o, n] + eps[n, n, n, n, n, o] ) e_abij = 1 / (-eps[v, n, n, n] - eps[n, v, n, n] + eps[n, n, o, n] + eps[ n, n, n, o]) e_ai = 1 / (-eps[v, n] + eps[n, o]) fock = soei + np.einsum('piiq->pq', astei[:, o, o, :]) hf_energy = 0.5 * np.einsum('ii', (fock + soei)[o, o]) hf_energy_test = 1.0 * einsum('ii', fock[o, o]) -0.5 * einsum('ijij', gtei[o, o, o, o]) print("") print(" SCF Total Energy: {: 20.12f}".format(hf_energy + molecule.nuclear_repulsion)) print("") assert np.isclose(hf_energy, mf.e_tot - molecule.nuclear_repulsion) assert np.isclose(hf_energy_test, hf_energy) g = gtei t1z = np.zeros((nsvirt, nsocc)) t2z = np.zeros((nsvirt, nsvirt, nsocc, nsocc)) t3z = np.zeros((nsvirt, nsvirt, nsvirt, nsocc, nsocc, nsocc)) t1f, t2f, t3f = kernel(t1z, t2z, t3z, fock, g, o, v, e_ai, e_abij,e_abcijk,hf_energy, stopping_eps=1e-10) en = ccsd_energy(t1f, t2f, fock, g, o, v) # determine triples amplitudes residual_triples = triples_residual(t1f, t2f, t3f, fock, g, o, v) fock_e_abcijk = np.reciprocal(e_abcijk) triples_res = residual_triples + fock_e_abcijk * t3f t3f = triples_res * e_abcijk # determine (t) correction ... need to transpose t1 t2 first (TODO: fix) l1 = t1f.transpose(1, 0) l2 = t2f.transpose(2, 3, 0, 1) t_en = t_energy(l1, l2, t3f, fock, g, o, v) print("") print(" CCSD Correlation Energy: {: 20.12f}".format(en - hf_energy)) print(" CCSD Total Energy: {: 20.12f}".format(en + molecule.nuclear_repulsion)) print("") print(" (T) Energy: {: 20.12f}".format(t_en)) print(" CCSD(T) Total Energy: {: 20.12f}".format(en + molecule.nuclear_repulsion + t_en)) print("") assert np.isclose(t_en,-0.003382913092468,atol=1e-9) assert np.isclose(en+molecule.nuclear_repulsion+t_en,-100.009057558929399,atol=1e-9)
import openfermion diatomic_bond_length = .7414 geometry = [('H', (0., 0., 0.)), ('H', (0., 0., diatomic_bond_length))] basis = 'sto-3g' multiplicity = 1 charge = 0 description = format(diatomic_bond_length) molecule = openfermion.MolecularData(geometry, basis, multiplicity, description=description) molecule.load() hamiltonian = molecule.get_molecular_hamiltonian() print("Bond Length in Angstroms: {}".format(diatomic_bond_length)) print("Hartree Fock (mean-field) energy in Hartrees: {}".format( molecule.hf_energy)) print("FCI (Exact) energy in Hartrees: {}".format(molecule.fci_energy)) import cirq import openfermioncirq import sympy class MyAnsatz(openfermioncirq.VariationalAnsatz): def params(self): """The parameters of the ansatz.""" return [sympy.Symbol('theta_0')]
uses_bounds=False) optimization_params = OptimizationParams(algorithm=algorithm) # Wave Function Ansatz (parameterized guess) U(theta) ansatz = MyAnsatz() q0, q1, _, _ = ansatz.qubits # Initialize to |11> state ## U(theta)|11> --> best guess ground state preparation_circuit = cq.Circuit.from_ops(cq.X(q0), cq.X(q1)) #%% ## Run a study on a single bond length molecule = of.MolecularData([('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))], 'sto-3g', 1, 0) molecule.load() objective = ofcq.HamiltonianObjective(molecule.get_molecular_hamiltonian()) study = ofcq.VariationalStudy(name='my_hydrogen_study', ansatz=ansatz, objective=objective, preparation_circuit=preparation_circuit) result = study.optimize(optimization_params) print("Initial state energy in Hartrees: {}".format(molecule.hf_energy)) print("Optimized energy result in Hartree: {}".format(result.optimal_value)) print("Exact energy result in Hartees for reference: {}".format( molecule.fci_energy)) #%%
) guess_vecs = [guess_wfn1, guess_wfn2] dl_w, dl_v = davidsonliu_fqe(elec_hamil, 1, guess_vecs, nele=nele, sz=sz, norb=norb) # dummy geometry geometry = [["Li", [0, 0, 0], ["H", [0, 0, 1.4]]]] charge = 0 multiplicity = 1 molecule = of.MolecularData( geometry=geometry, basis="sto-3g", charge=charge, multiplicity=multiplicity, ) molecule.one_body_integrals = h1e molecule.two_body_integrals = np.einsum("ijlk", -2 * h2e) molecular_hamiltonian = molecule.get_molecular_hamiltonian() molecular_hamiltonian.constant = 0 ham_fop = of.get_fermion_operator(molecular_hamiltonian) ham_mat = of.get_sparse_operator(of.jordan_wigner(ham_fop)).toarray() cirq_ci = fqe.to_cirq(wfn) cirq_ci = cirq_ci.reshape((2**12, 1)) assert np.isclose(cirq_ci.conj().T @ ham_mat @ cirq_ci, ecalc) hf_idx = int("111100000000", 2) hf_idx2 = int("111001000000", 2)