EME: Sweep

In practice, a taper length needs to be optimized to ensure proper modal transmission and low loss. This example shows how the sweep function can be used to visualize the transmission of an EME taper simulation.

This code example is licensed under the BSD 3-Clause License.

  • Python
  • MATLAB
import emodeconnection as emc
import numpy as np

## Set simulation parameters
wavelength = 1550 # [nm] wavelength
dx, dy = 20, 20 # [nm] resolution
h_core = 220 # [nm] waveguide core height
h_clad = 1000 # [nm] waveguide top and bottom clad

window_width = 4000
window_height = h_core + h_clad*2

num_modes = 10 # [-] number of modes
BC = 'TE'

## Connect and initialize EMode
em = emc.EMode(simulation_name = 'taper', verbose = True)

## Settings
em.settings(
    wavelength = wavelength, x_resolution = dx, y_resolution = dy,
    window_width = window_width, window_height = window_height,
    num_modes = num_modes, boundary_condition = BC,
    background_material = 'SiO2')

## Draw shapes
em.shape(name = 'BOX', material = 'SiO2',
    height = h_clad)
em.shape(name = 'core', material = 'Si',
height = h_core, etch_depth = h_core)

## Launch FDM solver and label profiles
em.shape(name = 'core', mask = 1000)
em.label_profile(name = 'a') # skips solving the modes here

em.shape(name = 'core', mask = 2000)
em.label_profile(name = 'b') # skips solving the modes here

## Draw EME sections
em.section(profile = 'a', section_type = 'straight',
    length = 2000)

em.section(name = 'taper', section_type = 'taper',
    profile = 'a', profile_end = 'b',
    length = 8000)

em.section(profile = 'b', section_type = 'straight',
    length = 2000)

## Run EME sweep
data = em.sweep(key = 'section, taper, length',
    values = np.arange(0, 8001, 250),
    result = ['S_matrix'])

## Close EMode
em.close()
%% Set simulation parameters
wavelength = 1550; % [nm] wavelength
dx = 20; dy = 20; % [nm] resolution
h_core = 220; % [nm] waveguide core height
h_clad = 1000; % [nm] waveguide top and bottom clad

window_width = 4000;
window_height = h_core + h_clad*2;

num_modes = 10; % [-] number of modes
BC = 'TE';

%% Connect and initialize EMode
em = emodeconnection(simulation_name = 'taper', verbose = true);

%% Settings
em.settings( ...
    wavelength = wavelength, x_resolution = dx, y_resolution = dy, ...
    window_width = window_width, window_height = window_height, ...
    num_modes = num_modes, boundary_condition = BC, ...
    background_material = 'SiO2');

%% Draw shapes
em.shape(name = 'BOX', material = 'SiO2', ...
    height = h_clad);
em.shape(name = 'core', material = 'Si', ...
    height = h_core, etch_depth = h_core);

%% Launch FDM solver and label profiles
em.shape(name = 'core', mask = 1000);
em.label_profile(name = 'a'); % skips solving the modes here

em.shape(name = 'core', mask = 2000);
em.label_profile(name = 'b'); % skips solving the modes here

%% Draw EME sections
em.section(profile = 'a', section_type = 'straight', ...
    length = 2000);

em.section(name = 'taper', section_type = 'taper', ...
    profile = 'a', profile_end = 'b', ...
    length = 8000);

em.section(profile = 'b', section_type = 'straight', ...
    length = 2000);

%% Run EME sweep
data = em.sweep(key = 'section, taper, length', ...
    values = 0:250:8000, ...
    result = {'S_matrix'});

%% Close EMode
em.close();

Console output:

EMode 0.2.4 - email
Connected on port 63000 to LM-2.
Session type: 3d
Successfully logged in to the license manager.
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec

Sweeping section parameter 'length'...
Meshing  completed in 0.1 sec


Solving slice at 0.0 nm... completed in 0.6 sec
Solving slice at 8000.0 nm... completed in 0.5 sec
Solving slice at 4000.0 nm... completed in 0.5 sec
Solving slice at 2000.0 nm... completed in 0.5 sec
Solving slice at 1000.0 nm... completed in 0.4 sec
Solving slice at 500.0 nm... completed in 0.5 sec
Solving slice at 1500.0 nm... completed in 0.4 sec
Solving slice at 1750.0 nm... completed in 0.4 sec
Solving slice at 3000.0 nm... completed in 0.5 sec
Solving slice at 2500.0 nm... completed in 0.4 sec
Solving slice at 2250.0 nm... completed in 0.5 sec
Solving slice at 2750.0 nm... completed in 0.4 sec
Reached minimum_z_step!
Solving slice at 3500.0 nm... completed in 0.5 sec
Solving slice at 3250.0 nm... completed in 0.4 sec
Solving slice at 3750.0 nm... completed in 0.5 sec
Reached minimum_z_step!
Solving slice at 6000.0 nm... completed in 0.5 sec
Solving slice at 5000.0 nm... completed in 0.5 sec
Solving slice at 4500.0 nm... completed in 0.5 sec
Solving slice at 4250.0 nm... completed in 0.5 sec
Reached minimum_z_step!
Solving slice at 4750.0 nm... completed in 0.5 sec
Solving slice at 5500.0 nm... completed in 0.4 sec
Solving slice at 5250.0 nm... completed in 0.5 sec
Reached minimum_z_step!
Solving slice at 5750.0 nm... completed in 0.5 sec
Solving slice at 7000.0 nm... completed in 0.5 sec
Solving slice at 6500.0 nm... completed in 0.5 sec
Solving slice at 6250.0 nm... completed in 0.5 sec
Solving slice at 7500.0 nm... completed in 0.5 sec
Solving slice at 7250.0 nm... completed in 0.5 sec
Solving slice at 7750.0 nm... completed in 0.5 sec
Slice solving complete.
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 26.1 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.7 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.7 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.7 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.7 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 2.3 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 2.0 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 2.0 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.9 sec
Meshing  completed in 0.2 sec
Meshing  completed in 0.2 sec
 completed in 1.8 sec
 completed in 1 min 26.3 sec
Exited EMode

While no figures are generated in the EMode script, a separate script can be used to plot the results.

  • Python
import emodeconnection as emc
import numpy as np

## Extract sweep results without an EMode license
data = emc.get(variable = 'sweep_data', simulation_name = 'taper')

## Plot
import matplotlib.pyplot as plt
from matplotlib import rc as mplrc

fw, LW = 8/2.54, 0.5
mplrc('font',**{'family':'sans-serif','size':7})
mplrc('axes', linewidth=LW, axisbelow=True)
mplrc('xtick', bottom=True, top=True, direction='in')
mplrc('ytick', left=True, right=True, direction='in')
mplrc('xtick.major', size=3, width=LW)
mplrc('ytick.major', size=3, width=LW)
mplrc('figure',figsize=[fw, fw/2**0.5])

fig, ax = plt.subplots(1, 1)
ax.set_xlabel('Taper length (nm)')
ax.set_ylabel('Tranmission (%)')
ax.grid(visible=True, which='major', axis='both', linewidth=LW/2, color='grey', alpha=0.25)

S = np.array(data['S_matrix'])
lines = []
for kk in range(S.shape[-1]):
    line, = ax.plot(data['values'],
        100*np.abs(S[:,1,0,kk,0])**2,
        marker = '', linestyle = '-', lw = LW*1.5,
        label = r'Mode 0$\rightarrow$%d' % kk)

    lines.append(line)

ax.set_xlim([
    np.min(data['values']),
    np.max(data['values'])])

lg = ax.legend(handles = lines[0:1], loc = 'center right')
lg.get_frame().set_linewidth(LW/2)
lg.get_frame().set_edgecolor('k')
ax.set_ylim([70, 101])
fig.savefig('taper_1.png', dpi=600, bbox_inches='tight')

lg = ax.legend(handles = lines[1:10], loc = 'upper right')
lg.get_frame().set_linewidth(LW/2)
lg.get_frame().set_edgecolor('k')
ax.set_ylim([-1, 25])
fig.savefig('taper_2.png', dpi=600, bbox_inches='tight')

Figures:

../_images/taper_1.png
../_images/taper_2.png