Effective Index¶
Effective Index of the Fundamental Mode¶
Effective index of the fundamental mode of a waveguide can be accessed by using neff function of effective_index module. Note that for the default parameters below, this mode happens to be a TE mode. The function takes the following arguments:
wavelength: Wavelength of the light in the waveguide, in micrometers. A list of wavelengths can also be passed. Wavelength range is from 1.2 μm to 1.7 μm; it will return 0 for wavelengths out of range.width: Width of the waveguide, in micrometers. A list of widths can also be passed. Width range is from 0.240 μm to 0.700 μm; it will return 0 for widths out of range.
In [1]:
Copied!
from sipkit.effective_index import neff
import jax.numpy as jnp
neff(width=0.5, wavelength=1.55)
from sipkit.effective_index import neff
import jax.numpy as jnp
neff(width=0.5, wavelength=1.55)
WARNING:jax._src.lib.xla_bridge:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
Out[1]:
DeviceArray(2.44523381, dtype=float64)
Use Cases¶
- Scalar width, scalar wavelength
In [2]:
Copied!
neff(width=0.5, wavelength=1.55)
neff(width=0.5, wavelength=1.55)
Out[2]:
DeviceArray(2.44523381, dtype=float64)
- Scalar width, 1D Array wavelength
In [3]:
Copied!
neff(width=0.5, wavelength=jnp.linspace(1.4, 1.5, 5))
neff(width=0.5, wavelength=jnp.linspace(1.4, 1.5, 5))
Out[3]:
DeviceArray([2.6138077 , 2.58583721, 2.55782222, 2.52975709, 2.50163816], dtype=float64)
- 1D Array width, scalar wavelength
In [4]:
Copied!
neff(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
neff(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
Out[4]:
DeviceArray([2.22706193, 2.29512748, 2.35308258, 2.40263554, 2.44523381], dtype=float64)
- 1D Array width, 1D Array wavelength
In [5]:
Copied!
neff(width=jnp.linspace(0.4, 0.5, 3), wavelength=jnp.linspace(1.4, 1.5, 5))
neff(width=jnp.linspace(0.4, 0.5, 3), wavelength=jnp.linspace(1.4, 1.5, 5))
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) /tmp/ipykernel_264/3451282617.py in <module> ----> 1 neff(width=jnp.linspace(0.4, 0.5, 3), wavelength=jnp.linspace(1.4, 1.5, 5)) [... skipping hidden 11 frame] ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/sipkit/effective_index.py in neff(width, wavelength) 69 (width - width_min) * ((width_size - 1) / (width_max - width_min)), 70 ], ---> 71 order=1, 72 ) 73 ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/jax/_src/scipy/ndimage.py in map_coordinates(input, coordinates, order, mode, cval) 139 input: ArrayLike, coordinates: Sequence[ArrayLike], order: int, mode: str = 'constant', cval: ArrayLike = 0.0, 140 ): --> 141 return _map_coordinates(input, coordinates, order, mode, cval) [... skipping hidden 5 frame] ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/jax/_src/scipy/ndimage.py in _map_coordinates(input, coordinates, order, mode, cval) 119 contribution = input_arr[indices] 120 else: --> 121 all_valid = functools.reduce(operator.and_, validities) 122 contribution = jnp.where(all_valid, input_arr[indices], cval) 123 outputs.append(_nonempty_prod(weights) * contribution) [... skipping hidden 1 frame] ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/jax/_src/numpy/lax_numpy.py in deferring_binary_op(self, other) 4934 args = (other, self) if swap else (self, other) 4935 if isinstance(other, _accepted_binop_types): -> 4936 return binary_op(*args) 4937 if isinstance(other, _rejected_binop_types): 4938 raise TypeError(f"unsupported operand type(s) for {opchar}: " [... skipping hidden 5 frame] ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/jax/_src/numpy/ufuncs.py in <lambda>(x1, x2) 81 fn = lambda x1, x2: lax_fn(*_promote_args_numeric(numpy_fn.__name__, x1, x2)) 82 else: ---> 83 fn = lambda x1, x2: lax_fn(*_promote_args(numpy_fn.__name__, x1, x2)) 84 fn.__qualname__ = f"jax.numpy.{numpy_fn.__name__}" 85 fn = jit(fn, inline=True) [... skipping hidden 7 frame] ~/checkouts/readthedocs.org/user_builds/sipkit/envs/1.4.0/lib/python3.7/site-packages/jax/_src/lax/lax.py in broadcasting_shape_rule(name, *avals) 1571 result_shape.append(non_1s[0]) 1572 else: -> 1573 raise TypeError(f'{name} got incompatible shapes for broadcasting: ' 1574 f'{", ".join(map(str, map(tuple, shapes)))}.') 1575 TypeError: and got incompatible shapes for broadcasting: (5,), (3,).
- Scalar width, 2D Array wavelength
In [6]:
Copied!
neff(width=0.45, wavelength=jnp.array([[1.4, 1.5], [1.6, 1.7]]))
neff(width=0.45, wavelength=jnp.array([[1.4, 1.5], [1.6, 1.7]]))
Out[6]:
DeviceArray([[2.53952222, 2.41551475],
[2.2904706 , 2.16536619]], dtype=float64)
- 2D Array width, scalar wavelength
In [7]:
Copied!
neff(width=jnp.array([[0.4, 0.45], [0.5, 0.55]]), wavelength=1.55)
neff(width=jnp.array([[0.4, 0.45], [0.5, 0.55]]), wavelength=1.55)
Out[7]:
DeviceArray([[2.22706193, 2.35308258],
[2.44523381, 2.51410111]], dtype=float64)
- 2D Array width, 2D Array wavelength
In [8]:
Copied!
waveguide_width = jnp.array([0.5, 0.6])
wavelength = np.array([1.5, 1.6, 1.7])
waveguide_width, wavelength = np.meshgrid(waveguide_width, wavelength)
neff(waveguide_width, wavelength)
waveguide_width = jnp.array([0.5, 0.6])
wavelength = np.array([1.5, 1.6, 1.7])
waveguide_width, wavelength = np.meshgrid(waveguide_width, wavelength)
neff(waveguide_width, wavelength)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) /tmp/ipykernel_264/1394243315.py in <module> 1 waveguide_width = jnp.array([0.5, 0.6]) ----> 2 wavelength = np.array([1.5, 1.6, 1.7]) 3 waveguide_width, wavelength = np.meshgrid(waveguide_width, wavelength) 4 neff(waveguide_width, wavelength) NameError: name 'np' is not defined
Effective Index of Higher Order Modes¶
Effective Index of first 5 modes in a waveguide can be accessed by using the following functions of effective_index module:
neff_te0: Effective index of TE0 mode. (Note that currently this is the same asneff, due to the waveguide width boundaries used.)neff_tm0: Effective index of TM0 mode.neff_te1: Effective index of TE1 mode.neff_tm1: Effective index of TM0 mode.neff_te2: Effective index of TE3 mode.
In [9]:
Copied!
from sipkit.effective_index import neff_te0, neff_tm0
neff_te0_list = neff_te0(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_te0_list)
neff_tm0_list = neff_tm0(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_tm0_list)
from sipkit.effective_index import neff_te0, neff_tm0
neff_te0_list = neff_te0(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_te0_list)
neff_tm0_list = neff_tm0(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_tm0_list)
[2.22706193 2.29512748 2.35308258 2.40263554 2.44523381] [1.69157614 1.71344278 1.73396505 1.75313724 1.77099004]
For the cases where the effective index of a mode does not exist, the function will return index of oxide layer as the effective index at that wavelength.
In [10]:
Copied!
from sipkit.effective_index import neff_te2
neff_te2_list = neff_te2(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_te2_list)
from sipkit.effective_index import neff_te2
neff_te2_list = neff_te2(width=jnp.linspace(0.4, 0.5, 5), wavelength=1.55)
print(neff_te2_list)
[1.4440023 1.4440023 1.4440023 1.4440023 1.4440023]
Last update:
2022-12-28
Created: 2022-10-19
Created: 2022-10-19