Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Molecular Degrees of Freedom and Classical Vibrations

Energies of molecules

Molecules consisting of N nuclei and n electrons are described by wave functions that depend on 3(n+N) variables in 3D space. These coordinates, or degrees of freedom (DOF), are usefully broken down into different kinds of motion classified as translational, rotational, vibrational and electronic. Because molecules are microscopic objects, we expect all of these energies to be quantized. The relative spacings, however, differ significantly because of the boundary conditions that restrict the motions of these DOFs. This is why different kinds of spectroscopy exist for probing the specific degrees of freedom in molecules.

E=ϵtrans+ϵrot+ϵvib+ϵelecE= \epsilon_{trans}+ \epsilon_{rot}+ \epsilon_{vib}+\epsilon_{elec}
mol deg freed

Figure 1:Energy levels associated with the different degrees of freedom in molecules.

3N Nuclear degrees of freedom

H^=i=1N22miRi2+E(R1,R2,...,RN){\hat{H} = \sum\limits_{i=1}^{N} -\frac{\hbar^2}{2m_i}\nabla_{R_i}^2 + E(R_1, R_2, ..., R_N)}
mol deg freed

Figure 2:The different degrees of freedom in molecules: translational, rotational and vibrational motion.

H^=H^tr+H^rot+H^vib{\hat{H} = \hat{H}_{tr} + \hat{H}_{rot} + \hat{H}_{vib}}

where HtrH_{tr} is the translational, HrotH_{rot} the rotational, and HvibH_{vib} the vibrational Hamiltonian. The translational and rotational terms have no potential part, but the vibrational part contains the potential EE, which depends on the distances between the nuclei.

In some cases the different degrees of freedom become coupled and one cannot use the following separation technique. Separation of HH means that we can write the wavefunction as a product:

ψ=ψtrψrotψvib{\psi = \psi_{tr}\psi_{rot}\psi_{vib}}

Separation of degrees of freedom

The resulting three Schrödinger equations are then:

H^trψtr=Etrψtr{\hat{H}_{tr}\psi_{tr} = E_{tr}\psi_{tr}}
H^rotψrot=Erotψrot{\hat{H}_{rot}\psi_{rot} = E_{rot}\psi_{rot}}
H^vibψvib=Evibψvib{\hat{H}_{vib}\psi_{vib} = E_{vib}\psi_{vib}}

Classical vibrations: the harmonic oscillator

Translations and rotations carry no potential energy, and the electronic problem is deferred to later chapters. The vibrational Hamiltonian is where the potential E(R1,...,RN)E(R_1, ..., R_N) lives, and near any stable geometry that potential looks like a spring. Before quantizing the oscillator in the next lecture, we need full command of its classical mechanics.

Bead, spring and a wall

compton

Figure 3:Harmonic motion governed by Hooke’s law. Any deviation from the equilibrium position is met with a restoring force, and in the absence of friction the bead oscillates indefinitely about equilibrium.

F=kxF=-kx

Solving harmonic oscillator problem

mx¨=kxm \ddot x=−kx
mx¨+kx=0x¨+ω2x=0m \ddot x+kx = 0 \,\,\,\,\rightarrow \,\,\,\, \ddot{x}+\omega^2 x =0
ω=(km)1/2\omega=\Big(\frac{k}{m}\Big)^{1/2}
x(t)=Asin(ωt+ϕ)x(t)= A sin(\omega t+\phi)
Source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

def sho_anim(m, k=1.0, A=0.9, phi=0.0, duration=4.0, fps=30):
    ω = np.sqrt(k/m)
    t = np.linspace(0, duration, int(fps*duration))
    x = A*np.sin(ω*t + phi)

    fig, axes = plt.subplots(1, 2, figsize=(8, 2.5))
    ax_mass, ax_wave = axes

    # --- left: oscillating mass ---
    ax_mass.set_xlim(-1.2, 1.2)
    ax_mass.set_ylim(-0.5, 0.5)
    ax_mass.axis("off")
    ax_mass.set_title(f"Mass–Spring (m={m:g})")
    (mass_point,) = ax_mass.plot([], [], "o", ms=12)
    (trace_line,) = ax_mass.plot([], [], lw=2)

    # --- right: sinusoidal wave ---
    ax_wave.set_xlim(0, duration)
    ax_wave.set_ylim(-1.2*A, 1.2*A)
    ax_wave.set_xlabel("time t")
    ax_wave.set_ylabel("x(t)")
    ax_wave.grid(True, ls="--", alpha=0.4)
    ax_wave.set_title("x(t) = A sin (ωt + φ)")
    (wave_line,) = ax_wave.plot([], [], lw=2)
    (wave_point,) = ax_wave.plot([], [], "o")

    def init():
        for line in (mass_point, trace_line, wave_line, wave_point):
            line.set_data([], [])
        return mass_point, trace_line, wave_line, wave_point

    def update(i):
        xi = x[i]
        mass_point.set_data([xi], [0])
        trace_line.set_data(x[:i+1], np.zeros(i+1))
        wave_line.set_data(t[:i+1], x[:i+1])
        wave_point.set_data([t[i]], [xi])
        return mass_point, trace_line, wave_line, wave_point

    return FuncAnimation(fig, update, init_func=init, frames=len(t), interval=1000/fps, blit=True)

# --- Two animations: normal mass and heavier mass ---
anim1 = sho_anim(m=1.0, duration=10.0)
anim2 = sho_anim(m=10.0, duration=10.0)  # slower oscillation

# Inline display in Jupyter / Jupyter Book
plt.close()  # Prevents static display of the last frame
HTML(anim1.to_jshtml() + "<br><hr><br>" + anim2.to_jshtml())
Loading...
<Figure size 800x250 with 2 Axes>

Energy of the harmonic oscillator

F=V(x)xF = - \frac{\partial V(x)}{\partial x}
V(x)=Fdx=(kx)dx=kx22+CV(x)= - \int F dx = - \int (-kx) dx =\frac{kx^2}{2}+C
E=p22m+kx22E=\frac{p^2}{2m} + \frac{kx^2}{2}
compton

Figure 4:A harmonic oscillator in vacuum is conservative: kinetic and potential energy interconvert with no total energy dissipated into the environment. Position x(t)x(t), velocity v=x˙(t)v=\dot{x}(t), and acceleration a=x(t)¨a=\ddot{x(t)} all oscillate at the same constant frequency ω\omega but with different amplitudes.

Diatomic molecules and two-body problem

compton

Figure 5:We can reduce the two-body problem of vibrating atoms to a one-body problem of a single particle with an effective reduced mass 1μ=1m1+1m2\frac{1}{\mu}=\frac{1}{m_1}+\frac{1}{m_2}, so μ=m1m2m1+m2\mu=\frac{m_1 m_2}{m_1+m_2}.

x¨=x2¨x1¨=(1m1+1m2)kx=kμx\ddot{x}=\ddot{x_2} - \ddot{x_1} =-\Big(\frac{1}{m_1}+\frac{1}{m_2} \Big)kx=-\frac{k}{\mu}x
m1x1¨=kxm2x2¨=kxm_1\ddot{x_1}=kx \\ m_2\ddot{x_2}=-kx
m1x1¨+m2x2¨=0m1x1¨+m2x2¨m1+m2=x¨com=0m_1\ddot{x_1}+ m_2\ddot{x_2}=0\,\,\,\, \rightarrow \frac{m_1\ddot{x_1}+ m_2\ddot{x_2}}{m_1+m_2}=\ddot{x}_{com}=0
x¨=x2¨x1¨=(1m1+1m2)kx=kμx\ddot{x}=\ddot{x_2} - \ddot{x_1} =-\Big(\frac{1}{m_1}+\frac{1}{m_2} \Big)kx=-\frac{k}{\mu}x

### Beads and springs model of molecules

- Before discussing the harmonic oscillator approximation, let us reflect on when it is a good approximation and under which circumstances it breaks down. For an arbitrary potential energy function of $x$, we can carry out a Taylor expansion around the equilibrium bond length $x_0$, obtaining an infinite series. 

$$U(x) = U(x_0)+U'(x_0)(x-x_0)+\frac{1}{2!}U''(x_0)(x-x_0)^2+\frac{1}{3!}U'''(x_0)(x-x_0)^3+...$$


:::{figure} images/harm_approx.png
:label: fig-classical-harmonic-oscillator-4
:alt: harmls
:width: 300px

Deviation of the true potential (blue) from the simple harmonic approximation (red), with the cubic correction shown in green.
U(x)=12!k(xx0)2+13!γ(xx0)3+...U(x) = \frac{1}{2!}k(x-x_0)^2+\frac{1}{3!}\gamma(x-x_0)^3+...
Source
import numpy as np
import matplotlib.pyplot as plt

# Define the range for x values, focusing on the dissociation region
x = np.linspace(0, 2.5, 500)

# Define the harmonic potential (quadratic term)
harmonic = 0.5 * x**2

# Define the harmonic + cubic potential
harmonic_cubic = 0.5 * x**2 - 0.2 * x**3

# Define the harmonic + cubic + quartic potential
harmonic_cubic_quartic = 0.5 * x**2 - 0.2 * x**3 + 0.05 * x**4

# Define the harmonic + cubic + quartic + higher-order polynomial (5th and 6th order)
polynomial_approx = 0.5 * x**2 - 0.2 * x**3 + 0.05 * x**4 - 0.01 * x**5 + 0.001 * x**6

# Define the Morse potential
def morse_potential(x, D=1, a=1):
    return D * (1 - np.exp(-a * x))**2

# Set parameters for Morse potential
D = 1  # Depth of the potential well
a = 1  # Width of the potential well

# Compute Morse potential
morse = morse_potential(x, D, a)

# Plot all the potentials, showing progression
plt.figure(figsize=(8, 6))

# Harmonic only
plt.plot(x, harmonic, label='Harmonic: $0.5  x^2$', color='b', lw=2)

# Harmonic + Cubic
plt.plot(x, harmonic_cubic, label='Harmonic + Cubic: $0.5  x^2 - 0.2  x^3$', color='g', lw=2)

# Harmonic + Cubic + Quartic
plt.plot(x, harmonic_cubic_quartic, label='Harmonic + Cubic + Quartic: $0.5  x^2 - 0.2  x^3 + 0.05  x^4$', color='r', lw=2)

# Polynomial approximation (up to 6th order)
plt.plot(x, polynomial_approx, label='Polynomial Approx (up to $x^6$)', color='c', lw=2)

# Morse potential
plt.plot(x, morse, label='Morse Potential', color='k', lw=3)

# Add labels and legend
plt.title('Polynomial Approximation of Harmonic Oscillator vs. Morse Potential')
plt.xlabel('x (dissociation region)')
plt.ylabel('Potential Energy')
plt.axhline(0, color='black',linewidth=0.5)
plt.axvline(0, color='black',linewidth=0.5)
plt.grid(True)
plt.legend()
plt.ylim([0, 2])
(0.0, 2.0)
<Figure size 800x600 with 1 Axes>

Problems

Problem 1: Count the degrees of freedom

How many vibrational modes do (a) HCl, (b) ammonia NH3_3 (nonlinear), and (c) acetylene C2_2H2_2 (linear) have?

Problem 2: Vibrational frequency of HCl

The force constant of the H35^{35}Cl bond is k=516k = 516 N/m. Compute the reduced mass and the angular frequency ω=k/μ\omega = \sqrt{k/\mu}, and convert to a wavenumber ν~=ω/(2πc)\tilde{\nu} = \omega / (2\pi c).

Problem 3: Isotope shift

Without recomputing from scratch, predict how ω\omega changes when H35^{35}Cl is replaced by D35^{35}Cl. The force constant kk does not change. Why not?

Problem 4: Spring constant from a potential

A bond is described by U(x)=D(1eax)2U(x) = D\left(1 - e^{-ax}\right)^2 (the Morse potential, with xx the displacement from equilibrium). Taylor expand around x=0x=0 to show that the effective spring constant is k=2Da2k = 2Da^2.

Problem 5: Energy bookkeeping

A classical oscillator has amplitude AA. At what displacement xx is the energy split exactly half kinetic, half potential? Sketch V(x)V(x), T(x)T(x), and EE on one plot.