def get_molecular_data(interaction_operator, geometry=None, basis=None, multiplicity=None, n_electrons=None, reduce_spin=True, data_directory=None): """Output a MolecularData object generated from an InteractionOperator Args: interaction_operator(InteractionOperator): two-body interaction operator defining the "molecular interaction" to be simulated. geometry(string or list of atoms): basis(string): String denoting the basis set used to discretize the system. multiplicity(int): Spin multiplicity desired in the system. n_electrons(int): Number of electrons in the system reduce_spin(bool): True if one wishes to perform spin reduction on integrals that are given in interaction operator. Assumes spatial (x) spin structure generically. Returns: molecule(MolecularData): Instance that captures the interaction_operator converted into the format that would come from an electronic structure package adorned with some meta-data that may be useful. """ n_spin_orbitals = interaction_operator.n_qubits # Introduce bare molecular operator to fill molecule = MolecularData(geometry=geometry, basis=basis, multiplicity=multiplicity, data_directory=data_directory) molecule.nuclear_repulsion = interaction_operator.constant # Remove spin from integrals and put into molecular operator if reduce_spin: reduction_indices = list(range(0, n_spin_orbitals, 2)) else: reduction_indices = list(range(n_spin_orbitals)) molecule.n_orbitals = len(reduction_indices) molecule.one_body_integrals = interaction_operator.one_body_tensor[ numpy.ix_(reduction_indices, reduction_indices)] molecule.two_body_integrals = interaction_operator.two_body_tensor[ numpy.ix_(reduction_indices, reduction_indices, reduction_indices, reduction_indices)] # Fill in other metadata molecule.overlap_integrals = numpy.eye(molecule.n_orbitals) molecule.n_qubits = n_spin_orbitals molecule.n_electrons = n_electrons molecule.multiplicity = multiplicity return molecule
def _build_of_molecule(self, molecule, mean_field): """Initialize the instance of Openfermion MolecularData class. Interface the pyscf and Openfermion data. `pyscf.ao2mo` is used to transform the AO integrals into the MO integrals. Args: molecule (pyscf.gto.Mole): The molecule to simulate. mean_field (pyscf.scf.RHF): The mean field of the molecule. Returns: openfermion.hamiltonian.MolecularData: Molecular Data in Openfermion (of_mole). """ of_mole = MolecularData(geometry=molecule.atom, basis=molecule.basis, multiplicity=molecule.spin + 1) of_mole.mf = mean_field of_mole.mol = molecule of_mole.n_atoms = molecule.natm of_mole.atoms = [row[0] for row in molecule.atom], of_mole.protons = 0 of_mole.nuclear_repulsion = molecule.energy_nuc() of_mole.charge = molecule.charge of_mole.n_electrons = molecule.nelectron of_mole.n_orbitals = len(mean_field.mo_energy) of_mole.n_qubits = 2 * of_mole.n_orbitals of_mole.hf_energy = mean_field.e_tot of_mole.orbital_energies = mean_field.mo_energy of_mole.mp2_energy = None of_mole.cisd_energy = None of_mole.fci_energy = None of_mole.ccsd_energy = None of_mole.general_calculations = {} of_mole._canonical_orbitals = mean_field.mo_coeff of_mole._overlap_integrals = mean_field.get_ovlp() of_mole.h_core = mean_field.get_hcore() of_mole._one_body_integrals = of_mole._canonical_orbitals.T @ of_mole.h_core @ of_mole._canonical_orbitals twoint = mean_field._eri eri = ao2mo.restore(8, twoint, of_mole.n_orbitals) eri = ao2mo.incore.full(eri, of_mole._canonical_orbitals) eri = ao2mo.restore(1, eri, of_mole.n_orbitals) of_mole._two_body_integrals = np.asarray(eri.transpose(0, 2, 3, 1), order='C') return of_mole
def make_molecular_energy_obj(molecule_name, basis="sto-3g", geometry_info=None, n_cancel_orbital=0, n_frozen_orbital=0, cas_irrep_nocc=None, cas_irrep_ncore=None, fermi_qubit_transform=bravyi_kitaev, is_computed=False): if geometry_info == None: geometry_info = equilibrium_geometry_dict[molecule_name] # Get geometry if molecule_name not in geometry_generator_dict.keys(): print("No such example molecule, using default H2 hamiltonian.") molecule_name = "H2" geometry = geometry_generator_dict[molecule_name](geometry_info) # Get fermion Hamiltonian multiplicity = 1 charge = 0 molecule = MolecularData(geometry, basis, multiplicity, charge, str(geometry_info)) molecule.symmetry = True if not is_computed: molecule = run_pyscf(molecule, run_fci=1, n_frozen_orbital=n_frozen_orbital, n_cancel_orbital=n_cancel_orbital, cas_irrep_nocc=cas_irrep_nocc, cas_irrep_ncore=cas_irrep_ncore, verbose=False) molecule.load() active_space_start = n_frozen_orbital active_space_stop = molecule.n_orbitals - n_cancel_orbital n_active_orb = active_space_stop - active_space_start molecule.n_orbitals = n_active_orb molecule.n_qubits = n_active_orb * 2 molecule.n_electrons = molecule.n_electrons - active_space_start * 2 fermion_hamiltonian = get_fermion_operator( molecule.get_molecular_hamiltonian( occupied_indices=molecule.frozen_orbitals, active_indices=molecule.active_orbitals)) # Map ferimon Hamiltonian to qubit Hamiltonian qubit_hamiltonian = fermi_qubit_transform(fermion_hamiltonian) # qubit_electron_operator=fermi_qubit_transform(get_electron_fermion_operator(molecule.n_electrons)) qubit_electron_operator = get_HF_operator(molecule.n_electrons, fermi_qubit_transform) # qubit_hamiltonian=get_dressed_operator(qubit_electron_operator,qubit_hamiltonian) # Ignore terms in Hamiltonian that close to zero qubit_hamiltonian.compress() # Set the terminate_energy to be achieving the chemical accuracy terminate_energy = molecule.fci_energy + CHEMICAL_ACCURACY obj_info = { "n_qubit": molecule.n_qubits, "start_cost": molecule.hf_energy, "terminate_cost": terminate_energy } init_operator = HartreeFockInitBlock( get_operator_qsubset(qubit_electron_operator)) return EnergyObjective(qubit_hamiltonian, molecule.n_qubits, init_operator, obj_info)