“Know how to solve every problem that has been solved.” “What I cannot create, I do not understand.” — Richard Feynman

The RLC Circuit

Circuits

Take the RC circuit and stick an inductor in series with the resistor and capacitor. Suddenly the circuit can ring. The capacitor charges past the source voltage, the inductor pushes back, the capacitor overshoots the other way, and the whole loop sloshes back and forth — losing energy to the resistor on every cycle — until it settles. RC was a first-order system with one state and one decay timescale. RLC is a second-order system with two state variables (the capacitor's voltage and the inductor's current) and the qualitatively new behavior of oscillation. This is the analog of a mass on a spring with a dashpot. Same math, different costume.

The circuit and what's new

A voltage source drives a series loop containing a resistor , an inductor , and a capacitor , with the capacitor's far plate grounded. Compared to the RC circuit there's one new component (the inductor) and one new constitutive law:

An inductor is the dual of a capacitor. The capacitor's voltage can't change instantaneously without infinite current; the inductor's current can't change instantaneously without infinite voltage. The capacitor stores energy in its electric field (); the inductor stores energy in its magnetic field (). Put both in a loop and energy can slosh between the two storage modes — that's where oscillation comes from.

Deriving the ODE

Apply KVL around the loop. Going around: source minus inductor drop minus resistor drop minus capacitor voltage equals zero.

In a series loop the same current flows everywhere, and into the capacitor that current is . Substitute and divide by :

A second-order linear ODE with constant coefficients. Two derivatives means two initial conditions (the capacitor's voltage and its rate of change, equivalently the inductor's current) and two timescales — and the relationship between those two timescales is what decides whether the circuit rings.

Two timescales and the quality factor

Two natural quantities fall out of the coefficients:

is the natural frequency — the angular frequency the circuit would oscillate at if there were no resistor. is the damping rate — how fast the resistor bleeds energy out of the oscillation. Both have units of , so their ratio is dimensionless:

The quality factor. It's the only parameter that matters qualitatively: tells you how many cycles the circuit rings for before the oscillation decays. A high- tuning fork rings for seconds. A low- dashpot doesn't ring at all. Three regimes:

The three closed forms

Solving the second-order ODE with rest initial conditions and a unit step input gives one formula per regime. Underdamped:

An envelope times a phase-shifted cosine, sitting on the steady state. The peak overshoot is — a clean exponential in the ratio . Critically damped:

The repeated root gives the polynomial-times-exponential form. Overdamped:

Two real eigenvalues, a coefficient on each. As from either side the two formulas above smoothly merge into the critical one — the regimes are different faces of the same characteristic polynomial .

Numerical simulation across all three regimes

Same setup as for the RC page — pick parameters, integrate with RK4, compare to the closed form. Use , so that rad/s, then vary to land in each regime.

"""
Series RLC circuit step response: numerical vs analytic in all three damping regimes.

Circuit: voltage source V_in in series with resistor R, inductor L, capacitor C.
State: V is the capacitor voltage; rest initial conditions V(0) = 0, V'(0) = 0.

ODE:        d^2 V/dt^2 + (R/L) dV/dt + (1/LC) V = V_in / (LC)
Damping:    alpha   = R / (2L)
Natural:    omega_0 = 1 / sqrt(LC)
Quality:    Q       = omega_0 / (2 alpha)   = (1/R) sqrt(L/C)

Three regimes:
  alpha <  omega_0   underdamped       Q > 1/2     decaying oscillation
  alpha == omega_0   critically damped Q = 1/2     fastest non-oscillating decay
  alpha >  omega_0   overdamped        Q < 1/2     two real decay modes
"""
import numpy as np


def simulate_rlc(L, R, C, V_in, t):
    """RK4 integration of the second-order RLC ODE from rest."""
    def f(y):
        V, dV = y
        return np.array([dV, (V_in - V) / (L * C) - (R / L) * dV])
    dt = t[1] - t[0]
    y  = np.zeros(2)
    out = np.zeros(len(t))
    for i in range(len(t)):
        out[i] = y[0]
        k1 = f(y)
        k2 = f(y + 0.5 * dt * k1)
        k3 = f(y + 0.5 * dt * k2)
        k4 = f(y + dt * k3)
        y = y + (dt / 6.0) * (k1 + 2*k2 + 2*k3 + k4)
    return out


def analytic_step_response(L, R, C, V_in, t):
    """Closed-form V_C(t) for the series RLC step from rest."""
    omega0 = 1.0 / np.sqrt(L * C)
    alpha  = R / (2.0 * L)
    if alpha < omega0:                          # underdamped
        omega_d = np.sqrt(omega0**2 - alpha**2)
        return V_in * (1 - np.exp(-alpha*t) * (np.cos(omega_d*t) + (alpha/omega_d)*np.sin(omega_d*t)))
    elif np.isclose(alpha, omega0):             # critically damped
        return V_in * (1 - (1 + omega0*t) * np.exp(-omega0*t))
    else:                                       # overdamped
        s  = np.sqrt(alpha**2 - omega0**2)
        r1 = -alpha + s
        r2 = -alpha - s
        A  =  r2 / (r1 - r2)
        B  = -r1 / (r1 - r2)
        return V_in * (1 + A * np.exp(r1*t) + B * np.exp(r2*t))


def report(name, L, R, C, V_in, T, dt):
    omega0 = 1.0 / np.sqrt(L * C)
    alpha  = R / (2.0 * L)
    Q      = omega0 / (2.0 * alpha)
    t      = np.arange(0.0, T + dt, dt)
    sim    = simulate_rlc(L, R, C, V_in, t)
    ana    = analytic_step_response(L, R, C, V_in, t)
    err    = np.max(np.abs(sim - ana))
    regime = 'under' if alpha < omega0 else 'critical' if np.isclose(alpha, omega0) else 'over'
    print(f"--- {name} ---")
    print(f"  L = {L} H,  R = {R} Ohm,  C = {C} F")
    print(f"  omega_0 = {omega0:9.3f} rad/s   alpha = {alpha:9.3f} rad/s   Q = {Q:.4f}")
    print(f"  regime: {regime}-damped")
    if alpha < omega0:
        omega_d   = np.sqrt(omega0**2 - alpha**2)
        period    = 2*np.pi / omega_d
        overshoot = np.exp(-alpha * np.pi / omega_d)
        peak_t    = np.pi / omega_d
        idx_peak  = np.argmax(sim)
        print(f"  damped period      : {period*1e3:.3f} ms")
        print(f"  envelope 1/alpha   : {1/alpha*1e3:.3f} ms")
        print(f"  predicted peak     : 1 + {overshoot:.4f}  at  t = {peak_t*1e3:.3f} ms")
        print(f"  measured peak      : {sim[idx_peak]:.4f}  at  t = {t[idx_peak]*1e3:.3f} ms")
    print(f"  max |numerical - analytic|: {err:.2e}")
    print()


L, C, V_in = 1.0, 1.0e-6, 1.0     # omega_0 = 1000 rad/s
T, dt      = 0.05, 1.0e-6

report("Underdamped (Q = 10)",  L, R=100.0,                  C=C, V_in=V_in, T=T, dt=dt)
report("Critically damped",     L, R=2.0 * np.sqrt(L/C),     C=C, V_in=V_in, T=T, dt=dt)
report("Overdamped (Q = 0.1)",  L, R=10.0 * np.sqrt(L/C),    C=C, V_in=V_in, T=T, dt=dt)
--- Underdamped (Q = 10) ---
  L = 1.0 H,  R = 100.0 Ohm,  C = 1e-06 F
  omega_0 =  1000.000 rad/s   alpha =    50.000 rad/s   Q = 10.0000
  regime: under-damped
  damped period      : 6.291 ms
  envelope 1/alpha   : 20.000 ms
  predicted peak     : 1 + 0.8545  at  t = 3.146 ms
  measured peak      : 1.8545  at  t = 3.146 ms
  max |numerical - analytic|: 6.84e-14

--- Critically damped ---
  L = 1.0 H,  R = 2000.0 Ohm,  C = 1e-06 F
  omega_0 =  1000.000 rad/s   alpha =  1000.000 rad/s   Q = 0.5000
  regime: critical-damped
  max |numerical - analytic|: 4.32e-14

--- Overdamped (Q = 0.1) ---
  L = 1.0 H,  R = 10000.0 Ohm,  C = 1e-06 F
  omega_0 =  1000.000 rad/s   alpha =  5000.000 rad/s   Q = 0.1000
  regime: over-damped
  max |numerical - analytic|: 3.06e-13

Three things to read off. (a) The circuit overshoots the source voltage by 85.45% on the first swing — closed form and simulation agree on the peak value and its time to 3 decimal places. (b) The critically damped case is exactly at , sitting on the boundary. (c) The agreement between numerical and analytic is at the level of machine precision () in all three regimes, which is what RK4 at should look like on a smooth second-order linear system.

The mechanical analogy

The equation above is the same equation as a mass on a spring with a dashpot. The dictionary:

Under this translation is the spring's natural frequency, is the dashpot's damping rate, and the three regimes are the same three regimes a spring shows: a stiff lightly-damped spring rings (underdamped), a heavily-damped one slowly creeps back (overdamped), and the optimal car suspension sits on the boundary (critical). The math is the same; the components have just been renamed.

Where this equation lives

Anything that has two coupled storage modes with a finite dissipation between them obeys this equation. A non-exhaustive list:

What's next

Several directions branch off from here:

Related on this site

KCL, KVL, and Ohm's law are the laws used in the derivation. The RC circuit is the first-order cousin — same template, one less component, no oscillation. Explicit Euler and higher-order integrators apply directly to the second-order system once it's written as a 2D first-order ODE for , which is what the simulation above does internally. Control theory treats the underdamped/critical/overdamped trichotomy abstractly for any second-order system — the language of damping ratio and natural frequency comes from there.