Skip to content

Commit 55b3065

Browse files
authored
Merge pull request #633 from gdsfactory/fix_meshwell
2 parents a2e9b87 + 5eda047 commit 55b3065

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3204
-5486
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.gds binary
2+
*.oas binary

.github/workflows/test_code.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fail-fast: false
2121
max-parallel: 12
2222
matrix:
23-
plugin: [femwell, gmsh, meow, sax, tidy3d, klayout, vlsir, path_length_analysis]
23+
plugin: [femwell, meow, sax, tidy3d, klayout, vlsir, path_length_analysis]
2424
os: [ubuntu-latest]
2525
python-version: [3.12]
2626
exclude:
@@ -123,7 +123,7 @@ jobs:
123123
run: |
124124
palace --help || echo "Palace help failed but container exists"
125125
- name: Test with pytest
126-
run: sudo env "PATH=$PATH" "$(which uv)" run --extra dev --extra gmsh pytest gplugins/palace -v
126+
run: sudo env "PATH=$PATH" "$(which uv)" run --extra dev --extra meshwell pytest gplugins/palace -v
127127

128128
test_code_coverage:
129129
runs-on: ubuntu-latest

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,7 @@ cython_debug/
189189
*.BAK
190190
*.sav
191191
*.plt
192+
193+
# Gmsh
194+
*.msh
195+
*.xao

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"python.defaultInterpreterPath":"python"}

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ venv:
66

77
install:
88
uv venv --python 3.11
9-
uv pip install -e .[dev,docs,femwell,gmsh,meow,sax,tidy3d,klayout,vlsir]
9+
uv pip install -e .[dev,docs,femwell,meow,sax,tidy3d,klayout,vlsir]
1010
uv run pre-commit install
1111

1212
dev: test-data gmsh elmer install
@@ -27,12 +27,12 @@ test:
2727
pytest
2828

2929
uv-test:
30-
@for plugin in femwell gmsh meow sax tidy3d klayout vlsir path_length_analysis; do \
30+
@for plugin in femwell meow sax tidy3d klayout vlsir path_length_analysis; do \
3131
uv run pytest gplugins/$$plugin; \
3232
done
3333

3434
cov:
35-
uv run pytest gplugins/femwell gplugins/gmsh gplugins/meow gplugins/sax gplugins/tidy3d gplugins/klayout gplugins/vlsir gplugins/path_length_analysis --cov=gplugins/femwell --cov=gplugins/gmsh --cov=gplugins/meow --cov=gplugins/sax --cov=gplugins/tidy3d --cov=gplugins/klayout --cov=gplugins/vlsir --cov=gplugins/path_length_analysis
35+
uv run pytest gplugins/femwell gplugins/meshwell gplugins/meow gplugins/sax gplugins/tidy3d gplugins/klayout gplugins/vlsir gplugins/path_length_analysis --cov=gplugins/femwell --cov=gplugins/meshwell --cov=gplugins/meow --cov=gplugins/sax --cov=gplugins/tidy3d --cov=gplugins/klayout --cov=gplugins/vlsir --cov=gplugins/path_length_analysis
3636

3737
test-data:
3838
git clone https://github.com/gdsfactory/gdsfactory-test-data.git -b test-data test-data

docs/_config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ execute:
2929
- "*luminescent*"
3030
- "*pso*"
3131
- "*mpb*"
32+
- "*palace_01_electrostatic*"
33+
- "*palace_02_fullwave*"
3234
# - "*20_schematic_driven_layout*"
3335
# - "*001_meep_sparameters*"
3436
# - "*00_tidy3d.ipynb"

docs/api_design.rst

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,14 @@ API Design
55
Meshing
66
************************
77

8-
.. currentmodule:: gplugins.gmsh
8+
.. currentmodule:: gplugins.meshwell
99

1010
.. rubric:: Meshing
1111

1212
.. autosummary::
1313
:toctree: _autosummary/
1414

15-
get_layer_overlaps_z
16-
get_layers_at_z
17-
list_unique_layer_stack_z
18-
map_unique_layer_stack_z
19-
order_layer_stack
20-
get_u_bounds_layers
21-
get_u_bounds_polygons
22-
get_uz_bounds_layers
23-
uz_xsection_mesh
24-
xy_xsection_mesh
15+
get_meshwell_prisms
2516

2617

2718
************************

gplugins/common/base_models/component.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,31 @@ def cleanup_component(component, layer_stack, round_tol=2, simplify_tol=1e-2):
8787
}
8888

8989

90+
def cleanup_component_layermap(component, layermap, round_tol=2, simplify_tol=1e-2):
91+
"""Process component polygons before processing.
92+
93+
Uses layermap (design layers) names.
94+
95+
Args:
96+
component: gdsfactory component
97+
layermap: LayerMap object or dict with layer names as keys
98+
round_tol: tolerance for rounding coordinates
99+
simplify_tol: tolerance for polygon simplification
100+
"""
101+
layer_dict = vars(layermap) if not isinstance(layermap, dict) else layermap
102+
103+
return {
104+
layer: fuse_polygons(
105+
component,
106+
layer,
107+
round_tol=round_tol,
108+
simplify_tol=simplify_tol,
109+
)
110+
for layername, layer in layer_dict.items()
111+
if not layername.startswith("_") # Skip private attributes
112+
}
113+
114+
90115
def move_polar_rad_copy(
91116
pos: Coordinate, angle: float, length: float
92117
) -> NDArray[np.float64]:

gplugins/common/utils/get_capacitance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def get_capacitance(
6060
return run_capacitive_simulation_palace(
6161
component,
6262
simulation_folder=simulation_folder,
63-
simulator_params=simulator_params,
63+
solver_config=simulator_params,
6464
**kwargs,
6565
)
6666
case _:

gplugins/common/utils/get_component_with_net_layers.py

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import copy
22

33
import gdsfactory as gf
4+
from gdsfactory.technology.layer_stack import DerivedLayer, LayerLevel
5+
from gdsfactory.typings import Port
46
import klayout.db as kdb
5-
from gdsfactory import Component
7+
from gdsfactory import Component, LayerEnum
68
from gdsfactory.technology import LayerStack, LogicalLayer
79

810

@@ -25,7 +27,9 @@ def get_component_layer_stack(
2527
layernames_dict = new_layer_stack.get_layer_to_layername()
2628
layernames_present = [
2729
name
28-
for sublist in [layernames_dict[LogicalLayer(layer=layer)] for layer in layers_present]
30+
for sublist in [
31+
layernames_dict[LogicalLayer(layer=layer)] for layer in layers_present
32+
]
2933
for name in sublist
3034
]
3135
for key in list(new_layer_stack.layers.keys()):
@@ -35,6 +39,43 @@ def get_component_layer_stack(
3539
return new_layer_stack
3640

3741

42+
def compare_layerlevel_and_port_layers(layer_level: LayerLevel, port: Port) -> bool:
43+
"""Compare the layer information between a :class:`~LayerLevel` and a :class:`~Port`.
44+
45+
Note:
46+
If ``layer_level.layer`` is :class:`~LogicalLayer`, ``layer_level.layer`` is used.
47+
If ``layer_level.layer`` is :class:`~DerivedLayer`, ``layer_level.derived_layer`` is used.
48+
49+
Args:
50+
layer_level: The LayerLevel object containing layer information
51+
port: The Port object containing layer_info with layer and datatype
52+
53+
Returns:
54+
bool: True if the layer and datatype match between both objects
55+
"""
56+
57+
port_layer_tuple = (
58+
port.layer_info.layer,
59+
port.layer_info.datatype,
60+
)
61+
62+
is_derived_layer = isinstance(layer_level.layer, DerivedLayer)
63+
if is_derived_layer:
64+
layer_level_tuple = (layer_level.derived_layer.layer.layer, layer_level.derived_layer.layer.datatype)
65+
return layer_level_tuple == port_layer_tuple
66+
67+
layer_enum_or_tuple = layer_level.layer.layer
68+
if isinstance(layer_enum_or_tuple, tuple):
69+
layer_level_tuple = layer_enum_or_tuple
70+
else:
71+
layer_level_tuple = (
72+
layer_enum_or_tuple.layer,
73+
layer_enum_or_tuple.datatype,
74+
)
75+
76+
return layer_level_tuple == port_layer_tuple
77+
78+
3879
def get_component_with_net_layers(
3980
component: Component,
4081
layer_stack: LayerStack,
@@ -56,57 +97,78 @@ def get_component_with_net_layers(
5697
new_layers_init: initial layer number for the temporary new layers.
5798
add_to_layerstack: True by default, but can be set to False to disable parsing of the layerstack.
5899
"""
59-
# return NotImplementedError(
60-
# "Meshing component with net layers not implemented in gdsfactory8 yet."
61-
# )
62100

63101
# Initialize returned component
64102
net_component = component.copy()
65103

104+
new_layerlevels = []
66105
# For each port to consider, convert relevant polygons
67-
for i, portname in enumerate(port_names):
68-
port = component.ports[portname]
106+
for i, port_name in enumerate(port_names):
107+
port = component.ports[port_name]
69108
# Get original port layer polygons, and modify a new component without that layer
70109
polygons = (
71110
net_component.extract(layers=(port.layer,))
72111
.get_polygons()
73112
.get(port.layer, [])
74113
)
75-
net_component = net_component.remove_layers(layers=(port.layer,),recursive=False)
114+
net_component = net_component.remove_layers(
115+
layers=(port.layer,), recursive=False
116+
)
76117
for polygon in polygons:
77118
# If polygon belongs to port, create a unique new layer, and add the polygon to it
78119
if polygon.sized(int(3 * gf.kcl.dbu)).inside(
79120
kdb.Point(*port.to_itype().center)
80121
):
81-
# if gdstk.inside(
82-
# [port.center],
83-
# gdstk.offset(gdstk.Polygon(polygon), gf.get_active_pdk().grid_size),
84-
# )[0]:
85122
try:
86-
port_layernames = layer_stack.get_layer_to_layername()[
87-
LogicalLayer(layer=port.layer)
123+
derived_layerlevels_touching_port = [
124+
e
125+
for e in layer_stack.layers.values()
126+
if e.derived_layer is not None
127+
and e not in new_layerlevels
128+
and compare_layerlevel_and_port_layers(e, port)
88129
]
130+
logical_layerlevels_touching_port = [
131+
e
132+
for e in layer_stack.layers.values()
133+
if not isinstance(
134+
e.layer, gf.technology.layer_stack.DerivedLayer
135+
)
136+
and e not in new_layerlevels
137+
and compare_layerlevel_and_port_layers(e, port)
138+
]
139+
140+
layerlevels_touching_port = (
141+
derived_layerlevels_touching_port
142+
+ logical_layerlevels_touching_port
143+
)
89144
except KeyError as e:
90145
raise KeyError(
91146
"Make sure your `layer_stack` contains all layers with ports"
92147
) from e
93-
for j, old_layername in enumerate(port_layernames):
148+
149+
for j, old_layerlevel in enumerate(layerlevels_touching_port):
94150
new_layer_number = (
95151
new_layers_init[0] + i,
96152
new_layers_init[1] + j,
97153
)
98154
if add_to_layerstack:
99-
new_layer = copy.deepcopy(layer_stack.layers[old_layername])
100-
new_layer.layer = LogicalLayer(
155+
# new_layer = copy.deepcopy(layer_stack.layers[old_layerlevel])
156+
new_layerlevel = copy.deepcopy(old_layerlevel)
157+
new_layerlevel.layer = LogicalLayer(
101158
layer=(
102159
new_layers_init[0] + i,
103160
new_layers_init[1] + j,
104161
)
105162
)
106-
new_layer.name = f"{old_layername}{delimiter}{portname}"
107-
layer_stack.layers[f"{old_layername}{delimiter}{portname}"] = (
108-
new_layer
163+
new_layerlevel.name = (
164+
f"{old_layerlevel.name}{delimiter}{port_name}"
109165
)
166+
# Increase mesh order to ensure new layer is on top old
167+
new_layerlevel.mesh_order = old_layerlevel.mesh_order - 1
168+
layer_stack.layers[
169+
f"{old_layerlevel.name}{delimiter}{port_name}"
170+
] = new_layerlevel
171+
new_layerlevels.append(new_layerlevel)
110172
net_component.add_polygon(polygon, layer=new_layer_number)
111173
# Otherwise put the polygon back on the same layer
112174
else:

0 commit comments

Comments
 (0)