def render_junction_inductor(self, qgeom: pd.Series, xmin: float, xmax: float, ymin: float, ymax: float, z: float, axis: str): """ Render a junction as an inductor with a bounding box given by xmin/xmax and ymin/ymax, a height z, and a horizontal or vertical axis. Args: qgeom (pd.Series): GeoSeries of element properties. xmin (float): Smallest x coordinate xmax (float): Largest x coordinate ymin (float): Smallest y coordinate ymax (float): Largest y coordinate z (float): z coordinate axis (str): Orientation, either 'x' or 'y' """ ansys_options = dict(transparency=0.0) qcomp = self.design._components[qgeom['component']].name qc_elt = get_clean_name(qgeom['name']) qc_name = 'Lj_' + qcomp inductor_name = f'{qc_name}{QAnsysRenderer.NAME_DELIM}{qc_elt}' # Draw rectangle for inductor. self.logger.debug(f'Drawing a rectangle: {inductor_name}') poly_ansys = self.modeler.draw_rect_corner([xmin, ymin, z], xmax - xmin, ymax - ymin, z, **ansys_options) poly_ansys.make_rlc_boundary(axis, l=qgeom['hfss_inductance'], c=qgeom['hfss_capacitance'], r=qgeom['hfss_resistance'], name='Lj_' + inductor_name) self.modeler.rename_obj(poly_ansys, 'JJ_rect_' + inductor_name) self.assign_mesh.append('JJ_rect_' + inductor_name) # Draw line for inductor. if axis == 'x': ymid = (ymin + ymax) / 2 start, end = [xmin, ymid, z], [xmax, ymid, z] elif axis == 'y': xmid = (xmin + xmax) / 2 start, end = [xmid, ymin, z], [xmid, ymax, z] induc_line = self.modeler.draw_polyline([start, end], closed=False, **dict(color=(128, 0, 128))) induc_line = induc_line.rename('JJ_' + inductor_name + '_') induc_line.show_direction = True
def render_junction_port(self, qgeom: pd.Series, xmin: float, xmax: float, ymin: float, ymax: float, z: float, axis: str): """ Render a junction as a port with a bounding box given by xmin/xmax and ymin/ymax, a height z, and a horizontal or vertical axis. Args: qgeom (pd.Series): GeoSeries of element properties. xmin (float): Smallest x coordinate xmax (float): Largest x coordinate ymin (float): Smallest y coordinate ymax (float): Largest y coordinate z (float): z coordinate axis (str): Orientation, either 'x' or 'y' """ ansys_options = dict(transparency=0.0) qcomp = self.design._components[qgeom['component']].name qc_elt = get_clean_name(qgeom['name']) port_name = f'Port_{qcomp}_{qc_elt}' impedance = self.jj_lumped_ports[(qcomp, qc_elt)][0] # Draw rectangle for lumped port. self.logger.debug(f'Drawing a rectangle: {port_name}') poly_ansys = self.modeler.draw_rect_corner([xmin, ymin, z], xmax - xmin, ymax - ymin, z, **ansys_options) poly_ansys.make_lumped_port(axis, z0=str(impedance) + 'ohm', name=f'LumpPort_{qcomp}_{qc_elt}') self.modeler.rename_obj(poly_ansys, port_name) # Draw line for lumped port. if axis == 'x': ymid = (ymin + ymax) / 2 start, end = [xmin, ymid, z], [xmax, ymid, z] elif axis == 'y': xmid = (xmin + xmax) / 2 start, end = [xmid, ymin, z], [xmid, ymax, z] lump_line = self.modeler.draw_polyline([start, end], closed=False, **dict(color=(128, 0, 128))) lump_line = lump_line.rename(f'voltage_line_{port_name}') lump_line.show_direction = True
def test_renderer_ansys_renderer_get_clean_name(self): """Test get_clean_name in ansys_renderer.py""" self.assertEqual(ansys_renderer.get_clean_name('name12'), 'name12') self.assertEqual(ansys_renderer.get_clean_name('12name12'), 'name12') self.assertEqual(ansys_renderer.get_clean_name('name!'), 'name')
def render_element_junction(self, qgeom: pd.Series): """ Render a Josephson junction depending on the solution type. If in HFSS eigenmode, junctions are rendered as inductors consisting of 1. A rectangle of length pad_gap and width inductor_width. Defines lumped element RLC boundary condition. 2. A line that is later used to calculate the voltage in post-processing analysis. If in HFSS driven modal, junctions can be inductors, lumped ports, both inductors and lumped ports, or omitted altogether. Ports are characterized by an impedance value given in the list jj_to_port when render_design() is called. Args: qgeom (pd.Series): GeoSeries of element properties. """ qcomp = self.design._components[qgeom['component']].name qc_elt = get_clean_name(qgeom['name']) if (qcomp, qc_elt) not in self.jj_to_ignore: qc_shapely = qgeom.geometry qc_chip_z = parse_units(self.design.get_chip_z(qgeom.chip)) qc_width = parse_units(qgeom.width) endpoints = parse_units(list(qc_shapely.coords)) endpoints_3d = to_vec3D(endpoints, qc_chip_z) x0, y0, z0 = endpoints_3d[0] x1, y1, z0 = endpoints_3d[1] if abs(y1 - y0) > abs(x1 - x0): # Junction runs vertically up/down axis = 'y' x_min, x_max = x0 - qc_width / 2, x0 + qc_width / 2 y_min, y_max = min(y0, y1), max(y0, y1) else: # Junction runs horizontally left/right axis = 'x' x_min, x_max = min(x0, x1), max(x0, x1) y_min, y_max = y0 - qc_width / 2, y0 + qc_width / 2 if (qcomp, qc_elt) in self.jj_lumped_ports: if self.jj_lumped_ports[(qcomp, qc_elt)][1]: # Draw both port and inductor side by side with small gap in between gap = parse_units(self.hfss_options['port_inductor_gap']) x_mid, y_mid = (x_min + x_max) / 2, (y_min + y_max) / 2 if axis == 'x': y_mid_hi = y_mid + gap / 2 y_mid_lo = y_mid - gap / 2 self.render_junction_port(qgeom, x_min, x_max, y_mid_hi, y_max, qc_chip_z, axis) self.render_junction_inductor(qgeom, x_min, x_max, y_min, y_mid_lo, qc_chip_z, axis) elif axis == 'y': x_mid_lo = x_mid - gap / 2 x_mid_hi = x_mid + gap / 2 self.render_junction_port(qgeom, x_mid_hi, x_max, y_min, y_max, qc_chip_z, axis) self.render_junction_inductor(qgeom, x_min, x_mid_lo, y_min, y_max, qc_chip_z, axis) else: # Only draw port self.render_junction_port(qgeom, x_min, x_max, y_min, y_max, qc_chip_z, axis) else: # Only draw inductor self.render_junction_inductor(qgeom, x_min, x_max, y_min, y_max, qc_chip_z, axis)