Open in Colab  Run this chapter’s code in Google Colab (no installation).

Slides 65–95. “Dispersion = spread of information.” A short pulse that enters the fiber leaves it broader, because its constituents (modes, wavelengths, polarisations) arrive at different times.

mechanism origin where
intermodal each mode has its own \(v_g\) MMF only
material \(n(\lambda)\), so \(N_g(\lambda)\) all fibers
waveguide \(v_g\) depends on \(V(\lambda)\) all fibers, tunable
profile \(\Delta(\lambda)\) small, \(<0.1\) ps nm\(^{-1}\) km\(^{-1}\)
polarisation (PMD) random birefringence SMF, grows as \(\sqrt L\)
self-phase modulation \(n=n_0+n_2I\) high power

3.1 Intermodal dispersion (slides 66–67)

Far from cut-off, the fastest and slowest rays differ by \(\Delta\tau/L\approx (n_1-n_2)/c=n_1\Delta/c\). The spread depends on length.

Show the Python
for n1, n2 in [(1.48, 1.46), (1.475, 1.475*0.99), (1.4532, 1.4485)]:
    print(f"n1 = {n1:.4f}, n2 = {n2:.4f}:  Δτ/L ≈ {(n1-n2)/c0*1e12:.1f} ns/km")
n1 = 1.4800, n2 = 1.4600:  Δτ/L ≈ 66.7 ns/km
n1 = 1.4750, n2 = 1.4603:  Δτ/L ≈ 49.2 ns/km
n1 = 1.4532, n2 = 1.4485:  Δτ/L ≈ 15.7 ns/km

3.2 Chromatic dispersion in the fundamental mode (slides 68–71)

A source of spectral width \(\Delta\lambda\) launches several wavelengths. Each has its own group delay \(\tau_g(\lambda)=L/v_g\). The dispersion coefficient is

\[ D=\frac1L\frac{d\tau_g}{d\lambda}\quad[\text{ps nm}^{-1}\text{km}^{-1}],\qquad \Delta\tau = |D|\,L\,\Delta\lambda . \]

3.2.1 Material dispersion from the Sellmeier equation

\[ n^2(\lambda)=1+\sum_{i=1}^{3}\frac{B_i\lambda^2}{\lambda^2-\lambda_i^2},\qquad N_g=n-\lambda\frac{dn}{d\lambda},\qquad D_m=-\frac{\lambda}{c}\frac{d^2n}{d\lambda^2}. \]

We use Malitson’s coefficients for SiO\(_2\) and Fleming’s for GeO\(_2\). A doped core (SiO\(_2\))\(_{1-x}\)(GeO\(_2\))\(_x\) is obtained by mixing the coefficients linearly.

Show the Python
lam = np.linspace(0.6, 1.8, 500) * 1e-6
fig, axs = plt.subplots(1, 3, figsize=(11, 3.6))
for k, x in enumerate([0, 0.05, 0.135]):
    lab = "SiO₂" if x == 0 else f"SiO₂ + {x*100:.1f}% GeO₂"
    axs[0].plot(lam * 1e6, fl.n_doped(lam, x), color=fl.PALETTE[k], label=lab)
    axs[1].plot(lam * 1e6, fl.group_index(lam, x), color=fl.PALETTE[k])
    axs[2].plot(lam * 1e6, fl.D_material(lam, x) / PS, color=fl.PALETTE[k])
axs[0].set_ylabel("n"); axs[1].set_ylabel("$N_g$"); axs[2].set_ylabel("$D_m$ (ps nm⁻¹ km⁻¹)")
axs[2].axhline(0, color=fl.INK2, lw=0.8)
for ax in axs: ax.set_xlabel("λ (µm)")
axs[0].legend(fontsize=8)
plt.tight_layout(); plt.show()
from scipy.optimize import brentq
print("Zero material dispersion of silica: λ0 = %.1f nm" % (brentq(fl.D_material, 1.2e-6, 1.35e-6) * 1e9))
Figure 3.1: Refractive index n, group index Ng and material dispersion Dm of pure silica and germania-doped silica. Ng has a minimum where Dm crosses zero, near 1.27 µm for silica.
Zero material dispersion of silica: λ0 = 1272.8 nm
TipPositive and negative \(D\) (slide 78)

\(D>0\) means longer wavelengths arrive later (\(N_g\) grows with \(\lambda\)). This is the “anomalous” regime above 1.3 µm in silica. \(D<0\) means shorter wavelengths arrive later. In fiber-optics jargon \(D>0\) corresponds to \(\beta_2=-\lambda^2D/2\pi c<0\).

3.2.2 Waveguide dispersion (slides 74–76)

Even with constant \(n_1, n_2\), the group delay depends on \(\lambda\) through \(V\):

\[ D_w\approx-\frac{n_2\Delta}{c\lambda}\,V\frac{d^2(Vb)}{dV^2}, \qquad V\frac{d^2(Vb)}{dV^2}\approx0.080+0.549(2.834-V)^2 . \]

3.2.3 Putting it together (slide 77)

The “exact” chromatic dispersion follows from the effective index \(n_\text{eff}^2=n_2^2+b(V)(n_1^2-n_2^2)\) computed with the wavelength-dependent Sellmeier indices and the exact \(b(V)\). Then \(\tau_g/L=(n_\text{eff}-\lambda\,dn_\text{eff}/d\lambda)/c\), and \(D\) is its derivative. This includes material, waveguide and profile dispersion at once, with no approximation beyond weak guidance.

Show the Python
a, xc = 4.1e-6, 0.035
lam = np.linspace(1.1, 1.7, 61) * 1e-6
Dtot = np.array([fl.D_total_smf(l, a, xc) for l in lam]) / PS
Dm = fl.D_material(lam, xc) / PS
n2l = fl.n_silica(lam); n1l = fl.n_doped(lam, xc)
Dw = fl.D_waveguide_approx(lam, a, n2l, fl.Delta(n1l, n2l)) / PS
fig, ax = plt.subplots(figsize=(8, 4.4))
ax.plot(lam * 1e9, Dm, label="material $D_m$ (core glass)")
ax.plot(lam * 1e9, Dw, label="waveguide $D_w$ (approx.)")
ax.plot(lam * 1e9, Dm + Dw, "--", label="$D_m + D_w$")
ax.plot(lam * 1e9, Dtot, color=fl.INK, lw=2.2, label="exact chromatic $D$")
ax.axhline(0, color=fl.INK2, lw=0.8)
l0 = brentq(lambda l: fl.D_total_smf(l, a, xc), 1.25e-6, 1.4e-6)
ax.axvline(l0 * 1e9, color=fl.INK2, lw=0.8, ls=":")
ax.text(l0 * 1e9 + 5, -25, f"λ₀ = {l0*1e9:.0f} nm", color=fl.INK2)
ax.set_xlabel("λ (nm)"); ax.set_ylabel("D (ps nm⁻¹ km⁻¹)"); ax.legend(fontsize=9)
plt.show()
S0 = (fl.D_total_smf(l0 + 5e-9, a, xc) - fl.D_total_smf(l0 - 5e-9, a, xc)) / 10e-9 / PS * 1e-9
print(f"λ0 = {l0*1e9:.1f} nm, S0 = {S0:.3f} ps nm⁻² km⁻¹, D(1550) = {fl.D_total_smf(1.55e-6, a, xc)/PS:.2f} ps nm⁻¹ km⁻¹")
Figure 3.2: Chromatic dispersion of a standard-like SMF (2a = 8.2 µm, core SiO2 + 3.5% GeO2, cladding SiO2). The exact result (black) matches Dm + Dw (approximation) closely and gives λ0 ≈ 1.31 µm and D ≈ 17 ps/nm/km at 1550 nm, like ITU-T G.652.
λ0 = 1307.8 nm, S0 = 0.086 ps nm⁻² km⁻¹, D(1550) = 16.78 ps nm⁻¹ km⁻¹

3.3 Dispersion engineering, live (slides 76, 87–89)

\(D_w\) is negative and grows in magnitude when the core gets smaller and the index step larger. Pushing \(\lambda_0\) to 1550 nm gives a dispersion-shifted fiber (DSF). Stopping slightly before gives a non-zero DSF (NZ-DSF, G.655), which keeps a little dispersion to suppress four-wave mixing in WDM. The curves below were computed with the exact model above. Pick a core radius and a GeO\(_2\) concentration.

3.4 Commercial fibers (slides 90–92)

Near \(\lambda_0\), the ITU-T recommendations describe \(D(\lambda)\) with only two numbers, \(\lambda_0\) and the slope \(S_0\):

\[ D(\lambda)=\frac{S_0}{4}\left(\lambda-\frac{\lambda_0^4}{\lambda^3}\right). \]

Show the Python
lam = np.linspace(1260, 1625, 300)
fibs = {"G.652 standard SMF (SMF-28e+)": (1317, 0.088),
        "G.655 NZ-DSF (TrueWave-like)": (1450, 0.045),
        "G.656 wideband NZ-DSF (REACH-like)": (1400, 0.045),
        "G.653 dispersion-shifted": (1550, 0.07)}
fig, ax = plt.subplots()
for k, (name, (l0_, S0_)) in enumerate(fibs.items()):
    ax.plot(lam, S0_ / 4 * (lam - l0_**4 / lam**3), color=fl.PALETTE[k], label=name)
ax.axvspan(1530, 1565, color=fl.PALETTE[2], alpha=0.1, lw=0)
ax.axhline(0, color=fl.INK2, lw=0.8)
ax.set_xlabel("λ (nm)"); ax.set_ylabel("D (ps nm⁻¹ km⁻¹)"); ax.legend(fontsize=8)
plt.show()
Figure 3.3: Chromatic dispersion of typical commercial fibers described with the ITU formula. Values follow the table on slide 90 (G.652/SMF-28e+: λ0 = 1317 nm, S0 = 0.088). The NZ-DSF curves are representative.

3.5 Is dispersion really zero at \(\lambda_0\)? (slide 79)

No. At \(\lambda_0\) the first-order term vanishes, but the delay is still a parabola in \(\lambda\): \(\tau(\lambda)\approx\tau_0+\tfrac{L S_0}{2}(\lambda-\lambda_0)^2\). The spread therefore scales as \(\Delta\lambda^2\).

Show the Python
L, S0_ = 100.0, 0.09          # km, ps/nm²/km
for dl in [0.1, 1, 2, 5, 10]:
    lin = 17 * L * dl
    quad = L * S0_ * dl**2 / 8          # spread over a ±Δλ/2 window around λ0
    print(f"Δλ = {dl:5.1f} nm : at 1550 nm {lin:9.1f} ps   |   at λ0 ≈ {quad:7.2f} ps")
Δλ =   0.1 nm : at 1550 nm     170.0 ps   |   at λ0 ≈    0.01 ps
Δλ =   1.0 nm : at 1550 nm    1700.0 ps   |   at λ0 ≈    1.12 ps
Δλ =   2.0 nm : at 1550 nm    3400.0 ps   |   at λ0 ≈    4.50 ps
Δλ =   5.0 nm : at 1550 nm    8500.0 ps   |   at λ0 ≈   28.12 ps
Δλ =  10.0 nm : at 1550 nm   17000.0 ps   |   at λ0 ≈  112.50 ps

3.6 Polarisation mode dispersion (slides 80–83)

Random strains make the fiber weakly birefringent (\(\delta n/n<10^{-6}\)), with axes that rotate randomly along the length. The total differential group delay (DGD) is therefore a random walk. The mean DGD grows as \(\sqrt L\), \(\langle\Delta\tau\rangle = D_\text{PMD}\sqrt L\), and its distribution is Maxwellian. The concatenation rule for PMD vectors in Stokes space, \(\vec\tau_{n+1}=R_n\vec\tau_n+\delta\vec\tau_n\), with random rotations \(R_n\), makes the vector perform a 3-D random walk:

Show the Python
rng = np.random.default_rng(3)
Lsec, nsec, nfib = 0.1, 1000, 4000            # 100 m sections, 100 km
dgd_sec = 0.1 / np.sqrt(1 / Lsec) * np.sqrt(3 * np.pi / 8)   # chosen so that <DGD> = 0.1 ps/√km
steps = rng.normal(size=(nfib, nsec, 3))
steps *= dgd_sec / np.linalg.norm(steps, axis=2, keepdims=True)
tau = np.linalg.norm(np.cumsum(steps, axis=1), axis=2)       # ps
z = np.arange(1, nsec + 1) * Lsec
fig, (a1, a2) = plt.subplots(1, 2, figsize=(10, 3.8))
a1.plot(z, tau[:20].T, color=fl.PALETTE[0], lw=0.6, alpha=0.5)
a1.plot(z, tau.mean(0), color=fl.INK, lw=2, label="mean DGD")
a1.plot(z, 0.1 * np.sqrt(z), "--", color=fl.PALETTE[1], label="0.1 ps/√km · √L")
a1.set_xlabel("L (km)"); a1.set_ylabel("DGD (ps)"); a1.legend()
t = tau[:, -1]; m = t.mean()
a2.hist(t, bins=50, density=True, color=fl.PALETTE[0], alpha=0.7, rwidth=0.9)
x = np.linspace(0, t.max(), 200)
a2.plot(x, 32 * x**2 / (np.pi**2 * m**3) * np.exp(-4 * x**2 / (np.pi * m**2)), color=fl.PALETTE[1], label="Maxwell")
a2.set_xlabel("DGD at 100 km (ps)"); a2.legend()
plt.tight_layout(); plt.show()
from scipy.special import erfc
s_ = m * np.sqrt(np.pi / 8)                    # Maxwell scale parameter
pmax = lambda x: erfc(x / (np.sqrt(2) * s_)) + np.sqrt(2 / np.pi) * x / s_ * np.exp(-x**2 / (2 * s_**2))
print(f"P(DGD > 2×mean): simulated {(t > 2*m).mean():.4f}, Maxwell {pmax(2*m):.4f}; "
      f"P(DGD > 3×mean) (Maxwell) = {pmax(3*m):.1e}. Outages are rare but not impossible.")
Figure 3.4: Monte-Carlo PMD. Left: DGD versus length for 20 random fibers (thin) and the ensemble mean ∝ √L. Right: histogram of the DGD at 100 km over 4000 fibers, with the Maxwell distribution.
P(DGD > 2×mean): simulated 0.0173, Maxwell 0.0171; P(DGD > 3×mean) (Maxwell) = 4.2e-05. Outages are rare but not impossible.

3.7 Self-phase modulation: a first power limit (slide 86)

With \(n'=n+CI\) and \(C=10^{-14}\) cm²/W, which intensity gives \(\Delta\tau/L\approx0.1\) ps/km? \(\Delta\tau/L = \Delta n/c\), so \(\Delta n = c\,(0.1\text{ ps/km})\) and \(I=\Delta n/C\).

Show the Python
dn = c0 * 0.1e-12 / 1e3
I = dn / 1e-14                       # W/cm²
A = np.pi * (5e-4) ** 2               # cm², 2a = 10 µm
print(f"Δn = {dn:.1e},  I = {I:.1e} W/cm²,  A = {A:.2e} cm²,  P = I·A = {I*A:.2f} W in a 10 µm core")
Δn = 3.0e-08,  I = 3.0e+06 W/cm²,  A = 7.85e-07 cm²,  P = I·A = 2.35 W in a 10 µm core

This SPM-induced spread is small compared with chromatic dispersion. Other nonlinear effects (SBS, FWM; see Chapter 7) set in at much lower powers, at a few to a few tens of mW.

3.8 Dispersion compensation (slides 93–95)

Add a short length \(L_c\) of fiber with large dispersion of opposite sign, \(D_c\). The accumulated dispersion is \(D_tL_t+D_cL_c\).

Show the Python
Dt, Dc = 10, -100
fig, ax = plt.subplots()
z = np.linspace(0, 1000, 500); ax.plot(np.r_[z, 1000 + np.linspace(0, 80, 50)],
        np.r_[Dt * z, Dt * 1000 + Dc * np.linspace(0, 80, 50)], label="DCF at the end (slide 93)")
zz, acc = [0], [0]
for span in range(10):
    zz += [zz[-1] + 100]; acc += [acc[-1] + Dt * 100]
    zz += [zz[-1] + 9.0]; acc += [acc[-1] + Dc * 9.0]
ax.plot(zz, acc, label="in-line DCF, 90 % compensation per span")
ax.set_xlabel("distance (km)"); ax.set_ylabel("accumulated dispersion (ps/nm)"); ax.legend()
plt.show()
print(f"Slide 93: total = {Dt*1000 + Dc*80} ps/nm over 1080 km → D_eff = {(Dt*1000 + Dc*80)/1080:.2f} ps/nm/km")
Figure 3.5: Dispersion map. 1000 km of D = +10 ps/nm/km fiber with 80 km of D = −100 ps/nm/km DCF placed at the end (slide 93), compared with periodic in-line compensation every 100 km.
Slide 93: total = 2000 ps/nm over 1080 km → D_eff = 1.85 ps/nm/km

In modern coherent systems, compensation is done digitally in the receiver DSP (see Chapter 10). This removed DCFs from most new links.

3.9 Try it yourself

  1. Design a fiber with \(\lambda_0=1550\) nm using the live panel. What happens to \(V\) at 1.55 µm and to the MFD?
  2. Using fl.D_total_smf, compute \(D\) for a W-profile (depressed cladding). You will need to extend the solver to three layers. This is how dispersion-flattened fibers (slide 88) are made.
  3. How many km of SMF can a 40 Gb/s NRZ signal travel if the tolerated spread is 0.3 bit periods, with a 0.1 nm source? And with a source linewidth dominated by the modulation itself?