Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ venv:

install:
uv venv --python 3.11
uv pip install -e .[dev,docs,femwell,gmsh,meow,sax,tidy3d,klayout,vlsir]
uv pip install -e .[dev,docs,femwell,gmsh,meow,sax,tidy3d,klayout,vlsir,emode]
uv run pre-commit install

dev: test-data gmsh elmer install
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ Run simulations with GDSFactory by installing plugins.
- `palace` for full-wave driven (S parameter) and electrostatic (capacitive) simulations.
- EME
- `meow` Eigen Mode Expansion (EME).
- `EMode`
- Mode Solver
- Tidy3d
- Femwell
- MPB
- `EMode`
- TCAD
- `devsim` TCAD device simulator.
- Circuit simulations
Expand All @@ -46,7 +48,7 @@ pip install "gdsfactory[full]" --upgrade
Or list the plugins individually:

```bash
pip install "gplugins[devsim,femwell,gmsh,schematic,meow,meshwell,sax,tidy3d]" --upgrade
pip install "gplugins[devsim,femwell,gmsh,schematic,meow,meshwell,ray,sax,tidy3d,emode]" --upgrade
```

Or install only the plugins you need. For example:
Expand Down
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ parts:
- file: notebooks/mode_solver_fdfd
- file: notebooks/mpb_001_mpb_waveguide
- file: notebooks/meow_01
- file: notebooks/emode
- file: plugins_fdtd
sections:
- file: notebooks/tidy3d_00_tidy3d
Expand Down
16 changes: 10 additions & 6 deletions docs/plugins_mode_solver.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

A mode solver computes the modes supported by a waveguide cross-section at a particular wavelength. Modes are definite-frequency eigenstates of Maxwell's equations.

You can use 3 open source mode solvers:
You can use several mode solvers with GDSFactory:

1. tidy3d. Finite difference Frequency Domain (FDFD).
2. MPB. FDFD with periodic boundary conditions.
3. Femwell. Finite Element (FEM).
**Open Source:**
- ``tidy3d``: Finite difference Frequency Domain (FDFD).
- ``MPB``: FDFD with periodic boundary conditions.
- ``Femwell``: Finite Element (FEM).
- ``meow``: The tidy3d mode solver is also used by the MEOW plugin to get the Sparameters of components via Eigenmode Expansion.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Typo: "Sparameters" should likely be "S-parameters".

"S-parameters" is the correct term for scattering parameters in this context.

Suggested change
- ``meow``: The tidy3d mode solver is also used by the MEOW plugin to get the Sparameters of components via Eigenmode Expansion.
- ``meow``: The tidy3d mode solver is also used by the MEOW plugin to get the S-parameters of components via Eigenmode Expansion.


The tidy3d mode solver is also used by the MEOW plugin to get the Sparameters of components via Eigenmode Expansion.
Notice that the tidy3d FDTD solver is not open source as it runs on the cloud server, but the mode solver is open source and runs locally on your computer.
**Notice**: The tidy3d FDTD solver is not open source as it runs on the cloud server, but the mode solver is open source and runs locally on your computer.

**Proprietary:**
- ``EMode``: A versatile waveguide mode solver using the Finite-Difference Frequency Domain (FDFD) method, and a propagation tool using the Eigenmode Expansion method (EME). Requires the EMode software suite to be installed separately. See [docs.emodephotonix.com/installation](https://docs.emodephotonix.com/installation) for installation instructions.

```{tableofcontents}
```
4 changes: 4 additions & 0 deletions gplugins/emode/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from emodeconnection import open_file, get, inspect
from .utils import EMode

__all__ = ["EMode", "open_file", "get", "inspect"]
60 changes: 60 additions & 0 deletions gplugins/emode/tests/SOI.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

import gplugins.emode as emc
from gdsfactory.cross_section import rib
from gdsfactory.generic_tech import LAYER_STACK
from gdsfactory.technology import LayerStack


## Set up GDSFactory LayerStack and CrossSection in units of microns
layer_stack = LayerStack(
layers={
k: LAYER_STACK.layers[k]
for k in (
"core",
"clad",
"slab90",
"box",
)
}
)

layer_stack.layers["core"].thickness = 0.22
layer_stack.layers["core"].zmin = 0

layer_stack.layers["slab90"].thickness = 0.09
layer_stack.layers["slab90"].zmin = 0

layer_stack.layers["box"].thickness = 1.5
layer_stack.layers["box"].zmin = -1.5

layer_stack.layers["clad"].thickness = 1.5
layer_stack.layers["clad"].zmin = 0

## Connect and initialize EMode
em = emc.EMode()

## build_waveguide converts units to nanometers, which EMode's default
modes = em.build_waveguide(
cross_section=rib(width=0.6),
layer_stack=layer_stack,
wavelength=1.55,
num_modes=1,
x_resolution=0.010,
y_resolution=0.010,
window_width = 3.0,
window_height = 3.0,
background_refractive_index='Air',
max_effective_index=2.631,
)

## Launch FDM solver
em.FDM()

## Display the effective indices, TE fractions, and core confinement
em.report()

## Plot the field and refractive index profiles
em.plot()

## Close EMode
em.close()
72 changes: 72 additions & 0 deletions gplugins/emode/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import emodeconnection as emc
from gdsfactory import CrossSection
from gdsfactory.technology import LayerStack

class EMode(emc.EMode):
def build_waveguide(
self,
cross_section: CrossSection,
layer_stack: LayerStack,
**kwargs,
) -> None:
"""Builds a waveguide structure in EMode based on GDSFactory CrossSection and LayerStack.

Args:
cross_section: A GDSFactory CrossSection object defining the waveguide's geometry.
layer_stack: A GDSFactory LayerStack object defining the material layers.
**kwargs: Additional keyword arguments to be passed directly to EMode's settings() function.
"""
nm = 1e3 # convert microns to nanometers
dim_keys = [
'wavelength',
'x_resolution',
'y_resolution',
'window_width',
'window_height',
'bend_radius',
'expansion_resolution',
'expansion_size',
'propagation_resolution',
]

# Pass all kwargs directly to EMode's settings function
kwargs = {key: (value * nm if key in dim_keys else value) for key, value in kwargs.items()}
self.settings(**kwargs)

# Get a list of EMode materials for cleaning GDSFactory material names
emode_materials = self.get('materials')

# Process layer_stack to create EMode shapes
max_order = max([info.mesh_order for name, info in layer_stack.layers.items()])
min_zmin = min([info.zmin for name, info in layer_stack.layers.items()])

for layer_name, layer_info in layer_stack.layers.items():

material = next(
(mat for mat in emode_materials if mat.lower() == layer_info.material.lower()),
layer_info.material
)

shape_info = {
'name': layer_name,
'refractive_index': material,
'height': layer_info.thickness * nm,
'mask': layer_info.width_to_z * nm,
'sidewall_angle': layer_info.sidewall_angle,
'etch_depth': layer_info.thickness * nm if layer_info.width_to_z > 0 else 0,
'position': [0.0, (layer_info.zmin - min_zmin + layer_info.thickness/2) * nm],
'priority': max_order - layer_info.mesh_order + 1,
}

# Find a matching CrossSection for this layer
xsection_ind = [k for k, s in enumerate(cross_section.sections) if str(layer_info.layer) == str(s.layer) or str(layer_info.derived_layer) == str(s.layer)]

# Apply settings from the matching CrossSection
if len(xsection_ind) > 0:
xsection = cross_section.sections[xsection_ind[0]]
shape_info['mask'] = xsection.width * nm
shape_info['mask_offset'] = xsection.offset * nm

self.shape(**shape_info)

return
88 changes: 88 additions & 0 deletions notebooks/emode.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "dec55ff8",
"metadata": {},
"source": [
"# EMode - Photonic Device Simulation\n",
"\n",
"The EMode plugin integrates simulation capabilities from [**EMode Photonix**](https://emodephotonix.com) with GDSFactory. This plugin enables the analysis of photonic devices through:\n",
"\n",
"- Waveguide mode solving using a Finite-Difference Frequency Domain (FDFD) method.\n",
"- Propagation simulations using the Eigenmode Expansion (EME) method.\n",
"\n",
"Cross-sectional simulations are available with a free EMode<sup>2D</sup> license. The propagation module requires an EMode<sup>3D</sup> license.\n",
"\n",
"See the complete EMode documentation at [**EMode Docs**](https://docs.emodephotonix.com).\n",
"\n",
"Get an EMode license at the [**EMode Shop**](https://emodephotonix.com/get-emode).\n",
"\n",
"## Software Requirement\n",
"\n",
"This plugin requires that the EMode software is already installed on the user's computer. Please refer to the installation guide at [docs.emodephotonix.com/installation](https://docs.emodephotonix.com/installation) for detailed instructions.\n",
"\n",
"## Using EMode Examples with gplugins\n",
"\n",
"All of the [**EMode examples**](https://docs.emodephotonix.com/examples) can be adapted for use with the GDSFactory plugin. Simply replace the standard EMode import:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "f0fbf103",
"metadata": {},
"outputs": [],
"source": [
"import emodeconnection as emc"
]
},
{
"cell_type": "markdown",
"id": "6f832fad",
"metadata": {},
"source": [
"with the plugin-specific import:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b62c1bf",
"metadata": {},
"outputs": [],
"source": [
"import gplugins.emode as emc"
]
},
{
"cell_type": "markdown",
"id": "1f863dfd",
"metadata": {},
"source": [
"The ``gplugins.emode`` import provides the same interface and usage as the ``emodeconnection`` package, detailed in the [EMode Python connection documentation](https://docs.emodephotonix.com/emodeconnection_python)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ sax = ["sax~=0.15.14"]
schematic = ["bokeh", "ipywidgets", "natsort"]
tidy3d = ["tidy3d>=2.8.2,<2.9", "gdstk"]
vlsir = ["vlsir", "vlsirtools"]
emode = ["emodeconnection"]

[tool.codespell]
ignore-words-list = 'te, te/tm, te, ba, fpr, fpr_spacing, ro, nd, donot, schem, Ue'
Expand Down