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 _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 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 _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 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 _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 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 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 _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 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 _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 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 _example(): from gdshelpers.geometry.chip import Cell from gdshelpers.parts.waveguide import Waveguide from gdshelpers.parts.resonator import RingResonator # ==== create some sample structures (straight line with ring resonator) wg = Waveguide(origin=(0, 0), angle=np.deg2rad(-90), width=1) wg.add_straight_segment(length=5) wg.add_bend(np.pi / 2, 5) wg2 = Waveguide.make_at_port(wg.current_port) wg2.add_straight_segment(15) reso = RingResonator.make_at_port(port=wg2.current_port, gap=0.2, radius=5) wg2.add_straight_segment(length=15) coupler2 = GratingCoupler.make_traditional_coupler_from_database_at_port( wg2.current_port, db_id='si220', wavelength=1550) underetching_parts = geometric_union([wg2, reso, coupler2]) structure = geometric_union([underetching_parts, wg]) # create the holes with a radius of 0.5 microns, a distance of 2 microns to the structure borders and # a distance of 2 microns between the holes holes = create_holes_for_under_etching(underetch_parts=underetching_parts, complete_structure=structure, hole_radius=0.5, hole_distance=2, hole_spacing=3, hole_length=3) # create a cell with the structures in layer 1 and the holes in layer 2 cell = Cell('CELL') cell.add_to_layer(1, structure) cell.add_to_layer(2, holes) # Show the cell cell.show()
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 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 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_cavity(): 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(12) 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) sim.add_structure([wg.get_shapely_object().difference(holes)], wgs, mp.Medium(epsilon=13), z_min=0, z_max=.33) sim.add_eigenmode_source(mp.GaussianSource(wavelength=1 / .25, fwidth=.35), start_port, z=0.33 / 2, height=1, eig_band=2) sim.init_sim() monitors_out = [sim.add_eigenmode_monitor(port.longitudinal_offset(1), 1 / .25, .2, 500, z=0.33 / 2, height=1) for port in [start_port, wg.current_port.inverted_direction]] sim.plot(mp.Hz) sim.run(until=1500) sim.plot(mp.Hz) frequencies = np.array(mp.get_eigenmode_freqs(monitors_out[0])) transmissions = [np.abs(sim.get_eigenmode_coefficients(monitors_out[i], [2]).alpha[0, :, 0]) ** 2 for i in range(2)] plt.plot(frequencies, transmissions[1] / transmissions[0]) plt.show()
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 _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 _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 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 _generate(self): if not self.tapermode: width_func = lambda x: self.width restlength = 0 elif self.tapermode == 'quadratic': width_func = lambda x: (self.widthdiff) * ((1 - x) ** 2) + self.width restlength = self.devlen / 2 - self.taperlength wgcavl = Waveguide.make_at_port(self._center_portl) wgcavl.add_parameterized_path(path=lambda x: (self.taperlength * x, 0), width=width_func, sample_points=self.samplepoints, sample_distance=None) wgcavl.add_straight_segment(length=restlength) self.leftport = wgcavl.current_port wgcavr = Waveguide.make_at_port(self._center_portr) wgcavr.add_parameterized_path(path=lambda x: (self.taperlength * x, 0), width=width_func, sample_points=self.samplepoints, sample_distance=None) wgcavr.add_straight_segment(length=restlength) self.rightport = wgcavr.current_port positionl = [self.origin[0] - (self.lenofcav + self.holediameters[0]) / 2 * np.cos(self.angle), self.origin[1] - (self.lenofcav + self.holediameters[0]) / 2 * np.sin(self.angle)] positionr = [self.origin[0] + (self.lenofcav + self.holediameters[0]) / 2 * np.cos(self.angle), self.origin[1] + (self.lenofcav + self.holediameters[0]) / 2 * np.sin(self.angle)] wgcavl = wgcavl.get_shapely_object() wgcavr = wgcavr.get_shapely_object() pointsl = Point(positionl).buffer(distance=self.holediameters[0] / 2) wgcavl = wgcavl.difference(pointsl) pointsr = Point(positionr).buffer(distance=self.holediameters[0] / 2) self.allholes.append(pointsl) self.allholes.append(pointsr) wgcavr = wgcavr.difference(pointsr) for i in range(1, self.numberofholes - 1): positionl = [positionl[0] - self.holedistances[i] * np.cos(self.angle), positionl[1] - self.holedistances[i] * np.sin(self.angle)] pointsl = Point(positionl).buffer(distance=self.holediameters[i + 1] / 2) self.allholes.append(pointsl) wgcavl = wgcavl.difference(pointsl) positionr = [positionr[0] + self.holedistances[i] * np.cos(self.angle), positionr[1] + self.holedistances[i] * np.sin(self.angle)] pointsr = Point(positionr).buffer(distance=self.holediameters[i + 1] / 2) self.allholes.append(pointsr) wgcavr = wgcavr.difference(pointsr) self.layer_photonic_cavity.extend([wgcavl, wgcavr])
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()
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 get_shapely_object(self): wg = Waveguide.make_at_port(self._origin_port) opposite_wg = Waveguide.make_at_port( self.opposite_side_port_in.inverted_direction) if self.straight_feeding: wg.add_straight_segment(self.radius) if self.draw_opposite_side_wg: opposite_wg.add_straight_segment(self.radius) ring_port = wg.current_port.parallel_offset(self._offset) ring_port.width = self.res_wg_width ring = Waveguide.make_at_port(ring_port) if self.race_length: wg.add_straight_segment(self.race_length) if self.draw_opposite_side_wg: opposite_wg.add_straight_segment(self.race_length) if self.straight_feeding: wg.add_straight_segment(self.radius) if self.draw_opposite_side_wg: opposite_wg.add_straight_segment(self.radius) # Build the ring bend_angle = math.copysign(0.5 * np.pi, self.gap) if self.race_length: ring.add_straight_segment(self.race_length) ring.add_bend(bend_angle, self.radius, n_points=self.points) if self.vertical_race_length: ring.add_straight_segment(self.vertical_race_length) ring.add_bend(bend_angle, self.radius, n_points=self.points) if self.race_length: ring.add_straight_segment(self.race_length) ring.add_bend(bend_angle, self.radius, n_points=self.points) if self.vertical_race_length: ring.add_straight_segment(self.vertical_race_length) ring.add_bend(bend_angle, self.radius, n_points=self.points) return geometric_union([ring, wg, opposite_wg])
def generate_bunch_of_guides(number_of_lines, line_widths, length): guides = Cell('guides') line_widths = iop.fill_list(number_of_lines, line_widths, sorting='ascending') for y in range(0, number_of_lines): guide = Waveguide.make_at_port(Port((0, y*5), 0, line_widths[y])) guide.add_straight_segment(length) guides.add_to_layer(1, guide) return guides
def _make_waveguide(self): wg = Waveguide.make_at_port(self._origin_port) wg.add_bezier_to_port(self._cnt_port.inverted_direction, 3, sample_distance=self.sample_distance) wg.add_bezier_to_port(self._out_port.inverted_direction, 3, sample_distance=self.sample_distance) self.waveguide.append(wg)