Skip to content
Projects
These are the docs of the development version (the devel branch). See the docs of the latest release.

Damped oscillator

Underdamped, critically damped and overdamped motion of a mass on a spring.

The displacement obeys x¨+2ζω0x˙+ω02x=0\ddot{x} + 2\zeta\omega_0\dot{x} + \omega_0^2 x = 0. The damping ratio ζ\zeta decides between the three regimes. This example is a matplotlib figure, so the page shows a PNG, and the script prints the decay rate of the underdamped case.

Damped oscillator, figure 1
damped_oscillator.py
import matplotlib.pyplot as plt
import numpy as np
omega0 = 2.0 * np.pi
t = np.linspace(0.0, 4.0, 800)
def displacement(zeta: float) -> np.ndarray:
"""x(t) for x(0) = 1, x'(0) = 0."""
if zeta < 1.0:
wd = omega0 * np.sqrt(1.0 - zeta**2)
return np.exp(-zeta * omega0 * t) * (
np.cos(wd * t) + zeta * omega0 / wd * np.sin(wd * t)
)
if zeta == 1.0:
return np.exp(-omega0 * t) * (1.0 + omega0 * t)
root = omega0 * np.sqrt(zeta**2 - 1.0)
a, b = -zeta * omega0 + root, -zeta * omega0 - root
return (b * np.exp(a * t) - a * np.exp(b * t)) / (b - a)
fig, ax = plt.subplots(figsize=(8, 4.5))
for zeta, label in [(0.1, "underdamped"), (1.0, "critical"), (2.0, "overdamped")]:
ax.plot(t, displacement(zeta), lw=2, label=f"$\\zeta = {zeta}$ ({label})")
ax.axhline(0.0, color="0.7", lw=0.8)
ax.set(xlabel="t", ylabel="x(t)", title="Damped harmonic oscillator")
ax.legend(frameon=False)
fig.tight_layout()
print(f"Envelope decay rate of the underdamped case: {0.1 * omega0:.3f} per unit time")
plt.show()
Printed output
Envelope decay rate of the underdamped case: 0.628 per unit time