예제 #1
0
    def run_pyquante(self):
        """Runs the PyQuante calculation.

        This method is part of the public interface to allow the user to easily overwrite it in a
        subclass to further tailor the behavior to some specific use case.

        Raises:
            QiskitNatureError: If an invalid HF method type was supplied.
        """
        # pylint: disable=import-error
        from pyquante2 import rhf, uhf, rohf, basisset

        self._bfs = basisset(self._mol, self.basis.value)

        if self.method == MethodType.RHF:
            self._calc = rhf(self._mol, self._bfs)
        elif self.method == MethodType.ROHF:
            self._calc = rohf(self._mol, self._bfs)
        elif self.method == MethodType.UHF:
            self._calc = uhf(self._mol, self._bfs)
        else:
            raise QiskitNatureError(f"Invalid method type: {self.method}")

        self._calc.converge(tol=self.tol, maxiters=self.maxiters)
        logger.debug("PyQuante2 processing information:\n%s", self._calc)
예제 #2
0
 def test_oh(self):
     bfs = basisset(oh,'sto-3g')
     hamiltonian = rohf(bfs)
     iterator = ROSCFIterator(hamiltonian)
     iterator.converge()
     self.assertTrue(iterator.converged)
     self.assertAlmostEqual(iterator.energy, -74.359151530162, 5)
예제 #3
0
 def test_N8(self):
     """N8"""
     N8 = read_xyz('./molfiles/N8.xyz')
     bfs = basisset(N8,'cc-pvdz')
     hamiltonian = rohf(bfs, twoe_factory=libint_twoe_integrals)
     iterator = ROSCFIterator(hamiltonian)
     iterator.converge()
     self.assertTrue(iterator.converged)
     self.assertAlmostEqual(iterator.energy, -434.992755329296, 5)
예제 #4
0
 def test_CF3(self):
     """CF3 radical"""
     CF3 = read_xyz('./molfiles/CF3.xyz')
     bfs = basisset(CF3,'sto-3g')
     hamiltonian = rohf(bfs, twoe_factory=libint_twoe_integrals)
     iterator = ROSCFIterator(hamiltonian)
     iterator.converge()
     self.assertTrue(iterator.converged)
     self.assertAlmostEqual(iterator.energy, -331.479340943449, 5)
예제 #5
0
def _calculate_integrals(molecule, basis='sto3g', calc_type='rhf'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        molecule : A pyquante2 molecular object.
        basis : The basis set for the electronic structure computation
        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.
        orbs: Molecular orbital coefficients
        orbs_energy: Orbital energies
    """
    bfs = basisset(molecule, basis)
    integrals = onee_integrals(bfs, molecule)
    hij = integrals.T + integrals.V
    hijkl_compressed = twoe_integrals(bfs)

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

    if calc_type == 'rhf':
        solver = rhf(molecule, bfs)
    elif calc_type == 'rohf':
        solver = rohf(molecule, bfs)
    elif calc_type == 'uhf':
        solver = uhf(molecule, bfs)
    else:
        raise QiskitChemistryError('Invalid calc_type: {}'.format(calc_type))
    logger.debug('Solver name {}'.format(solver.name))
    ehf = solver.converge()
    if hasattr(solver, 'orbs'):
        orbs = solver.orbs
    else:
        orbs = solver.orbsa
    norbs = len(orbs)
    if hasattr(solver, 'orbe'):
        orbs_energy = solver.orbe
    else:
        orbs_energy = solver.orbea
    enuke = molecule.nuclear_repulsion()
    # Get ints in molecular orbital basis
    mohij = simx(hij, orbs)
    mohijkl_compressed = transformintegrals(hijkl_compressed, orbs)
    mohijkl = np.zeros((norbs, norbs, norbs, norbs))
    for i in range(norbs):
        for j in range(norbs):
            for k in range(norbs):
                for l in range(norbs):
                    mohijkl[i, j, k,
                            l] = mohijkl_compressed[ijkl2intindex(i, j, k, l)]

    return ehf[0], enuke, norbs, mohij, mohijkl, orbs, orbs_energy
예제 #6
0
 def test_CrCO6(self):
     # FAIL
     """Cr(CO)6 symmetry Oh
     Reference: Whitaker, A.; Jeffery, J. W. Acta Cryst. 1967, 23, 977. DOI: 10.1107/S0365110X67004153
     """
     CrCO6 = read_xyz('./molfiles/CrCO6.xyz')
     bfs = basisset(CrCO6,'sto-3g')
     hamiltonian = rohf(bfs, twoe_factory=libint_twoe_integrals)
     iterator = ROSCFIterator(hamiltonian)
     iterator.converge()
     self.assertTrue(iterator.converged)
     self.assertAlmostEqual(iterator.energy, -1699.539642257497, 0)
예제 #7
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:
        QiskitNatureError: 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 QiskitNatureError("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_molecular_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_
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 : A pyquante2 molecular object.
        basis : The basis set for the electronic structure computation
        hf_method: rhf, uhf, rohf
    Returns:
        QMolecule: QMolecule populated with driver integrals etc
    """
    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{}'.format(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 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_.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_
예제 #9
0
 def test_li_rohf(self):
     from pyquante2 import li
     bfs = basisset(li, 'sto3g')
     solver = rohf(li, bfs)
     Es = solver.converge()
     self.assertAlmostEqual(solver.energy, -7.31552591799, match_digits)
예제 #10
0
 def test_oh_rohf(self):
     from pyquante2 import oh
     bfs = basisset(oh, 'sto3g')
     solver = rohf(oh, bfs)
     Es = solver.converge()
     self.assertAlmostEqual(solver.energy, -74.3591663559, match_digits)