Exemplo n.º 1
0
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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
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)