Skip to content

Commit

Permalink
Merge branch 'HelgeGehring:main' into plot_component
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasgrjn authored Mar 4, 2024
2 parents 37efdda + 9247d6d commit a89f6f3
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ jobs:
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.7.1
version: 1.8.1
virtualenvs-create: false
installer-parallel: true
- name: Install dependencies
run: |
sudo apt-get install -y libglu1-mesa
poetry install --no-interaction
pip install --upgrade scipy
mamba install slepc4py=*=complex* -y
mamba install julia
pip install jupyter-book
Expand Down
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ repos:
# - id: markdownlint

- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
args: [--profile, black]

- repo: https://github.com/psf/black
rev: 23.10.0
rev: 24.2.0
hooks:
- id: black

- repo: https://github.com/python-poetry/poetry
rev: 1.6.0
rev: 1.8.0
hooks:
- id: poetry-check

- repo: "https://github.com/domluna/JuliaFormatter.jl"
rev: "v1.0.40"
rev: "v1.0.50"
hooks:
- id: "julia-formatter"

Expand Down
5 changes: 4 additions & 1 deletion docs/photonics/examples/effective_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
# name: python3
# ---
# %% [markdown]
# # Effective area and effective refractive index of a Si-NCs waveguide from {cite}`Rukhlenko2012`.
# # Effective area of a Si-NCs waveguide

# In this example we calculate the effective area and the effective refractive index of a Si-NCs waveguide from {cite}`Rukhlenko2012`

# %% tags=["hide-input"]
from collections import OrderedDict

Expand Down
27 changes: 24 additions & 3 deletions docs/photonics/examples/metal_heater_phase_shifter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,18 @@
from femwell.thermal import solve_thermal

# %% [markdown]
# Simulating the TiN TOPS heater in {cite}`Jacques2019`.
# In this example we'll show how to calculate the efficiency of a thermal phase shifter based on calculating the temperature distribution on a 2D plane.
# I.e. we make the approximation, that the thermal phase shifter is quite long, so that boundary effects will play a negligible role.

# We'll reproduce the TiN TOPS heater presented in {cite}`Jacques2019`.
# First we set up the mesh:

# It consists of a substrate, with a box layer ontop.
# On the box layer, a waveguide is structured. In this example it's a silicon waveguide, which has a quite high thermal optical coefficient.

# Above the waveguide, within the deposited cladding layer, a TiN resistor is placed for heating up the thermal phase shifter.
# We refine the mesh within the region of most intered (for very precise results, of course an even finer mesh is required).

# %% tags=["remove-stderr"]

w_sim = 8 * 2
Expand Down Expand Up @@ -105,7 +114,13 @@
mesh.draw().show()

# %% [markdown]
# And then we solve it!
# Using the previously defined geometry and the resulting mesh, we can calculate the thermal distribution!
# For this we start with defining the current densities we want to simulate within the TiN resistor.
# Here we use the same values as in the referenced paper.

# For each temperature distribution we calculate the modes of the waveguide and track their change in effective refractive index.
# Using the change of the effective refractive index we can calculate the phase shift accumulated within the thermal phase shifter of a given length.
# To stay consistent with the referenced paper, we use a length of 320um.

# %% tags=["remove-stderr"]
currents = np.linspace(0.0, 7.4e-3, 10)
Expand Down Expand Up @@ -151,12 +166,18 @@

neffs.append(np.real(modes[0].n_eff))

print(f"Phase shift: {2 * np.pi / 1.55 * (neffs[-1] - neffs[0]) * 320}")
plt.xlabel("Current / mA")
plt.ylabel("Effective refractive index $n_{eff}$")
plt.plot(currents * 1e3, neffs)
plt.show()

# %% [markdown]

# Using the values we calculated for no applied current density and the highest applied current density, we can calculate the phase shift introduced by the current:

# %% tags=["remove-stderr"]

print(f"Phase shift: {2 * np.pi / 1.55 * (neffs[-1] - neffs[0]) * 320}")

# %% [markdown]
# ## Bibliography
Expand Down
20 changes: 18 additions & 2 deletions docs/photonics/examples/vary_width.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

# %% [markdown]
# # Variation of the width
#
# To understand the propagation in a waveguide, it's often helpful to look at how the effective refractive indices of the modes change when adjusting the width of the waveguide.
# As the modes continously change their refractive index, we can track them through their evolution.
# We gray the area which would indicate a effective refractive index below the refractive index of the underlying layer (commonly refered to as box), as such modes would not be guided.
# The refractive index of the box called "cutoff", as it defines the effective refractive index level under which modes stop being guided.

# %% tags=["hide-input"]

Expand All @@ -39,7 +44,7 @@
all_neffs = np.zeros((widths.shape[0], num_modes))
all_te_fracs = np.zeros((widths.shape[0], num_modes))
for i, width in enumerate(tqdm(widths)):
core = box(0, 0, width, 0.5)
core = box(0, 0, width, 0.33)
polygons = OrderedDict(
core=core,
box=clip_by_rect(core.buffer(1.0, resolution=4), -np.inf, -np.inf, np.inf, 0),
Expand All @@ -63,9 +68,20 @@
all_neffs = np.real(all_neffs)
plt.xlabel("Width of waveguide / µm")
plt.ylabel("Effective refractive index")
plt.ylim(1.444, np.max(all_neffs) + 0.1 * (np.max(all_neffs) - 1.444))
plt.fill_between(widths, 1.444, alpha=0.5, color="gray")
plt.ylim(1.36, np.max(all_neffs) + 0.1 * (np.max(all_neffs) - 1.444))
for lams, te_fracs in zip(all_neffs.T, all_te_fracs.T):
plt.plot(widths, lams)
plt.scatter(widths, lams, c=te_fracs, cmap="cool")
plt.colorbar().set_label("TE fraction")
plt.show()

# %% [markdown]

# The graph shows a TE mode emerging (getting a greater effective refractive index than the box) at a width of ~750nm.
# The second mode emerges at a wavelength of ~1700nm.
# Thus, the waveguide is a single mode waveguide with a width within the range from ~750nm to 1700nm.

# The second mode is at the width at which it emerges a TM-mode, but shows for slightly wider waveguides an anti-crossing with the emerging TE-mode.
# After this anti-crossing, the mode with the second highest effective refracteive index is TE10-mode, while the TM00-mode keeps existing in the system with an effective refractive inded slightly above the cutoff.
# At a width of ~2600nm, a third TE-mode starts being guided.
4 changes: 1 addition & 3 deletions femwell/pn_analytical.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ def dn_carriers(wavelength: float, dN: float, dP: float) -> float:
return -2.98 * 1e-22 * np.power(dN, 1.016) - 1.25 * 1e-18 * np.power(dP, 0.835)
else:
wavelength *= 1e-6
return -3.64 * 1e-10 * wavelength**2 * dN - 3.51 * 1e-6 * wavelength**2 * np.power(
dP, 0.8
)
return -3.64 * 1e-10 * wavelength**2 * dN - 3.51 * 1e-6 * wavelength**2 * np.power(dP, 0.8)


def dalpha_carriers(wavelength: float, dN: float, dP: float) -> float:
Expand Down

0 comments on commit a89f6f3

Please sign in to comment.