Skip to content

Commit 218a456

Browse files
authored
Merge pull request #174 from simbilod/layer_to_physical_name
layernames to physical labels dict
2 parents 746eecc + f5bf7a6 commit 218a456

File tree

7 files changed

+157
-4
lines changed

7 files changed

+157
-4
lines changed

gplugins/gmsh/define_polysurfaces.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
def define_polysurfaces(
99
polygons_dict: dict,
1010
layer_stack: LayerStack,
11+
layer_physical_map: dict,
1112
model: Any,
1213
resolutions: dict,
1314
scale_factor: float = 1,
@@ -32,7 +33,9 @@ def define_polysurfaces(
3233
model=model,
3334
resolution=resolutions.get(layername, None),
3435
mesh_order=layer_stack.layers.get(layername).mesh_order,
35-
physical_name=layername,
36+
physical_name=layer_physical_map[layername]
37+
if layername in layer_physical_map
38+
else layername,
3639
)
3740
)
3841

gplugins/gmsh/get_mesh.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def get_mesh(
2222
component: ComponentSpec,
2323
type: str,
2424
layer_stack: LayerStack,
25+
layer_physical_map: dict | None = None,
26+
layer_meshbool_map: dict | None = None,
2527
z: float | None = None,
2628
xsection_bounds=None,
2729
wafer_padding: float = 0.0,
@@ -35,6 +37,8 @@ def get_mesh(
3537
component: component
3638
type: one of "xy", "uz", or "3D". Determines the type of mesh to return.
3739
layer_stack: LayerStack object containing layer information.
40+
layer_physical_map: by default, physical are tagged with layername; this dict allows you to specify custom mappings.
41+
layer_meshbool_map: by default, all polygons on layer_stack layers are meshed; this dict allows you set True of False to the meshing of given layers.
3842
z: used to define z-slice for xy meshing.
3943
xsection_bounds: used to define in-plane line for uz meshing.
4044
wafer_padding: padding beyond bbox to add to WAFER layers.
@@ -73,6 +77,26 @@ def get_mesh(
7377
else:
7478
new_resolutions = None
7579

80+
# Default layer labels
81+
if layer_physical_map is None:
82+
layer_physical_map = {}
83+
for layer_name in layer_stack.layers.keys():
84+
layer_physical_map[layer_name] = layer_name
85+
else:
86+
for layer_name in layer_stack.layers.keys():
87+
if layer_name not in layer_physical_map.keys():
88+
layer_physical_map[layer_name] = layer_name
89+
90+
# Default meshing flags (all True)
91+
if layer_meshbool_map is None:
92+
layer_meshbool_map = {}
93+
for layer_name in layer_stack.layers.keys():
94+
layer_meshbool_map[layer_name] = True
95+
else:
96+
for layer_name in layer_stack.layers.keys():
97+
if layer_name not in layer_physical_map.keys():
98+
layer_meshbool_map[layer_name] = True
99+
76100
if type == "xy":
77101
if z is None:
78102
raise ValueError(
@@ -85,6 +109,7 @@ def get_mesh(
85109
layer_stack=layer_stack,
86110
default_characteristic_length=default_characteristic_length,
87111
resolutions=new_resolutions,
112+
layer_physical_map=layer_physical_map,
88113
**kwargs,
89114
)
90115
elif type == "uz":
@@ -100,6 +125,7 @@ def get_mesh(
100125
layer_stack=layer_stack,
101126
default_characteristic_length=default_characteristic_length,
102127
resolutions=new_resolutions,
128+
layer_physical_map=layer_physical_map,
103129
**kwargs,
104130
)
105131
elif type == "3D":
@@ -108,6 +134,7 @@ def get_mesh(
108134
layer_stack=layer_stack,
109135
default_characteristic_length=default_characteristic_length,
110136
resolutions=new_resolutions,
137+
layer_physical_map=layer_physical_map,
111138
**kwargs,
112139
)
113140
else:
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from __future__ import annotations
2+
3+
import gdsfactory as gf
4+
from gdsfactory.pdk import get_layer_stack
5+
from gdsfactory.technology import LayerStack
6+
7+
from gplugins.gmsh.get_mesh import get_mesh
8+
9+
10+
def test_custom_physical_uz() -> None:
11+
waveguide = gf.components.straight_pin(length=10, taper=None)
12+
13+
filtered_layer_stack = LayerStack(
14+
layers={
15+
k: get_layer_stack().layers[k]
16+
for k in (
17+
"slab90",
18+
"core",
19+
"via_contact",
20+
)
21+
}
22+
)
23+
24+
layer_physical_map = {
25+
"slab90": "silicon",
26+
"core": "silicon",
27+
"via_contact": "metal",
28+
}
29+
30+
mesh = get_mesh(
31+
type="uz",
32+
component=waveguide,
33+
xsection_bounds=[(4, -15), (4, 15)],
34+
layer_stack=filtered_layer_stack,
35+
layer_physical_map=layer_physical_map,
36+
background_tag="Oxide",
37+
filename="uzmesh_ref.msh",
38+
)
39+
40+
for value in layer_physical_map.values():
41+
assert value in mesh.cell_sets_dict.keys()
42+
43+
44+
def test_custom_physical_xy() -> None:
45+
waveguide = gf.components.straight_pin(length=10, taper=None)
46+
47+
filtered_layer_stack = LayerStack(
48+
layers={
49+
k: get_layer_stack().layers[k]
50+
for k in (
51+
"slab90",
52+
"core",
53+
"via_contact",
54+
)
55+
}
56+
)
57+
58+
layer_physical_map = {
59+
"slab90": "silicon",
60+
"core": "silicon",
61+
"via_contact": "metal",
62+
}
63+
64+
mesh = get_mesh(
65+
type="xy",
66+
component=waveguide,
67+
z=0.09,
68+
layer_stack=filtered_layer_stack,
69+
layer_physical_map=layer_physical_map,
70+
background_tag="Oxide",
71+
filename="xymesh.msh",
72+
)
73+
74+
for value in layer_physical_map.values():
75+
assert value in mesh.cell_sets_dict.keys()
76+
77+
78+
def test_custom_physical_xyz() -> None:
79+
waveguide = gf.components.straight_pin(length=10, taper=None)
80+
81+
filtered_layer_stack = LayerStack(
82+
layers={
83+
k: get_layer_stack().layers[k]
84+
for k in (
85+
"slab90",
86+
"core",
87+
"via_contact",
88+
)
89+
}
90+
)
91+
92+
layer_physical_map = {
93+
"slab90": "silicon",
94+
"core": "silicon",
95+
"via_contact": "metal",
96+
}
97+
98+
mesh = get_mesh(
99+
type="3D",
100+
component=waveguide,
101+
layer_stack=filtered_layer_stack,
102+
layer_physical_map=layer_physical_map,
103+
background_tag="Oxide",
104+
filename="xyzmesh.msh",
105+
)
106+
107+
for value in layer_physical_map.values():
108+
assert value in mesh.cell_sets_dict.keys()
109+
110+
111+
if __name__ == "__main__":
112+
test_custom_physical_uz()

gplugins/gmsh/tests/test_meshing_3D.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from gdsfactory.pdk import get_layer_stack
66
from gdsfactory.technology import LayerStack
77

8-
from gplugins.gmsh.xyz_mesh import xyz_mesh
8+
from gplugins.gmsh.get_mesh import get_mesh
99

1010

1111
def test_gmsh_xyz_mesh() -> None:
@@ -43,7 +43,8 @@ def test_gmsh_xyz_mesh() -> None:
4343
resolutions = {
4444
"core": {"resolution": 0.3},
4545
}
46-
xyz_mesh(
46+
get_mesh(
47+
type="3D",
4748
component=c,
4849
layer_stack=filtered_layer_stack,
4950
resolutions=resolutions,

gplugins/gmsh/uz_xsection_mesh.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ def uz_xsection_mesh(
194194
component: ComponentOrReference,
195195
xsection_bounds: tuple[tuple[float, float], tuple[float, float]],
196196
layer_stack: LayerStack,
197+
layer_physical_map: dict,
197198
resolutions: dict | None = None,
198199
default_characteristic_length: float = 0.5,
199200
background_tag: str | None = None,
@@ -278,6 +279,7 @@ def uz_xsection_mesh(
278279
model=model,
279280
scale_factor=global_scaling_premesh,
280281
resolutions=resolutions,
282+
layer_physical_map=layer_physical_map,
281283
)
282284

283285
# Add background polygon

gplugins/gmsh/xy_xsection_mesh.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def xy_xsection_mesh(
5858
component: ComponentOrReference,
5959
z: float,
6060
layer_stack: LayerStack,
61+
layer_physical_map: dict,
6162
resolutions: dict | None = None,
6263
default_characteristic_length: float = 0.5,
6364
background_tag: str | None = None,
@@ -150,6 +151,7 @@ def xy_xsection_mesh(
150151
model=model,
151152
scale_factor=global_scaling_premesh,
152153
resolutions=resolutions,
154+
layer_physical_map=layer_physical_map,
153155
)
154156

155157
# Mesh

gplugins/gmsh/xyz_mesh.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def define_edgeport(
7575
def define_prisms(
7676
layer_polygons_dict: dict,
7777
layer_stack: LayerStack,
78+
layer_physical_map: dict,
7879
model: Any,
7980
resolutions: dict,
8081
scale_factor: float = 1,
@@ -84,6 +85,7 @@ def define_prisms(
8485
Args:
8586
layer_polygons_dict: dictionary of polygons for each layer
8687
layer_stack: gdsfactory LayerStack to parse
88+
layer_physical_map: map layer names to physical names
8789
model: meshwell Model object
8890
resolutions: Pairs {"layername": {"resolution": float, "distance": "float}} to roughly control mesh refinement.
8991
scale_factor: scaling factor to apply to the polygons (default: 1)
@@ -120,7 +122,9 @@ def define_prisms(
120122
model=model,
121123
resolution=resolutions.get(layername, None),
122124
mesh_order=buffered_layer_stack.layers.get(layername).mesh_order,
123-
physical_name=layername,
125+
physical_name=layer_physical_map[layername]
126+
if layername in layer_physical_map
127+
else layername,
124128
)
125129
)
126130

@@ -130,6 +134,7 @@ def define_prisms(
130134
def xyz_mesh(
131135
component: ComponentOrReference,
132136
layer_stack: LayerStack,
137+
layer_physical_map: dict,
133138
resolutions: dict | None = None,
134139
default_characteristic_length: float = 0.5,
135140
background_tag: str | None = None,
@@ -254,6 +259,7 @@ def xyz_mesh(
254259
model=model,
255260
scale_factor=global_scaling_premesh,
256261
resolutions=resolutions,
262+
layer_physical_map=layer_physical_map,
257263
)
258264

259265
# Add edgeports

0 commit comments

Comments
 (0)