The H\(_2^+\) Molecular Ion

Author

Daniel Fischer

Introduction

The hydrogen molecular ion, H\(_2^+\), is the simplest conceivable molecule: two protons and one electron. Despite its simplicity, it is of profound importance in molecular physics.

  • It provides the first step beyond the hydrogen atom, introducing the physics of chemical bonding within a fully quantum-mechanical framework.
  • The system’s simplicity allows an almost complete analytical treatment—though not a fully exact one—making it an ideal prototype for discussing approximation methods such as the Born-Oppenheimer approximation and the variational method.
  • Remarkably, in prolate spheroidal (ellipsoidal) coordinates, the Schrödinger equation becomes separable, at least partially, allowing us to identify distinct “radial” and “angular” degrees of freedom.

We will see that the key to understanding H\(_2^+\) lies in a clever choice of coordinates and the recognition that the electron experiences the combined Coulomb field of two fixed nuclei.


1. Setting up the System Hamiltonian

Let’s consider two protons, labeled A and B, separated by a distance \(R\). An electron with position vector \(\vec{r}\) moves in the combined potential of these two nuclei.

We define:

  • \(\vec{R}_A\) and \(\vec{R}_B\) as the position vectors of the nuclei,
  • \(\vec{r}_A = \vec{r} - \vec{R}_A\) and \(\vec{r}_B = \vec{r} - \vec{R}_B\) as the electron’s position relative to each nucleus.

Under the Born–Oppenheimer approximation, we assume that the nuclei are fixed in space (since they are much heavier than the electron). The electronic Hamiltonian then reads:

\[ \hat{H}_e = - \frac{\hbar^2}{2m_e} \nabla^2 - \frac{e^2}{4\pi \epsilon_0 r_A} - \frac{e^2}{4\pi \epsilon_0 r_B}. \]

The total energy of the system also includes the repulsive interaction between the two protons:

\[ E_\text{total} = E_e + \frac{e^2}{4\pi \epsilon_0 R}. \]


Here’s a sketch of the molecular geometry, including the relevant position vectors:

Code
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 12

fig, ax = plt.subplots(figsize=(7, 5))
ax.set_aspect('equal', adjustable='box')
ax.set_xlim(-1, 5)
ax.set_ylim(-1, 5)
ax.axis('off')

A = np.array([0, 0])
B = np.array([4, 0])
e_minus = np.array([3.5, 3.5])
S = np.array([2, 0])

# Nuclei
ax.plot(A[0], A[1], 'o', color='red', markersize=15)
ax.text(A[0]-0.2, A[1]+0.3, 'A', ha='right', va='bottom', fontsize=12)
ax.text(A[0]-0.2, A[1]-0.3, '$p^+$', ha='right', va='top', fontsize=12)

ax.plot(B[0], B[1], 'o', color='red', markersize=15)
ax.text(B[0]+0.2, B[1]+0.3, 'B', ha='left', va='bottom', fontsize=12)
ax.text(B[0]+0.2, B[1]-0.3, '$p^+$', ha='left', va='top', fontsize=12)

# Electron
ax.plot(e_minus[0], e_minus[1], 'o', color='green', markersize=10)
ax.text(e_minus[0]+0.2, e_minus[1]+0.2, '$e^-$', ha='left', va='center', fontsize=12)

# Center and vectors
ax.plot(S[0], S[1], 'x', color='black', markersize=10)
ax.text(S[0], S[1]-0.2, 'O', ha='center', va='top', fontsize=12)

# Vector annotations
ax.annotate('', xy=(S[0], S[1]), xytext=(A[0], A[1]),
            arrowprops={'arrowstyle': '<-', 'lw': 1.5, 'color': 'black'})
ax.text(1, -0.2, r'$\vec{R}_A$', ha='center', va='top', fontsize=12)

ax.annotate('', xy=(B[0], B[1]), xytext=(S[0], S[1]),
            arrowprops={'arrowstyle': '->', 'lw': 1.5, 'color': 'black'})
ax.text(3, -0.2, r'$\vec{R}_B$', ha='center', va='top', fontsize=12)

ax.annotate('', xy=(A[0], A[1]-0.7), xytext=(B[0], B[1]-0.7),
            arrowprops={'arrowstyle': '<->', 'lw': 1.5, 'color': 'black'})
ax.text(2, -0.9, r'$\vec{R}$', ha='center', va='top', fontsize=12)

ax.annotate('', xy=(e_minus[0], e_minus[1]), xytext=(A[0], A[1]),
            arrowprops={'arrowstyle': '->', 'lw': 1.5, 'color': 'black'})
ax.text(1.5, 1.7, r'$\vec{r}_A$', ha='center', va='bottom', fontsize=12)

ax.annotate('', xy=(e_minus[0], e_minus[1]), xytext=(B[0], B[1]),
            arrowprops={'arrowstyle': '->', 'lw': 1.5, 'color': 'black'})
ax.text(4, 1.7, r'$\vec{r}_B$', ha='center', va='bottom', fontsize=12)

ax.annotate('', xy=(e_minus[0], e_minus[1]), xytext=(S[0], S[1]),
            arrowprops={'arrowstyle': '->', 'lw': 1.5, 'color': 'black'})
ax.text(2.6, 1.7, r'$\vec{r}$', ha='center', va='bottom', fontsize=12)

plt.show()

Sketch of the molecular geometry, including the relevant position vectors.


2. Ellipsoidal Coordinates

Because the potential depends on the distances to the two nuclei, \((r_A,r_B)\), it is natural to choose coordinates that are built from those distances. Prolate spheroidal coordinates do exactly that and therefore align with the geometry and symmetry of the problem.

Concretely, define \[ \xi=\frac{r_A+r_B}{R},\qquad \eta=\frac{r_A-r_B}{R},\qquad \phi=\arctan\!\frac{y}{x}, \] with \[ 1 \leq \xi < \infty,\qquad -1 \leq \eta \leq 1,\qquad 0 \leq \phi < 2\pi, \] so that \[ r_A=\frac{R}{2}(\xi+\eta),\qquad r_B=\frac{R}{2}(\xi-\eta). \] Two geometric facts follow immediately:

  • Surfaces of constant \(\xi\) satisfy \(r_A+r_B=\text{const}\) and are therefore ellipsoids with foci at the nuclear positions.
  • Surfaces of constant \(\eta\) satisfy \(r_A-r_B=\text{const}\) and are therefore hyperboloids (level surfaces of the difference of distances to the foci).

These coordinate surfaces conform to the two-center geometry: one family of surfaces (the ellipsoids) encloses both nuclei, while the other family (the hyperboloids) separates regions nearer to one nucleus from regions nearer to the other. Because the physical potential is built from \(1/r_A\) and \(1/r_B\), expressing \(r_A,r_B\) in terms of \((\xi,\eta)\) yields compact algebraic formulae. For example, the two-center Coulomb potential becomes \[ \frac{1}{r_A}+\frac{1}{r_B} = \frac{2}{R}\!\left(\frac{1}{\xi+\eta}+\frac{1}{\xi-\eta}\right) = \frac{4\xi}{R(\xi^2-\eta^2)}. \] Thus the potential is a rational function of \(\xi\) and \(\eta\), and—crucially—has the simple factor structure \(\propto \xi/(\xi^2-\eta^2)\).

The figure visualizes the prolate spheroidal coordinate system: on the left, \(\xi\)– and \(\eta\)–lines form a two-dimensional grid in the \(xz\)–plane, while on the right, an ellipsoid of constant \(\xi\) is shown together with its \(\eta\)– and \(\phi\)–grid lines.

Code
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Line3DCollection

plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 15


# Set up 1x2 subplots
# Create a figure and a standard 2D axes array
fig, axes = plt.subplots(1, 2, figsize=(10, 5))

# Remove the second (right-side) axis
axes[1].remove()

# Add a new 3D axis in the same position
ax3d = fig.add_subplot(1, 2, 2, projection='3d')


# --- 3D Ellipsoid Plot Setup ---
R = 0.25  # Half-distance between foci
f1 = np.array([0, 0, R])
f2 = np.array([0, 0, -R])

# Set viewing angle
view_azimuth = 45
view_elevation = 30
ax3d.view_init(elev=view_elevation, azim=view_azimuth)

# Calculate view direction vector
view_az_rad = np.radians(view_azimuth)
view_el_rad = np.radians(view_elevation)
view_dir = np.array([
    np.cos(view_el_rad) * np.cos(view_az_rad),
    np.cos(view_el_rad) * np.sin(view_az_rad),
    np.sin(view_el_rad)
])

def ellipsoidal_to_cartesian(mu, nu, phi, R):
    """Convert prolate spheroidal coordinates to Cartesian"""
    x = R * np.sqrt((mu**2 - 1) * (1 - nu**2)) * np.cos(phi)
    y = R * np.sqrt((mu**2 - 1) * (1 - nu**2)) * np.sin(phi)
    z = R * mu * nu
    return x, y, z

# --- Generate and plot ellipsoid surface ---
mu_surface = 2.0
nu_vals = np.linspace(-1, 1, 100)
phi_vals = np.linspace(0, 2 * np.pi, 100)
Nu, Phi = np.meshgrid(nu_vals, phi_vals)

X = R * np.sqrt((mu_surface**2 - 1) * (1 - Nu**2)) * np.cos(Phi)
Y = R * np.sqrt((mu_surface**2 - 1) * (1 - Nu**2)) * np.sin(Phi)
Z = R * mu_surface * Nu

ax3d.plot_surface(X, Y, Z, alpha=0.3, color='lightblue', edgecolor='none')


# --- Generate and plot phi lines ---
n_phi_lines = 12
phi_lines_visible = []
phi_lines_hidden = []
for phi in np.linspace(0, 2 * np.pi, n_phi_lines, endpoint=False):
    nu = np.linspace(-1, 1, 200)
    x, y, z = ellipsoidal_to_cartesian(mu_surface, nu, phi, R)

    points = np.column_stack([x, y, z])
    visibility = np.dot(points, view_dir)
    
    for i in range(len(nu) - 1):
        if (visibility[i] + visibility[i+1]) / 2 > 0:
            phi_lines_visible.append(np.array([x[i:i+2], y[i:i+2], z[i:i+2]]).T)
        else:
            phi_lines_hidden.append(np.array([x[i:i+2], y[i:i+2], z[i:i+2]]).T)

if phi_lines_visible:
    phi_vis_coll = Line3DCollection(phi_lines_visible, colors='g', linewidth=1.5, linestyle='-', alpha=0.8)
    ax3d.add_collection(phi_vis_coll)
if phi_lines_hidden:
    phi_hid_coll = Line3DCollection(phi_lines_hidden, colors='g', linewidth=0.8, linestyle='--', alpha=0.3)
    ax3d.add_collection(phi_hid_coll)


# --- Generate and plot nu lines ---
n_nu_lines = 9
nu_lines_visible = []
nu_lines_hidden = []
for nu in np.linspace(-0.9, 0.9, n_nu_lines):
    phi = np.linspace(0, 2 * np.pi, 200)
    x, y, z = ellipsoidal_to_cartesian(mu_surface, nu * np.ones_like(phi), phi, R)

    points = np.column_stack([x, y, z])
    visibility = np.dot(points, view_dir)

    for i in range(len(phi) - 1):
        if (visibility[i] + visibility[i+1]) / 2 > 0:
            nu_lines_visible.append(np.array([x[i:i+2], y[i:i+2], z[i:i+2]]).T)
        else:
            nu_lines_hidden.append(np.array([x[i:i+2], y[i:i+2], z[i:i+2]]).T)

if nu_lines_visible:
    nu_vis_coll = Line3DCollection(nu_lines_visible, colors='r', linewidth=1.5, linestyle='-', alpha=0.8)
    ax3d.add_collection(nu_vis_coll)
if nu_lines_hidden:
    nu_hid_coll = Line3DCollection(nu_lines_hidden, colors='r', linewidth=0.8, linestyle='--', alpha=0.3)
    ax3d.add_collection(nu_hid_coll)


# --- Finalize plot ---
ax3d.scatter(*f1, color='r', s=100, marker='o', label='Focus 1', zorder=10)
ax3d.scatter(*f2, color='r', s=100, marker='o', label='Focus 2', zorder=10)
ax3d.set_box_aspect(aspect=(1,1,1))
max_range = 0.3
ax3d.set_xlim([-max_range, max_range])
ax3d.set_ylim([-max_range, max_range])
ax3d.set_zlim([-max_range, max_range])
ax3d.set_axis_off()

# You can add a plot to the 2D axes here
# Plot constant mu lines (varying nu)
# --- Generate and plot grid on the 2D subplot (axes) ---
# Project onto the xz-plane, for phi = 0 and phi = 180 degrees
phi_xz_values = [0, np.pi] # 0 and 180 degrees in radians

for phi_xz in phi_xz_values:
    # Plot constant mu lines (varying nu)
    mu_lines_to_plot = [1., 1.25, 1.5, 1.75, 2.0]
    nu_vals = np.linspace(-1, 1, 100)
    for mu in mu_lines_to_plot:
        x_mu, _, z_mu = ellipsoidal_to_cartesian(mu, nu_vals, phi_xz, R)
        axes[0].plot(x_mu, z_mu, 'b-', alpha=0.6)
        # Add label for the mu line
        label_text = rf'$\xi={{{mu:.2f}}}$'
        # Position label near the line end. Adjust spacing as needed.
        if (phi_xz == 0): axes[0].text(x_mu[50]+0.025, z_mu[50]+0.015, label_text, fontsize=8, rotation=-90, ha='center', color='blue')


    # Plot constant nu lines (varying mu)
    nu_lines_to_plot = [-0.9, -0.6, -0.3, 0, 0.3, 0.6, 0.9]
    mu_vals = np.linspace(1.0, 2.0, 100) # mu > 1
    for nu in nu_lines_to_plot:
        x_nu, _, z_nu = ellipsoidal_to_cartesian(mu_vals, nu, phi_xz, R)
        axes[0].plot(x_nu, z_nu, 'r-', alpha=0.6)

axes[0].text(-0.225, 0.505, rf'$\eta=0.9$', fontsize=8, rotation=-61, ha='center', va='center', color='red')
axes[0].text(-0.41, 0.34, rf'$\eta=0.6$', fontsize=8, rotation=-35, ha='center', va='center', color='red')
axes[0].text(-0.48, 0.168, rf'$\eta=0.3$', fontsize=8, rotation=-15, ha='center', va='center', color='red')
axes[0].text(-0.5, 0, rf'$\eta=0$', fontsize=8, rotation=0, ha='center', va='center', color='red')
axes[0].text(-0.5, -0.18, rf'$\eta=-0.3$', fontsize=8, rotation=15, ha='center', va='center', color='red')
axes[0].text(-0.42, -0.35, rf'$\eta=-0.6$', fontsize=8, rotation=35, ha='center', va='center', color='red')
axes[0].text(-0.22, -0.525, rf'$\eta=-0.9$', fontsize=8, rotation=61, ha='center', va='center', color='red')
axes[0].scatter([0,0], [R,-R], color='r', s=100, marker='o', label='Focus 1', zorder=10)


axes[0].set_xlabel(r'$x$')
axes[0].set_ylabel(r'$z$')
axes[0].set_box_aspect(1) # Equal aspect ratio
max_range =  0.6
axes[0].set_xlim([-max_range, max_range])
axes[0].set_ylim([-max_range, max_range])

plt.tight_layout()
plt.show()

Ellipsoid of constant xi with eta and phi grid lines.


3. Separation of Variables

In ellipsoidal coordinates, the variables in the Hamiltonian can be separated. This separation is possible not only because the potential takes a simple form in \((\xi, \eta)\), but also because the Laplacian in these coordinates factorizes in a way that mirrors the structure of the potential.

The Laplacian in prolate spheroidal coordinates has the form (schematically)

\[ \nabla^2 = \frac{1}{R^2(\xi^2-\eta^2)}\left[ \frac{\partial}{\partial\xi}\!\big[(\xi^2-1)\partial_\xi\big] + \frac{\partial}{\partial\eta}\!\big[(1-\eta^2)\partial_\eta\big] + \frac{\xi^2-\eta^2}{(\xi^2-1)(1-\eta^2)}\partial_\phi^2 \right]. \]

When the full electronic Schrödinger equation

\[ \left[-\frac{\hbar^2}{2m}\nabla^2 - \frac{e^2}{4\pi\varepsilon_0}\!\left(\frac{1}{r_A}+\frac{1}{r_B}\right)\right]\psi = E\psi \]

is expressed in \((\xi,\eta,\phi)\) and multiplied by the common factor \(R^2(\xi^2-\eta^2)\), the differential operator naturally separates into parts depending only on \(\xi\), only on \(\eta\), and only on \(\phi\), up to an overall separation constant.

This motivates the ansatz

\[ \psi(\xi,\eta,\phi)=\Lambda(\xi)\,M(\eta)\,\Phi(\phi), \]

which leads to three ordinary differential equations—one for each coordinate—coupled through a shared separation constant. The \(\phi\)-dependence separates trivially, giving

\[ \Phi(\phi) = e^{im\phi}, \]

exactly as in the hydrogen atom, where \(m\) is the magnetic quantum number.

The remaining two equations for \(\xi\) and \(\eta\) are linked through the energy eigenvalue and take the general form

\[ \begin{aligned} \frac{d}{d\xi}\!\left[(\xi^2-1)\frac{d\Lambda}{d\xi}\right] &+ \left(A + \frac{2R\xi}{a_0} - \frac{m^2}{\xi^2-1} - R^2E(\xi^2-1)\right)\Lambda = 0, \\[6pt] \frac{d}{d\eta}\!\left[(1-\eta^2)\frac{dM}{d\eta}\right] &+ \left(-A - \frac{2R\eta}{a_0} - \frac{m^2}{1-\eta^2} + R^2E(1-\eta^2)\right)M = 0, \end{aligned} \tag{1}\]

where \(A\) is the separation constant introduced during the variable decoupling. These two coupled ordinary differential equations must be solved simultaneously for both \(A\) and \(E\), typically requiring numerical methods or variational approximations.

At large internuclear separations (\(R \to \infty\)), the system approaches two isolated hydrogen atoms; for small \(R\), it converges toward the helium ion (He\(^+\)). The continuous interpolation between these two limits makes the hydrogen molecular ion H\(_2^+\) a uniquely rich and instructive system in quantum mechanics.


In summary:

  • The coordinates are constructed directly from \(r_A\) and \(r_B\), making the potential algebraically simple.
  • The metric factors in the Laplacian combine naturally with the potential, allowing additive separation.
  • The axial symmetry about the internuclear axis ensures that the \(\phi\)-dependence separates trivially.

This geometric and algebraic harmony is why prolate spheroidal coordinates are the standard framework for analyzing H\(_2^+\) and other two-center Coulomb systems.


4. Angular Momentum and Reflection Symmetries in H\(_2^+\)

In the hydrogen atom, the potential depends only on the radial distance \(r\), so the Hamiltonian commutes with both \(\hat{L}^2\) and \(\hat{L}_z\). This implies full rotational symmetry and allows eigenstates to be labeled by the quantum numbers \((\ell, m)\) of total and projected orbital angular momentum.

For the hydrogen molecular ion H\(_2^+\), this symmetry is partially broken. The potential \[ V(\vec{r}) = -\frac{e^2}{4\pi\varepsilon_0}\!\left(\frac{1}{r_A} + \frac{1}{r_B}\right) \] depends on the distances to two fixed nuclei, not on the total radius \(r = |\vec{r}|\) from a single center. As a result, the Hamiltonian is not spherically symmetric but only axially symmetric about the internuclear axis (the \(z\)-axis).


4.1 Loss of Spherical Symmetry

Mathematically, this means that the total orbital angular momentum operator \[ \hat{L}^2 = -\hbar^2\!\left[ \frac{1}{\sin\theta}\frac{\partial}{\partial\theta} \!\left(\sin\theta \frac{\partial}{\partial\theta}\right) + \frac{1}{\sin^2\theta}\frac{\partial^2}{\partial\phi^2} \right] \] does not commute with the Hamiltonian: \[ [\hat{H}_e, \hat{L}^2] \neq 0. \] A simple way to see this is to note that \(\hat{L}^2\) generates any rotation, whereas the potential is invariant only under rotations about the \(z\)-axis. By Noether’s theorem, conservation of a component of angular momentum corresponds to a rotational symmetry. Because the potential loses full spherical symmetry but retains axial symmetry, only the \(z\)-component of angular momentum remains conserved.


4.2 The Conserved Component \(\hat{L}_z\)

The \(z\)-component operator is \[ \hat{L}_z = -i\hbar\frac{\partial}{\partial\phi}. \] Since \(V(\vec{r})\) does not depend on the azimuthal angle \(\phi\), we have \[ [\hat{H}_e, \hat{L}_z] = 0. \] Therefore, the eigenfunctions of the Hamiltonian can be chosen to be simultaneous eigenfunctions of \(\hat{L}_z\), with eigenvalue \[ \hat{L}_z \psi = \hbar \lambda \psi. \]

The corresponding azimuthal dependence is \[ \Phi(\phi) = e^{i\lambda \phi}. \] Because the potential of H\(_2^+\) is invariant under reflection through any plane containing the molecular axis, the states with \(\lambda\) and \(-\lambda\) are physically equivalent and degenerate. Hence, it is conventional to define \(\lambda\) as a non-negative integer: \[ \lambda = 0, 1, 2, \ldots \] Only the absolute value of the angular momentum projection has physical meaning for this system.

In H\(_2^+\), the electron moves in a potential that is symmetric around the molecular axis. This means that “rotating clockwise” around the axis looks just like “rotating counterclockwise” if you flip the view in a mirror plane that contains the axis.

  • The quantum number \(\lambda\) tells us how much the electron is “twisting” around the axis.
  • Flipping the twist from clockwise to counterclockwise just produces a mirror image, which is physically the same.
  • That’s why states with \(+\lambda\) and \(-\lambda\) have the same energy — they are degenerate.

💡 Note: Angular momentum is a pseudovector. This is why its behavior under reflections is a bit unusual: some reflections flip it, some don’t. Here, the mirror plane containing the axis flips the twist, giving the \(\pm\lambda\) equivalence.


4.3 Molecular Angular Momentum Labels

The quantum number \(\lambda\) specifies the magnitude of the orbital angular momentum projection along the internuclear axis.
Since \(\lambda \ge 0\) by convention, the total angular momentum quantum number \(\ell\) no longer appears explicitly.

Spectroscopically, the values of \(\lambda\) are denoted by Greek letters: \[ \begin{array}{c|c} \lambda & \text{Label} \\ \hline 0 & \sigma \\ 1 & \pi \\ 2 & \delta \\ 3 & \phi \\ \vdots & \vdots \end{array} \] Thus, \(\lambda = 0\) corresponds to a \(\sigma\) state, \(\lambda = 1\) to a \(\pi\) state, and so on.
In this chapter we avoid using the symbol \(\sigma\) to denote spin (Pauli matrices) to prevent confusion.


4.4 Including Electron Spin

Each electronic state is further characterized by the spin projection quantum number \(m_s = \pm \tfrac{1}{2}\). The spin and orbital projections are often combined to describe the total angular momentum projection along the molecular axis \[ \Omega = |\lambda + m_s|. \] For H\(_2^+\), which has only one electron, this simply distinguishes spin-up and spin-down components for each orbital state.


4.5 Reflection symmetry along the midplane (gerade/ungerade)

Another important symmetry in H\(_2^+\) comes from reflecting the electron across the plane halfway between the two nuclei (perpendicular to the molecular axis).

  • This reflection does not change the electron’s twist around the axis, so it does not affect \(\lambda\).
  • However, it does produce two types of states:
    • Gerade (g): symmetric under the reflection (wavefunction stays the same).
    • Ungerade (u): antisymmetric under the reflection (wavefunction changes sign).

This classification will become useful when we label molecular orbitals. It explains, for example, why some states have a node at the center of the molecule while others do not.


Summary

  • The H\(_2^+\) Hamiltonian is not spherically symmetric, so total \(L\) is not conserved.
  • The system remains axially symmetric, so \(L_z\) is conserved.
  • Molecular states are labeled by the quantum number \(\lambda\) (orbital angular momentum projection) and spin projection \(m_s\).
  • The familiar spectroscopic notation (\(\sigma\), \(\pi\), \(\delta\), …) reflects the value of \(|\lambda|\).

This framework connects directly to the structure of the potential energy curves discussed in the next section.


5. The Energy Eigenvalues

While we will not attempt to solve the coupled differential equations (1) explicitly here, we can discuss the structure and qualitative behavior of the energy eigenvalues.

Just as in the atomic hydrogen problem, the stationary Schrödinger equation admits only discrete eigenvalues for bound electronic states. These discrete levels arise because the wavefunction must remain finite and single-valued—boundary conditions that can only be satisfied for specific energy values.

However, there is an important difference compared to the atomic case. For the hydrogen molecular ion, the internuclear distance \(R\) enters the Hamiltonian explicitly. In the Born–Oppenheimer approximation, the nuclei are treated as fixed in space, so \(R\) acts merely as a parameter in the electronic Schrödinger equation.

For each fixed value of \(R\), we can solve the electronic problem and obtain a discrete set of eigenvalues: \[ E_n(R), \quad n = 1, 2, 3, \ldots \]

If we now plot these electronic energies as a function of \(R\), we obtain the potential energy curves for the molecule. These curves determine how the total molecular energy changes as the nuclei move relative to one another.

At certain distances, one of the potential curves may exhibit a minimum—indicating a stable or quasi-stable equilibrium separation. Such a minimum corresponds to a bound molecular state. Higher-lying curves may be purely repulsive or correspond to excited electronic configurations that dissociate more easily.

Below is an illustrative plot showing four typical potential energy curves for H\(_2^+\), labeled according to their symmetry.

Code
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 12

# --- Load benchmark data ---
# Replace with actual filename / format
# Suppose data files with columns: R_bohr, E_hartree for various states
# Example format: "H2p_ground.csv", "H2p_first_excited.csv", etc.

def load_curve(filename):
    # Allow any whitespace as separator
    data = np.loadtxt(filename, delimiter=',', comments='#')
    # Handle possible extra columns (some files have >2)
    R = data[:, 0]
    E1 = data[:, 1]
    E2 = data[:, 2]
    E3 = data[:, 3]
    E4 = data[:, 4]
    return R, E1, E2, E3, E4


# Example: you must supply these files
R, E1, E2, E3, E4 = load_curve('./h2pluspotc.csv')

#from scipy.interpolate import interp1d

f1 = interp1d(R, E1, kind='cubic', fill_value='extrapolate')
f2 = interp1d(R, E2, kind='cubic', fill_value='extrapolate')
f3 = interp1d(R, E3, kind='cubic', fill_value='extrapolate')
f4 = interp1d(R, E4, kind='cubic', fill_value='extrapolate')

R_plot = np.linspace(min(R), max(R), 500)

E1s = f1(R_plot)
E2s = f2(R_plot)
E3s = f3(R_plot)
E4s = f4(R_plot)


# --- Plotting ---
fig, ax = plt.subplots(figsize=(7,5))

ax.plot(R_plot, E1s, label=r'$1s\sigma_g$', color='blue', lw=2)
ax.plot(R_plot, E2s, label=r'$2p\sigma_u$', color='red', lw=2)
ax.plot(R_plot, E3s, label=r'$2p\pi_u$', color='green', lw=2)
ax.plot(R_plot, E4s, label=r'$3d\pi_g$', color='orange', lw=2)

ax.set_xlabel(r'Internuclear distance $R$ (Å)')
ax.set_ylabel(r'Energy (Rydberg)')
#ax.set_title(r'Potential Energy Curves for H$_2^+$')
ax.legend()
ax.grid(True)



ax.set_xlim([0, 9])
ax.set_ylim([-1.5, 1])

plt.tight_layout()
plt.show()

At small internuclear separations (\(R \to 0\)), the two nuclei strongly repel each other, and all electronic energies rise steeply. At large separations (\(R \to \infty\)), each curve asymptotically approaches the energy of a hydrogen atom plus a free proton.

Only the lowest curve, corresponding to the \(1s\sigma_g\) state, exhibits a potential minimum—signifying a bound molecular ion. The excited states (\(2p\sigma_u\), \(2p\pi_u\), \(3d\pi_g\)) are either weakly bound or entirely repulsive, describing unbound molecular states.