Source code for qnngds.devices.diode

"""Layout for superconducting diode `[1] <https://doi.org/10.1038/s41928-025-01376-4>`_."""

# can be removed in python 3.14, see https://peps.python.org/pep-0749/
from __future__ import annotations

import qnngds as qg


import numpy as np

from functools import partial

from qnngds.typing import LayerSpec, DeviceSpec
from qnngds import Device


[docs]@qg.device def basic( width: float = 2, notch_depth: float = 1, notch_angle: float = 90, length: float = 5, mirror: bool = False, layer: LayerSpec = (1, 0), ) -> Device: """Create notched vortex diode on single layer Args: width (float): wire width in microns notch_depth (float): amount notch protrudes into wire notch_angle (float): angle of notch opening in degrees length (float): length of device mirror (bool): if True, place notch on left side layer (LayerSpec): GDS layer specification Returns: (Device): the diode """ DIODE = Device("diode_basic") points = [ (-width, -length / 2), (0, -length / 2), (0, -notch_depth * np.sin(notch_angle / 2)), (-notch_depth, 0), (0, notch_depth * np.sin(notch_angle / 2)), (0, length / 2), (-width, length / 2), ] DIODE.add_polygon(points, layer=layer) DIODE.move((DIODE.x + width / 2 - notch_depth, DIODE.y), (0, 0)) DIODE.add_port( name=1, midpoint=(DIODE.x, length / 2), width=width, orientation=90, layer=layer, ) DIODE.add_port( name=2, midpoint=(DIODE.x, -length / 2), width=width, orientation=270, layer=layer, ) return DIODE
[docs]@qg.device def gated( channel_spec: DeviceSpec = basic, gate_spec: DeviceSpec = partial( qg.geometries.optimal_hairpin, width=2, pitch=4, turn_ratio=2, layer=(10, 0), ), ) -> Device: """Create notched vortex diode with a gate. Lateral offset of the gate can be done by first offsetting the gate before passing it as an argument to this function. Args: channel_spec (DeviceSpec): what to use for diode channel (e.g. diode.basic) gate_spec (DeviceSpec): what to use for top gate (e.g. geometries.optimal_hairpin) Returns: (Device): the gated diode """ DIODE = Device("diode_gated") channel = DIODE << qg.get_device(channel_spec) gate = DIODE << qg.get_device(gate_spec) gate.movex(channel.ports[1].width / 2) for n, port_name in enumerate(channel.ports): DIODE.add_port(name=f"c{n + 1}", port=channel.ports[port_name]) for n, port_name in enumerate(gate.ports): DIODE.add_port(name=f"g{n + 1}", port=gate.ports[port_name]) return DIODE