Beispiel #1
0
def _calculate_integrals(mol,
                         hf_method='rhf',
                         conv_tol=1e-9,
                         max_cycle=50,
                         init_guess='minao'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        mol (gto.Mole) : A PySCF gto.Mole object.
        hf_method (str): rhf, uhf, rohf
        conv_tol (float): Convergence tolerance
        max_cycle (int): Max convergence cycles
        init_guess (str): Initial guess for SCF
    Returns:
        QMolecule: QMolecule populated with driver integrals etc
    Raises:
        QiskitChemistryError: Invalid hf method type
    """
    enuke = gto.mole.energy_nuc(mol)

    if hf_method == 'rhf':
        m_f = scf.RHF(mol)
    elif hf_method == 'rohf':
        m_f = scf.ROHF(mol)
    elif hf_method == 'uhf':
        m_f = scf.UHF(mol)
    else:
        raise QiskitChemistryError(
            'Invalid hf_method type: {}'.format(hf_method))

    m_f.conv_tol = conv_tol
    m_f.max_cycle = max_cycle
    m_f.init_guess = init_guess
    ehf = m_f.kernel()
    logger.info('PySCF kernel() converged: %s, e(hf): %s', m_f.converged,
                m_f.e_tot)
    if isinstance(m_f.mo_coeff, tuple):
        mo_coeff = m_f.mo_coeff[0]
        mo_coeff_b = m_f.mo_coeff[1]
        # mo_occ   = m_f.mo_occ[0]
        # mo_occ_b = m_f.mo_occ[1]
    else:
        # With PySCF 1.6.2, instead of a tuple of 2 dimensional arrays, its a 3 dimensional
        # array with the first dimension indexing to the coeff arrays for alpha and beta
        if len(m_f.mo_coeff.shape) > 2:
            mo_coeff = m_f.mo_coeff[0]
            mo_coeff_b = m_f.mo_coeff[1]
            # mo_occ   = m_f.mo_occ[0]
            # mo_occ_b = m_f.mo_occ[1]
        else:
            mo_coeff = m_f.mo_coeff
            mo_coeff_b = None
            # mo_occ   = mf.mo_occ
            # mo_occ_b = None
    norbs = mo_coeff.shape[0]

    if isinstance(m_f.mo_energy, tuple):
        orbs_energy = m_f.mo_energy[0]
        orbs_energy_b = m_f.mo_energy[1]
    else:
        # See PYSCF 1.6.2 comment above - this was similarly changed
        if len(m_f.mo_energy.shape) > 1:
            orbs_energy = m_f.mo_energy[0]
            orbs_energy_b = m_f.mo_energy[1]
        else:
            orbs_energy = m_f.mo_energy
            orbs_energy_b = None

    if logger.isEnabledFor(logging.DEBUG):
        # Add some more to PySCF output...
        # First analyze() which prints extra information about MO energy and occupation
        mol.stdout.write('\n')
        m_f.analyze()
        # Now labelled orbitals for contributions to the MOs for s,p,d etc of each atom
        mol.stdout.write('\n\n--- Alpha Molecular Orbitals ---\n\n')
        dump_mat.dump_mo(mol, mo_coeff, digits=7, start=1)
        if mo_coeff_b is not None:
            mol.stdout.write('\n--- Beta Molecular Orbitals ---\n\n')
            dump_mat.dump_mo(mol, mo_coeff_b, digits=7, start=1)
        mol.stdout.flush()

    hij = m_f.get_hcore()
    mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff)
    mohij_b = None
    if mo_coeff_b is not None:
        mohij_b = np.dot(np.dot(mo_coeff_b.T, hij), mo_coeff_b)

    eri = mol.intor('int2e', aosym=1)
    mo_eri = ao2mo.incore.full(m_f._eri, mo_coeff, compact=False)
    mohijkl = mo_eri.reshape(norbs, norbs, norbs, norbs)
    mohijkl_bb = None
    mohijkl_ba = None
    if mo_coeff_b is not None:
        mo_eri_b = ao2mo.incore.full(m_f._eri, mo_coeff_b, compact=False)
        mohijkl_bb = mo_eri_b.reshape(norbs, norbs, norbs, norbs)
        mo_eri_ba = ao2mo.incore.general(
            m_f._eri, (mo_coeff_b, mo_coeff_b, mo_coeff, mo_coeff),
            compact=False)
        mohijkl_ba = mo_eri_ba.reshape(norbs, norbs, norbs, norbs)

    # dipole integrals
    mol.set_common_orig((0, 0, 0))
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    x_dip_ints = ao_dip[0]
    y_dip_ints = ao_dip[1]
    z_dip_ints = ao_dip[2]

    d_m = m_f.make_rdm1(m_f.mo_coeff, m_f.mo_occ)
    if hf_method in ('rohf', 'uhf'):
        d_m = d_m[0]
    elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, d_m).real)
    elec_dip = np.round(elec_dip, decimals=8)
    nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords())
    nucl_dip = np.round(nucl_dip, decimals=8)
    logger.info("HF Electronic dipole moment: %s", elec_dip)
    logger.info("Nuclear dipole moment: %s", nucl_dip)
    logger.info("Total dipole moment: %s", nucl_dip + elec_dip)

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    _q_.origin_driver_version = pyscf_version
    # Energies and orbits
    _q_.hf_energy = ehf
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = mol.nelec[0]
    _q_.num_beta = mol.nelec[1]
    _q_.mo_coeff = mo_coeff
    _q_.mo_coeff_b = mo_coeff_b
    _q_.orbital_energies = orbs_energy
    _q_.orbital_energies_b = orbs_energy_b
    # Molecule geometry
    _q_.molecular_charge = mol.charge
    _q_.multiplicity = mol.spin + 1
    _q_.num_atoms = mol.natm
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([mol.natm, 3])
    _ = mol.atom_coords()
    for n_i in range(0, _q_.num_atoms):
        xyz = mol.atom_coord(n_i)
        _q_.atom_symbol.append(mol.atom_pure_symbol(n_i))
        _q_.atom_xyz[n_i][0] = xyz[0]
        _q_.atom_xyz[n_i][1] = xyz[1]
        _q_.atom_xyz[n_i][2] = xyz[2]
    # 1 and 2 electron integrals AO and MO
    _q_.hcore = hij
    _q_.hcore_b = None
    _q_.kinetic = mol.intor_symmetric('int1e_kin')
    _q_.overlap = m_f.get_ovlp()
    _q_.eri = eri
    _q_.mo_onee_ints = mohij
    _q_.mo_onee_ints_b = mohij_b
    _q_.mo_eri_ints = mohijkl
    _q_.mo_eri_ints_bb = mohijkl_bb
    _q_.mo_eri_ints_ba = mohijkl_ba
    # dipole integrals AO and MO
    _q_.x_dip_ints = x_dip_ints
    _q_.y_dip_ints = y_dip_ints
    _q_.z_dip_ints = z_dip_ints
    _q_.x_dip_mo_ints = QMolecule.oneeints2mo(x_dip_ints, mo_coeff)
    _q_.x_dip_mo_ints_b = None
    _q_.y_dip_mo_ints = QMolecule.oneeints2mo(y_dip_ints, mo_coeff)
    _q_.y_dip_mo_ints_b = None
    _q_.z_dip_mo_ints = QMolecule.oneeints2mo(z_dip_ints, mo_coeff)
    _q_.z_dip_mo_ints_b = None
    if mo_coeff_b is not None:
        _q_.x_dip_mo_ints_b = QMolecule.oneeints2mo(x_dip_ints, mo_coeff_b)
        _q_.y_dip_mo_ints_b = QMolecule.oneeints2mo(y_dip_ints, mo_coeff_b)
        _q_.z_dip_mo_ints_b = QMolecule.oneeints2mo(z_dip_ints, mo_coeff_b)
    # dipole moment
    _q_.nuclear_dipole_moment = nucl_dip
    _q_.reverse_dipole_sign = True

    return _q_
Beispiel #2
0
    def run(
        self, qmolecule: QMolecule
    ) -> Tuple[WeightedPauliOperator, List[WeightedPauliOperator]]:
        """ run method"""
        logger.debug('Processing started...')
        # Save these values for later combination with the quantum computation result
        self._hf_energy = qmolecule.hf_energy
        self._nuclear_repulsion_energy = qmolecule.nuclear_repulsion_energy
        self._nuclear_dipole_moment = qmolecule.nuclear_dipole_moment
        self._reverse_dipole_sign = qmolecule.reverse_dipole_sign

        core_list = qmolecule.core_orbitals if self._freeze_core else []
        reduce_list = self._orbital_reduction

        if self._freeze_core:
            logger.info(
                "Freeze_core specified. Core orbitals to be frozen: %s",
                core_list)
        if reduce_list:
            logger.info("Configured orbital reduction list: %s", reduce_list)
            reduce_list = [
                x + qmolecule.num_orbitals if x < 0 else x for x in reduce_list
            ]

        freeze_list = []
        remove_list = []

        # Orbitals are specified by their index from 0 to n-1, where n is the number of orbitals the
        # molecule has. The combined list of the core orbitals, when freeze_core is true, with any
        # user supplied orbitals is what will be used. Negative numbers may be used to indicate the
        # upper virtual orbitals, so -1 is the highest, then -2 etc. and these will
        # be converted to the
        # positive 0-based index for computation.
        # In the combined list any orbitals that are occupied are added to a freeze list and an
        # energy is stored from these orbitals to be added later.
        # Unoccupied orbitals are just discarded.
        # Because freeze and eliminate is done in separate steps,
        # with freeze first, we have to re-base
        # the indexes for elimination according to how many orbitals were removed when freezing.
        #
        orbitals_list = list(set(core_list + reduce_list))
        num_alpha = qmolecule.num_alpha
        num_beta = qmolecule.num_beta
        new_num_alpha = num_alpha
        new_num_beta = num_beta
        if orbitals_list:
            orbitals_list = np.array(orbitals_list)
            orbitals_list = \
                orbitals_list[(cast(np.ndarray, orbitals_list) >= 0) &
                              (orbitals_list < qmolecule.num_orbitals)]

            freeze_list_alpha = [i for i in orbitals_list if i < num_alpha]
            freeze_list_beta = [i for i in orbitals_list if i < num_beta]
            freeze_list = np.append(
                freeze_list_alpha,
                [i + qmolecule.num_orbitals for i in freeze_list_beta])

            remove_list_alpha = [i for i in orbitals_list if i >= num_alpha]
            remove_list_beta = [i for i in orbitals_list if i >= num_beta]
            rla_adjust = -len(freeze_list_alpha)
            rlb_adjust = -len(freeze_list_alpha) - len(
                freeze_list_beta) + qmolecule.num_orbitals
            remove_list = np.append(
                [i + rla_adjust for i in remove_list_alpha],
                [i + rlb_adjust for i in remove_list_beta])

            logger.info("Combined orbital reduction list: %s", orbitals_list)
            logger.info(
                "  converting to spin orbital reduction list: %s",
                np.append(np.array(orbitals_list),
                          np.array(orbitals_list) + qmolecule.num_orbitals))
            logger.info("    => freezing spin orbitals: %s", freeze_list)
            logger.info(
                "    => removing spin orbitals: %s (indexes accounting for freeze %s)",
                np.append(remove_list_alpha,
                          np.array(remove_list_beta) + qmolecule.num_orbitals),
                remove_list)

            new_num_alpha -= len(freeze_list_alpha)
            new_num_beta -= len(freeze_list_beta)

        new_nel = [new_num_alpha, new_num_beta]

        fer_op = FermionicOperator(h1=qmolecule.one_body_integrals,
                                   h2=qmolecule.two_body_integrals)
        fer_op, self._energy_shift, did_shift = \
            Hamiltonian._try_reduce_fermionic_operator(fer_op, freeze_list, remove_list)
        if did_shift:
            logger.info("Frozen orbital energy shift: %s", self._energy_shift)
        if self._transformation == TransformationType.PARTICLE_HOLE.value:
            fer_op, ph_shift = fer_op.particle_hole_transformation(new_nel)
            self._ph_energy_shift = -ph_shift
            logger.info("Particle hole energy shift: %s",
                        self._ph_energy_shift)
        logger.debug('Converting to qubit using %s mapping',
                     self._qubit_mapping)
        qubit_op = Hamiltonian._map_fermionic_operator_to_qubit(
            fer_op, self._qubit_mapping, new_nel, self._two_qubit_reduction)
        qubit_op.name = 'Electronic Hamiltonian'

        logger.debug('  num paulis: %s, num qubits: %s', len(qubit_op.paulis),
                     qubit_op.num_qubits)

        aux_ops = []

        def _add_aux_op(aux_op, name):
            aux_qop = Hamiltonian._map_fermionic_operator_to_qubit(
                aux_op, self._qubit_mapping, new_nel,
                self._two_qubit_reduction)
            aux_qop.name = name
            aux_ops.append(aux_qop)
            logger.debug('  num paulis: %s', aux_qop.paulis)

        logger.debug('Creating aux op for Number of Particles')
        _add_aux_op(fer_op.total_particle_number(), 'Number of Particles')
        logger.debug('Creating aux op for S^2')
        _add_aux_op(fer_op.total_angular_momentum(), 'S^2')
        logger.debug('Creating aux op for Magnetization')
        _add_aux_op(fer_op.total_magnetization(), 'Magnetization')

        if qmolecule.has_dipole_integrals():

            def _dipole_op(dipole_integrals, axis):
                logger.debug('Creating aux op for dipole %s', axis)
                fer_op_ = FermionicOperator(h1=dipole_integrals)
                fer_op_, shift, did_shift_ = self._try_reduce_fermionic_operator(
                    fer_op_, freeze_list, remove_list)
                if did_shift_:
                    logger.info("Frozen orbital %s dipole shift: %s", axis,
                                shift)
                ph_shift_ = 0.0
                if self._transformation == TransformationType.PARTICLE_HOLE.value:
                    fer_op_, ph_shift_ = fer_op_.particle_hole_transformation(
                        new_nel)
                    ph_shift_ = -ph_shift_
                    logger.info("Particle hole %s dipole shift: %s", axis,
                                ph_shift_)
                qubit_op_ = self._map_fermionic_operator_to_qubit(
                    fer_op_, self._qubit_mapping, new_nel,
                    self._two_qubit_reduction)
                qubit_op_.name = 'Dipole ' + axis
                logger.debug('  num paulis: %s', len(qubit_op_.paulis))
                return qubit_op_, shift, ph_shift_

            op_dipole_x, self._x_dipole_shift, self._ph_x_dipole_shift = \
                _dipole_op(qmolecule.x_dipole_integrals, 'x')
            op_dipole_y, self._y_dipole_shift, self._ph_y_dipole_shift = \
                _dipole_op(qmolecule.y_dipole_integrals, 'y')
            op_dipole_z, self._z_dipole_shift, self._ph_z_dipole_shift = \
                _dipole_op(qmolecule.z_dipole_integrals, 'z')

            aux_ops.append(op_dipole_x)
            aux_ops.append(op_dipole_y)
            aux_ops.append(op_dipole_z)

        logger.info('Molecule num electrons: %s, remaining for processing: %s',
                    [num_alpha, num_beta], new_nel)
        nspinorbs = qmolecule.num_orbitals * 2
        new_nspinorbs = nspinorbs - len(freeze_list) - len(remove_list)
        logger.info(
            'Molecule num spin orbitals: %s, remaining for processing: %s',
            nspinorbs, new_nspinorbs)

        self._add_molecule_info(self.INFO_NUM_PARTICLES,
                                (new_num_alpha, new_num_beta))
        self._add_molecule_info(self.INFO_NUM_ORBITALS, new_nspinorbs)
        self._add_molecule_info(
            self.INFO_TWO_QUBIT_REDUCTION, self._two_qubit_reduction
            if self._qubit_mapping == 'parity' else False)

        z2symmetries = Z2Symmetries([], [], [], None)
        if self._z2symmetry_reduction is not None:
            logger.debug('Processing z2 symmetries')
            qubit_op, aux_ops, z2symmetries = self._process_z2symmetry_reduction(
                qubit_op, aux_ops)
        self._add_molecule_info(self.INFO_Z2SYMMETRIES, z2symmetries)

        logger.debug('Processing complete ready to run algorithm')
        return qubit_op, aux_ops
Beispiel #3
0
    def run(self) -> QMolecule:
        """Constructs a QMolecule instance out of a FCIDump file.

        Returns:
            A QMolecule instance populated with a minimal set of required data.
        """
        fcidump_data = parse(self._fcidump_input)

        q_mol = QMolecule()

        q_mol.nuclear_repulsion_energy = fcidump_data.get('ecore', None)
        q_mol.num_orbitals = fcidump_data.get('NORB')
        q_mol.multiplicity = fcidump_data.get('MS2', 0) + 1
        q_mol.charge = 0  # ensures QMolecule.log() works
        q_mol.num_beta = (fcidump_data.get('NELEC') -
                          (q_mol.multiplicity - 1)) // 2
        q_mol.num_alpha = fcidump_data.get('NELEC') - q_mol.num_beta
        if self.atoms is not None:
            q_mol.num_atoms = len(self.atoms)
            q_mol.atom_symbol = self.atoms
            q_mol.atom_xyz = [[float('NaN')] * 3] * len(
                self.atoms)  # ensures QMolecule.log() works

        q_mol.mo_onee_ints = fcidump_data.get('hij', None)
        q_mol.mo_onee_ints_b = fcidump_data.get('hij_b', None)
        q_mol.mo_eri_ints = fcidump_data.get('hijkl', None)
        q_mol.mo_eri_ints_bb = fcidump_data.get('hijkl_bb', None)
        q_mol.mo_eri_ints_ba = fcidump_data.get('hijkl_ba', None)

        return q_mol
Beispiel #4
0
                     max_cycle=5000,
                     max_memory=1024 * 128,
                     basis='sto3g'
                     )
#driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
#                     unit=UnitsType.ANGSTROM,
#                     basis='sto3g')
                     
#FILENAME = "hdf5_files/femoco_sto3g_(-1,3).hdf5"
#FILENAME = "hdf5_files/femoco_nosulfer_sto3g_(-1,3).hdf5"
FILENAME = "hdf5_files/lih_sto3g_(0,0).hdf5"
#FILENAME = "hdf5_files/hydrogen.hdf5"

if os.path.exists(FILENAME):
    print(f"Found {FILENAME}. Loading...")
    molecule = QMolecule(FILENAME)
    molecule.load()
else:
    # Regenerate
    print(f"Couldn't find {FILENAME}. Regenerating...")
    molecule = driver.run()
    molecule.save(FILENAME)

#print("Loading 1 body integrals...")
#one_body_integrals = molecule.one_body_integrals
##np.save("results/old/lih_1d.npy", one_body_integrals)
#np.save("results/new/lih_1d.npy", one_body_integrals)
#
#print("Loading 2 body integrals...")
#two_body_integrals = molecule.two_body_integrals
#np.save("results/new/lih_2d.npy", two_body_integrals)
    def _parse_matrix_file(self, fname, useao2e=False):
        # get_driver_class is used here because the discovery routine will load all the gaussian
        # binary dependencies, if not loaded already. It won't work without it.
        try:
            # add gauopen to sys.path so that binaries can be loaded
            gauopen_directory = os.path.join(
                os.path.dirname(os.path.realpath(__file__)), 'gauopen')
            if gauopen_directory not in sys.path:
                sys.path.insert(0, gauopen_directory)
            # pylint: disable=import-outside-toplevel
            from .gauopen.QCMatEl import MatEl
        except ImportError as mnfe:
            msg = ('qcmatrixio extension not found. '
                   'See Gaussian driver readme to build qcmatrixio.F using f2py') \
                if mnfe.name == 'qcmatrixio' else str(mnfe)

            logger.info(msg)
            raise QiskitChemistryError(msg)

        mel = MatEl(file=fname)
        logger.debug('MatrixElement file:\n%s', mel)

        # Create driver level molecule object and populate
        _q_ = QMolecule()
        _q_.origin_driver_version = mel.gversion
        # Energies and orbits
        _q_.hf_energy = mel.scalar('ETOTAL')
        _q_.nuclear_repulsion_energy = mel.scalar('ENUCREP')
        _q_.num_orbitals = 0  # updated below from orbital coeffs size
        _q_.num_alpha = (mel.ne + mel.multip - 1) // 2
        _q_.num_beta = (mel.ne - mel.multip + 1) // 2
        moc = self._get_matrix(mel, 'ALPHA MO COEFFICIENTS')
        moc_b = self._get_matrix(mel, 'BETA MO COEFFICIENTS')
        if np.array_equal(moc, moc_b):
            logger.debug(
                'ALPHA and BETA MO COEFFS identical, keeping only ALPHA')
            moc_b = None
        _q_.num_orbitals = moc.shape[0]
        _q_.mo_coeff = moc
        _q_.mo_coeff_b = moc_b
        orbs_energy = self._get_matrix(mel, 'ALPHA ORBITAL ENERGIES')
        _q_.orbital_energies = orbs_energy
        orbs_energy_b = self._get_matrix(mel, 'BETA ORBITAL ENERGIES')
        _q_.orbital_energies_b = orbs_energy_b if moc_b is not None else None
        # Molecule geometry
        _q_.molecular_charge = mel.icharg
        _q_.multiplicity = mel.multip
        _q_.num_atoms = mel.natoms
        _q_.atom_symbol = []
        _q_.atom_xyz = np.empty([mel.natoms, 3])
        syms = mel.ian
        xyz = np.reshape(mel.c, (_q_.num_atoms, 3))
        for n_i in range(0, _q_.num_atoms):
            _q_.atom_symbol.append(QMolecule.symbols[syms[n_i]])
            for idx in range(xyz.shape[1]):
                coord = xyz[n_i][idx]
                if abs(coord) < 1e-10:
                    coord = 0
                _q_.atom_xyz[n_i][idx] = coord

        # 1 and 2 electron integrals
        hcore = self._get_matrix(mel, 'CORE HAMILTONIAN ALPHA')
        logger.debug('CORE HAMILTONIAN ALPHA %s', hcore.shape)
        hcore_b = self._get_matrix(mel, 'CORE HAMILTONIAN BETA')
        if np.array_equal(hcore, hcore_b):
            # From Gaussian interfacing documentation: "The two
            # core Hamiltonians are identical unless
            # a Fermi contact perturbation has been applied."
            logger.debug(
                'CORE HAMILTONIAN ALPHA and BETA identical, keeping only ALPHA'
            )
            hcore_b = None
        logger.debug('CORE HAMILTONIAN BETA %s',
                     '- Not present' if hcore_b is None else hcore_b.shape)
        kinetic = self._get_matrix(mel, 'KINETIC ENERGY')
        logger.debug('KINETIC ENERGY %s', kinetic.shape)
        overlap = self._get_matrix(mel, 'OVERLAP')
        logger.debug('OVERLAP %s', overlap.shape)
        mohij = QMolecule.oneeints2mo(hcore, moc)
        mohij_b = None
        if moc_b is not None:
            mohij_b = QMolecule.oneeints2mo(
                hcore if hcore_b is None else hcore_b, moc_b)

        eri = self._get_matrix(mel, 'REGULAR 2E INTEGRALS')
        logger.debug('REGULAR 2E INTEGRALS %s', eri.shape)
        if moc_b is None and mel.matlist.get('BB MO 2E INTEGRALS') is not None:
            # It seems that when using ROHF, where alpha and beta coeffs are
            # the same, that integrals
            # for BB and BA are included in the output, as well as just AA
            # that would have been expected
            # Using these fails to give the right answer (is ok for UHF).
            # So in this case we revert to
            # using 2 electron ints in atomic basis from the output and
            # converting them ourselves.
            useao2e = True
            logger.info(
                'Identical A and B coeffs but BB ints are present - using regular 2E ints instead'
            )

        if useao2e:
            # eri are 2-body in AO. We can convert to MO via the QMolecule
            # method but using ints in MO already, as in the else here, is better
            mohijkl = QMolecule.twoeints2mo(eri, moc)
            mohijkl_bb = None
            mohijkl_ba = None
            if moc_b is not None:
                mohijkl_bb = QMolecule.twoeints2mo(eri, moc_b)
                mohijkl_ba = QMolecule.twoeints2mo_general(
                    eri, moc_b, moc_b, moc, moc)
        else:
            # These are in MO basis but by default will be reduced in size by
            # frozen core default so to use them we need to add Window=Full
            # above when we augment the config
            mohijkl = self._get_matrix(mel, 'AA MO 2E INTEGRALS')
            logger.debug('AA MO 2E INTEGRALS %s', mohijkl.shape)
            mohijkl_bb = self._get_matrix(mel, 'BB MO 2E INTEGRALS')
            logger.debug(
                'BB MO 2E INTEGRALS %s',
                '- Not present' if mohijkl_bb is None else mohijkl_bb.shape)
            mohijkl_ba = self._get_matrix(mel, 'BA MO 2E INTEGRALS')
            logger.debug(
                'BA MO 2E INTEGRALS %s',
                '- Not present' if mohijkl_ba is None else mohijkl_ba.shape)

        _q_.hcore = hcore
        _q_.hcore_b = hcore_b
        _q_.kinetic = kinetic
        _q_.overlap = overlap
        _q_.eri = eri

        _q_.mo_onee_ints = mohij
        _q_.mo_onee_ints_b = mohij_b
        _q_.mo_eri_ints = mohijkl
        _q_.mo_eri_ints_bb = mohijkl_bb
        _q_.mo_eri_ints_ba = mohijkl_ba

        # dipole moment
        dipints = self._get_matrix(mel, 'DIPOLE INTEGRALS')
        dipints = np.einsum('ijk->kji', dipints)
        _q_.x_dip_ints = dipints[0]
        _q_.y_dip_ints = dipints[1]
        _q_.z_dip_ints = dipints[2]
        _q_.x_dip_mo_ints = QMolecule.oneeints2mo(dipints[0], moc)
        _q_.x_dip_mo_ints_b = None
        _q_.y_dip_mo_ints = QMolecule.oneeints2mo(dipints[1], moc)
        _q_.y_dip_mo_ints_b = None
        _q_.z_dip_mo_ints = QMolecule.oneeints2mo(dipints[2], moc)
        _q_.z_dip_mo_ints_b = None
        if moc_b is not None:
            _q_.x_dip_mo_ints_b = QMolecule.oneeints2mo(dipints[0], moc_b)
            _q_.y_dip_mo_ints_b = QMolecule.oneeints2mo(dipints[1], moc_b)
            _q_.z_dip_mo_ints_b = QMolecule.oneeints2mo(dipints[2], moc_b)

        nucl_dip = np.einsum('i,ix->x', syms, xyz)
        nucl_dip = np.round(nucl_dip, decimals=8)
        _q_.nuclear_dipole_moment = nucl_dip
        _q_.reverse_dipole_sign = True

        return _q_
Beispiel #6
0
def _calculate_integrals(mol, calc_type='rhf'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        mol : A PySCF gto.Mole object.
        calc_type: rhf, uhf, rohf
    Returns:
        ehf : Hartree-Fock energy
        enuke : Nuclear repulsion energy
        norbs : Number of orbitals
        mohij : One electron terms of the Hamiltonian.
        mohijkl : Two electron terms of the Hamiltonian.
        mo_coeff: Orbital coefficients
        orbs_energy: Orbitals energies
        x_dip_ints: x dipole moment integrals
        y_dip_ints: y dipole moment integrals
        z_dip_ints: z dipole moment integrals
        nucl_dipl : Nuclear dipole moment
    """
    enuke = gto.mole.energy_nuc(mol)

    if calc_type == 'rhf':
        mf = scf.RHF(mol)
    elif calc_type == 'rohf':
        mf = scf.ROHF(mol)
    elif calc_type == 'uhf':
        mf = scf.UHF(mol)
    else:
        raise QiskitChemistryError('Invalid calc_type: {}'.format(calc_type))

    ehf = mf.kernel()

    if type(mf.mo_coeff) is tuple:
        mo_coeff = mf.mo_coeff[0]
        mo_occ   = mf.mo_occ[0]
    else:
        mo_coeff = mf.mo_coeff
        mo_occ   = mf.mo_occ

    norbs = mo_coeff.shape[0]
    orbs_energy = mf.mo_energy

    hij = mf.get_hcore()
    mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff)

    eri = ao2mo.incore.full(mf._eri, mo_coeff, compact=False)
    mohijkl = eri.reshape(norbs, norbs, norbs, norbs)

    # dipole integrals
    mol.set_common_orig((0, 0, 0))
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    x_dip_ints = QMolecule.oneeints2mo(ao_dip[0], mo_coeff)
    y_dip_ints = QMolecule.oneeints2mo(ao_dip[1], mo_coeff)
    z_dip_ints = QMolecule.oneeints2mo(ao_dip[2], mo_coeff)

    dm = mf.make_rdm1(mf.mo_coeff, mf.mo_occ)
    if calc_type == 'rohf' or calc_type == 'uhf':
        dm = dm[0]
    elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, dm).real)
    elec_dip = np.round(elec_dip, decimals=8)
    nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords())
    nucl_dip = np.round(nucl_dip, decimals=8)
    logger.info("HF Electronic dipole moment: {}".format(elec_dip))
    logger.info("Nuclear dipole moment: {}".format(nucl_dip))
    logger.info("Total dipole moment: {}".format(nucl_dip+elec_dip))

    return ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip_ints, y_dip_ints, z_dip_ints, nucl_dip
Beispiel #7
0
def compute_integrals(atom,
                      unit,
                      charge,
                      spin,
                      basis,
                      max_memory,
                      calc_type='rhf'):
    # Get config from input parameters
    # molecule is in PySCF atom string format e.g. "H .0 .0 .0; H .0 .0 0.2"
    #          or in Z-Matrix format e.g. "H; O 1 1.08; H 2 1.08 1 107.5"
    # other parameters are as per PySCF got.Mole format

    atom = _check_molecule_format(atom)
    if max_memory is None:
        max_memory = param.MAX_MEMORY
    calc_type = calc_type.lower()

    try:
        mol = gto.Mole(atom=atom, unit=unit, basis=basis, max_memory=max_memory, verbose=pylogger.QUIET)
        mol.symmetry = False
        mol.charge = charge
        mol.spin = spin
        mol.build(parse_arg=False)
        ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip, y_dip, z_dip, nucl_dip = _calculate_integrals(mol, calc_type)
    except Exception as exc:
        raise QiskitChemistryError('Failed electronic structure computation') from exc

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    # Energies and orbits
    _q_.hf_energy = ehf
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = mol.nelec[0]
    _q_.num_beta = mol.nelec[1]
    _q_.mo_coeff = mo_coeff
    _q_.orbital_energies = orbs_energy
    # Molecule geometry
    _q_.molecular_charge = mol.charge
    _q_.multiplicity = mol.spin + 1
    _q_.num_atoms = mol.natm
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([mol.natm, 3])
    atoms = mol.atom_coords()
    for _n in range(0, _q_.num_atoms):
        xyz = mol.atom_coord(_n)
        _q_.atom_symbol.append(mol.atom_pure_symbol(_n))
        _q_.atom_xyz[_n][0] = xyz[0]
        _q_.atom_xyz[_n][1] = xyz[1]
        _q_.atom_xyz[_n][2] = xyz[2]
    # 1 and 2 electron integrals. h1 & h2 are ready to pass to FermionicOperator
    _q_.mo_onee_ints = mohij
    _q_.mo_eri_ints = mohijkl
    # dipole integrals
    _q_.x_dip_mo_ints = x_dip
    _q_.y_dip_mo_ints = y_dip
    _q_.z_dip_mo_ints = z_dip
    # dipole moment
    _q_.nuclear_dipole_moment = nucl_dip
    _q_.reverse_dipole_sign = True

    return _q_
Beispiel #8
0
def _calculate_integrals(molecule,
                         basis='sto3g',
                         hf_method='rhf',
                         tol=1e-8,
                         maxiters=100):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        molecule (pyQuante2.molecule): A pyquante2 molecular object.
        basis (str) : The basis set for the electronic structure computation
        hf_method (str): rhf, uhf, rohf
        tol (float): tolerance
        maxiters (int): max. iterations
    Returns:
        QMolecule: QMolecule populated with driver integrals etc
    Raises:
        QiskitChemistryError: Invalid hf methods type
    """
    bfs = basisset(molecule, basis)
    integrals = onee_integrals(bfs, molecule)
    hij = integrals.T + integrals.V
    hijkl = twoe_integrals(bfs)

    # convert overlap integrals to molecular basis
    # calculate the Hartree-Fock solution of the molecule

    if hf_method == 'rhf':
        solver = rhf(molecule, bfs)
    elif hf_method == 'rohf':
        solver = rohf(molecule, bfs)
    elif hf_method == 'uhf':
        solver = uhf(molecule, bfs)
    else:
        raise QiskitChemistryError(
            'Invalid hf_method type: {}'.format(hf_method))
    ehf = solver.converge(tol=tol, maxiters=maxiters)
    logger.debug('PyQuante2 processing information:\n%s', solver)
    if hasattr(solver, 'orbs'):
        orbs = solver.orbs
        orbs_b = None
    else:
        orbs = solver.orbsa
        orbs_b = solver.orbsb
    norbs = len(orbs)
    if hasattr(solver, 'orbe'):
        orbs_energy = solver.orbe
        orbs_energy_b = None
    else:
        orbs_energy = solver.orbea
        orbs_energy_b = solver.orbeb
    enuke = molecule.nuclear_repulsion()
    # Get ints in molecular orbital basis
    mohij = simx(hij, orbs)
    mohij_b = None
    if orbs_b is not None:
        mohij_b = simx(hij, orbs_b)

    eri = hijkl.transform(np.identity(norbs))
    mohijkl = hijkl.transform(orbs)
    mohijkl_bb = None
    mohijkl_ba = None
    if orbs_b is not None:
        mohijkl_bb = hijkl.transform(orbs_b)
        mohijkl_ba = np.einsum('aI,bJ,cK,dL,abcd->IJKL', orbs_b, orbs_b, orbs,
                               orbs, hijkl[...])

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    _q_.origin_driver_version = '?'  # No version info seems available to access
    # Energies and orbits
    _q_.hf_energy = ehf[0]
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = molecule.nup()
    _q_.num_beta = molecule.ndown()
    _q_.mo_coeff = orbs
    _q_.mo_coeff_b = orbs_b
    _q_.orbital_energies = orbs_energy
    _q_.orbital_energies_b = orbs_energy_b
    # Molecule geometry
    _q_.molecular_charge = molecule.charge
    _q_.multiplicity = molecule.multiplicity
    _q_.num_atoms = len(molecule)
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([len(molecule), 3])
    atoms = molecule.atoms
    for n_i in range(0, _q_.num_atoms):
        atuple = atoms[n_i].atuple()
        _q_.atom_symbol.append(QMolecule.symbols[atuple[0]])
        _q_.atom_xyz[n_i][0] = atuple[1]
        _q_.atom_xyz[n_i][1] = atuple[2]
        _q_.atom_xyz[n_i][2] = atuple[3]
    # 1 and 2 electron integrals
    _q_.hcore = hij
    _q_.hcore_b = None
    _q_.kinetic = integrals.T
    _q_.overlap = integrals.S
    _q_.eri = eri
    _q_.mo_onee_ints = mohij
    _q_.mo_onee_ints_b = mohij_b
    _q_.mo_eri_ints = mohijkl
    _q_.mo_eri_ints_bb = mohijkl_bb
    _q_.mo_eri_ints_ba = mohijkl_ba

    return _q_
Beispiel #9
0
def mol_r_matrices(MoleculeFlag,check_r_matrix_flag,is_atomic):

	mol = gto.Mole()
	#=================================
	# Hydrogen molecule
	#=================================

	if MoleculeFlag == 'H2':
		r_matrices=[]
		num_particles = 2
		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'ao.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2


		# Defining R-matrix --> r
		# Swapping the spatial orbitals. This involves swapping both the spin orbitals corresponding to a spatial orbital.
		# This could be treated as a reflection symmetry or rotational symmetry.
		r1 = np.zeros([4,4])
		r1[0,1]=1
		r1[1,0]=1
		r1[2,3]=1
		r1[3,2]=1

		# Swapping the spin oritals. Spin symmetry.
		r2=np.zeros([4,4])
		for i in range(4):
			if i<2:
				r2[i+2,i]=1.
			else:
				r2[i-2,i]=1.
		
		r_matrices.append(r1)
		r_matrices.append(r2)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')


	#=================================
	# Water molecule (with different basis sets)
	#=================================

	elif MoleculeFlag== 'H2O_L':
		r_matrices = []
		print(MoleculeFlag)
		# Configuration from 
		# mol.atom = [['O',(0.8638, 0.4573,0.0)], ['H',(0, 0, 0)], ['H',(1.7785,0.0,0.0)]]
		# mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]]
		#mol.atom = [['O',(0, 0, 0)], ['H',(0, 1, 0)], ['H@2',(0, 0, 1)]]
		#mol.basis = {'O': 'sto-3g', 'H': 'cc-pvdz', 'H@2': '6-31G'}
		
		num_particles=10
		
		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'ao.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2

		 
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign.
		r1=np.zeros([14,14])
		r1[0,0]=1
		r1[1,1]=1
		r1[2,2]=1
		r1[3,3]=1
		r1[4,4]=-1
		r1[5,5]=1
		r1[6,6]=1
		r1[7,7]=1
		r1[8,8]=1
		r1[9,9]=1
		r1[10,10]=1
		r1[11,11]=-1
		r1[12,12]=1
		r1[13,13]=1

		r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign.
		r2=np.eye(14)
		r2[3,3]=-1
		r2[10,10]=-1
		r_matrices.append(r2)

		# R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap.
		r3=np.zeros([14,14])
		r3[0,0]=1
		r3[1,1]=1
		r3[2,2]=-1
		r3[3,3]=1
		r3[4,4]=1
		r3[5,6]=1
		r3[6,5]=1
		r3[7,7]=1
		r3[8,8]=1
		r3[9,9]=-1
		r3[10,10]=1
		r3[11,11]=1
		r3[12,13]=1
		r3[13,12]=1
		r_matrices.append(r3)

		# R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry:
		# About z-axis
		r4=np.zeros([14,14])
		r4[0,0]=1
		r4[1,1]=1
		r4[2,2]=-1
		r4[3,3]=-1
		r4[4,4]=1
		r4[5,6]=1
		r4[6,5]=1
		r4[7,7]=1
		r4[8,8]=1
		r4[9,9]=-1
		r4[10,10]=-1
		r4[11,11]=1
		r4[12,13]=1
		r4[13,12]=1
		r_matrices.append(r4)
		#About y-axis
		r5=np.zeros([14,14])
		r5[0,0]=1
		r5[1,1]=1
		r5[2,2]=-1
		r5[3,3]=1
		r5[4,4]=-1
		r5[5,6]=1
		r5[6,5]=1
		r5[7,7]=1
		r5[8,8]=1
		r5[9,9]=-1
		r5[10,10]=1
		r5[11,11]=-1
		r5[12,13]=1
		r5[13,12]=1
		r_matrices.append(r5)
		#Symmetry about x-axis:
		r6=np.zeros([14,14])
		r6[0,0]=1
		r6[1,1]=1
		r6[2,2]=1
		r6[3,3]=-1
		r6[4,4]=-1
		r6[5,5]=1
		r6[6,6]=1
		r6[7,7]=1
		r6[8,8]=1
		r6[9,9]=1
		r6[10,10]=-1
		r6[11,11]=-1
		r6[12,12]=1
		r6[13,13]=1
		r_matrices.append(r6)
		
		#Spin symmetry:
		r7=np.zeros([14,14])
		for i in range(14):
			if i<7:
				r7[i+7,i]=1.
			else:
				r7[i-7,i]=1.
		r_matrices.append(r7)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')

	#=================================
	# Water molecule (with different basis sets)
	#=================================

	elif MoleculeFlag== 'H2O':
		r_matrices=[]
		print(MoleculeFlag)

		num_particles = 10

		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'ao.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['O',(0.0000, 0.0000, 0.0000)],
							['H',(0.757, 0.586, 0.0)],
							['H',(-0.757, 0.586, 0.0)]]

				# mol.atom = [['N', (0.0000,  0.0000, 0.0000)],   
					# ['H', (0.0000,	-1.,-0.3816)],  
					# ['H', (0.8,	0.6	,-0.3816)],  
					# ['H', (-0.8,	0.6	,-0.3816)]]		
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['O',(0.0000, 0.0000, 0.0000)],
					['H',(0.757, 0.586, 0.0)],
					['H',(-0.757, 0.586, 0.0)]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2

		

		#Spin symmetry:
		r1=np.zeros([14,14])
		for i in range(14):
			if i<7:
				r1[i+7,i]=1.
			else:
				r1[i-7,i]=1.
		# r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign.
		r2=np.eye(14)
		r2[4,4]=-1
		r2[11,11]=-1
		r_matrices.append(r2)
		# R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and the hydrogen atoms swap.
		r3=np.eye(14)
		r3[2,2]=-1
		r3[9,9]=-1
		r3[12,12]=0
		r3[13,13]=0
		r3[12,13]=1
		r3[13,12]=1
		r3[5,6]=1
		r3[6,5]=1
		r3[5,5]=0
		r3[6,6]=0
		# print(r)
		r_matrices.append(r3)
		#Axial symmetry about y-axis
		r4=np.zeros([14,14])
		r4[0,0]=1
		r4[1,1]=1
		r4[2,2]=-1
		r4[3,3]=1
		r4[4,4]=-1
		r4[5,6]=1
		r4[6,5]=1
		r4[7,7]=1
		r4[8,8]=1
		r4[9,9]=-1
		r4[10,10]=1
		r4[11,11]=-1
		r4[12,13]=1
		r4[13,12]=1
		r_matrices.append(r4)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')

	#=================================
		# Ammonia molecule
	#=================================

	elif MoleculeFlag=='NH3':
		print(MoleculeFlag)
		num_particles = 10

		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'ao.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['N' ,  ( 0.0000000,    0.0000000,    0.1493220)],
							['H' ,  ( 0.0000000 ,   0.9474830 ,   -0.3484190)],
							['H' ,  ( 0.8205440  ,  -0.4737420 ,   -0.3484190)],
							['H' ,  ( -0.8205440  ,  -0.4737420 ,   -0.3484190)]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['N' ,  ( 0.0000000,    0.0000000,    0.1493220)],
						['H' ,  ( 0.0000000 ,   0.9474830 ,   -0.3484190)],
						['H' ,  ( 0.8205440  ,  -0.4737420 ,   -0.3484190)],
						['H' ,  ( -0.8205440  ,  -0.4737420 ,   -0.3484190)]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2
		r_matrices=[]
		#Spin symmetry:
		r1=np.zeros([16,16])
		for i in range(16):
			if i<8:
				r1[i+8,i]=1.
			else:
				r1[i-8,i]=1.
		r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{yz}. Two hydrogen atoms are swapped and the px orbital picks up
		# a negative sign. 
		r3=np.zeros([16,16])
		r3[0,0]=1
		r3[1,1]=1
		r3[2,2]=-1
		r3[3,3]=1
		r3[4,4]=1
		r3[5,5]=1
		r3[6,7]=1
		r3[7,6]=1
		r3[8,8]=1
		r3[9,9]=1
		r3[10,10]=-1
		r3[11,11]=1
		r3[12,12]=1
		r3[13,13]=1
		r3[14,15]=1
		r3[15,14]=1
		r_matrices.append(r3)
		######################################
		# The following mtrices commute with Hamiltonian
		# and hence are symmetries, but these cannot be used
		# to taper off qubits.
		theta = -2*np.pi/3
		r4 = np.eye(16)
		r4[5,5]=r4[6,6]=r4[7,7]=0
		r4[13,13]=r4[14,14]=r4[15,15]=0
		r4[5,6]=r4[6,7]=r4[7,5]=1
		# r4[6,5]=r4[7,6]=r4[5,7]=1
		r4[13,14]=r4[14,15]=r4[15,13]=1
		# r4[14,13]=r4[15,14]=r4[13,15]=1
		r4[2,2]=r4[3,3]=r4[10,10]=r4[11,11]=np.cos(theta)
		r4[2,3]=  np.sin(theta)
		r4[3,2]=  -np.sin(theta)
		r4[10,11]=np.sin(theta)
		r4[11,10]=-np.sin(theta)
		r5 = r4.copy()


		theta = np.pi/3
		r4 = np.eye(16,dtype=complex)
		r4[5,5]=r4[6,6]=0
		r4[13,13]=r4[14,14]=0
		r4[5,6]=r4[6,5]=1
		r4[13,14]=r4[14,13]=1
		r4[2,2]=r4[10,10]=np.cos(theta)
		r4[3,3]=r4[11,11]=-np.cos(theta)
		r4[2,3]=  np.sin(theta)
		r4[3,2]=  np.sin(theta)
		r4[10,11]=np.sin(theta)
		r4[11,10]=np.sin(theta)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	#=================================
		# Methane molecule
	#=================================

	elif MoleculeFlag=='CH4':
		# print(MoleculeFlag)
		
		mol.atom=[['C',  (0.0000 ,	0.0000 ,	0.0000 )],    
				['H',  (0.6276 ,	0.6276 ,	0.6276 )],  
				['H',  (0.6276 ,	-0.6276,	-0.6276)],  
				['H',  (-0.6276,	0.6276 ,	-0.6276)],    
				['H',  (-0.6276,	-0.6276,	0.6276 )]]    

		mol.basis='sto-3g'
		mol.build()
		_q_=int_func.qmol_func(mol, atomic=True)
		fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)
		# Spin symmetry:
		r1=np.zeros([18,18])
		for i in range(18):
			if i<8:
				r1[i+9,i]=1.
			else:
				r1[i-9,i]=1.
		
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')

	#=================================
		# Carbon dioxide molecule
	#=================================
	elif MoleculeFlag=='CO2':
		r_matrices = []
		# print(MoleculeFlag)
		mol.atom = [['C',(0., 0., 0.)],
					['O',(-1.1621, 0., 0.)],
					['O',(1.1621, 0., 0.)]]

		mol.basis='sto-3g'
		mol.build()
		_q_=int_func.qmol_func(mol, atomic=True)
		fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)

		# Spin symmetry:
		r1=np.zeros([30,30])
		for i in range(30):
			if i<15:
				r1[i+15,i]=1.
			else:
				r1[i-15,i]=1.
		r_matrices.append(r1)
		
		# Permutation matrix for inversion. \sigma{yz} All the oxygen orbitals are swapped.
		# Oxygen px orbital picks up a negative sign and the px of carbon picks up a 
		# negative sign.
		r2=np.zeros([30,30])
		r2[0,0]=1
		r2[1,1]=1
		r2[3,3]=1
		r2[2,2]=-1
		r2[4,4]=r2[19,19]=1
		r2[5,10]=r2[10,5]=1
		r2[11,6]=r2[6,11]=1
		r2[7,12]=r2[12,7]=-1
		r2[8,13]=r2[13,8]=1
		r2[14,9]=r2[9,14]=1
		r2[15,15]=1
		r2[16,16]=1
		r2[17,17]=-1
		r2[18,18]=1
		r2[20,25]=r2[25,20]=1
		r2[21,26]=r2[26,21]=1
		r2[22,27]=r2[27,22]=-1
		r2[23,28]=r2[28,23]=1
		r2[24,29]=r2[29,24]=1
		r_matrices.append(r2)
		# Permutation matrix for inversion. \sigma{xy} 
		# pz orbitals of oxygen and carbon pick up negative sign
		r3=np.eye(30)
		r3[4,4]=-1
		r3[19,19]=-1
		r3[9,9]=-1
		r3[14,14]=-1
		r3[24,24]=-1
		r3[29,29]=-1
		r_matrices.append(r3)
		# Permutation matrix for inversion. \sigma{xz} 
		# py orbitals of oxygen and carbon pick up negative sign
		r4=np.eye(30)
		r4[3,3]=-1
		r4[18,18]=-1
		r4[8,8]=-1
		r4[13,13]=-1
		r4[23,23]=-1
		r4[28,28]=-1
		r_matrices.append(r4)
		# Permutation matrix for axial symmetry. C_2{x}
		# pz and py orbitals of oxygen and carbon pick up negative sign
		r5=np.eye(30)
		r5[3,3]=-1
		r5[18,18]=-1
		r5[8,8]=-1
		r5[13,13]=-1
		r5[23,23]=-1
		r5[28,28]=-1
		r5[4,4]=-1
		r5[19,19]=-1
		r5[9,9]=-1
		r5[14,14]=-1
		r5[24,24]=-1
		r5[29,29]=-1	
		r_matrices.append(r5)
		# Permutation matrix for axial symmetry. C_2{y} All the oxygen orbitals are swapped.
		# Oxygen px and pz orbital picks up a negative sign and the px and pz of carbon picks up a 
		# negative sign.
		r6=np.zeros([30,30])
		r6[0,0]=r6[1,1]=1
		r6[3,3]=r6[18,18]=1
		r6[17,17]=r6[2,2]=-1
		r6[4,4]=r6[19,19]=-1
		r6[5,10]=r6[10,5]=1
		r6[11,6]=r6[6,11]=1
		r6[7,12]=r6[12,7]=-1
		r6[8,13]=r6[13,8]=1
		r6[14,9]=r6[9,14]=-1
		r6[15,15]=r6[16,16]=1
		r6[20,25]=r6[25,20]=1
		r6[21,26]=r6[26,21]=1
		r6[22,27]=r6[27,22]=-1
		r6[23,28]=r6[28,23]=1
		r6[24,29]=r6[29,24]=-1
		r_matrices.append(r6)
		# Permutation matrix for axial symmetry. C_2{z} All the oxygen orbitals are swapped.
		# Oxygen px and py orbital picks up a negative sign and the px and py of carbon picks up a 
		# negative sign.
		r7=np.zeros([30,30])
		r7[0,0]=r7[1,1]=1
		r7[3,3]=r7[18,18]=-1
		r7[17,17]=r7[2,2]=-1
		r7[4,4]=r7[19,19]=1
		r7[5,10]=r7[10,5]=1
		r7[11,6]=r7[6,11]=1
		r7[7,12]=r7[12,7]=-1
		r7[8,13]=r7[13,8]=-1
		r7[14,9]=r7[9,14]=1
		r7[15,15]=r7[16,16]=1
		r7[20,25]=r7[25,20]=1
		r7[21,26]=r7[26,21]=1
		r7[22,27]=r7[27,22]=-1
		r7[23,28]=r7[28,23]=-1
		r7[24,29]=r7[29,24]=1
		r_matrices.append(r7)

		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	#=================================
		# Ethyne molecule
	#=================================

	elif MoleculeFlag=='C2H2':
		r_matrices =[]
		print(MoleculeFlag)
		num_particles = 14

		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['C',(-0.6000, 0.0000, 0.0000 )], 
					['C',(0.6000, 0.0000, 0.0000 )],
					['H',(-1.6650,0.0000, 0.000 )],
					['H',(1.6650,0.0000, 0.000 )]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['C',(-0.6000, 0.0000, 0.0000 )], 
					['C',(0.6000, 0.0000, 0.0000 )],
					['H',(-1.6650,0.0000, 0.000 )],
					['H',(1.6650,0.0000, 0.000 )]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2

		# Spin symmetry:
		r1=np.zeros([24,24])
		for i in range(24):
			if i<12:
				r1[i+12,i]=1.
			else:
				r1[i-12,i]=1.
		# r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. 
		r2=np.eye(24)
		r2[4,4]=-1
		r2[9,9]=-1
		r2[16,16]=-1
		r2[21,21]=-1
		# R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign. 
		r3=np.eye(24)
		r3[3,3]=-1
		r3[8,8]=-1
		r3[15,15]=-1
		r3[20,20]=-1
		# R-matrix for plane of symmetry \sigma_{yz}. 
		r4=np.zeros([24,24])
		#Swapping px picks up a negative sign
		r4[2,7]=r4[7,2]=-1
		r4[14,19]=r4[19,14]=-1
		#Swapping 1s, 2s, 2py and 2pz of Carbon
		r4[0,5]=r4[5,0]=1
		r4[1,6]=r4[6,1]=1
		r4[12,17]=r4[17,12]=1
		r4[13,18]=r4[18,13]=1
		r4[3,8]=r4[8,3]=1
		r4[15,20]=r4[20,15]=1
		r4[21,16]=r4[16,21]=1
		r4[9,4]=r4[4,9]=1
		#Swapping 1s of hydrogen	
		r4[10,11]=r4[11,10]=1
		r4[22,23]=r4[23,22]=1

		# R-matrix for axis of symmetry C_2 around y axis. 
		r5=np.zeros([24,24])
		#Swapping px picks up a negative sign
		r5[2,7]=r5[7,2]=-1
		r5[14,19]=r5[19,14]=-1
		r5[21,16]=r5[16,21]=-1
		r5[9,4]=r5[4,9]=-1
		#Swapping 1s, 2s, 2py and 2pz of Carbon
		r5[0,5]=r5[5,0]=1
		r5[1,6]=r5[6,1]=1
		r5[12,17]=r5[17,12]=1
		r5[13,18]=r5[18,13]=1
		r5[3,8]=r5[8,3]=1
		r5[15,20]=r5[20,15]=1
		#Swapping 1s of hydrogen	
		r5[10,11]=r5[11,10]=1
		r5[22,23]=r5[23,22]=1
		# R-matrix for axis of symmetry C_2 around z axis. 
		r6=np.zeros([24,24])
		#Swapping px picks up a negative sign
		r6[2,7]=r6[7,2]=-1
		r6[14,19]=r6[19,14]=-1
		r6[15,20]=r6[20,15]=-1
		r6[3,8]=r6[8,3]=-1
		#Swapping 1s, 2s, 2py and 2pz of Carbon
		r6[0,5]=r6[5,0]=1
		r6[1,6]=r6[6,1]=1
		r6[12,17]=r6[17,12]=1
		r6[13,18]=r6[18,13]=1
		r6[9,4]=r6[4,9]=1
		r6[21,16]=r6[16,21]=1
		#Swapping 1s of hydrogen	
		r6[10,11]=r6[11,10]=1
		r6[22,23]=r6[23,22]=1
		
		# R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign.
		r7=np.eye(24)	
		r7[3,3]=-1
		r7[4,4]=-1
		r7[8,8]=-1
		r7[9,9]=-1
		r7[16,16]=-1
		r7[15,15]=-1
		r7[20,20]=-1
		r7[21,21]=-1
		r_matrices.append(r7)
		r_matrices.append(r6)
		r_matrices.append(r5)
		r_matrices.append(r2)
		r_matrices.append(r3)
		r_matrices.append(r4)
		r_matrices.append(r1)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	#=================================
		# Ethylene molecule
	#=================================

	elif MoleculeFlag=='C2H4':
		r_matrices =[]
		print(MoleculeFlag)
		try:
			data = np.load(MoleculeFlag+'.npz')
			data.files
			one_b = data['one_b']
			two_b = data['two_b']
		except IOError:
			mol.atom = [['C',( 0.6695, 0.0000 , 0.0000)],
		 	 			['C',(-0.6695, 0.0000 , 0.0000)],
		 	 			['H',( 1.2321, 0.9289 , 0.0000)],
		 	 			['H',( 1.2321, -0.9289, 0.0000)],
		 	 			['H',(-1.2321, 0.9289 , 0.0000)],
		 	 			['H',(-1.2321, -0.9289, 0.0000)]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=True)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)

		fer_op = FermionicOperator(h1=one_b, h2=two_b)
		r_matrices = []
		

		# Spin symmetry:
		r1=np.zeros([28,28])
		for i in range(28):
			if i<14:
				r1[i+14,i]=1.
			else:
				r1[i-14,i]=1.
		# r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. 
		r2=np.eye(28)
		r2[4,4]=-1
		r2[9,9]=-1
		r2[18,18]=-1
		r2[23,23]=-1
		# R-matrix for plane of symmetry \sigma_{xz}. 
		r3=np.eye(28)
		r3[3,3]=-1
		r3[8,8]=-1
		r3[17,17]=-1
		r3[22,22]=-1
		r3[10,10]=r3[11,11]=r3[12,12]=r3[13,13]=0
		r3[24,24]=r3[25,25]=r3[26,26]=r3[27,27]=0
		r3[10,11]=r3[11,10]=r3[12,13]=r3[13,12]=1
		r3[24,25]=r3[25,24]=r3[26,27]=r3[27,26]=1
		# R-matrix for plane of symmetry \sigma_{yz}. 
		r4=np.zeros([28,28])
		# #Swapping px picks up a negative sign
		r4[2,7]=r4[7,2]=-1
		r4[16,21]=r4[21,16]=-1
		# #Swapping 1s, 2s, 2py and 2pz of Carbon
		r4[0,5]=r4[5,0]=1
		r4[1,6]=r4[6,1]=1
		r4[3,8]=r4[8,3]=1
		r4[4,9]=r4[9,4]=1
		r4[14,19]=r4[19,14]=1
		r4[15,20]=r4[20,15]=1
		r4[17,22]=r4[22,17]=1
		r4[18,23]=r4[23,18]=1
		# #Swapping 1s of hydrogen	
		r4[10,12]=r4[12,10]=1
		r4[24,26]=r4[26,24]=1
		r4[11,13]=r4[13,11]=1
		r4[25,27]=r4[27,25]=1
		
		# R-matrix for axis of symmetry C_2 around y axis. 
		r5=np.zeros([28,28])
		#Swapping px picks up a negative sign
		r5[2,7]=r5[7,2]=-1
		r5[4,9]=r5[9,4]=-1
		r5[16,21]=r5[21,16]=-1
		r5[18,23]=r5[23,18]=-1
		#Swapping 1s, 2s, 2py and 2pz of Carbon
		r5[0,5]=r5[5,0]=1
		r5[1,6]=r5[6,1]=1
		r5[3,8]=r5[8,3]=1
		r5[14,19]=r5[19,14]=1
		r5[15,20]=r5[20,15]=1
		r5[17,22]=r5[22,17]=1
		#Swapping 1s of hydrogen	
		r5[10,12]=r5[12,10]=1
		r5[24,26]=r5[26,24]=1
		r5[11,13]=r5[13,11]=1
		r5[25,27]=r5[27,25]=1
		# R-matrix for axis of symmetry C_2 around z axis. 
		r6=np.zeros([28,28])
		#Swapping px picks up a negative sign
		r6[2,7]=r6[7,2]=-1
		r6[3,8]=r6[8,3]=-1
		r6[16,21]=r6[21,16]=-1
		r6[17,22]=r6[22,17]=-1
		#Swapping 1s, 2s, 2py and 2pz of Carbon
		r6[0,5]=r6[5,0]=1
		r6[1,6]=r6[6,1]=1
		r6[4,9]=r6[9,4]=1
		r6[14,19]=r6[19,14]=1
		r6[15,20]=r6[20,15]=1
		r6[18,23]=r6[23,18]=1
		#Swapping 1s of hydrogen	
		r6[10,13]=r6[13,10]=1
		r6[24,27]=r6[27,24]=1
		r6[11,12]=r6[12,11]=1
		r6[25,26]=r6[26,25]=1
		
		# # R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign.
		r7=np.eye(28)	
		r7[3,3]=-1
		r7[4,4]=-1
		r7[8,8]=-1
		r7[9,9]=-1
		r7[17,17]=-1
		r7[18,18]=-1
		r7[22,22]=-1
		r7[23,23]=-1
		r7[10,10]=r7[11,11]=r7[12,12]=r7[13,13]=0
		r7[24,24]=r7[25,25]=r7[26,26]=r7[27,27]=0
		r7[10,11]=r7[11,10]=r7[12,13]=r7[13,12]=1
		r7[24,25]=r7[25,24]=r7[26,27]=r7[27,26]=1
		r_matrices.append(r1)
		r_matrices.append(r2)
		r_matrices.append(r3)
		r_matrices.append(r4)
		r_matrices.append(r5)
		r_matrices.append(r6)
		r_matrices.append(r7)
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	#=================================
		# Boron trifluoride molecule
	#=================================

	elif MoleculeFlag == 'BF3':
		r_matrices = []
		
		try:
			data = np.load(MoleculeFlag+'.npz')
			one_b = data['one_b']
			two_b = data['two_b']
		except IOError:
			mol.atom = [['B',(0.0000	,0.0000	,0.000000 )], 
						['F',(0.0000	,1.3070	,0.00000 )],
						['F',(1.1319	,-0.6535,	0.000 )],
						['F',(-1.1319	,-0.6535,	0.00)]]
			mol.basis = 'sto-3g'
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=True)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)

		fer_op = FermionicOperator(h1=one_b, h2=two_b)
		
		
		
		# Spin symmetry:
		r1=np.zeros([40,40])
		for i in range(40):
			if i<20:
				r1[i+20,i]=1.
			else:
				r1[i-20,i]=1.
		r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xy}. 
		r2=np.eye(40)
		r2[4,4]=-1
		r2[9,9]=-1
		r2[14,14]=-1
		r2[19,19]=-1
		r2[24,24]=-1
		r2[29,29]=-1
		r2[34,34]=-1
		r2[39,39]=-1
		r_matrices.append(r2)

		# R-matrix for plane of symmetry \sigma_{yz}. 
		r3=np.eye(40)
		r3[2,2]=-1
		r3[7,7]=-1
		r3[22,22]=-1
		r3[27,27]=-1
		for i in range(5):
			r3[10+i,10+i]=0
			r3[15+i,15+i]=0
			r3[30+i,30+i]=0
			r3[35+i,35+i]=0
			r3[10+i,15+i]=1
			r3[15+i,10+i]=1
			r3[30+i,35+i]=1
			r3[35+i,30+i]=1
		
		r3[12,17]=-1
		r3[17,12]=-1
		r3[32,37]=-1
		r3[37,32]=-1
		r_matrices.append(r3)
		# R-matrix for axis of symmetry C_2 around y axis. 
		r4=np.eye(40)
		r4[2,2]=-1
		r4[4,4]=-1
		r4[7,7]=-1
		r4[9,9]=-1
		r4[22,22]=-1
		r4[24,24]=-1
		r4[29,29]=-1
		r4[27,27]=-1
		for i in range(5):
			r4[10+i,10+i]=0
			r4[15+i,15+i]=0
			r4[30+i,30+i]=0
			r4[35+i,35+i]=0
			r4[10+i,15+i]=1
			r4[15+i,10+i]=1
			r4[30+i,35+i]=1
			r4[35+i,30+i]=1
		
		r4[12,17]=-1
		r4[17,12]=-1
		r4[14,19]=-1
		r4[19,14]=-1
		r4[32,37]=-1
		r4[37,32]=-1
		r4[34,39]=-1
		r4[39,34]=-1
		r_matrices.append(r4)
		# R-matrix for plane of symmetry \sigma_{yz}. 
		# r4=np.zeros([24,24])
		# #Swapping px picks up a negative sign
		# r4[2,7]=r4[7,2]=-1
		# r4[14,19]=r4[19,14]=-1
		# #Swapping 1s, 2s, 2py and 2pz of Carbon
		# r4[0,5]=r4[5,0]=1
		# r4[1,6]=r4[6,1]=1
		# r4[12,17]=r4[17,12]=1
		# r4[13,18]=r4[18,13]=1
		# r4[3,8]=r4[8,3]=1
		# r4[15,20]=r4[20,15]=1
		# r4[21,16]=r4[16,21]=1
		# r4[9,4]=r4[4,9]=1
		# #Swapping 1s of hydrogen	
		# r4[10,11]=r4[11,10]=1
		# r4[22,23]=r4[23,22]=1


	

		# # R-matrix for axis of symmetry C_2 around z axis. 
		# r6=np.zeros([24,24])
		# #Swapping px picks up a negative sign
		# r6[2,7]=r6[7,2]=-1
		# r6[14,19]=r6[19,14]=-1
		# r6[15,20]=r6[20,15]=-1
		# r6[3,8]=r6[8,3]=-1
		# #Swapping 1s, 2s, 2py and 2pz of Carbon
		# r6[0,5]=r6[5,0]=1
		# r6[1,6]=r6[6,1]=1
		# r6[12,17]=r6[17,12]=1
		# r6[13,18]=r6[18,13]=1
		# r6[9,4]=r6[4,9]=1
		# r6[21,16]=r6[16,21]=1
		# #Swapping 1s of hydrogen	
		# r6[10,11]=r6[11,10]=1
		# r6[22,23]=r6[23,22]=1

		# # R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign.
		# r7=np.eye(24)
		
		# r7[3,3]=-1
		# r7[4,4]=-1
		# r7[8,8]=-1
		# r7[9,9]=-1
		# r7[16,16]=-1
		# r7[15,15]=-1
		# r7[20,20]=-1
		# r7[21,21]=-1

		# print(r4)
		# print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]))		
		# fer_op.transform(r4)
		# # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]))		
		# # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]-_q_.one_body_integrals[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]))
		# # print(np.real(fer_op.h1[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))]-_q_.one_body_integrals[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))]))
		# print(MoleculeFlag)
		# # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]))
		# # print(np.real(fer_op.h1[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))]))
		# # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]))
		# print(np.all(np.abs(fer_op.h1-_q_.one_body_integrals)<1.e-14))
		# print(np.all(np.abs(fer_op.h2-_q_.two_body_integrals)<1.e-14))
		# print(np.linalg.norm(fer_op.h2-_q_.two_body_integrals))
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	
#=================================
	# Lithium hydride
#=================================

	elif MoleculeFlag == "LiH":
		r_matrices =[]
		print(MoleculeFlag)

		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['Li',(0.000, 0.0000, 0.0000 )],
					['H',(1.5949,0.0000, 0.000 )]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=is_atomic)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))
			print(_q_.one_body_integrals)
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['Li',(0.000, 0.0000, 0.0000 )],
					['H',(1.5949,0.0000, 0.000 )]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2

		# Spin symmetry:
		r1=np.zeros([12,12])
		for i in range(12):
			if i<6:
				r1[i+6,i]=1.
			else:
				r1[i-6,i]=1.
		r_matrices.append(r1)
		# sigma{xy}
		r2 = np.eye(12)
		r2[4,4]=-1
		r2[10,10]=-1
		r_matrices.append(r2)

		#sigma(yz)
		r3 = np.eye(12)
		r3[3,3]=-1
		r3[9,9]=-1
		r_matrices.append(r3)
		if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
			print('All the above matrices work!')
#=================================
	# Beryllium hydride
#=================================
	
	elif MoleculeFlag == "BeH2":
		num_particles = 6
		r_matrices =[]
		print(MoleculeFlag)
		
		if is_atomic:
			try:
				data = np.load(MoleculeFlag+'.npz')
				data.files
				one_b = data['one_b']
				two_b = data['two_b']
			except IOError:
				mol.atom = [['Be',(0.000, 0.0000, 0.0000 )],
						['H',(1.291,0.0000, 0.000 )],
						['H',(-1.291,0.0000, 0.000 )]]
				mol.build()
				_q_=int_func.qmol_func(mol, atomic=True)
				one_b=_q_.one_body_integrals
				two_b=_q_.two_body_integrals
				# np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)
		
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			mol.atom = [['Be',(0.000, 0.0000, 0.0000 )],
						['H',(1.291,0.0000, 0.000 )],
						['H',(-1.291,0.0000, 0.000 )]]
			mol.build()
			_q_=int_func.qmol_func(mol, atomic=is_atomic)
			one_b=_q_.one_body_integrals
			two_b=_q_.two_body_integrals
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2

		# fer_op = FermionicOperator(h1=one_b, h2=two_b)
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign.
		r1=np.zeros([14,14])
		r1[0,0]=1
		r1[1,1]=1
		r1[2,2]=1
		r1[3,3]=1
		r1[4,4]=-1
		r1[5,5]=1
		r1[6,6]=1
		r1[7,7]=1
		r1[8,8]=1
		r1[9,9]=1
		r1[10,10]=1
		r1[11,11]=-1
		r1[12,12]=1
		r1[13,13]=1

		r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign.
		r2=np.eye(14)
		r2[3,3]=-1
		r2[10,10]=-1
		r_matrices.append(r2)

		# R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap.
		r3=np.zeros([14,14])
		r3[0,0]=1
		r3[1,1]=1
		r3[2,2]=-1
		r3[3,3]=1
		r3[4,4]=1
		r3[5,6]=1
		r3[6,5]=1
		r3[7,7]=1
		r3[8,8]=1
		r3[9,9]=-1
		r3[10,10]=1
		r3[11,11]=1
		r3[12,13]=1
		r3[13,12]=1
		r_matrices.append(r3)

		# R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry:
		# About z-axis
		r4=np.zeros([14,14])
		r4[0,0]=1
		r4[1,1]=1
		r4[2,2]=-1
		r4[3,3]=-1
		r4[4,4]=1
		r4[5,6]=1
		r4[6,5]=1
		r4[7,7]=1
		r4[8,8]=1
		r4[9,9]=-1
		r4[10,10]=-1
		r4[11,11]=1
		r4[12,13]=1
		r4[13,12]=1
		# r_matrices.append(r4)
		#About y-axis
		r5=np.zeros([14,14])
		r5[0,0]=1
		r5[1,1]=1
		r5[2,2]=-1
		r5[3,3]=1
		r5[4,4]=-1
		r5[5,6]=1
		r5[6,5]=1
		r5[7,7]=1
		r5[8,8]=1
		r5[9,9]=-1
		r5[10,10]=1
		r5[11,11]=-1
		r5[12,13]=1
		r5[13,12]=1
		# r_matrices.append(r5)
		#Symmetry about x-axis:
		r6=np.zeros([14,14])
		r6[0,0]=1
		r6[1,1]=1
		r6[2,2]=1
		r6[3,3]=-1
		r6[4,4]=-1
		r6[5,5]=1
		r6[6,6]=1
		r6[7,7]=1
		r6[8,8]=1
		r6[9,9]=1
		r6[10,10]=-1
		r6[11,11]=-1
		r6[12,12]=1
		r6[13,13]=1
		# r_matrices.append(r6)
		
		#Spin symmetry:
		r7=np.zeros([14,14])
		for i in range(14):
			if i<7:
				r7[i+7,i]=1.
			else:
				r7[i-7,i]=1.
		r_matrices.append(r7)

		if check_r_matrix_flag and is_atomic:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
		

	elif MoleculeFlag == "test":
		r_matrices =[]
		num_particles = 6
		print(MoleculeFlag)
		# try:
		# 	data = np.load(MoleculeFlag+'.npz')
		# 	data.files
		# 	one_b = data['one_b']
		# 	two_b = data['two_b']
		# except IOError:
		mol.atom = [['Be',(0.000, 0.0000, 0.0000 )],
					['H',(1.3264,0.0000, 0.000 )],
					['H',(-1.3264,0.0000, 0.000 )]]
		mol.atom = [['Be',(0.000, 0.0000, 0.0000 )],
					['H',(1.291,0.0000, 0.000 )],
					['H',(-1.291,0.0000, 0.000 )]]
		mol.atom = [['Be',(0.000, 0.0000, 0.0000 )],
					['H',(1.3,0.0000, 0.000 )],
					['H',(-1.3,0.0000, 0.000 )]]		
		mol.basis = 'sto-6g'					
		# mol.symmetry=True
		# mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]]		
		mol.build()
		# is_atomic = 
		_q_ = qmol_func(mol, atomic=is_atomic)
		if is_atomic:
			two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
			temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
			two_body_temp = QMolecule.twoe_to_spin(temp_int)
			mol = gto.M(atom=mol.atom, basis='sto-3g')

			O = get_ovlp(mol)
			X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
			fer_op.transform(X)
		else:
			fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals)


		one_b = fer_op.h1
		two_b = fer_op.h2
		
			# np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals)

		# fer_op = FermionicOperator(h1=one_b, h2=two_b)
		# print(fer_op.h1)
		# exit()
		# r_matrices.append(np.eye(14))
		# R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign.
		r1=np.zeros([14,14])
		r1[0,0]=1
		r1[1,1]=1
		r1[2,2]=1
		r1[3,3]=1
		r1[4,4]=-1
		r1[5,5]=1
		r1[6,6]=1
		r1[7,7]=1
		r1[8,8]=1
		r1[9,9]=1
		r1[10,10]=1
		r1[11,11]=-1
		r1[12,12]=1
		r1[13,13]=1

		r_matrices.append(r1)
		# R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign.
		r2=np.eye(14)
		r2[3,3]=-1
		r2[10,10]=-1
		r_matrices.append(r2)

		# R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap.
		r3=np.zeros([14,14])
		r3[0,0]=1
		r3[1,1]=1
		r3[2,2]=-1
		r3[3,3]=1
		r3[4,4]=1
		r3[5,6]=1
		r3[6,5]=1
		r3[7,7]=1
		r3[8,8]=1
		r3[9,9]=-1
		r3[10,10]=1
		r3[11,11]=1
		r3[12,13]=1
		r3[13,12]=1
		r_matrices.append(r3)

		# R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry:
		# About z-axis
		r4=np.zeros([14,14])
		r4[0,0]=1
		r4[1,1]=1
		r4[2,2]=-1
		r4[3,3]=-1
		r4[4,4]=1
		r4[5,6]=1
		r4[6,5]=1
		r4[7,7]=1
		r4[8,8]=1
		r4[9,9]=-1
		r4[10,10]=-1
		r4[11,11]=1
		r4[12,13]=1
		r4[13,12]=1
		# r_matrices.append(r4)
		#About y-axis
		r5=np.zeros([14,14])
		r5[0,0]=1
		r5[1,1]=1
		r5[2,2]=-1
		r5[3,3]=1
		r5[4,4]=-1
		r5[5,6]=1
		r5[6,5]=1
		r5[7,7]=1
		r5[8,8]=1
		r5[9,9]=-1
		r5[10,10]=1
		r5[11,11]=-1
		r5[12,13]=1
		r5[13,12]=1
		# r_matrices.append(r5)
		#Symmetry about x-axis:
		r6=np.zeros([14,14])
		r6[0,0]=1
		r6[1,1]=1
		r6[2,2]=1
		r6[3,3]=-1
		r6[4,4]=-1
		r6[5,5]=1
		r6[6,6]=1
		r6[7,7]=1
		r6[8,8]=1
		r6[9,9]=1
		r6[10,10]=-1
		r6[11,11]=-1
		r6[12,12]=1
		r6[13,13]=1
		# r_matrices.append(r6)
		
		#Spin symmetry:
		r7=np.zeros([14,14])
		for i in range(14):
			if i<7:
				r7[i+7,i]=1.
			else:
				r7[i-7,i]=1.
		# r_matrices.append(r7)
		
		r8=np.zeros([14,14])
		r8[0,0]=1
		r8[1,1]=1
		r8[2,2]=-1
		r8[3,3]=-1
		r8[4,4]=-1
		r8[5,6]=1
		r8[6,5]=1
		r8[7,7]=1
		r8[8,8]=1
		r8[9,9]=-1
		r8[10,10]=-1
		r8[11,11]=-1
		r8[12,13]=1
		r8[13,12]=1
		# r_matrices.append(r8)
		# r_matrices=[]
		# r_matrices.append(np.eye(fer_op.modes))
		if check_r_matrix_flag:
			if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)):
				print('All the above matrices work!')
	if is_atomic:
		return [r_matrices,fer_op,num_particles]
	else:
		r_matrices =[]
		r_matrices.append(np.eye(fer_op.modes))
		return [r_matrices,fer_op, num_particles]
    def _do_transform(
        self,
        qmolecule: QMolecule,
        aux_operators: Optional[List[FermionicOperator]] = None
    ) -> Tuple[WeightedPauliOperator, List[WeightedPauliOperator]]:
        """
        Args:
            qmolecule: qmolecule
            aux_operators: Additional ``FermionicOperator``s to map to a qubit operator.

        Returns:
            (qubit operator, auxiliary operators)

        """
        logger.debug('Processing started...')
        # Save these values for later combination with the quantum computation result
        self._hf_energy = qmolecule.hf_energy
        self._nuclear_repulsion_energy = qmolecule.nuclear_repulsion_energy
        self._nuclear_dipole_moment = qmolecule.nuclear_dipole_moment
        self._reverse_dipole_sign = qmolecule.reverse_dipole_sign

        core_list = qmolecule.core_orbitals if self._freeze_core else []
        reduce_list = self._orbital_reduction

        if self._freeze_core:
            logger.info(
                "Freeze_core specified. Core orbitals to be frozen: %s",
                core_list)
        if reduce_list:
            logger.info("Configured orbital reduction list: %s", reduce_list)
            reduce_list = [
                x + qmolecule.num_orbitals if x < 0 else x for x in reduce_list
            ]

        freeze_list = []
        remove_list = []

        # Orbitals are specified by their index from 0 to n-1, where n is the number of orbitals the
        # molecule has. The combined list of the core orbitals, when freeze_core is true, with any
        # user supplied orbitals is what will be used. Negative numbers may be used to indicate the
        # upper virtual orbitals, so -1 is the highest, then -2 etc. and these will
        # be converted to the
        # positive 0-based index for computation.
        # In the combined list any orbitals that are occupied are added to a freeze list and an
        # energy is stored from these orbitals to be added later.
        # Unoccupied orbitals are just discarded.
        # Because freeze and eliminate is done in separate steps,
        # with freeze first, we have to re-base
        # the indexes for elimination according to how many orbitals were removed when freezing.
        #
        orbitals_list = list(set(core_list + reduce_list))
        num_alpha = qmolecule.num_alpha
        num_beta = qmolecule.num_beta
        new_num_alpha = num_alpha
        new_num_beta = num_beta
        if orbitals_list:
            orbitals_list = np.array(orbitals_list)
            orbitals_list = orbitals_list[
                (cast(np.ndarray, orbitals_list) >= 0)
                & (orbitals_list < qmolecule.num_orbitals)]

            freeze_list_alpha = [i for i in orbitals_list if i < num_alpha]
            freeze_list_beta = [i for i in orbitals_list if i < num_beta]
            freeze_list = np.append(
                freeze_list_alpha,
                [i + qmolecule.num_orbitals for i in freeze_list_beta])

            remove_list_alpha = [i for i in orbitals_list if i >= num_alpha]
            remove_list_beta = [i for i in orbitals_list if i >= num_beta]
            rla_adjust = -len(freeze_list_alpha)
            rlb_adjust = -len(freeze_list_alpha) - len(
                freeze_list_beta) + qmolecule.num_orbitals
            remove_list = np.append(
                [i + rla_adjust for i in remove_list_alpha],
                [i + rlb_adjust for i in remove_list_beta])

            logger.info("Combined orbital reduction list: %s", orbitals_list)
            logger.info(
                "  converting to spin orbital reduction list: %s",
                np.append(np.array(orbitals_list),
                          np.array(orbitals_list) + qmolecule.num_orbitals))
            logger.info("    => freezing spin orbitals: %s", freeze_list)
            logger.info(
                "    => removing spin orbitals: %s (indexes accounting for freeze %s)",
                np.append(remove_list_alpha,
                          np.array(remove_list_beta) + qmolecule.num_orbitals),
                remove_list)

            new_num_alpha -= len(freeze_list_alpha)
            new_num_beta -= len(freeze_list_beta)

        new_nel = [new_num_alpha, new_num_beta]

        # construct the fermionic operator
        fer_op = FermionicOperator(h1=qmolecule.one_body_integrals,
                                   h2=qmolecule.two_body_integrals)

        # try to reduce it according to the freeze and remove list
        fer_op, self._energy_shift, did_shift = \
            FermionicTransformation._try_reduce_fermionic_operator(fer_op, freeze_list, remove_list)
        # apply same transformation for the aux operators
        if aux_operators is not None:
            aux_operators = [
                FermionicTransformation._try_reduce_fermionic_operator(
                    op, freeze_list, remove_list)[0] for op in aux_operators
            ]

        if did_shift:
            logger.info("Frozen orbital energy shift: %s", self._energy_shift)
        # apply particle hole transformation, if specified
        if self._transformation == FermionicTransformationType.PARTICLE_HOLE.value:
            fer_op, ph_shift = fer_op.particle_hole_transformation(new_nel)
            self._ph_energy_shift = -ph_shift
            logger.info("Particle hole energy shift: %s",
                        self._ph_energy_shift)

            # apply the same transformation for the aux operators
            if aux_operators is not None:
                aux_operators = [
                    op.particle_hole_transformation(new_nel)[0]
                    for op in aux_operators
                ]

        logger.debug('Converting to qubit using %s mapping',
                     self._qubit_mapping)
        qubit_op = FermionicTransformation._map_fermionic_operator_to_qubit(
            fer_op, self._qubit_mapping, new_nel, self._two_qubit_reduction)
        qubit_op.name = 'Fermionic Operator'

        logger.debug('  num paulis: %s, num qubits: %s', len(qubit_op.paulis),
                     qubit_op.num_qubits)

        aux_ops = []  # list of the aux operators

        def _add_aux_op(aux_op: FermionicOperator, name: str) -> None:
            """
            Add auxiliary operators

            Args:
                aux_op: auxiliary operators
                name: name

            """
            aux_qop = FermionicTransformation._map_fermionic_operator_to_qubit(
                aux_op, self._qubit_mapping, new_nel,
                self._two_qubit_reduction)
            aux_qop.name = name

            aux_ops.append(aux_qop)
            logger.debug('  num paulis: %s', aux_qop.paulis)

        # the first three operators are hardcoded to number of particles, angular momentum
        # and magnetization in this order
        logger.debug('Creating aux op for Number of Particles')
        _add_aux_op(fer_op.total_particle_number(), 'Number of Particles')
        logger.debug('Creating aux op for S^2')
        _add_aux_op(fer_op.total_angular_momentum(), 'S^2')
        logger.debug('Creating aux op for Magnetization')
        _add_aux_op(fer_op.total_magnetization(), 'Magnetization')

        # the next three are dipole moments, if supported by the qmolecule
        if qmolecule.has_dipole_integrals():
            self._has_dipole_moments = True

            def _dipole_op(dipole_integrals: np.ndarray, axis: str) \
                    -> Tuple[WeightedPauliOperator, float, float]:
                """
                Dipole operators

                Args:
                    dipole_integrals: dipole integrals
                    axis: axis for dipole moment calculation

                Returns:
                    (qubit_op_, shift, ph_shift_)
                """
                logger.debug('Creating aux op for dipole %s', axis)
                fer_op_ = FermionicOperator(h1=dipole_integrals)
                fer_op_, shift, did_shift_ = self._try_reduce_fermionic_operator(
                    fer_op_, freeze_list, remove_list)
                if did_shift_:
                    logger.info("Frozen orbital %s dipole shift: %s", axis,
                                shift)
                ph_shift_ = 0.0
                if self._transformation == FermionicTransformationType.PARTICLE_HOLE.value:
                    fer_op_, ph_shift_ = fer_op_.particle_hole_transformation(
                        new_nel)
                    ph_shift_ = -ph_shift_
                    logger.info("Particle hole %s dipole shift: %s", axis,
                                ph_shift_)
                qubit_op_ = self._map_fermionic_operator_to_qubit(
                    fer_op_, self._qubit_mapping, new_nel,
                    self._two_qubit_reduction)
                qubit_op_.name = 'Dipole ' + axis
                logger.debug('  num paulis: %s', len(qubit_op_.paulis))
                return qubit_op_, shift, ph_shift_

            op_dipole_x, self._x_dipole_shift, self._ph_x_dipole_shift = \
                _dipole_op(qmolecule.x_dipole_integrals, 'x')
            op_dipole_y, self._y_dipole_shift, self._ph_y_dipole_shift = \
                _dipole_op(qmolecule.y_dipole_integrals, 'y')
            op_dipole_z, self._z_dipole_shift, self._ph_z_dipole_shift = \
                _dipole_op(qmolecule.z_dipole_integrals, 'z')

            aux_ops += [op_dipole_x, op_dipole_y, op_dipole_z]

        # add user specified auxiliary operators
        if aux_operators is not None:
            for aux_op in aux_operators:
                if hasattr(aux_op, 'name'):
                    name = aux_op.name
                else:
                    name = ''
                _add_aux_op(aux_op, name)

        logger.info('Molecule num electrons: %s, remaining for processing: %s',
                    [num_alpha, num_beta], new_nel)
        nspinorbs = qmolecule.num_orbitals * 2
        new_nspinorbs = nspinorbs - len(freeze_list) - len(remove_list)
        logger.info(
            'Molecule num spin orbitals: %s, remaining for processing: %s',
            nspinorbs, new_nspinorbs)

        self._molecule_info['num_particles'] = (new_num_alpha, new_num_beta)
        self._molecule_info['num_orbitals'] = new_nspinorbs
        reduction = self._two_qubit_reduction if self._qubit_mapping == 'parity' else False
        self._molecule_info['two_qubit_reduction'] = reduction
        self._untapered_qubit_op = qubit_op

        z2symmetries = Z2Symmetries([], [], [], None)
        if self._z2symmetry_reduction is not None:
            logger.debug('Processing z2 symmetries')
            qubit_op, aux_ops, z2symmetries = self._process_z2symmetry_reduction(
                qubit_op, aux_ops)
        self._molecule_info['z2_symmetries'] = z2symmetries

        logger.debug('Processing complete ready to run algorithm')
        return qubit_op, aux_ops
Beispiel #11
0
def compute_integrals(atoms,
                      units,
                      charge,
                      multiplicity,
                      basis,
                      calc_type='rhf'):
    # Get config from input parameters
    # Molecule is in this format xyz as below or in Z-matrix e.g "H; O 1 1.08; H 2 1.08 1 107.5":
    # atoms=H .0 .0 .0; H .0 .0 0.2
    # units=Angstrom
    # charge=0
    # multiplicity=1
    # where we support symbol for atom as well as number

    units = _check_units(units)
    mol = _parse_molecule(atoms, units, charge, multiplicity)
    calc_type = calc_type.lower()

    try:
        ehf, enuke, norbs, mohij, mohijkl, orbs, orbs_energy = _calculate_integrals(mol, basis, calc_type)
    except Exception as exc:
        raise QiskitChemistryError('Failed electronic structure computation') from exc

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    # Energies and orbits
    _q_.hf_energy = ehf
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = mol.nup()
    _q_.num_beta = mol.ndown()
    _q_.mo_coeff = orbs
    _q_.orbital_energies = orbs_energy
    # Molecule geometry
    _q_.molecular_charge = mol.charge
    _q_.multiplicity = mol.multiplicity
    _q_.num_atoms = len(mol)
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([len(mol), 3])
    atoms = mol.atoms
    for _n in range(0, _q_.num_atoms):
        atuple = atoms[_n].atuple()
        _q_.atom_symbol.append(QMolecule.symbols[atuple[0]])
        _q_.atom_xyz[_n][0] = atuple[1]
        _q_.atom_xyz[_n][1] = atuple[2]
        _q_.atom_xyz[_n][2] = atuple[3]
    # 1 and 2 electron integrals
    _q_.mo_onee_ints = mohij
    _q_.mo_eri_ints = mohijkl

    return _q_
Beispiel #12
0
def _calculate_integrals(mol, calc_type='rhf', atomic=False):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        mol : A PySCF gto.Mole object.
        calc_type: rhf, uhf, rohf
    Returns:
        ehf : Hartree-Fock energy
        enuke : Nuclear repulsion energy
        norbs : Number of orbitals
        mohij : One electron terms of the Hamiltonian.
        mohijkl : Two electron terms of the Hamiltonian.
        mo_coeff: Orbital coefficients
        orbs_energy: Orbitals energies
        x_dip_ints: x dipole moment integrals
        y_dip_ints: y dipole moment integrals
        z_dip_ints: z dipole moment integrals
        nucl_dipl : Nuclear dipole moment
    """
    enuke = gto.mole.energy_nuc(mol)

    if calc_type == 'rhf':
        mf = scf.RHF(mol)
    elif calc_type == 'rohf':
        mf = scf.ROHF(mol)
    elif calc_type == 'uhf':
        mf = scf.UHF(mol)
    else:
        raise QiskitChemistryError('Invalid calc_type: {}'.format(calc_type))

    ehf = mf.kernel()

    if type(mf.mo_coeff) is tuple:
        mo_coeff = mf.mo_coeff[0]
        mo_occ = mf.mo_occ[0]
    else:
        mo_coeff = mf.mo_coeff
        mo_occ = mf.mo_occ

    norbs = mo_coeff.shape[0]
    orbs_energy = mf.mo_energy
    # print(np.dot(mo_coeff,mo_coeff.T))
    O = get_ovlp(mol)
    # print(np.dot(O,O.T))
    mo_tr = np.dot(np.dot(O, mo_coeff), O.T)

    # print(np.dot(mo_tr,mo_tr.T))

    # two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints)
    # temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints)
    # two_body_temp = QMolecule.twoe_to_spin(temp_int)
    # mol = gto.M(atom=mol.atom, basis='sto-3g')

    # X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

    ### for atomic basis
    if atomic:
        mo_coeff = np.identity(len(mo_coeff))
    ###
    # print(mo_coeff)
    hij = mf.get_hcore()
    mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff)
    # mohij = hij

    eri = ao2mo.incore.full(mf._eri, mo_coeff, compact=False)
    # eri_1 = mf._eri
    # print(np.shape(eri))
    # print(np.shape(eri_1))
    mohijkl = eri.reshape(norbs, norbs, norbs, norbs)

    # exit()

    # dipole integrals
    mol.set_common_orig((0, 0, 0))
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    x_dip_ints = QMolecule.oneeints2mo(ao_dip[0], mo_coeff)
    y_dip_ints = QMolecule.oneeints2mo(ao_dip[1], mo_coeff)
    z_dip_ints = QMolecule.oneeints2mo(ao_dip[2], mo_coeff)

    dm = mf.make_rdm1(mf.mo_coeff, mf.mo_occ)
    if calc_type == 'rohf' or calc_type == 'uhf':
        dm = dm[0]
    elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, dm).real)
    elec_dip = np.round(elec_dip, decimals=8)
    nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords())
    nucl_dip = np.round(nucl_dip, decimals=8)
    logger.info("HF Electronic dipole moment: {}".format(elec_dip))
    logger.info("Nuclear dipole moment: {}".format(nucl_dip))
    logger.info("Total dipole moment: {}".format(nucl_dip + elec_dip))

    return ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip_ints, y_dip_ints, z_dip_ints, nucl_dip
Beispiel #13
0
def qmol_func(mol, calc_type='rhf', atomic=False):
    ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip, y_dip, z_dip, nucl_dip = _calculate_integrals(
        mol, calc_type, atomic)
    # Create driver level molecule object and populate
    _q_ = QMolecule()

    # Energies and orbits
    _q_.hf_energy = ehf
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = mol.nelec[0]
    _q_.num_beta = mol.nelec[1]
    _q_.mo_coeff = mo_coeff
    _q_.orbital_energies = orbs_energy
    # Molecule geometry
    _q_.molecular_charge = mol.charge
    _q_.multiplicity = mol.spin + 1
    _q_.num_atoms = mol.natm
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([mol.natm, 3])
    atoms = mol.atom_coords()
    for _n in range(0, _q_.num_atoms):
        xyz = mol.atom_coord(_n)
        _q_.atom_symbol.append(mol.atom_pure_symbol(_n))
        _q_.atom_xyz[_n][0] = xyz[0]
        _q_.atom_xyz[_n][1] = xyz[1]
        _q_.atom_xyz[_n][2] = xyz[2]
    # 1 and 2 electron integrals. h1 & h2 are ready to pass to FermionicOperator
    _q_.mo_onee_ints = mohij
    _q_.mo_eri_ints = mohijkl
    # dipole integrals
    _q_.x_dip_mo_ints = x_dip
    _q_.y_dip_mo_ints = y_dip
    _q_.z_dip_mo_ints = z_dip
    # dipole moment
    _q_.nuclear_dipole_moment = nucl_dip
    _q_.reverse_dipole_sign = True
    return _q_
Beispiel #14
0
def _calculate_integrals(mol, hf_method='rhf', conv_tol=1e-9, max_cycle=50, init_guess='minao',outfile=None):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        mol (gto.Mole) : A PySCF gto.Mole object.
        hf_method (str): rhf, uhf, rohf
        conv_tol (float): Convergence tolerance
        max_cycle (int): Max convergence cycles
        init_guess (str): Initial guess for SCF
    Returns:
        QMolecule: QMolecule populated with driver integrals etc
    Raises:
        QiskitChemistryError: Invalid hf method type
    """
    enuke = gto.mole.energy_nuc(mol)

    if hf_method == 'rhf':
        m_f = scf.RHF(mol)
    elif hf_method == 'rohf':
        m_f = scf.ROHF(mol)
    elif hf_method == 'uhf':
        m_f = scf.UHF(mol)
    else:
        raise QiskitChemistryError('Invalid hf_method type: {}'.format(hf_method))

    m_f.conv_tol = conv_tol
    m_f.max_cycle = max_cycle
    m_f.init_guess = init_guess
    ehf = m_f.kernel()

    from pyscf import tools

    from prettytable import PrettyTable
    C = m_f.mo_coeff

    irr = get_irreps(mol,C)
    table_ancillary_info = [[str(round(m_f.mo_energy[i],4)),irr[i],str(int(m_f.mo_occ[i]))] for i in range(mol.nao_nr())]

    outfile.write("SCF orbitals\n")
    t = PrettyTable(['MO']+mol.ao_labels()+['E','irr','occ'])
    for i in range(C.shape[1]):
        if(C[np.argmax(np.abs(C[:,i])),i]<0): C[:,i] *= -1
        t.add_row([str(i)]+[str(round(x,4)) for x in C[:,i]]+table_ancillary_info[i])
    outfile.write(str(t))

    filename = 'mos'
    for i in range(m_f.mo_coeff.shape[1]):
        moldenfile = filename+'-'+str(i)+'.molden'
        tools.molden.from_mo(mol,moldenfile,m_f.mo_coeff)
        jmol_script = filename+'-'+str(i)+'.spt'
        fspt = open(jmol_script,'w')
        fspt.write('''
        initialize;
        set background [xffffff];
        set frank off
        set autoBond true;
        set bondRadiusMilliAngstroms 66;
        set bondTolerance 0.5;
        set forceAutoBond false;
        load %s
        ''' % moldenfile)
        fspt.write('''
        zoom 130;
        rotate -20 z
        rotate -60 x
        axes
        MO COLOR [xff0020] [x0060ff];
        MO COLOR translucent 0.25;
        MO fill noDots noMesh;
        MO titleformat "";
        ''')
        fspt.write('MO %d cutoff 0.02;\n' % (i+1))
        fspt.write('write IMAGE 400 400 PNG 180 "%s-%02d.png";\n' % (filename,i+1))
        fspt.close()

    logger.info('PySCF kernel() converged: %s, e(hf): %s', m_f.converged, m_f.e_tot)
    if isinstance(m_f.mo_coeff, tuple):
        mo_coeff = m_f.mo_coeff[0]
        mo_coeff_b = m_f.mo_coeff[1]
        # mo_occ   = m_f.mo_occ[0]
        # mo_occ_b = m_f.mo_occ[1]
    else:
        # With PySCF 1.6.2, instead of a tuple of 2 dimensional arrays, its a 3 dimensional
        # array with the first dimension indexing to the coeff arrays for alpha and beta
        if len(m_f.mo_coeff.shape) > 2:
            mo_coeff = m_f.mo_coeff[0]
            mo_coeff_b = m_f.mo_coeff[1]
            # mo_occ   = m_f.mo_occ[0]
            # mo_occ_b = m_f.mo_occ[1]
        else:
            mo_coeff = m_f.mo_coeff
            mo_coeff_b = None
            # mo_occ   = mf.mo_occ
            # mo_occ_b = None
    norbs = mo_coeff.shape[0]

    if isinstance(m_f.mo_energy, tuple):
        orbs_energy = m_f.mo_energy[0]
        orbs_energy_b = m_f.mo_energy[1]
    else:
        # See PYSCF 1.6.2 comment above - this was similarly changed
        if len(m_f.mo_energy.shape) > 1:
            orbs_energy = m_f.mo_energy[0]
            orbs_energy_b = m_f.mo_energy[1]
        else:
            orbs_energy = m_f.mo_energy
            orbs_energy_b = None

    if logger.isEnabledFor(logging.DEBUG):
        # Add some more to PySCF output...
        # First analyze() which prints extra information about MO energy and occupation
        mol.stdout.write('\n')
        m_f.analyze()
        # Now labelled orbitals for contributions to the MOs for s,p,d etc of each atom
        mol.stdout.write('\n\n--- Alpha Molecular Orbitals ---\n\n')
        dump_mat.dump_mo(mol, mo_coeff, digits=7, start=1)
        if mo_coeff_b is not None:
            mol.stdout.write('\n--- Beta Molecular Orbitals ---\n\n')
            dump_mat.dump_mo(mol, mo_coeff_b, digits=7, start=1)
        mol.stdout.flush()

    hij = m_f.get_hcore()
    mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff)
    mohij_b = None
    if mo_coeff_b is not None:
        mohij_b = np.dot(np.dot(mo_coeff_b.T, hij), mo_coeff_b)

    eri = mol.intor('int2e', aosym=1)
    mo_eri = ao2mo.incore.full(m_f._eri, mo_coeff, compact=False)
    mohijkl = mo_eri.reshape(norbs, norbs, norbs, norbs)
    mohijkl_bb = None
    mohijkl_ba = None
    if mo_coeff_b is not None:
        mo_eri_b = ao2mo.incore.full(m_f._eri, mo_coeff_b, compact=False)
        mohijkl_bb = mo_eri_b.reshape(norbs, norbs, norbs, norbs)
        mo_eri_ba = ao2mo.incore.general(m_f._eri,
                                         (mo_coeff_b, mo_coeff_b, mo_coeff, mo_coeff),
                                         compact=False)
        mohijkl_ba = mo_eri_ba.reshape(norbs, norbs, norbs, norbs)

    # dipole integrals
    mol.set_common_orig((0, 0, 0))
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    x_dip_ints = ao_dip[0]
    y_dip_ints = ao_dip[1]
    z_dip_ints = ao_dip[2]

    d_m = m_f.make_rdm1(m_f.mo_coeff, m_f.mo_occ)
    if hf_method in ('rohf', 'uhf'):
        d_m = d_m[0]
    elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, d_m).real)
    elec_dip = np.round(elec_dip, decimals=8)
    nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords())
    nucl_dip = np.round(nucl_dip, decimals=8)
    logger.info("HF Electronic dipole moment: %s", elec_dip)
    logger.info("Nuclear dipole moment: %s", nucl_dip)
    logger.info("Total dipole moment: %s", nucl_dip+elec_dip)

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    _q_.origin_driver_version = pyscf_version
    # Energies and orbits
    _q_.hf_energy = ehf
    _q_.nuclear_repulsion_energy = enuke
    _q_.num_orbitals = norbs
    _q_.num_alpha = mol.nelec[0]
    _q_.num_beta = mol.nelec[1]
    _q_.mo_coeff = mo_coeff
    _q_.mo_coeff_b = mo_coeff_b
    _q_.orbital_energies = orbs_energy
    _q_.orbital_energies_b = orbs_energy_b
    # Molecule geometry
    _q_.molecular_charge = mol.charge
    _q_.multiplicity = mol.spin + 1
    _q_.num_atoms = mol.natm
    _q_.atom_symbol = []
    _q_.atom_xyz = np.empty([mol.natm, 3])
    _ = mol.atom_coords()
    for n_i in range(0, _q_.num_atoms):
        xyz = mol.atom_coord(n_i)
        _q_.atom_symbol.append(mol.atom_pure_symbol(n_i))
        _q_.atom_xyz[n_i][0] = xyz[0]
        _q_.atom_xyz[n_i][1] = xyz[1]
        _q_.atom_xyz[n_i][2] = xyz[2]
    # 1 and 2 electron integrals AO and MO
    _q_.hcore = hij
    _q_.hcore_b = None
    _q_.kinetic = mol.intor_symmetric('int1e_kin')
    _q_.overlap = m_f.get_ovlp()
    _q_.eri = eri
    _q_.mo_onee_ints = mohij
    _q_.mo_onee_ints_b = mohij_b
    _q_.mo_eri_ints = mohijkl
    _q_.mo_eri_ints_bb = mohijkl_bb
    _q_.mo_eri_ints_ba = mohijkl_ba
    # dipole integrals AO and MO
    _q_.x_dip_ints = x_dip_ints
    _q_.y_dip_ints = y_dip_ints
    _q_.z_dip_ints = z_dip_ints
    _q_.x_dip_mo_ints = QMolecule.oneeints2mo(x_dip_ints, mo_coeff)
    _q_.x_dip_mo_ints_b = None
    _q_.y_dip_mo_ints = QMolecule.oneeints2mo(y_dip_ints, mo_coeff)
    _q_.y_dip_mo_ints_b = None
    _q_.z_dip_mo_ints = QMolecule.oneeints2mo(z_dip_ints, mo_coeff)
    _q_.z_dip_mo_ints_b = None
    if mo_coeff_b is not None:
        _q_.x_dip_mo_ints_b = QMolecule.oneeints2mo(x_dip_ints, mo_coeff_b)
        _q_.y_dip_mo_ints_b = QMolecule.oneeints2mo(y_dip_ints, mo_coeff_b)
        _q_.z_dip_mo_ints_b = QMolecule.oneeints2mo(z_dip_ints, mo_coeff_b)
    # dipole moment
    _q_.nuclear_dipole_moment = nucl_dip
    _q_.reverse_dipole_sign = True

    return _q_