Mode solver Fully Vectorial¶
Strip waveguides¶
Lets compute the modes for different types of waveguides
_________________________________
clad_thickness
width
<---------->
___________ _ _ _ _ _ _
| |
_____| |____ |
wg_heigth
slab_thickness |
_______________________ _ _ _ _ __
sub_thickness
_________________________________
<------------------------------->
sub_width
[1]:
import numpy as np
import matplotlib.pyplot as plt
import modes as ms
from tqdm import tqdm
[2]:
ms.waveguide(width=0.5, slab_thickness=0)
[2]:
0.5 x 0.22 um, n_wg = 3.4757, n_clad = [1.444023621703261]
[3]:
ymargin = 1
s = ms.mode_solver_full(plot=True, plot_index=True, logscale=True, n_modes=1, width=0.2, thickness=0.22, fields_to_write=('Ex'), clad_thickness=[ymargin], sub_thickness=ymargin)
[4]:
ymargin = 1.5
s = ms.mode_solver_full(plot=True, plot_index=True, logscale=True, n_modes=1, width=0.25, thickness=0.22, fields_to_write=('Ex'), clad_thickness=[ymargin], sub_thickness=ymargin, sub_width=2*ymargin)
We can also plot the mode in logscale
[5]:
s = ms.mode_solver_full(plot=True, plot_index=True, logscale=True, n_modes=1, width=0.5, thickness=0.22, fields_to_write=('Ex'))
[6]:
s = ms.mode_solver_full(plot=True, plot_index=True) # by default it will plot at the fields
[7]:
ms.mode_solver_full?
where the waveguide parameters
[8]:
s.results['n_effs'][0].real
[8]:
2.4717079418312657
[9]:
s = ms.mode_solver_full(plot=False, n_modes=1, width=0.5, thickness=0.22, fields_to_write=('Ex'), overwrite=True)
A, centre, sigma_2 = ms.fit.fit_gaussian(s.wg.xc, s.wg.yc, np.abs(s.modes[0].fields['Ex']))
print(f"Aeff = {A:.2f}, mode_center = {centre}, Sigma2 = ({sigma_2[0]:.2f}, {sigma_2[1]:.2f})")
Aeff = 3.19, mode_center = (1.0, 0.6), Sigma2 = (0.76, 0.50)
What is the waveguide geometry that gives the smallest mode area, for the TE polarization at 1550, for a silicon thickness of 220 nm, strip waveguide?
[10]:
nm = 1e-3
widths = np.linspace(250, 600, 15)*nm
aeffs = []
sigma2x = []
sigma2y = []
for width in tqdm(widths):
s = ms.mode_solver_full(plot=False, n_modes=1, width=width, thickness=0.22, fields_to_write=('Ex'), clad_thickness=[ymargin], sub_thickness=ymargin, sub_width=2*ymargin+width, overwrite=True)
A, centre, sigma2 = ms.fit.fit_gaussian(s.wg.xc, s.wg.yc, np.abs(s.modes[0].fields['Ex']))
aeffs.append(A)
sigma2x.append(sigma2[0])
sigma2y.append(sigma2[1])
100%|██████████| 15/15 [00:34<00:00, 2.30s/it]
[11]:
plt.plot(widths, aeffs, 'o')
plt.xlabel('wg width (nm)')
plt.ylabel(r'Aeff ($\mu m^2$)')
plt.figure()
plt.plot(widths, sigma2x)
plt.xlabel('wg width (nm)')
plt.ylabel(r'$\sigma_x^2$')
plt.figure()
plt.plot(widths, sigma2y)
plt.xlabel('wg width (nm)')
plt.ylabel(r'$\sigma_y^2$')
[11]:
Text(0, 0.5, '$\\sigma_y^2$')
As you can see 350 nm width will give you the smallest mode area for 220nm Silicon strip waveguides
Rib waveguides¶
[12]:
s = ms.mode_solver_full(plot=True, plot_index=True, n_modes=1, width=0.5, thickness=0.22, slab_thickness=0.09, fields_to_write=('Ex'), overwrite=True)
Convergence tests¶
Lets do some convergence tests wherer we reduce the meshsize (20 nm by default)
[13]:
# dx=np.linspace(0.01, 0.02, 3)
dx = np.array([5, 10, 20, 40])*1e-3
n_effs = [ms.mode_solver_full(n_modes=1, x_step=dxi, y_step=dxi, plot=False).results['n_effs'][0].real for dxi in dx]
[14]:
plt.plot(dx*1e3, n_effs)
plt.xlabel('mesh size (nm)')
plt.ylabel('neff0')
[14]:
Text(0, 0.5, 'neff0')