From 15d9b80e20fe1f855784b83e0a37417e0654b3b2 Mon Sep 17 00:00:00 2001 From: simbilod Date: Mon, 9 Oct 2023 11:12:15 -0700 Subject: [PATCH] layernames to physical labels dict --- gplugins/gmsh/define_polysurfaces.py | 5 +- gplugins/gmsh/get_mesh.py | 15 +++ gplugins/gmsh/tests/test_custom_names.py | 112 +++++++++++++++++++++++ gplugins/gmsh/tests/test_meshing_3D.py | 5 +- gplugins/gmsh/uz_xsection_mesh.py | 2 + gplugins/gmsh/xy_xsection_mesh.py | 2 + 6 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 gplugins/gmsh/tests/test_custom_names.py diff --git a/gplugins/gmsh/define_polysurfaces.py b/gplugins/gmsh/define_polysurfaces.py index d4beda74..34855c2c 100644 --- a/gplugins/gmsh/define_polysurfaces.py +++ b/gplugins/gmsh/define_polysurfaces.py @@ -8,6 +8,7 @@ def define_polysurfaces( polygons_dict: dict, layer_stack: LayerStack, + layer_physical_map: dict, model: Any, resolutions: dict, scale_factor: float = 1, @@ -32,7 +33,9 @@ def define_polysurfaces( model=model, resolution=resolutions.get(layername, None), mesh_order=layer_stack.layers.get(layername).mesh_order, - physical_name=layername, + physical_name=layer_physical_map[layername] + if layername in layer_physical_map + else layername, ) ) diff --git a/gplugins/gmsh/get_mesh.py b/gplugins/gmsh/get_mesh.py index 24ca3192..7203dde0 100644 --- a/gplugins/gmsh/get_mesh.py +++ b/gplugins/gmsh/get_mesh.py @@ -22,6 +22,7 @@ def get_mesh( component: ComponentSpec, type: str, layer_stack: LayerStack, + layer_physical_map: dict | None = None, z: float | None = None, xsection_bounds=None, wafer_padding: float = 0.0, @@ -35,6 +36,7 @@ def get_mesh( component: component type: one of "xy", "uz", or "3D". Determines the type of mesh to return. layer_stack: LayerStack object containing layer information. + layer_physical_map: by default, physical are tagged with layername; this dict allows you to specify custom mappings. z: used to define z-slice for xy meshing. xsection_bounds: used to define in-plane line for uz meshing. wafer_padding: padding beyond bbox to add to WAFER layers. @@ -73,6 +75,16 @@ def get_mesh( else: new_resolutions = None + # Default layer labels + if layer_physical_map is None: + layer_physical_map = {} + for layer_name in layer_stack.layers.keys(): + layer_physical_map[layer_name] = layer_name + else: + for layer_name in layer_stack.layers.keys(): + if layer_name not in layer_physical_map.keys(): + layer_physical_map[layer_name] = layer_name + if type == "xy": if z is None: raise ValueError( @@ -85,6 +97,7 @@ def get_mesh( layer_stack=layer_stack, default_characteristic_length=default_characteristic_length, resolutions=new_resolutions, + layer_physical_map=layer_physical_map, **kwargs, ) elif type == "uz": @@ -100,6 +113,7 @@ def get_mesh( layer_stack=layer_stack, default_characteristic_length=default_characteristic_length, resolutions=new_resolutions, + layer_physical_map=layer_physical_map, **kwargs, ) elif type == "3D": @@ -108,6 +122,7 @@ def get_mesh( layer_stack=layer_stack, default_characteristic_length=default_characteristic_length, resolutions=new_resolutions, + layer_physical_map=layer_physical_map, **kwargs, ) else: diff --git a/gplugins/gmsh/tests/test_custom_names.py b/gplugins/gmsh/tests/test_custom_names.py new file mode 100644 index 00000000..192a87a2 --- /dev/null +++ b/gplugins/gmsh/tests/test_custom_names.py @@ -0,0 +1,112 @@ +from __future__ import annotations + +import gdsfactory as gf +from gdsfactory.pdk import get_layer_stack +from gdsfactory.technology import LayerStack + +from gplugins.gmsh.get_mesh import get_mesh + + +def test_custom_physical_uz() -> None: + waveguide = gf.components.straight_pin(length=10, taper=None) + + filtered_layer_stack = LayerStack( + layers={ + k: get_layer_stack().layers[k] + for k in ( + "slab90", + "core", + "via_contact", + ) + } + ) + + layer_physical_map = { + "slab90": "silicon", + "core": "silicon", + "via_contact": "metal", + } + + mesh = get_mesh( + type="uz", + component=waveguide, + xsection_bounds=[(4, -15), (4, 15)], + layer_stack=filtered_layer_stack, + layer_physical_map=layer_physical_map, + background_tag="Oxide", + filename="uzmesh_ref.msh", + ) + + for value in layer_physical_map.values(): + assert value in mesh.cell_sets_dict.keys() + + +def test_custom_physical_xy() -> None: + waveguide = gf.components.straight_pin(length=10, taper=None) + + filtered_layer_stack = LayerStack( + layers={ + k: get_layer_stack().layers[k] + for k in ( + "slab90", + "core", + "via_contact", + ) + } + ) + + layer_physical_map = { + "slab90": "silicon", + "core": "silicon", + "via_contact": "metal", + } + + mesh = get_mesh( + type="xy", + component=waveguide, + z=0.09, + layer_stack=filtered_layer_stack, + layer_physical_map=layer_physical_map, + background_tag="Oxide", + filename="xymesh.msh", + ) + + for value in layer_physical_map.values(): + assert value in mesh.cell_sets_dict.keys() + + +def test_custom_physical_xyz() -> None: + waveguide = gf.components.straight_pin(length=10, taper=None) + + filtered_layer_stack = LayerStack( + layers={ + k: get_layer_stack().layers[k] + for k in ( + "slab90", + "core", + "via_contact", + ) + } + ) + + layer_physical_map = { + "slab90": "silicon", + "core": "silicon", + "via_contact": "metal", + } + + mesh = get_mesh( + type="3D", + component=waveguide, + layer_stack=filtered_layer_stack, + layer_physical_map=layer_physical_map, + background_tag="Oxide", + filename="xyzmesh.msh", + ) + + for value in layer_physical_map.values(): + assert value in mesh.cell_sets_dict.keys() + + +if __name__ == "__main__": + test_custom_physical_uz() diff --git a/gplugins/gmsh/tests/test_meshing_3D.py b/gplugins/gmsh/tests/test_meshing_3D.py index fbbcb3eb..efc7c33f 100644 --- a/gplugins/gmsh/tests/test_meshing_3D.py +++ b/gplugins/gmsh/tests/test_meshing_3D.py @@ -5,7 +5,7 @@ from gdsfactory.pdk import get_layer_stack from gdsfactory.technology import LayerStack -from gplugins.gmsh.xyz_mesh import xyz_mesh +from gplugins.gmsh.get_mesh import get_mesh def test_gmsh_xyz_mesh() -> None: @@ -43,7 +43,8 @@ def test_gmsh_xyz_mesh() -> None: resolutions = { "core": {"resolution": 0.3}, } - xyz_mesh( + get_mesh( + type="3D", component=c, layer_stack=filtered_layer_stack, resolutions=resolutions, diff --git a/gplugins/gmsh/uz_xsection_mesh.py b/gplugins/gmsh/uz_xsection_mesh.py index 932395a3..2b1f88ab 100644 --- a/gplugins/gmsh/uz_xsection_mesh.py +++ b/gplugins/gmsh/uz_xsection_mesh.py @@ -194,6 +194,7 @@ def uz_xsection_mesh( component: ComponentOrReference, xsection_bounds: tuple[tuple[float, float], tuple[float, float]], layer_stack: LayerStack, + layer_physical_map: dict, resolutions: dict | None = None, default_characteristic_length: float = 0.5, background_tag: str | None = None, @@ -278,6 +279,7 @@ def uz_xsection_mesh( model=model, scale_factor=global_scaling_premesh, resolutions=resolutions, + layer_physical_map=layer_physical_map, ) # Add background polygon diff --git a/gplugins/gmsh/xy_xsection_mesh.py b/gplugins/gmsh/xy_xsection_mesh.py index 4425c999..71f3c09c 100644 --- a/gplugins/gmsh/xy_xsection_mesh.py +++ b/gplugins/gmsh/xy_xsection_mesh.py @@ -58,6 +58,7 @@ def xy_xsection_mesh( component: ComponentOrReference, z: float, layer_stack: LayerStack, + layer_physical_map: dict, resolutions: dict | None = None, default_characteristic_length: float = 0.5, background_tag: str | None = None, @@ -150,6 +151,7 @@ def xy_xsection_mesh( model=model, scale_factor=global_scaling_premesh, resolutions=resolutions, + layer_physical_map=layer_physical_map, ) # Mesh