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]
../_images/notebooks_11_mode_full_3_1.png
[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)
../_images/notebooks_11_mode_full_4_0.png
../_images/notebooks_11_mode_full_4_1.png
[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)
../_images/notebooks_11_mode_full_5_0.png
../_images/notebooks_11_mode_full_5_1.png

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'))
../_images/notebooks_11_mode_full_7_0.png
../_images/notebooks_11_mode_full_7_1.png
[6]:
s = ms.mode_solver_full(plot=True, plot_index=True) # by default it will plot at the fields
../_images/notebooks_11_mode_full_8_0.png
../_images/notebooks_11_mode_full_8_1.png
../_images/notebooks_11_mode_full_8_2.png
../_images/notebooks_11_mode_full_8_3.png
../_images/notebooks_11_mode_full_8_4.png
../_images/notebooks_11_mode_full_8_5.png
../_images/notebooks_11_mode_full_8_6.png
../_images/notebooks_11_mode_full_8_7.png
../_images/notebooks_11_mode_full_8_8.png
../_images/notebooks_11_mode_full_8_9.png
../_images/notebooks_11_mode_full_8_10.png
../_images/notebooks_11_mode_full_8_11.png
../_images/notebooks_11_mode_full_8_12.png
[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$')
../_images/notebooks_11_mode_full_15_1.png
../_images/notebooks_11_mode_full_15_2.png
../_images/notebooks_11_mode_full_15_3.png

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)
../_images/notebooks_11_mode_full_17_0.png
../_images/notebooks_11_mode_full_17_1.png

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')
../_images/notebooks_11_mode_full_20_1.png