.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/structure/kekule/plot_01_kekule_structures.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_structure_kekule_plot_01_kekule_structures.py: Kekulé's benzene: enumerating the Kekulé structures of aromatic hydrocarbons ============================================================================ August Kekulé (1865) proposed that benzene's six carbons form a ring with alternating single and double bonds, and soon after that the two alternating arrangements interconvert, which explained why benzene has only one ortho-disubstituted isomer. A Kekulé structure is a choice of double bonds that gives every carbon exactly one; in graph language, a perfect matching of the carbon skeleton. This example uses :func:`~chemistrykit.structure.systems.kekule.kekule_structures` to list benzene's two Kekulé structures and naphthalene's three, and counts them for larger benzenoid hydrocarbons: a linear acene with :math:`r` rings has :math:`r+1`, while angular phenanthrene has five, one reason it is more stable than its linear isomer anthracene (four). .. GENERATED FROM PYTHON SOURCE LINES 21-49 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from chemistrykit.structure.systems.kekule import count_kekule_structures, kekule_structures def hexagon(cx, cy, start=90.0): """Six vertex positions of a unit hexagon centred at (cx, cy).""" a = np.radians(start + 60.0 * np.arange(6)) return np.column_stack([cx + np.cos(a), cy + np.sin(a)]) # Benzene: atoms 0-5 around the ring. benzene_xy = hexagon(0.0, 0.0) benzene_bonds = [(i, (i + 1) % 6) for i in range(6)] # Naphthalene: two hexagons sharing the bond between atoms 4 and 9. naphthalene_bonds = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 9), (9, 0), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)] left = hexagon(-np.sqrt(3) / 2, 0.0, start=30.0) right = hexagon(np.sqrt(3) / 2, 0.0, start=30.0) naphthalene_xy = np.array([left[1], left[2], left[3], left[4], left[5], right[4], right[5], right[0], right[1], right[2]]) benzene_k = kekule_structures(6, benzene_bonds) naphthalene_k = kekule_structures(10, naphthalene_bonds) print(f"benzene: {len(benzene_k)} Kekule structures -> {benzene_k}") print(f"naphthalene: {len(naphthalene_k)} Kekule structures") assert len(benzene_k) == 2 and len(naphthalene_k) == 3 .. rst-class:: sphx-glr-script-out .. code-block:: none benzene: 2 Kekule structures -> [[(0, 1), (2, 3), (4, 5)], [(0, 5), (1, 2), (3, 4)]] naphthalene: 3 Kekule structures .. GENERATED FROM PYTHON SOURCE LINES 50-53 Each benzene bond is double in exactly one of the two structures, so averaging them gives every bond the same order, 1.5. That averaging is how Kekulé's oscillation hypothesis makes the six bonds equivalent. .. GENERATED FROM PYTHON SOURCE LINES 53-58 .. code-block:: Python double_fraction = [sum((min(b), max(b)) in s for s in benzene_k) / len(benzene_k) for b in benzene_bonds] print(f"fraction of Kekule structures in which each benzene bond is double: {double_fraction}") .. rst-class:: sphx-glr-script-out .. code-block:: none fraction of Kekule structures in which each benzene bond is double: [0.5, 0.5, 0.5, 0.5, 0.5, 0.5] .. GENERATED FROM PYTHON SOURCE LINES 59-60 Kekulé structure counts of larger benzenoid hydrocarbons: .. GENERATED FROM PYTHON SOURCE LINES 60-78 .. code-block:: Python def acene(n_rings): """Linear acene skeleton with n_rings fused rings (4n+2 carbons).""" top = list(range(2 * n_rings + 1)) bottom = list(range(2 * n_rings + 1, 4 * n_rings + 2)) bonds = [(a, a + 1) for a in top[:-1]] + [(b, b + 1) for b in bottom[:-1]] bonds += [(top[2 * k], bottom[2 * k]) for k in range(n_rings + 1)] return 4 * n_rings + 2, bonds phenanthrene = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 0), (4, 6), (6, 7), (7, 8), (8, 9), (9, 3), (8, 10), (10, 11), (11, 12), (12, 13), (13, 9)] counts = {name: count_kekule_structures(*acene(r)) for r, name in enumerate(["benzene", "naphthalene", "anthracene", "tetracene", "pentacene"], start=1)} counts["phenanthrene"] = count_kekule_structures(14, phenanthrene) for name, k in counts.items(): print(f"{name:12s}: K = {k}") assert counts["anthracene"] == 4 and counts["phenanthrene"] == 5 .. rst-class:: sphx-glr-script-out .. code-block:: none benzene : K = 2 naphthalene : K = 3 anthracene : K = 4 tetracene : K = 5 pentacene : K = 6 phenanthrene: K = 5 .. GENERATED FROM PYTHON SOURCE LINES 79-80 Draw benzene's two and naphthalene's three Kekulé structures: .. GENERATED FROM PYTHON SOURCE LINES 80-100 .. code-block:: Python def draw(ax, xy, bonds, doubles, title): double_set = {tuple(sorted(b)) for b in doubles} for i, j in bonds: is_double = tuple(sorted((i, j))) in double_set ax.plot(*zip(xy[i], xy[j]), color="crimson" if is_double else "black", linewidth=4.0 if is_double else 1.5) ax.set_aspect("equal") ax.axis("off") ax.set_title(title, fontsize=10) fig, axes = plt.subplots(1, 5, figsize=(15, 3.2)) for k, s in enumerate(benzene_k): draw(axes[k], benzene_xy, benzene_bonds, s, f"benzene, structure {k + 1}") for k, s in enumerate(naphthalene_k): draw(axes[2 + k], naphthalene_xy, naphthalene_bonds, s, f"naphthalene, structure {k + 1}") fig.suptitle("Kekulé structures (double bonds drawn thick red)") fig.tight_layout() plt.show() .. image-sg:: /api/gallery/structure/kekule/images/sphx_glr_plot_01_kekule_structures_001.png :alt: Kekulé structures (double bonds drawn thick red), benzene, structure 1, benzene, structure 2, naphthalene, structure 1, naphthalene, structure 2, naphthalene, structure 3 :srcset: /api/gallery/structure/kekule/images/sphx_glr_plot_01_kekule_structures_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.054 seconds) .. _sphx_glr_download_api_gallery_structure_kekule_plot_01_kekule_structures.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_kekule_structures.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_kekule_structures.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_kekule_structures.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_