Esempio n. 1
0
    def init_sim(self, **kwargs):
        """
        Initializes the simulation. This has to be done after adding all structures in order to correctly determine the
        size of the simulation.

        :param kwargs: Parameters which are directly passed to Meep
        """
        z_min = np.min([
            structure['z_min'] for structure in self.structures
            if structure['structure']
        ])
        z_max = np.max([
            structure['z_max'] for structure in self.structures
            if structure['structure']
        ])

        bounds = geometric_union(
            (geometric_union(x['structure']) for x in self.structures)).bounds
        size = np.array(
            (bounds[2] - bounds[0], bounds[3] - bounds[1], (z_max - z_min)))
        self.center = np.round([(bounds[2] + bounds[0]) / 2,
                                (bounds[3] + bounds[1]) / 2,
                                (z_max + z_min) / 2])
        self.size = np.ceil(size + self.padding * 2 + self.pml_thickness * 2)
        if self.reduce_to_2d:
            self.center[2] = self.size[2] = 0

        structures = []
        for structure in self.structures:
            polygon = geometric_union(structure['structure'] + structure['extra_structures']) \
                .buffer(np.finfo(np.float32).eps, resolution=0).simplify(np.finfo(np.float32).eps)
            objs = shapely_collection_to_basic_objs(polygon)

            for obj in objs:
                if obj.is_empty:
                    continue
                for polygon in fracture_intelligently(obj, np.inf, np.inf):
                    structures += [
                        mp.Prism(vertices=[
                            mp.Vector3(
                                *point,
                                0 if self.reduce_to_2d else structure['z_min'])
                            for point in polygon.exterior.coords[:-1]
                        ],
                                 material=structure['material'],
                                 height=structure['z_max'] -
                                 structure['z_min'])
                    ]

        self.sim = mp.Simulation(mp.Vector3(*self.size),
                                 self.resolution,
                                 geometry=structures,
                                 geometry_center=mp.Vector3(*self.center),
                                 sources=self.sources,
                                 boundary_layers=[mp.PML(self.pml_thickness)],
                                 **kwargs)
        self.sim.init_sim()
Esempio n. 2
0
def create_holes_for_under_etching(underetch_parts,
                                   complete_structure,
                                   hole_radius,
                                   hole_distance,
                                   hole_spacing,
                                   hole_length=0,
                                   cap_style='round'):
    """
    Creates holes around given parts which can be used for underetching processes

    :param underetch_parts: List of gdshelpers parts around which the holes shall be placed
    :param complete_structure: geometric union of the complete structure, needed to avoid collisions between
        underetching holes and other structures, e.g. waveguides
    :param hole_radius: Radius of the holes in microns
    :param hole_distance: Distance between the holes edges from the the structures in microns
    :param hole_spacing: Distance between the holes in microns
    :param hole_length: Length of the holes (if 0 creates circles, else rectangle like)
    :param cap_style: CAP_STYLE of the holes (i.e. 'round' or 'square', see Shapely Docs)
    :return: Geometric union of the created holes
    """
    cap_style = {
        'round': CAP_STYLE.round,
        'square': CAP_STYLE.square
    }[cap_style]
    union = geometric_union(underetch_parts)
    no_hole_zone = complete_structure.buffer(0.9 *
                                             (hole_distance + hole_radius),
                                             resolution=32,
                                             cap_style=3)
    poly = union.buffer(hole_distance + hole_radius,
                        resolution=32,
                        cap_style=CAP_STYLE.square)

    base_polygon = shapely_adapter.shapely_collection_to_basic_objs(poly)

    holes = []
    for obj in base_polygon:
        for interior in [obj.exterior] + list(obj.interiors):
            dist = 0
            while dist < interior.length:
                if hole_length == 0:
                    hole = interior.interpolate(distance=dist)
                    dist += hole_spacing + 2 * hole_radius
                else:
                    positions = [
                        interior.interpolate(distance=d) for d in np.linspace(
                            dist - hole_length / 2 + hole_radius, dist +
                            hole_length / 2 - hole_radius, 10)
                    ]
                    dist += hole_spacing + hole_length

                    hole = LineString(positions)
                if not no_hole_zone.contains(hole):
                    holes.append(hole.buffer(hole_radius, cap_style=cap_style))

    return geometric_union(holes)
Esempio n. 3
0
 def __init__(self,
              poly,
              extrude_val_min,
              extrude_val_max,
              rgb=(255, 255, 255)):
     if type(poly) in (list, tuple):
         self.poly = shapely_adapter.geometric_union(poly)
     self.poly = shapely_adapter.shapely_collection_to_basic_objs(poly)
     self.rgb = rgb
     self.extrude_val_min = extrude_val_min
     self.extrude_val_max = extrude_val_max
Esempio n. 4
0
 def get_fractured_layer_dict(self, max_points=4000, max_line_points=4000):
     from gdshelpers.geometry.shapely_adapter import shapely_collection_to_basic_objs, fracture_intelligently
     fractured_layer_dict = {}
     for layer, geometries in self.layer_dict.items():
         fractured_geometries = []
         for geometry in geometries:
             geometry = geometry.get_shapely_object() if hasattr(geometry, 'get_shapely_object') else geometry
             if type(geometry) in [list, tuple]:
                 geometry = geometric_union(geometry)
             geometry = shapely_collection_to_basic_objs(geometry)
             geometry = itertools.chain(
                 *[fracture_intelligently(geo, max_points, max_line_points) for geo in geometry if not geo.is_empty])
             fractured_geometries.append(geometry)
         fractured_layer_dict[layer] = itertools.chain(*fractured_geometries)
     return fractured_layer_dict
Esempio n. 5
0
def create_holes_for_under_etching(underetch_parts, complete_structure,
                                   hole_radius, hole_distance, hole_spacing):
    """
    Creates holes around given parts which can be used for underetching processes

    :param underetch_parts: List of gdshelpers parts around which the holes shall be placed
    :param complete_structure: geometric union of the complete structure, needed to avoid collisions between
        underetching holes and other structures, e.g. waveguides
    :param hole_radius: Radius of the holes in microns
    :param hole_distance: Distance of the holes center from the the structures in microns
    :param hole_spacing: Distance between the holes in microns
    :return: Geometric union of the created holes
    """

    union = geometric_union(underetch_parts)
    no_hole_zone = complete_structure.buffer(0.9 * hole_distance,
                                             resolution=32,
                                             cap_style=3)
    poly = union.buffer(hole_distance, resolution=32, cap_style=3)

    base_polygon = shapely_adapter.shapely_collection_to_basic_objs(poly)

    holes = []
    for obj in base_polygon:
        ext = obj.exterior
        for dist in np.arange(0, ext.length, hole_spacing):
            pos = ext.interpolate(distance=dist)
            if not no_hole_zone.contains(pos):
                holes.append(pos.buffer(hole_radius))
        for interior in obj.interiors:
            for dist in np.arange(0, interior.length, hole_spacing):
                pos = interior.interpolate(distance=dist)
                if not no_hole_zone.contains(pos):
                    holes.append(pos.buffer(hole_radius))

    return geometric_union(holes)