Skip to content

Commit

Permalink
Merge pull request gdsfactory#1038 from gdsfactory/615e
Browse files Browse the repository at this point in the history
fix femwell and try to fix meow plugin

Former-commit-id: 28ebd43
  • Loading branch information
joamatab committed Dec 21, 2022
2 parents d1cce4c + e8a8958 commit 5bd7860
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 49 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## 6.15.0

- Add femwell mode solver [PR](https://github.com/gdsfactory/gdsfactory/pull/1032)
- meow improvements [PR](https://github.com/gdsfactory/gdsfactory/pull/1033)
- MEOW improvements [PR](https://github.com/gdsfactory/gdsfactory/pull/1033)

## 6.14.1

Expand All @@ -19,7 +19,7 @@
## 6.13.0

- Add z_to_bias processing in xy meshing [PR](https://github.com/gdsfactory/gdsfactory/pull/1011)
- Add MEAOW EME plugin [PR](https://github.com/gdsfactory/gdsfactory/pull/1015)
- Add MEOW EME plugin [PR](https://github.com/gdsfactory/gdsfactory/pull/1015)
- update tidy3d to 1.8.0

## 6.12.0
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ plugins:
pip install -e .[tidy3d]
pip install jax jaxlib
mamba install pymeep=*=mpi_mpich_* -y
mamba install petsc4py -y
mamba install slepc4py=*=complex* -y
pip install --upgrade "protobuf<=3.20.1"
pip install femwell
pip install scikit-fem[all] --upgrade
pip install git+https://github.com/HelgeGehring/femwell.git

plugins-debian: plugins
sudo apt-get install -y python3-gmsh
Expand Down
43 changes: 39 additions & 4 deletions docs/notebooks/plugins/eme/01_meow.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"outputs": [],
"source": [
"import gdsfactory as gf\n",
"import numpy as np\n",
"\n",
"c = gf.components.taper_cross_section_sine()\n",
"c"
Expand Down Expand Up @@ -167,7 +168,7 @@
"metadata": {},
"outputs": [],
"source": [
"sp"
"print(np.abs(sp['o1@0,o2@0'])**2)"
]
},
{
Expand Down Expand Up @@ -220,7 +221,7 @@
" }\n",
")\n",
"\n",
"c = gf.components.taper(width2=10)\n",
"c = gf.components.taper(width2=2)\n",
"c"
]
},
Expand All @@ -242,6 +243,15 @@
"eme.plot_cross_section(xs_num=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eme.plot_mode(xs_num=0, mode_num=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -251,6 +261,15 @@
"eme.plot_cross_section(xs_num=-1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eme.plot_mode(xs_num=-1, mode_num=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -280,6 +299,15 @@
"T"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.abs(sp['o1@0,o2@2'])**2"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -288,7 +316,7 @@
"source": [
"import numpy as np\n",
"\n",
"lengths = np.array([2, 10, 20])\n",
"lengths = np.array([1, 5, 10])\n",
"T = np.zeros_like(lengths, dtype=float)"
]
},
Expand All @@ -299,7 +327,7 @@
"outputs": [],
"source": [
"for length in lengths:\n",
" c = gf.components.taper(width2=10, length=length)\n",
" c = gf.components.taper(width2=2, length=length)\n",
" c.plot()"
]
},
Expand Down Expand Up @@ -338,6 +366,13 @@
"source": [
"T"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
131 changes: 91 additions & 40 deletions gdsfactory/simulation/eme/meow_eme.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
from itertools import permutations
from typing import List
from typing import Dict, List, Tuple

import meow as mw
import numpy as np
import pandas as pd
from tqdm.auto import tqdm

import gdsfactory as gf
from gdsfactory.pdk import _ACTIVE_PDK
from gdsfactory.simulation.gmsh.parse_layerstack import list_unique_layerstack_z
from gdsfactory.tech import LAYER, LayerStack

ColorRGB = Tuple[float, float, float]

material_to_color_default = {
"si": (0.9, 0, 0, 0.9),
"sio2": (0.9, 0.9, 0.9, 0.9),
Expand All @@ -20,21 +23,23 @@
class MEOW:
def __init__(
self,
component,
component: gf.Component,
layerstack,
wavelength: float = 1.55,
temperature: float = 25,
num_modes: int = 4,
cell_length: float = 1.0,
spacing_x: float = 2.0,
offset_x: float = 0,
center_x: float = 0,
resolution_x: int = 100,
spacing_y: float = 2.0,
offset_y: float = 0,
center_y: float = 0,
resolution_y: int = 100,
material_to_color=material_to_color_default,
material_to_color: Dict[str, ColorRGB] = material_to_color_default,
) -> None:
"""Computes multimode 2-port S-parameters for a gdsfactory component, assuming port 1 is at the left boundary and port 2 at the right boundary.
"""Computes multimode 2-port S-parameters for a gdsfactory component.
assumes port 1 is at the left boundary and port 2 at the right boundary.
Note coordinate systems:
gdsfactory uses x,y in the plane to represent components, with the layerstack existing in z
Expand All @@ -45,12 +50,56 @@ def __init__(
component: gdsfactory component.
layerstack: gdsfactory layerstack.
wavelength: wavelength in microns (for FDE, and for material properties).
temperature: temperature in C (for material properties).
temperature: temperature in C (for material properties). Unused now.
num_modes: number of modes to compute for the eigenmode expansion.
num_cells: number of component slices along the propagation direction for the EME.
cell_length: in un.
spacing_x: at beginning and end of the simulation region.
center_x: in um.
resolution_x: pixels in horizontal region.
spacing_y: at the beginning and end of simulation region.
center_y: in um.
resolution_y: pixels in vertical direction.
material_to_color: dict of ma
Returns:
S-parameters in form o1@0,o2@0 at wavelength.
::
cross_section view:
________________________________
| |
| |
| spacing_x spacing_x | spacing_y
|<---------> <-------->|
| ___________ _ _ _ |
| | | |
| | |_ _ _ _ _ |_ center_y
| | | |
| |___________| |
| | |
| |
| | | spacing_y
| |
|_______________|________________|
center_x
top side view:
________________________________
| |
| |
|cell_length |
|<--------> |
|_____________________ __________|
| | | |
| | | |
| cell0 | cell1 | cell2 |
|_________|___________|__________|
| |
| |
| |
| |
|________________________________|
"""
# Validate component
self.validate_component(component)
Expand All @@ -63,28 +112,29 @@ def __init__(

# Process simulation bounds
self.span_x = np.diff(component.bbox[:, 1])[0] + spacing_x
num_cells = self.num_cells = int(self.span_x / cell_length)
self.num_cells = int(self.span_x / cell_length)
zs = list_unique_layerstack_z(layerstack)
self.vert_span = np.max(zs) - np.min(zs) + spacing_y
self.offset_x = offset_x
self.span_y = np.max(zs) - np.min(zs) + spacing_y
self.center_x = center_x
self.resolution_x = resolution_x
self.offset_y = offset_y
self.center_y = center_y
self.resolution_y = resolution_y

# Setup simulation
self.component, self.layerstack = self.add_global_layers(component, layerstack)
self.extrusion_rules = self.layerstack_to_extrusion()
self.structs = mw.extrude_gds(self.component, self.extrusion_rules)
self.cells = self.get_eme_cells()
self.cells = self.create_cells(cell_length=cell_length)
self.env = mw.Environment(wl=self.wavelength, T=self.temperature)
self.css = [mw.CrossSection(cell=cell, env=self.env) for cell in self.cells]
self.modes = [None] * num_cells
self.modes_per_cell = [None] * self.num_cells
self.S = None
self.port_map = None

def gf_material_to_meow_material(
self, material_name: str = "si", wavelengths=None, color=None
):
"""Converts a gdsfactory material into a MEOW material."""
wavelengths = wavelengths or np.linspace(1.5, 1.6, 101)
color = color or (0.9, 0.9, 0.9, 0.9)
ns = _ACTIVE_PDK.materials_index[material_name](wavelengths)
Expand Down Expand Up @@ -159,28 +209,29 @@ def layerstack_to_extrusion(self):
)
return extrusions

def get_eme_cells(self, cell_length: float = 1.0) -> List[mw.Cell]:
def create_cells(self, cell_length: float = 1.0) -> List[mw.Cell]:
"""Get meow cells from extruded component.
Arguments:
Args:
cell_length: in um.
"""
bbox = self.component.bbox
self.cell_length = cell_length
length = self.component.xsize # in the propagation direction

num_cells = int(self.span_x / cell_length)
self.num_cells = int(length / cell_length)
Ls = np.array([length / self.num_cells for _ in range(self.num_cells)])

Ls = [np.diff(bbox[:, 0]).item() / num_cells for _ in range(num_cells)]
return mw.create_cells(
structures=self.structs,
mesh=mw.Mesh2d(
x=np.linspace(
self.offset_x - self.span_x / 2,
self.offset_x + self.span_x / 2,
self.center_x - self.span_x / 2,
self.center_x + self.span_x / 2,
self.resolution_x,
),
y=np.linspace(
self.offset_y - self.vert_span / 2,
self.offset_y + self.vert_span / 2,
self.center_y - self.span_y / 2,
self.center_y + self.span_y / 2,
self.resolution_y,
),
),
Expand All @@ -196,9 +247,9 @@ def plot_cross_section(self, xs_num):
return mw.visualize(css[xs_num])

def plot_mode(self, xs_num, mode_num):
if self.modes[xs_num] is None:
self.modes[xs_num] = self.compute_mode(xs_num)
return mw.visualize(self.modes[xs_num][mode_num])
if self.modes_per_cell[xs_num] is None:
self.modes_per_cell[xs_num] = self.compute_mode(xs_num)
return mw.visualize(self.modes_per_cell[xs_num][mode_num])

def get_port_map(self):
if self.port_map is None:
Expand Down Expand Up @@ -228,16 +279,18 @@ def validate_component(self, component):
def compute_mode(self, xs_num):
return mw.compute_modes(self.css[xs_num], num_modes=self.num_modes)

def compute_all_modes(self):
for xs_num in range(self.num_cells):
if self.modes[xs_num] is None:
self.modes[xs_num] = self.compute_mode(xs_num)
def compute_all_modes(self) -> None:
self.modes_per_cell = []
for cs in tqdm(self.css):
modes_in_cs = mw.compute_modes(cs, num_modes=self.num_modes)
self.modes_per_cell.append(modes_in_cs)

def compute_sparameters(self):
# Compute EME
def compute_sparameters(self) -> Dict[str, np.ndarray]:
"""Returns Sparameters using EME."""
self.compute_all_modes()

if self.S is None or self.port_map is None:
self.S, self.port_map = mw.compute_s_matrix(self.modes)
self.S, self.port_map = mw.compute_s_matrix(self.modes_per_cell)

# Convert coefficients to existing format
meow_to_gf_keys = {
Expand All @@ -260,8 +313,7 @@ def compute_sparameters(self):


if __name__ == "__main__":

c = gf.components.taper_cross_section_linear()
c = gf.components.taper(length=10, width2=2)
c.show()

from gdsfactory.tech import get_layer_stack_generic
Expand All @@ -277,9 +329,8 @@ def compute_sparameters(self):
)
}
)
m = MEOW(component=c, layerstack=filtered_layerstack, wavelength=1.55)
print(len(m.cells))

sp = MEOW(component=c, layerstack=filtered_layerstack, wavelength=1.55)

import pprint

pprint.pprint(sp.compute_sparameters())
# import pprint
# pprint.pprint(m.compute_sparameters())

0 comments on commit 5bd7860

Please sign in to comment.