Beispiel #1
0
def spiral_with_coupler(cell, origin=(0, 0), width=0.5, angle=0, gap=3, num=4):
        l_wg = 100

        left_wg = Waveguide(origin, angle, width)
        left_wg.add_straight_segment(l_wg) 

        spiral = Spiral.make_at_port(left_wg.current_port, num=num, gap=gap, inner_gap=30)
        print(spiral.length, "um")
        print(spiral.out_port)
        right_wg = Waveguide.make_at_port(spiral.out_port)
        right_wg.add_straight_segment(l_wg) 

        layout = positive_resist.convert_to_positive_resist([left_wg, spiral, right_wg], gap, outer_resolution=1e-3)

        outer_corners = [origin, (origin[0], origin[1]+2*gap), (origin[0]-2*gap, origin[1]+2*gap), (origin[0]-2*gap, origin[1]-2*gap), (origin[0], origin[1]-2*gap)]
        polygon1 = Polygon(outer_corners)
        origin = spiral.out_port.origin
        origin[0] = origin[0] + l_wg + 2*gap
        outer_corners = [origin, (origin[0], origin[1]+2*gap), (origin[0]-2*gap, origin[1]+2*gap), (origin[0]-2*gap, origin[1]-2*gap), (origin[0], origin[1]-2*gap)]
        polygon2 = Polygon(outer_corners)
        polygon = polygon1.union(polygon2)

        layout_fixed = layout.difference(polygon)

        cell.add_to_layer(1, layout_fixed)

        # add the text of the length of spiral
        cell.add_to_layer(101, Text((origin[0], origin[1]-50), 20, str(spiral.length) ) )
Beispiel #2
0
def coupler_coupler(origin, width=0.5, angle=0, gap=3):
    l_wg = 100

    left_wg = Waveguide(origin, angle, width)
    left_wg.add_straight_segment(l_wg)

    right_wg = Waveguide.make_at_port(left_wg.port)
    right_wg.add_straight_segment(l_wg)

    layout = positive_resist.convert_to_positive_resist([left_wg, right_wg],
                                                        gap,
                                                        outer_resolution=1e-3)

    outer_corners = [
        origin, (origin[0], origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] - 2 * gap),
        (origin[0], origin[1] - 2 * gap)
    ]
    polygon1 = Polygon(outer_corners)
    origin = (origin[0] + 2 * l_wg + 2 * gap, origin[1])
    outer_corners = [
        origin, (origin[0], origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] - 2 * gap),
        (origin[0], origin[1] - 2 * gap)
    ]
    polygon2 = Polygon(outer_corners)
    polygon = polygon1.union(polygon2)

    layout_fixed = layout.difference(polygon)

    cell.add_to_layer(1, layout_fixed)
Beispiel #3
0
def _example():
    from gdshelpers.geometry.chip import Cell
    from gdshelpers.parts.splitter import Splitter
    from gdshelpers.parts.coupler import GratingCoupler

    port = Port([0, 0], 0, 1)
    path = Waveguide.make_at_port(port)

    path.add_straight_segment(10)
    path.add_bend(np.pi / 2, 10, final_width=0.5)
    path.add_bend(-np.pi / 2, 10, final_width=1)
    path.add_arc(np.pi * 3 / 4, 10, )

    splitter = Splitter.make_at_root_port(path.current_port, 30, 10)
    path2 = Waveguide.make_at_port(splitter.right_branch_port)
    path2.add_bend(-np.pi / 4, 10)

    n = 10
    path2.add_parameterized_path(lambda t: (n * 10 * t, np.cos(n * 2 * np.pi * t) - 1),
                                 path_derivative=lambda t: (n * 10, -n * 2 * np.pi * np.sin(n * 2 * np.pi * t)),
                                 width=lambda t: np.cos(n * 2 * np.pi * t) * 0.2 + np.exp(-t) * 0.3 + 0.5,
                                 width_function_supports_numpy=True)
    path2.add_straight_segment(10, width=[.5, .5, .5])
    print(path2.length)
    print(path2.length_last_segment)

    path2.add_cubic_bezier_path((0, 0), (5, 0), (10, 10), (5, 10))
    path2.add_bend(-np.pi, 40)

    coupler1 = GratingCoupler([100, 50], 0, 1, np.deg2rad(30), [10, 0.1, 2, 0.1, 2], start_radius_absolute=True)

    path3 = Waveguide((0, -50), np.deg2rad(0), 1)
    path3.add_bezier_to(coupler1.port.origin, coupler1.port.inverted_direction.angle, bend_strength=50)

    splitter2 = Splitter.make_at_left_branch_port(splitter.left_branch_port, 30, 10, wavelength_root=2)

    path4 = Waveguide.make_at_port(splitter2.root_port)
    path4.add_straight_segment(20)
    path4.width = 1
    path4.add_straight_segment(20)

    empty_path = Waveguide.make_at_port(path4.current_port)

    whole_layout = (path, splitter, path2, splitter2, coupler1, path3, path4, empty_path)

    layout = Cell('LIBRARY')
    cell = Cell('TOP')
    cell.add_to_layer(1, *whole_layout)
    cell.add_to_layer(2, empty_path)
    cell.add_to_layer(4, splitter.root_port.debug_shape)

    layout.add_cell(cell)

    cell_df = Cell('TOP_DF')
    cell_df.add_to_layer(1, convert_to_positive_resist(whole_layout, buffer_radius=1.5))
    layout.add_cell(cell_df)

    layout.save('output.gds')
    cell.show()
    def test_positive_resist(self):
        distance = 1e-3

        waveguide = Waveguide([0, 0], 0, 1)
        for i_bend in range(9):
            waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40)

        waveguide_positive = convert_to_positive_resist(waveguide, 1)

        self.assertFalse(waveguide.get_shapely_object().buffer(
            -distance).intersects(waveguide_positive))
        self.assertTrue(waveguide.get_shapely_object().buffer(
            distance).intersects(waveguide_positive))
        self.assertTrue(
            waveguide_positive.convex_hull.contains(
                waveguide.get_shapely_object()))
Beispiel #5
0
def IL_mmi(origin=(0, 0),
           len_in=500,
           radius=10,
           num_roundtrip=3,
           len_deltaL=250,
           w_etch=3):
    """
        total delta L =  4*len_delta_L * num_rountrip
        """
    # coupler_params = {
    # 'width': 0.45,
    # 'full_opening_angle': np.deg2rad(40),
    # 'grating_period': 0.64,
    # 'grating_ff': 0.546875,
    # 'n_gratings': 20,
    # 'taper_length': 16,
    # }
    mmi_params = {
        'length': 31.37,
        'width': 6,
        'taper_width': 2.9,
        'taper_length': 20,
    }
    # gc_start
    # gc_start = GratingCoupler.make_traditional_coupler(origin, angle=-np.pi, **coupler_params)
    # staright wg
    wg_start = Waveguide(origin, angle=0, width=0.5)
    wg_start.add_straight_segment(10)
    # mmi_in
    mmi_in = MMI.make_at_port(wg_start.port,
                              num_inputs=1,
                              num_outputs=2,
                              **mmi_params)
    # mmi_in.
    # len_in is the length of the input straight wg
    # len_out is the length of the out straight wg
    #
    # len_in = 500
    len_out = len_in
    # len_deltaL = 400
    # radius = 10
    gap = 10
    # num_roundtrip = 3
    # port 1
    wg1 = Waveguide.make_at_port(mmi_in.left_branch_port)
    wg1.add_straight_segment(len_in)
    i = 0
    while i < num_roundtrip:
        wg1.add_bend(np.pi, radius)
        wg1.add_straight_segment(len_deltaL)
        wg1.add_bend(-np.pi, radius)
        wg1.add_straight_segment(len_deltaL)
        i += 1
    wg1.add_straight_segment(6 * radius + 3 * gap)
    i = 0
    while i < num_roundtrip:
        wg1.add_straight_segment(len_deltaL)
        wg1.add_bend(-np.pi, radius)
        wg1.add_straight_segment(len_deltaL)
        wg1.add_bend(np.pi, radius)
        i += 1
    wg1.add_straight_segment(len_out)
    # port 2
    wg2 = Waveguide.make_at_port(mmi_in.right_branch_port)
    wg2.add_straight_segment(len_in + 2 * radius + gap)
    i = 0
    while i < num_roundtrip:
        wg2.add_bend(np.pi, radius)
        wg2.add_bend(-np.pi, radius)
        i += 1
    wg2.add_straight_segment(2 * radius + gap)
    i = 0
    while i < num_roundtrip:
        wg2.add_bend(-np.pi, radius)
        wg2.add_bend(np.pi, radius)
        i += 1
    wg2.add_straight_segment(len_out + 2 * radius + gap)
    # mmi_out
    mmi_out = MMI.make_at_port(wg1.port,
                               num_inputs=2,
                               num_outputs=1,
                               **mmi_params)
    # straight wg
    wg_end = Waveguide.make_at_port(mmi_out.right_branch_port)
    wg_end.add_straight_segment(10)

    # convert to positive resist
    layout = positive_resist.convert_to_positive_resist(
        [mmi_in, mmi_out, wg1, wg2, wg_end, wg_start],
        w_etch,
        outer_resolution=1e-3)

    gap = 10
    outer_corners = [
        origin, (origin[0], origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] - 2 * gap),
        (origin[0], origin[1] - 2 * gap)
    ]
    polygon1 = Polygon(outer_corners)
    origin = wg_end._current_port.origin
    print("End Point: ", origin)
    origin[0] = origin[0] + 2 * gap
    outer_corners = [
        origin, (origin[0], origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] + 2 * gap),
        (origin[0] - 2 * gap, origin[1] - 2 * gap),
        (origin[0], origin[1] - 2 * gap)
    ]
    polygon2 = Polygon(outer_corners)
    polygon = polygon1.union(polygon2)

    layout_fixed = layout.difference(polygon)

    return layout_fixed
Beispiel #6
0
    cell.add_to_layer(1, layout_fixed)


cell = Cell('CELL')
# spiral_with_coupler(cell, origin=(0,0), gap=3, num=10)
# spiral_with_coupler(cell, origin=(0,200), gap=3, num=15)
# spiral_with_coupler(cell, origin=(0,850), gap=3, num=64)

# coupler_coupler((0, -150))
# coupler_coupler((0, -300))
w_wg = 0.5
w_GC = 10
l_taper = 500
l_wg = 100
l_GC = 100
origin = 0
taperVector = [(origin, -w_wg / 2), (origin, w_wg / 2),
               (origin + l_taper, w_GC / 2),
               (origin + l_taper + l_GC, w_GC / 2),
               (origin + 2 * l_taper + l_GC, w_wg / 2),
               (origin + 2 * l_taper + l_GC, -w_wg / 2),
               (origin + l_taper + l_GC, -w_GC / 2),
               (origin + l_taper, -w_GC / 2), (origin, -w_wg / 2)]
taperGCTaper = Polygon(taperVector)
taperGCTaper2 = positive_resist.convert_to_positive_resist(
    [taperGCTaper], 3, outer_resolution=1e-3)
cell.add_to_layer(1, taperGCTaper2)

# _example()
cell.save("./taper.gds")
# cell.start_viewer()