def _example(): from gdshelpers.geometry import convert_to_gdscad import gdsCAD cell = gdsCAD.core.Cell('test') wg1 = Waveguide.make_at_port(Port((0, 0), 0, 1.)) wg1.add_straight_segment(100) ring1 = RingResonator.make_at_port(wg1.current_port, 1., 50., race_length=30, straight_feeding=True, draw_opposite_side_wg=True) wg2 = Waveguide.make_at_port(ring1.port) wg2.add_straight_segment(100) ring2 = RingResonator.make_at_port(wg2.current_port, 1., 50., vertical_race_length=30, straight_feeding=True, draw_opposite_side_wg=True) wg3 = Waveguide.make_at_port(ring2.port) wg3.add_straight_segment(100) ring3 = RingResonator.make_at_port(wg3.current_port, -1., 50., vertical_race_length=30, straight_feeding=True, draw_opposite_side_wg=True) cell.add(convert_to_gdscad([wg1, ring1, wg2, ring2, wg3, ring3], layer=1)) cell.show()
def _example(): from gdshelpers.geometry.chip import Cell cell = Cell('test') wg1 = Waveguide.make_at_port(Port((0, 0), 0, 1.)) wg1.add_straight_segment(100) ring1 = RingResonator.make_at_port(wg1.current_port, 1., 50., race_length=30, straight_feeding=True, draw_opposite_side_wg=True) wg2 = Waveguide.make_at_port(ring1.port) wg2.add_straight_segment(100) ring2 = RingResonator.make_at_port(wg2.current_port, 1., 50., vertical_race_length=30, straight_feeding=True, draw_opposite_side_wg=True) wg3 = Waveguide.make_at_port(ring2.port) wg3.add_straight_segment(100) ring3 = RingResonator.make_at_port(wg3.current_port, -1., 50., vertical_race_length=30, straight_feeding=True, draw_opposite_side_wg=True) cell.add_to_layer(1, wg1, ring1, wg2, ring2, wg3, ring3) cell.show()
def get_shapely_object(self): splitter1 = MMI(origin=self.origin, angle=self.angle, wg_width=self.width, length=self.splitter_length, width=self.splitter_width, num_inputs=1, num_outputs=2) print(splitter1.output_ports) upper_wg = Waveguide.make_at_port(splitter1.left_branch_port) upper_wg.add_bend(np.deg2rad(90), self.bend_radius) upper_wg.add_straight_segment(self.upper_vertical_length) upper_wg.add_bend(np.deg2rad(-90), self.bend_radius) upper_wg.add_straight_segment(self.horizontal_length) upper_wg.add_bend(np.deg2rad(-90), self.bend_radius) upper_wg.add_straight_segment(self.upper_vertical_length) upper_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg = Waveguide.make_at_port(splitter1.right_branch_port) lower_wg.add_bend(np.deg2rad(-90), self.bend_radius) lower_wg.add_straight_segment(self.lower_vertical_length) lower_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg.add_straight_segment(self.horizontal_length) lower_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg.add_straight_segment(self.lower_vertical_length) lower_wg.add_bend(np.deg2rad(-90), self.bend_radius) splitter2 = MMI(origin=[self.origin[0] + self.dev_width, self.origin[1]], angle=self.angle + np.pi, wg_width=self.width, length=self.splitter_length, width=self.splitter_width, num_inputs=1, num_outputs=2) print(splitter2.input_ports) return geometric_union([splitter1, splitter2, upper_wg, lower_wg])
def _example(): from gdshelpers.geometry.chip import Cell from gdshelpers.parts.port import Port from gdshelpers.parts.waveguide import Waveguide from gdshelpers.parts.mode_converter import StripToSlotModeConverter wg_1 = Waveguide.make_at_port( Port(origin=(0, 0), angle=0, width=1.2)) # scalar as width -> strip waveguide wg_1.add_straight_segment(5) mc_1 = StripToSlotModeConverter.make_at_port( wg_1.current_port, 5, [0.4, 0.2, 0.4], 2, 0.2) # array as width -> slot waveguide wg_2 = Waveguide.make_at_port(mc_1.out_port) wg_2.add_bend(angle=np.pi, radius=5) mc_2 = StripToSlotModeConverter.make_at_port( wg_2.current_port, 5, 1, 2, 0.2) # scalar as width -> strip waveguide wg_3 = Waveguide.make_at_port(mc_2.out_port) wg_3.add_straight_segment(5) cell = Cell('CELL') cell.add_to_layer(1, wg_1, mc_1, wg_2, mc_2, wg_3) cell.show()
def test_region_layers(self): cell = Cell("test_device") wg1 = Waveguide([0, 0], 0, 1) wg1.add_straight_segment(10) wg1_shapely = wg1.get_shapely_object() cell.add_to_layer(1, wg1) wg2 = Waveguide([40, 0], 0, 1) wg2.add_straight_segment(10) wg2_shapely = wg2.get_shapely_object() cell.add_to_layer(2, wg2) cell.add_region_layer(100) cell.add_region_layer(101, [1]) cell.add_region_layer(102, [1, 2]) self.assertTrue(100 in cell.layer_dict) self.assertTrue(cell.layer_dict[100][0].contains(wg1_shapely)) self.assertTrue(cell.layer_dict[100][0].contains(wg2_shapely)) self.assertTrue(101 in cell.layer_dict) self.assertTrue(cell.layer_dict[101][0].contains(wg1_shapely)) self.assertFalse(cell.layer_dict[101][0].contains(wg2_shapely)) self.assertTrue(102 in cell.layer_dict) self.assertTrue(cell.layer_dict[102][0].contains(wg1_shapely)) self.assertTrue(cell.layer_dict[102][0].contains(wg2_shapely))
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)
def _generate(self): tip_radius = 0.5 * (self.nano_wire_gap + self.nano_wire_width) nano_wire_port = self._origin_port \ .longitudinal_offset(self.nano_wire_length + tip_radius + self.passivation_buffer) \ .parallel_offset(tip_radius) self._nano_wire = Waveguide.make_at_port(nano_wire_port.inverted_direction, width=self.nano_wire_width) self._nano_wire.add_straight_segment(self.nano_wire_length - tip_radius) self._nano_wire.add_bend(np.pi, tip_radius) self._nano_wire.add_straight_segment(self.nano_wire_length - tip_radius) self._wings = [] for sign, port in [(1, self._nano_wire.current_port), (-1, self._nano_wire.in_port)]: wing_outer_port = port.longitudinal_offset(14).parallel_offset(-sign * 10).rotated(sign * 0.75 * np.pi) wing_outer_port.width = 5 wing_inner_port = wing_outer_port.longitudinal_offset(10) wing_inner_port.width = 0.5 self._wings.append(Waveguide.make_at_port(port) .add_bezier_to_port(port=wing_inner_port, bend_strength=2.5) .add_bezier_to_port(port=wing_outer_port, bend_strength=6) .add_straight_segment(1)) self._waveguide = Waveguide.make_at_port(self._origin_port) self._waveguide.add_straight_segment_until_level_of_port(self._wings[0].current_port.rotated(-0.75 * np.pi)) if self.waveguide_tapering: self._waveguide.add_straight_segment(5. * self._origin_port.width, final_width=0.01)
def example(): start_port = Port((0, 0), 0.5 * np.pi, 1.) wg1 = Waveguide.make_at_port(start_port) wg1.add_straight_segment(100.) # wg1.add_bend(0, 60.) detector = SNSPD.make_at_port(wg1.current_port, **snspd_parameters) wg = detector.get_waveguide() electrodes = detector.get_electrodes() pl = detector.get_passivation_layer(passivation_buffer=0.2) wg2 = Waveguide.make_at_port(detector.current_port) wg2.add_straight_segment(50.) # cell = gdsCAD.core.Cell('test') cell = Cell('test') cell.add_to_layer(3, Point(detector.get_aux_top()[0]).buffer(0.05)) cell.add_to_layer(4, Point(detector.get_aux_top()[1]).buffer(0.05)) cell.add_to_layer(3, Point(detector.get_aux_bottom()[0]).buffer(0.05)) cell.add_to_layer(4, Point(detector.get_aux_bottom()[1]).buffer(0.05)) cell.add_to_layer(3, wg1) cell.add_to_layer(1, detector) cell.add_to_layer(2, detector.get_waveguide()) cell.add_to_layer(6, detector.get_electrodes()) cell.add_to_layer(5, pl) # cell.add_to_layer(6, detector.right_electrode_port.debug_shape) # cell.add_to_layer(6, detector.left_electrode_port.debug_shape) cell.add_to_layer(3, wg2) cell.save('SNSPD_test.gds') cell.show()
def _generate(self): self.left_ports.append(Port(self._origin, self._angle, self._wg_width)) wg = Waveguide.make_at_port(self.left_ports[0]) wg.add_bend(angle=self._bend_angle, radius=self._bend_radius) wg.add_bend(angle=-self._bend_angle, radius=self._bend_radius) wg.add_straight_segment(self._length) wg.add_bend(angle=-self._bend_angle, radius=self._bend_radius) wg.add_bend(angle=self._bend_angle, radius=self._bend_radius) self._wgs.append(wg) self.right_ports.append(wg.current_port) self.left_ports.append(self.left_ports[0].parallel_offset( 4 * (self._bend_radius - np.cos(self._bend_angle) * self._bend_radius) + self._wg_width + self._gap)) wg = Waveguide.make_at_port(self.left_ports[1]) wg.add_bend(angle=-self._bend_angle, radius=self._bend_radius) wg.add_bend(angle=self._bend_angle, radius=self._bend_radius) wg.add_straight_segment(self._length) wg.add_bend(angle=self._bend_angle, radius=self._bend_radius) wg.add_bend(angle=-self._bend_angle, radius=self._bend_radius) self._wgs.append(wg) self.right_ports.append(wg.current_port) self.total_length = wg.length self.left_ports = [port.inverted_direction for port in self.left_ports]
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) ) )
def get_shapely_object(self): splitter1 = Splitter(self.origin, self.angle, self.splitter_length, self.width, self.splitter_separation) upper_wg = Waveguide.make_at_port(splitter1.left_branch_port) upper_wg.add_bend(np.deg2rad(90), self.bend_radius) upper_wg.add_straight_segment(self.upper_vertical_length) upper_wg.add_bend(np.deg2rad(-90), self.bend_radius) upper_wg.add_straight_segment(self.horizontal_length) upper_wg.add_bend(np.deg2rad(-90), self.bend_radius) upper_wg.add_straight_segment(self.upper_vertical_length) upper_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg = Waveguide.make_at_port(splitter1.right_branch_port) lower_wg.add_bend(np.deg2rad(-90), self.bend_radius) lower_wg.add_straight_segment(self.lower_vertical_length) lower_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg.add_straight_segment(self.horizontal_length) lower_wg.add_bend(np.deg2rad(90), self.bend_radius) lower_wg.add_straight_segment(self.lower_vertical_length) lower_wg.add_bend(np.deg2rad(-90), self.bend_radius) splitter2 = Splitter.make_at_right_branch_port(upper_wg.current_port, self.splitter_length, self.splitter_separation) return geometric_union([splitter1, splitter2, upper_wg, lower_wg])
def _example(): import gdsCAD.core from gdshelpers.geometry import convert_to_gdscad from gdshelpers.parts.waveguide import Waveguide mpsv2 = MultiPortSwitch(origin=[0, 0], angle=np.deg2rad(0.), in_ports=4, out_ports=7, port_spacing=10, taper_length=40, taper_function=lambda t: t * (1.0 - 0.05) + 0.05, radius=50., displacement=0., wg_bend_radius=40., minimal_final_spacing=20) wg = Waveguide([100, 100], np.pi / 4, 1) wg.add_straight_segment(100) # mpsv2_2 = MultiPortSwitch.make_at_out_port(wg.current_port, 3, # in_ports=2, out_ports=7, # port_spacing=10, # taper_length=10, taper_function=lambda t: t * (1.0 - 0.05) + 0.05, # radius=50., displacement=00., # wg_bend_radius=40., ) cell = gdsCAD.core.Cell('TEST') cell.add(convert_to_gdscad([ mpsv2, wg, ])) cell.show()
def test_route_to_port_functions(self): """ Test consistency of route functions of the Waveguide class. Verify that the port to be routed to points in the direction of the waveguide to route from. """ import numpy as np xmax = 200 start_port = Port([0, 0], 0.5 * np.pi, 1) target_port = Port([xmax, 200], 0, 1) wg1 = Waveguide.make_at_port(start_port) wg1.add_route_single_circle_to_port(target_port.inverted_direction) wg2 = Waveguide.make_at_port(start_port) wg2.add_bezier_to_port(target_port.inverted_direction, bend_strength=50) wg3 = Waveguide.make_at_port(start_port) wg3.add_route_straight_to_port(target_port.inverted_direction) # Check that they are all within the bounding box (to prevent routing from the wrong side) # (This would fail, for example, for add_bezier_to_port if routed to target_port instead of # target_port.inverted_direction, which both works) for wg in [wg1, wg2, wg3]: bounds = wg.get_shapely_object().bounds print(bounds) self.assertLessEqual(bounds[2], xmax)
def Ring_Test(label, gap, ring_r, ring_wg_width=wg_width): cell = Cell('Ring_Test' + label) r_bend = 60 #bend_r r_eff = r_bend / euler_to_bend_coeff outports = [Port((opt_space * i, 0), np.pi / 2, std_coupler_params['width']) for i in (0, 1)] gratingcouplers = [GratingCoupler.make_traditional_coupler_at_port(outport, **std_coupler_params) for outport in outports] port = outports[0].inverted_direction wg = Waveguide.make_at_port(port) wg.add_straight_segment(grating_added_taper_len, wg_width) # wgAdd_EulerBend(wg, np.pi / 2., r_eff, False) wg.add_bend(np.pi / 2., r_bend) dist_straight = opt_space - 2 * r_bend wg.add_straight_segment(dist_straight / 2.) ring_res = RingResonator.make_at_port(wg.current_port.inverted_direction, gap=gap, radius=ring_r, res_wg_width=ring_wg_width) wg.add_straight_segment(dist_straight / 2.) # wgAdd_EulerBend(wg, np.pi / 2., r_eff, False) wg.add_bend(np.pi / 2., r_bend) wg.add_straight_segment_until_y(outports[1].origin[1]-grating_added_taper_len) wg.add_straight_segment(grating_added_taper_len, std_coupler_params['width']) label_txt = Text((opt_space / 2., -6), 25, label, alignment='center-top') shapely_object = geometric_union(gratingcouplers + [label_txt] + [wg] + [ring_res]) cell.add_to_layer(wg_layer, shapely_object) comments = Text((60, 40), 10, 'gap={:.2f}\nrad={:.2f}\nwg_width={:.2f}'.format(gap, ring_r, ring_wg_width), alignment='center-top') cell.add_to_layer(comment_layer, comments) x_cords = [] y_cords = [] box_disty = 2 for this_poly in shapely_object.geoms: temp_x_cords, temp_y_cords = this_poly.exterior.coords.xy x_cords = x_cords + list(temp_x_cords) y_cords = y_cords + list(temp_y_cords) x_max = max(x_cords) + box_dist x_min = min(x_cords) - box_dist y_max = max(y_cords) + box_disty y_min = min(y_cords) - box_disty box_size = (x_max - x_min, y_max - y_min) box = Waveguide(((x_min + x_max) / 2., y_min), np.pi / 2, box_size[0]) box.add_straight_segment(box_size[1]) total_box = geometric_union([box]) cell.add_to_layer(wg_wf_layer, total_box) cell.add_to_layer(wg_reg_layer, total_box) return cell
def Efficiency_Grating(label, period, ff, grating_angle = None): cell = Cell('GC_Test' + label) r_bend = 60 #bend_r r_eff = r_bend / euler_to_bend_coeff coupler_params = std_coupler_params.copy() coupler_params['grating_period'] = period coupler_params['grating_ff'] = ff if grating_angle is not None: coupler_params['full_opening_angle'] = grating_angle outports = [Port((opt_space * i, 0), np.pi / 2, std_coupler_params['width']) for i in (0, 1)] gratingcouplers = [GratingCoupler.make_traditional_coupler_at_port(outport, **coupler_params) for outport in outports] port = outports[0].inverted_direction wg = Waveguide.make_at_port(port) wg.add_straight_segment(grating_added_taper_len, wg_width) wg.add_bend(np.pi / 2., r_bend) wg.add_straight_segment(opt_space - 2 * r_bend) wg.add_bend(np.pi / 2., r_bend) wg.add_straight_segment_until_y(outports[1].origin[1]-grating_added_taper_len) wg.add_straight_segment(grating_added_taper_len, std_coupler_params['width']) label_txt = Text((opt_space / 2., -6), 25, label, alignment='center-top') # self.shapely_object = geometric_union([wg] + [label] + gratingcouplers) shapely_object = geometric_union(gratingcouplers + [label_txt] + [wg]) cell.add_to_layer(wg_layer, shapely_object) comments = Text((60, 40), 10, 'period={:.2f}\nff={:.2f}'.format(coupler_params['grating_period'], coupler_params['grating_ff']), alignment='center-top') cell.add_to_layer(comment_layer, comments) x_cords = [] y_cords = [] box_disty = 2 # 2.5 * marker_dims for this_poly in shapely_object.geoms: temp_x_cords, temp_y_cords = this_poly.exterior.coords.xy x_cords = x_cords + list(temp_x_cords) y_cords = y_cords + list(temp_y_cords) x_max = max(x_cords) + box_dist x_min = min(x_cords) - box_dist y_max = max(y_cords) + box_disty y_min = min(y_cords) - box_disty box_size = (x_max - x_min, y_max - y_min) box = Waveguide(((x_min + x_max) / 2., y_min), np.pi / 2, box_size[0]) box.add_straight_segment(box_size[1]) total_box = geometric_union([box]) cell.add_to_layer(wg_wf_layer, total_box) cell.add_to_layer(wg_reg_layer, total_box) return cell
def grid_marker(size, port=Port((0, 0), 0, 1), offset=(0, 0), num_grid=10, space_grad=(1.5, 1.2), line_width=2, theta=(0 * pi, np.pi / 2)): """ Creates a square aperiodic grid marker used for alignment during transfer printing. :param size: integer value that determines the length of the grid marker's sides :param port: the imPORTant port in which the shape coordinates are based off. :param offset: the fixed distance away from the port that the grid is centred around. :param num_grid: integer number of horizontal and vertical grid lines :param space_grad: a tuple of form (a, b), a and b represent the gradient of the spacing between the grid lines :param line_width: thickness of the grid marker lines :param theta: leave as default, legacy feature that changes the angle of the grid lines, set as perpendicular. :return: returns a list containing the gridmarker shapely object and cartesian offset from the port it is based off Note: this behaviour is different from other functions in that is gives a local position rather than a global. """ origin = port.origin num_grid = fill_list(2, num_grid) spacing_x = np.linspace(0, size, num_grid[0]) spacing_y = np.linspace(0, size, num_grid[1]) spacing1 = spacing_y**space_grad[0] spacing1 = spacing1 / (np.max(spacing1) / size) spacing1 = spacing1 - (size / 2) + offset[1] + origin[1] spacing2 = spacing_x**space_grad[1] spacing2 = spacing2 / (np.max(spacing2) / size) spacing2 = spacing2 - (size / 2) + offset[0] + origin[0] grid = [] for num in range(0, np.size(spacing1)): temp_port = Port((offset[0] + origin[0] - (size / 2), spacing1[num]), angle=theta[0], width=line_width) wg_1 = Waveguide.make_at_port(temp_port) wg_1.add_straight_segment(size) wg_1 = wg_1.get_shapely_object() if num == 0: grid = wg_1 else: grid = grid.union(wg_1) for num in range(0, np.size(spacing2)): temp_port = Port((spacing2[num], offset[1] + origin[1] - (size / 2)), angle=theta[1], width=line_width) wg_1 = Waveguide.make_at_port(temp_port) wg_1.add_straight_segment(size) wg_1 = wg_1.get_shapely_object() grid = grid.union(wg_1) return grid, offset
def _generate(self): left = Port(self._origin, self._angle, self._wg_width) wg = Waveguide.make_at_port(left, width=self._width) wg.add_straight_segment(self._length) self._wgs.append(wg) right = wg.current_port input_positions, output_positions = self._calculate_positions( self.num_inputs, self.num_outputs) self._sep = input_positions[-1] - input_positions[0] for pos in input_positions: wg = Waveguide([ self._origin[0] - pos * self._width * np.sin(self._angle), self._origin[1] + pos * self._width * np.cos(self._angle) ], angle=self._angle - np.pi, width=self._taper_width) wg.add_straight_segment(self._taper_length, final_width=self._wg_width) self._wgs.append(wg) self.input_ports.append(wg.current_port) for pos in output_positions: wg = Waveguide([ right.origin[0] - pos * self._width * np.sin(self._angle), right.origin[1] + pos * self._width * np.cos(self._angle) ], angle=self._angle, width=self._taper_width) wg.add_straight_segment(self._taper_length, final_width=self._wg_width) self._wgs.append(wg) self.output_ports.append(wg.current_port)
def test_waveguide_construction(self): wg = Waveguide([0, 0], 0, 1) self.assertAlmostEqual(wg.length, 0) # Add straight waveguide wg.add_straight_segment(10) self.assertAlmostEqual(wg.x, 10) self.assertAlmostEqual(wg.y, 0) self.assertAlmostEqual(wg.angle, 0) self.assertAlmostEqual(wg.length, 10) # Add upwards 90 degree bend wg.add_bend(math.pi / 2, 5) self.assertAlmostEqual(wg.current_port.origin[0], 15) self.assertAlmostEqual(wg.current_port.origin[1], 5) self.assertAlmostEqual(wg.current_port.angle, math.pi / 2) self.assertAlmostEqual(wg.length_last_segment, math.pi / 2 * 5, delta=10e-5) # Add another arc, so that we are finally pointing 180 degree backwards wg.add_arc(math.pi, 5) self.assertAlmostEqual(wg.current_port.origin[0], 10) self.assertAlmostEqual(wg.current_port.origin[1], 10) self.assertAlmostEqual(abs(wg.current_port.angle), math.pi)
def test_waveguide_multiple_widths(self): widths = [1, 2, 1] wg = Waveguide([0, 0], 0, widths) wg.add_straight_segment(100) wg.add_parameterized_path(lambda t: [10 * t, t]) wg.get_shapely_object()
def example_cavity_harminv(): from gdshelpers.parts.waveguide import Waveguide from shapely.geometry import Point wg = Waveguide((-6, 0), 0, 1.2) start_port = wg.current_port wg.add_straight_segment(6) center_port = wg.current_port wg.add_straight_segment(6) wgs = [Waveguide.make_at_port(port).add_straight_segment(4) for port in [start_port.inverted_direction, wg.current_port]] holes = geometric_union( [Point(x * sign, 0).buffer(.36) for x in [1.4 / 2 + x * 1 for x in range(3)] for sign in [-1, 1]]) sim = Simulation(resolution=20, reduce_to_2d=True, padding=2, pml_thickness=1) sim.add_structure([wg.get_shapely_object().difference(holes)], wgs, mp.Medium(epsilon=13), z_min=0, z_max=.33) sim.add_source(mp.GaussianSource(wavelength=1 / .25, fwidth=.2), mp.Hz, center_port, z=0) sim.init_sim() sim.plot(fields=mp.Hz) mp.simulation.display_run_data = lambda *args, **kwargs: None harminv = mp.Harminv(mp.Hz, mp.Vector3(), .25, .2) sim.run(mp.after_sources(harminv._collect_harminv()(harminv.c, harminv.pt)), until_after_sources=300) sim.plot(fields=mp.Hz) print(harminv._analyze_harminv(sim.sim, 100))
def _example(): from gdshelpers.geometry.chip import Cell wg = Waveguide((0, 0), 1, 1) wg.add_straight_segment(30) spiral = Spiral.make_at_port(wg.current_port, 2, 5, 50) wg2 = Waveguide.make_at_port(spiral.out_port) wg2.add_straight_segment(100) print(spiral.length) cell = Cell('Spiral') cell.add_to_layer(1, wg, spiral, wg2) cell.show()
def example_bend_coupling(): from gdshelpers.parts.waveguide import Waveguide waveguide_straight = Waveguide((0, 0), 0, width=1) waveguide_straight.add_straight_segment(5) bend_port = waveguide_straight.current_port.parallel_offset(1.1) waveguides_bend_1 = Waveguide.make_at_port(bend_port) waveguides_bend_1.add_bend(angle=np.pi / 2, radius=15, n_points=30) waveguides_bend_2 = Waveguide.make_at_port(bend_port.inverted_direction) waveguides_bend_2.add_bend(angle=-np.pi / 5, radius=15, n_points=20) waveguide_straight.add_straight_segment(5) wgs = [ Waveguide.make_at_port(port).add_straight_segment(40) for port in [ waveguide_straight.in_port, waveguide_straight.current_port, waveguides_bend_1.current_port, waveguides_bend_2.current_port ] ] sim = Simulation(resolution=20, reduce_to_2d=True, padding=2, pml_thickness=.5) sim.add_structure([waveguide_straight, waveguides_bend_1], wgs + [waveguides_bend_2], mp.Medium(index=1.666), z_min=0, z_max=.33) # GaussianSource or ContinousSource source = sim.add_eigenmode_source( mp.ContinuousSource(wavelength=1.55, width=2), waveguide_straight.in_port.longitudinal_offset(1), z=0.33 / 2, height=1, eig_band=2) sim.init_sim(subpixel_maxeval=0) # subpixel_maxeval=0 for quick testing monitors_out = [ sim.add_eigenmode_monitor(port, 1.55, 2, 1, z=0.33 / 2, height=1) for port in [waveguide_straight.current_port, waveguides_bend_1.current_port] ] # sim.plot(mp.Hz) sim.run(until=150) sim.plot(mp.Hz) transmissions = [ np.abs( sim.get_eigenmode_coefficients(monitors_out[i], [2]).alpha[0, 0, 0])**2 / source.eig_power(1 / 1.55) for i in range(2) ] print('transmission in bus waveguide: {:.3f}'.format(transmissions[0])) print('transmission to bent waveguide: {:.3f}'.format(transmissions[1]))
def test_parallel_export(self): waveguide = Waveguide([0, 0], 0, 1) for i_bend in range(9): waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40) cells = [Cell('main')] for i in range(10): cell = Cell('sub_cell_' + str(i)) cell.add_to_layer(waveguide) cells[-1].add_cell(cell, (10, 10)) cells[0].save('serial.gds', library='gdshelpers', parallel=False) cells[0].save('parallel.gds', library='gdshelpers', parallel=True) self.assertTrue(filecmp.cmp('serial.gds', 'parallel.gds'))
def _example(): import gdsCAD.core from math import pi from gdshelpers.geometry import convert_to_gdscad from gdshelpers.parts.waveguide import Waveguide from gdshelpers.parts.coupler import GratingCoupler left_coupler = GratingCoupler.make_traditional_coupler_from_database( [0, 0], 1, 'sn330', 1550) wg = Waveguide.make_at_port(left_coupler.port) wg.add_straight_segment(length=10) wg.add_bend(-pi / 2, radius=50) wg.add_straight_segment(length=150) wg.add_bend(-pi / 2, radius=50) wg.add_straight_segment(length=10) right_coupler = GratingCoupler.make_traditional_coupler_from_database_at_port( wg.current_port, 'sn330', 1550) cell = gdsCAD.core.Cell('SIMPLE_DEVICE') cell.add(convert_to_gdscad([left_coupler, wg, right_coupler], layer=1)) cell.add( convert_to_gdscad([ left_coupler.get_description_text(side='right'), right_coupler.get_description_text(side='left') ], layer=2)) save_as_image(cell, '/tmp/test.png', resolution=1) save_as_image(cell, '/tmp/test.pdf') save_as_image(cell, '/tmp/test.svg')
def _generate(self): def path(a): return (self.num * (self.width + self.gap) * np.abs(1 - a) + self.inner_gap) * np.array((np.sin( np.pi * a * self.num), np.cos(np.pi * a * self.num))) self.wg_in = Waveguide.make_at_port(self._origin_port) self.wg_in.add_parameterized_path(path) self.wg_out = Waveguide.make_at_port( self._origin_port.inverted_direction) self.wg_out.add_parameterized_path(path) self.wg_in.add_route_single_circle_to_port( self._origin_port.rotated(-np.pi * (self.num % 2))) self.wg_in.add_route_single_circle_to_port(self.wg_out.port)
def add_dlw_taper_at_port(self, label, layer, port, taper_length, tip_width=.01, with_markers=True): """ Adds a taper for 3D-hybrid-integration at a certain port :param label: Name of the port, needs to be unique within the device :param layer: Layer at which the taper and markers should be written :param port: Port to which the taper should be attached :param taper_length: length of the taper :param tip_width: final width of the tip :param with_markers: for recognizing the taper markers near to the taper are necessary. In certain designs the standard positions are not appropriate and can therefore be disabled and manually added """ taper_port = port.longitudinal_offset(taper_length) if taper_length > 0: wg = Waveguide.make_at_port(port) wg.add_straight_segment(taper_length, final_width=tip_width) self.add_to_layer(layer, wg.get_shapely_object()) self.add_to_layer(std_layers.parnamelayer1, Text(taper_port.origin, 2, label, alignment='center-center')) self.add_dlw_data('taper', str(label), {'origin': taper_port.origin.tolist(), 'angle': port.angle, 'starting_width': port.width, 'taper_length': taper_length}) if with_markers: for i, (v, l) in enumerate(itertools.product((-20, 20), (taper_length, 0))): self.add_dlw_marker(str(label) + '-' + str(i), layer, port.parallel_offset(v).longitudinal_offset(l).origin)
def test_waveguide_add_route_straight_to_port(self): import numpy as np start_port = Port([0, 0], 0.5 * np.pi, 1) test_data = [(Port([10, 10], 0.5 * np.pi, 3), (10, 12)), (Port([10, 10], 0, 3), (12, 10)), (Port([10, 10], 0.25 * np.pi, 3), (10 + np.sqrt(2), 10 + np.sqrt(2)))] waveguides = [] for end_port, target_pos in test_data: wg = Waveguide.make_at_port(start_port) wg.add_straight_segment(2) wg.add_route_straight_to_port(end_port.inverted_direction) wg.add_straight_segment(2) waveguides.append(wg) self.assertAlmostEqual(wg.current_port.angle, end_port.angle) self.assertAlmostEqual(wg.current_port.width, end_port.width) self.assertAlmostEqual(wg.current_port.origin[0], target_pos[0]) self.assertAlmostEqual(wg.current_port.origin[1], target_pos[1]) # Enable to generate output """from gdshelpers.geometry.chip import Cell
def _example_iii(): from gdshelpers.parts.waveguide import Waveguide from gdshelpers.parts.coupler import GratingCoupler from gdshelpers.geometry import geometric_union import numpy as np coupler1 = GratingCoupler.make_traditional_coupler((250 / 2, 0), 1.3, np.deg2rad(40), 1.13, 0.85, 20, taper_length=16, ap_max_ff=0.985, n_ap_gratings=10) wave_guide = Waveguide.make_at_port(coupler1.port) wave_guide.add_straight_segment(20) wave_guide.add_bend(0.5 * np.pi, 40) wave_guide.add_straight_segment(250 - 2 * 40) wave_guide.add_bend(0.5 * np.pi, 40) wave_guide.add_straight_segment(20) coupler2 = GratingCoupler.make_traditional_coupler( (wave_guide.current_port.origin[0], wave_guide.current_port.origin[1]), 1.3, np.deg2rad(40), 1.13, 0.85, 20, taper_length=16, ap_max_ff=0.985, n_ap_gratings=10) shapely_objects = [ Shapely3d( geometric_union([ coupler1.get_shapely_object(), wave_guide.get_shapely_object(), coupler2.get_shapely_object() ]), 0.0, 0.7, (255, 255, 255)) ] render_image_and_save_as_blend(shapely_objects, "test_device_under_right", camera_position_y='under', camera_position_x='right') render_image_and_save_as_blend(shapely_objects, "test_device_above_left", camera_position_y='above', camera_position_x='left') render_image_and_save_as_blend(shapely_objects, "test_device_under_left", camera_position_y='under', camera_position_x='left') render_image_and_save_as_blend(shapely_objects, "test_device_above_right", camera_position_y='above', camera_position_x='right')
def _example(): from gdshelpers.geometry.chip import Cell devicename = 'MZI' mzi = MachZehnderInterferometer(origin=(0, 0), angle=0, width=1.2, splitter_length=10, splitter_separation=5, bend_radius=50, upper_vertical_length=50, lower_vertical_length=0, horizontal_length=0) mzi_mmi = MachZehnderInterferometerMMI(origin=(300, 0), angle=0, width=1.2, splitter_length=33, splitter_width=7.7, bend_radius=50, upper_vertical_length=50, lower_vertical_length=0, horizontal_length=0) print(mzi_mmi.device_width) wg = Waveguide.make_at_port(mzi_mmi.port) wg.add_straight_segment(length=50) cell = Cell(devicename) cell.add_to_layer(1, mzi) cell.add_to_layer(1, mzi_mmi) cell.add_to_layer(1, wg) cell.save('%s.gds' % devicename)
def _example(): import gdsCAD.core from gdshelpers.geometry import convert_to_gdscad dc = DirectionalCoupler((0, 0), np.pi / 4, 1, 10, 1, 10) dc2 = DirectionalCoupler.make_at_port(dc.right_ports[1], 5, 2, 10, which=0) wg = Waveguide.make_at_port(dc.left_ports[1]) wg.add_straight_segment(12) wg2 = Waveguide.make_at_port(dc2.right_ports[0]) wg2.add_straight_segment(12) mmi = MMI((80, 0), 0, 1, 20, 10, 2, 1) mmi2 = MMI.make_at_port(dc2.right_ports[1], 10, 10, 2, 2, 'i1') cell = gdsCAD.core.Cell('Splitter') cell.add(convert_to_gdscad(geometric_union((dc, dc2, wg, wg2, mmi, mmi2)))) cell.show()