diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index b8b5c7794cf..0b18c0c68e4 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -44,6 +44,9 @@
* Observable validation for `default.qubit` is now based on execution mode (analytic vs. finite shots) and measurement type (sample measurement vs. state measurement).
[(#5890)](https://github.com/PennyLaneAI/pennylane/pull/5890)
+* Molecules and Hamiltonians can now be constructed for all the elements present in the periodic table.
+ [(#5821)](https://github.com/PennyLaneAI/pennylane/pull/5821)
+
Community contributions 🥳
* `DefaultQutritMixed` readout error has been added using parameters `readout_relaxation_probs` and
@@ -92,6 +95,7 @@
This release contains contributions from (in alphabetical order):
Guillermo Alonso,
+Utkarsh Azad
Astral Cai,
Yushao Chen,
Gabriel Bottrill,
diff --git a/pennylane/qchem/basis_data.py b/pennylane/qchem/basis_data.py
index eac4f8cdae6..5dc381dc0f7 100644
--- a/pennylane/qchem/basis_data.py
+++ b/pennylane/qchem/basis_data.py
@@ -20,18 +20,30 @@
import itertools
+# Note: Below markers are added to prevent reformatting of this dictionary by black
+# fmt: off
+# IUPAC Periodic Table of the Elements: https://iupac.org/what-we-do/periodic-table-of-elements/
atomic_numbers = {
- "H": 1,
- "He": 2,
- "Li": 3,
- "Be": 4,
- "B": 5,
- "C": 6,
- "N": 7,
- "O": 8,
- "F": 9,
- "Ne": 10,
+ 'H': 1, 'He': 2, # Period 1
+ 'Li': 3, 'Be': 4, 'B': 5, 'C': 6, 'N': 7, 'O': 8, 'F': 9, 'Ne': 10, # Period 2
+ 'Na': 11, 'Mg': 12, 'Al': 13, 'Si': 14, 'P': 15, 'S': 16, 'Cl': 17, 'Ar': 18, # Period 3
+ 'K': 19, 'Ca': 20, 'Sc': 21, 'Ti': 22, 'V': 23, 'Cr': 24, 'Mn': 25, 'Fe': 26, 'Co': 27, # Period 4
+ 'Ni': 28, 'Cu': 29, 'Zn': 30, 'Ga': 31, 'Ge': 32, 'As': 33, 'Se': 34, 'Br': 35, 'Kr': 36,
+ 'Rb': 37, 'Sr': 38, 'Y': 39, 'Zr': 40, 'Nb': 41, 'Mo': 42, 'Tc': 43, 'Ru': 44, 'Rh': 45, # Period 5
+ 'Pd': 46, 'Ag': 47, 'Cd': 48, 'In': 49, 'Sn': 50, 'Sb': 51, 'Te': 52, 'I': 53, 'Xe': 54,
+ 'Cs': 55, 'Ba': 56, # Period 6
+ 'La': 57, 'Ce': 58, 'Pr': 59, 'Nd': 60, 'Pm': 61, 'Sm': 62, 'Eu': 63, 'Gd': 64, 'Tb': 65, # Lanthanides
+ 'Dy': 66, 'Ho': 67, 'Er': 68, 'Tm': 69, 'Yb': 70, 'Lu': 71,
+ 'Hf': 72, 'Ta': 73, 'W': 74, 'Re': 75, 'Os': 76, 'Ir': 77, 'Pt': 78, 'Au': 79, 'Hg': 80, # Period 6
+ 'Tl': 81, 'Pb': 82, 'Bi': 83, 'Po': 84, 'At': 85, 'Rn': 86,
+ 'Fr': 87, 'Ra': 88, # Period 7
+ 'Ac': 89, 'Th': 90, 'Pa': 91, 'U': 92, 'Np': 93, 'Pu': 94, 'Am': 95, 'Cm': 96, 'Bk': 97, # Actinides
+ 'Cf': 98, 'Es': 99, 'Fm': 100, 'Md': 101, 'No': 102, 'Lr': 103,
+ 'Rf': 104, 'Db': 105, 'Sg': 106, 'Bh': 107, 'Hs': 108, 'Mt': 109, 'Ds': 110, 'Rg': 111, # Period 7
+ 'Cn': 112, 'Nh': 113, 'Fl': 114, 'Mc': 115, 'Lv': 116, 'Ts': 117, 'Og': 118
}
+# fmt: on
+
STO3G = {
"H": {
@@ -797,11 +809,14 @@ def load_basisset(basis, element):
"[3]": "F",
"[4]": "G",
"[5]": "H",
+ "[6]": "I",
}
- element = str(atomic_numbers[element])
+ atomic_number = atomic_numbers.get(element, None)
+ if atomic_number is None:
+ raise ValueError(f"Requested element {element} doesn't exist in the periodic table.")
- data = bse.get_basis(basis)["elements"][element]["electron_shells"]
+ data = bse.get_basis(basis)["elements"][str(atomic_number)]["electron_shells"]
orbitals = []
exponents = []
diff --git a/pennylane/qchem/basis_set.py b/pennylane/qchem/basis_set.py
index 6afac08f166..3e8fe2633cc 100644
--- a/pennylane/qchem/basis_set.py
+++ b/pennylane/qchem/basis_set.py
@@ -100,7 +100,14 @@ def atom_basis_data(name, atom, load_data=False):
if load_data:
basis = load_basisset(name, atom)
else:
- basis = basis_sets[name][atom]
+ basis = basis_sets[name].get(atom, None)
+ if basis is None:
+ raise ValueError(
+ f"The requested basis set data is not available for {atom}. "
+ "Please consider using `load_data=True` to download the basis set "
+ "from the external library basis-set-exchange that can be installed with: "
+ "pip install basis-set-exchange."
+ )
params = []
sp_count = 0
diff --git a/pennylane/qchem/openfermion_pyscf.py b/pennylane/qchem/openfermion_pyscf.py
index 7e98ab2baa1..fd3031a7178 100644
--- a/pennylane/qchem/openfermion_pyscf.py
+++ b/pennylane/qchem/openfermion_pyscf.py
@@ -609,10 +609,7 @@ def dipole_of(
for i in symbols:
if i not in atomic_numbers:
- raise ValueError(
- f"Currently, only first- or second-row elements of the periodic table are supported;"
- f" got element {i}"
- )
+ raise ValueError(f"Requested element {i} doesn't exist")
hf_file = qml.qchem.meanfield(symbols, coordinates, name, charge, mult, basis, package, outpath)
diff --git a/tests/qchem/openfermion_pyscf_tests/test_dipole_of.py b/tests/qchem/openfermion_pyscf_tests/test_dipole_of.py
index 36fb9422b9e..739965c5813 100644
--- a/tests/qchem/openfermion_pyscf_tests/test_dipole_of.py
+++ b/tests/qchem/openfermion_pyscf_tests/test_dipole_of.py
@@ -274,7 +274,7 @@ def circuit(hf_state, obs):
("symbols", "coords", "mult", "msg_match"),
[
(["H", "H"], x_h2, 2, "this functionality is constrained to Hartree-Fock states"),
- (["H", "Ca"], x_h2, 1, "only first- or second-row elements of the periodic table"),
+ (["H", "Cx"], x_h2, 1, "Requested element Cx doesn't exist"),
],
)
@pytest.mark.usefixtures("skip_if_no_openfermion_support")
diff --git a/tests/qchem/test_basis_set.py b/tests/qchem/test_basis_set.py
index 435f947d3b0..35df4301342 100644
--- a/tests/qchem/test_basis_set.py
+++ b/tests/qchem/test_basis_set.py
@@ -477,6 +477,15 @@ def test_mol_basis_data(self, basis_data):
assert np.allclose(params, params_ref)
+ def test_mol_basis_data_error(self):
+ """Test that correct error is raised if the element is not present in the internal basis-sets"""
+
+ with pytest.raises(ValueError, match="The requested basis set data is not available for"):
+ qchem.basis_set.atom_basis_data(name="sto-3g", atom="Os")
+
+ with pytest.raises(ValueError, match="Requested element Ox doesn't exist"):
+ qchem.basis_data.load_basisset(basis="sto-3g", element="Ox")
+
class TestLoadBasis:
"""Tests for loading data from external libraries."""
diff --git a/tests/qchem/test_molecule.py b/tests/qchem/test_molecule.py
index b4e797e5687..ea0195647ff 100644
--- a/tests/qchem/test_molecule.py
+++ b/tests/qchem/test_molecule.py
@@ -49,7 +49,7 @@ def test_basis_error(self, symbols, geometry):
@pytest.mark.parametrize(
("symbols", "geometry"),
[
- (["H", "Og"], np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]])),
+ (["H", "Ox"], np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]])),
],
)
def test_symbol_error(self, symbols, geometry):