Source code for qpdk.samples.cpw_jpa_chip

# /// script
# requires-python = ">=3.12,<3.15"
# dependencies = [
#   "qpdk[models] @ git+https://github.com/gdsfactory/quantum-rf-pdk.git",
# ]
# ///

r"""Flux-driven CPW JPA chip with signal and pump launchers.

A flux-driven :math:`\lambda/4` CPW Josephson parametric amplifier following
:cite:`yamamotoFluxdrivenJosephsonParametric2008`: an interdigital capacitor
couples the signal into a meandered :math:`\lambda/4` line that is shorted to
ground through a DC SQUID, and a shorted CPW pump line next to the SQUID loop
modulates the flux. The static flux bias comes from an off-chip coil. The
coupling and critical current follow the WMI devices of
:cite:`pogorzalekHystereticFluxResponse2017`.

Running this script writes the chip GDS and prints the SAX resonance of the
full chip netlist against flux.
"""

import gdsfactory as gf

from qpdk.cells.launcher import launcher
from qpdk.cells.parametric_amplifier import cpw_jpa
from qpdk.tech import route_bundle_cpw


[docs] @gf.cell(tags=["samples", "resonators", "junctions"]) def cpw_jpa_chip( signal_route_length: float = 800.0, pump_route_length: float = 800.0, ) -> gf.Component: """Flux-driven CPW JPA with launchers on the signal and pump lines. Args: signal_route_length: Distance in µm between the signal launcher and the JPA signal port. pump_route_length: Distance in µm between the pump launcher and the JPA pump port. Returns: Component: The chip with the signal launcher waveport ``o1`` and the pump launcher waveport ``o2``. """ c = gf.Component() jpa_ref = c.add_ref(cpw_jpa(), name="jpa") signal_port = jpa_ref.ports["o1"] pump_port = jpa_ref.ports["o2"] signal_launcher_ref = c.add_ref(launcher(), name="signal_launcher") signal_launcher_ref.dmove(( signal_port.dx - signal_route_length - signal_launcher_ref.ports["o1"].dx, signal_port.dy - signal_launcher_ref.ports["o1"].dy, )) pump_launcher_ref = c.add_ref(launcher(), name="pump_launcher") pump_launcher_ref.drotate(90) pump_launcher_ref.dmove(( pump_port.dx - pump_launcher_ref.ports["o1"].dx, pump_port.dy - pump_route_length - pump_launcher_ref.ports["o1"].dy, )) for name, launcher_ref, port in ( ("signal_route", signal_launcher_ref, signal_port), ("pump_route", pump_launcher_ref, pump_port), ): existing_names = {instance.name for instance in c.insts} route_bundle_cpw(c, ports1=[launcher_ref.ports["o1"]], ports2=[port]) (route_ref,) = (i for i in c.insts if i.name not in existing_names) route_ref.name = name c.add_port("o1", port=signal_launcher_ref.ports["waveport"]) c.add_port("o2", port=pump_launcher_ref.ports["waveport"]) c.info.update({f"jpa_{k}": v for k, v in jpa_ref.cell.info.model_dump().items()}) return c
if __name__ == "__main__": import jax.numpy as jnp import sax from qpdk import PATH, PDK, logger from qpdk.models import models from qpdk.models.constants import Φ_0 PDK.activate() chip = cpw_jpa_chip() gds_path = chip.write_gds(PATH.gds / "cpw_jpa_chip.gds") logger.info(f"Wrote {gds_path}") # The SQUID flux is an instance override of the JPA's termination model. circuit, _ = sax.circuit(chip.get_netlist(recursive=True), models=models) f = jnp.linspace(5.5e9, 6.5e9, 20001) for flux in (0.0, 0.2, 0.3, 0.4): s11 = circuit(f=f, jpa={"squid_termination": {"flux": flux * Φ_0}})["o1", "o1"] # The reflection phase turns fastest at resonance. phase_slope = jnp.abs(jnp.diff(jnp.unwrap(jnp.angle(s11)))) logger.info(f"Φ = {flux:.1f} Φ0: f0 = {f[phase_slope.argmax()] / 1e9:.3f} GHz") chip.show()