Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gaps at Waveguide Junctions in 3D MEEP geometries with angled sidewalls #391

Closed
doddgray opened this issue May 7, 2024 · 3 comments · Fixed by gdsfactory/gdsfactory#2726

Comments

@doddgray
Copy link

doddgray commented May 7, 2024

I think I noticed a bug while trying to use gplugins.gmeep to simulate a 3D geometry including waveguides with angled sidewalls. Specifically the tapered polygons defined by the shapes in a layer are always extruded "bottom up" (rather than "top down"), introducing gaps at waveguide junctions which are connected in your layer geometry. See the example below, where gaps appear between connected subcomponents of a gf.components.coupler defined using a single waveguide layer with ~25deg sidewall angles (where 0deg is vertical).

image

In the image above, the X-Z and Y-Z cross section plots correspond to the dashed red lines in the top X-Y refractive index plot generated with the meep simulation, and X-Y index plots are shown at three different values of z.

This also means that patterned waveguide widths are mapped to the layer bottom (the LayerLevel's zmin). I think that in some cases it is conventional for the pattern widths to correspond to the waveguide top widths. Am I doing something wrong? If not it would be nice to update gmeep.get_meep_geometry.get_meep_geometry_from_component to avoid these gaps in 3D geometries and expose some control over whether the layer pattern corresponds to the top or bottom when sidewall_angle!=0.

The optional width_to_z property of LayerLevels seems apt for controlling this if it isn't deprecated. Briefly playing around with this in a local branch, I was able to get the behavior I wanted (extruding the layer pattern "top down") by identifying layers with sidewall angles, placing their polygons at z=zmin+height, and extruding downward by passing axis = mp.Vector3(0,0,-1) to meep.geom.Prism. The pasted snippet below shows my hotfix. I can submit a pull request with a more general version of this controlled by width_to_z if it looks like the right approach, but I imagine there could be a smarter way.

    # ... edited code within `gmeep.get_meep_geometry.get_meep_geometry_from_component`
    for layername in ordered_layer_stack_keys:
        print(f"layername:\t{layername}")
        layer = layer_stack.layers[layername].layer
        polygons = layer_to_polygons[layer_stack.layers[layername].layer]
        if layer in layer_to_thickness and layer in layer_to_material:
            height = layer_to_thickness[layer] if is_3d else mp.inf
            zmin_um = layer_to_zmin[layer] if is_3d else 0
            
            if is_3d and (abs(layer_to_sidewall_angle[layer])>0.0):
                zpoly = zmin_um + height
                prism_axis = mp.Vector3(0,0,-1)
            else: # (is_3d == False) or (layer_to_sidewall_angle[layer]==0.0)
                zpoly = zmin_um
                prism_axis = mp.Vector3(0,0,1)

            for polygon in polygons:
                vertices = [mp.Vector3(p[0], p[1], zpoly) for p in polygon]
                material_name = layer_to_material[layer]

                if material_name:
                    material = get_material(
                        name=material_name,
                        dispersive=dispersive,
                        material_name_to_meep=material_name_to_meep,
                        wavelength=wavelength,
                    )
                    if is_3d:
                        geometry.append(
                            mp.Prism(
                                vertices=vertices,
                                height=height,
                                sidewall_angle=(np.pi * layer_to_sidewall_angle[layer] / 180),
                                material=material,
                                axis=prism_axis,
                            )
                        )
                    else:   # is_3d == False
                        geometry.append(
                            mp.Prism(
                                vertices=vertices,
                                height=height,
                                sidewall_angle=0,
                                material=material,
                            )
                        )
    return geometry

Thanks for all of your great work.

@joamatab
Copy link
Contributor

joamatab commented May 7, 2024

yes, you have to merge the polygons to avoid that

@joamatab
Copy link
Contributor

joamatab commented May 8, 2024

I was able to reproduce the issue and i think i solved it by merging all the polygons touching before extruding them

see gdsfactory/gdsfactory#2726

@doddgray
Copy link
Author

doddgray commented May 9, 2024

Thanks for taking a look and making a quick fix.

I had also tried to merge all the polygons in the coupler component above and was having trouble getting them to robustly merge, so I was worried that would be too fragile for components with lots of connected sub-components. That also still maps the pattern to the polygon bottoms at 'zmin', which I would guess is the less-common case for etched waveguides with angled sidewalls.

What do you think? Is there a significant downside to extruding downward from 'zmin+height' or at least exposing the option to do so?

Sorry for bad formatting, sending from phone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants