# 1.3. Thermo-optic phase shifter (Heater)¶

A thermo-optic phase shifter works by varying the temperature of the waveguide. This modulates the refractive index of the waveguide material through the thermo-optic effect. This, in turn, modulates the effective index and the phase of the light at the end of the waveguide.

## 1.3.1. Layout¶

SiFab contains a heater that is used in this application example. This heated waveguide can be used as any other waveguide in IPKISS.

import si_fab.all as pdk
from ipkiss3 import all as i3

# Heater with straight shape
ht = pdk.HeatedWaveguide(heater_width=0.6,
heater_offset=1.0,
m1_width=1.0,
m1_length=3.0)
ht_lv = ht.Layout(shape=[(0.0, 0.0), (10.0, 0.0)])
ht_lv.visualize(annotate=True)

xs = ht_lv.cross_section(cross_section_path=i3.Shape([(1.0, -8.0), (1.0, 8.0)]))
xs.visualize()

# Heater with rounded shape
ht = pdk.HeatedWaveguide()
start_angle=280,
end_angle=260))
ht_lv.visualize(annotate=True)


## 1.3.2. Model¶

As described in the SiFab documentation of the heater, the phase shift is proportional to the dissipated power in the heater. As the dynamics controlling the temperature are much slower than the electro-optic effects in the phase shifter, we chose an instantaneous model. By doing so, we can reach steady-state immediately. The heater in SiFab has a simulation recipe, which is used to ramp up the voltage and check the phase variation.

import si_fab.all as pdk
from si_fab.components.heater.simulation.simulate import simulate_heater
from si_fab.components.heater.pcell.cell import r_sheet
import pylab as plt
import numpy as np
import os

# Phase Shifter
name = "heater_sweep"
length = 100
ht = pdk.HeatedWaveguide(heater_width=0.6,
heater_offset=1.0,
m1_width=1.0,
m1_length=3.0)
ht_lv = ht.Layout(shape=[(0.0, 0.0), (length, 0.0)])

# Power for pi phase shift per square of unit sheet resistance
p_pi = 30e-3  # W
p_pi_sq = r_sheet * p_pi
ht.CircuitModel(p_pi_sq=p_pi_sq)

results = simulate_heater(cell=ht,
v_start=0,
v_end=1,
nsteps=500,
center_wavelength=1.5,
debug=False)
times = results.timesteps

def phase_unwrap_normalize(transmission):
unwrapped = np.unwrap(np.angle(transmission))
return unwrapped - unwrapped[0]

signals = ["optical_in", "gnd", "vsrc", "optical_out"]
process = [np.real, np.real, np.real, phase_unwrap_normalize]
ylabels = ["power [W]", "voltage [V]", "voltage [V]", "phase [radians]"]

fig, axs = plt.subplots(nrows=len(signals), ncols=1, figsize=(6, 8))
for axes, process, signal, ylabel in zip(axs, process, signals, ylabels):
data = process(results[signal])
axes.set_title(signal)
axes.plot(times[1:], data[1:])
axes.set_ylabel(ylabel)
axes.set_xlabel("time [s]")
plt.tight_layout()
fig.savefig(os.path.join("{}.png".format(name)), bbox_inches='tight')
plt.show()


1. Open topical_training/mzm/explore_heater/example_heated_waveguide.py.
1. Open topical_training/mzm/explore_heater/example_heater_simulation.py.
3. With the heater having a $$P_{\pi}=$$ 30 mW, find the the length of the heater that would lead to a tuning range of $$\pi/2$$ under a voltage swing of 0 to 1.
Solution