Source code for kqcircuits.simulations.waveguides_sim

# This code is part of KQCircuits
# Copyright (C) 2022 IQM Finland Oy
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program. If not, see
# https://www.gnu.org/licenses/gpl-3.0.html.
#
# The software distribution should follow IQM trademark policy for open-source software
# (meetiqm.com/iqm-open-source-trademark-policy). IQM welcomes contributions to the code.
# Please see our contribution agreements for individuals (meetiqm.com/iqm-individual-contributor-license-agreement)
# and organizations (meetiqm.com/iqm-organization-contributor-license-agreement).

from kqcircuits.simulations.simulation import Simulation
from kqcircuits.simulations.port import EdgePort
from kqcircuits.pya_resolver import pya
from kqcircuits.util.parameters import Param, pdt
from kqcircuits.elements.waveguide_coplanar import WaveguideCoplanar
from kqcircuits.elements.flip_chip_connectors.flip_chip_connector_dc import FlipChipConnectorDc


[docs] class WaveGuidesSim(Simulation): cpw_length = Param(pdt.TypeDouble, "Waveguide length", 100, unit="μm") n_guides = Param(pdt.TypeInt, "Number of guides", 5) spacing = Param(pdt.TypeDouble, "Parallel spacing", 100, unit="μm") guide_face_id = Param(pdt.TypeString, "Guide face id", "1t1") add_bumps = Param(pdt.TypeBoolean, "Add ground bumps", False) port_termination_end = Param(pdt.TypeBoolean, "Port termination end", True) use_edge_ports = Param(pdt.TypeBoolean, "Use edge ports", True) etch_whole_opposite_face = Param(pdt.TypeBoolean, "Remove the whole opposite face metal if flip chip", False)
[docs] def build(self): self.produce_guides() if self.add_bumps: self.produce_ground_bumps()
[docs] def produce_guides(self): cpw_length = self.cpw_length n_guides = self.n_guides a = self.a b = self.b spacing = self.spacing tot_y = (n_guides - 1) * spacing guide_face_id = self.guide_face_id face_id = {f: i for i, f in enumerate(self.face_ids)} for i in range(n_guides): y_pos = i * spacing - tot_y / 2.0 p1 = pya.DPoint(-cpw_length / 2, y_pos) p2 = pya.DPoint(cpw_length / 2.0, y_pos) p0 = pya.DPoint(0, y_pos) # waveguide_cell = self.add_element(WaveguideCoplanar, path=pya.DPath([p1, p2], 0), # face_ids=[guide_face_id]) if self.use_edge_ports: wg_cell = self.add_element( WaveguideCoplanar, path=pya.DPath([p1, p2], 0), term1=0, term2=0, face_ids=[guide_face_id] ) self.insert_cell(wg_cell) self.ports.append(EdgePort(i + 1, p1, face=face_id[guide_face_id])) if self.port_termination_end: self.ports.append(EdgePort(n_guides + i + 1, p2, face=face_id[guide_face_id])) else: if self.port_termination_end: self.produce_waveguide_to_port( p0, p1, i + 1, waveguide_length=cpw_length / 2.0, a=a, b=b, face=face_id[guide_face_id] ) self.produce_waveguide_to_port( p0, p2, n_guides + i + 1, waveguide_length=cpw_length / 2.0, a=a, b=b, face=face_id[guide_face_id], ) else: self.produce_waveguide_to_port( p0, p1, i + 1, waveguide_length=cpw_length / 2.0, a=a, b=b, face=face_id[guide_face_id] ) wg_cell = self.add_element( WaveguideCoplanar, path=pya.DPath([p0, p2], 0), term1=0, term2=self.b, face_ids=[guide_face_id] ) self.insert_cell(wg_cell) if self.etch_whole_opposite_face: region = pya.Region(self.box.to_itype(self.layout.dbu)) self.cell.shapes(self.get_layer("base_metal_gap_wo_grid", face_id=1)).insert(region)
[docs] def produce_ground_bumps(self): n_guides = self.n_guides spacing = self.spacing tot_y = (n_guides - 1) * spacing bump = self.add_element(FlipChipConnectorDc) for i in range(n_guides - 1): y_pos = i * spacing - tot_y / 2.0 + spacing / 2.0 self.insert_cell(bump, pya.DCplxTrans(1, 0, False, pya.DVector(0, y_pos)))