Transmon

[1]:
import numpy as np
import matplotlib.pyplot as plt

from bfqcircuits.core import transmon as trm
[2]:
transmon = trm.Transmon()
fig = transmon.draw_circuit()
fig = transmon.show_formulas()
../_images/examples_Transmon_2_0.png
../_images/examples_Transmon_2_1.png
[3]:
C = 25.0e-15
Ej = 10.0
N = 25

transmon = trm.Transmon()
transmon.set_parameters(C=C, Ej=Ej, N=N)
print(transmon.__repr__())
C = 2.5000e-14
Ec = 6.1985e+00
Ej = 1.0000e+01,
ℏω = 7.8730e+00
Ej / Ec = 1.2702e+00

[4]:
fig = plt.figure()
ax = fig.add_subplot(111)

transmon.set_parameters(ng=0.0)
transmon.diagonalize_hamiltonian()
transmon.plot_transmon(ax, 5, x_range=1.5, remove_ng=True, fill_between=True)

E_approx = transmon.energies_first_order_approx()
for i in range(3):
    ax.plot((-0.75, 0.75), (E_approx[i], E_approx[i]), color="grey", ls="--", zorder=-1)

plt.show()
../_images/examples_Transmon_4_0.png

Parameter sweeps

  • the program is designed for 1D sweeps of the circuit parameters

  • for the transmon certainly most important is the sweep of the offset charge

[5]:
fig = plt.figure()
ax = fig.add_subplot(111)

transmon.sweep_offset_charge(np.linspace(-0.5, 0.5, 101))
transmon.substract_groundstate_energy_sweep()
transmon.plot_energy_sweep(ax, np.arange(5))

ax.set_xlabel("$n_g$ (2e)")

plt.show()
../_images/examples_Transmon_6_0.png
[6]:
fig = plt.figure()
ax = fig.add_subplot(111)

transmon.add_groundstate_energy_sweep()
transmon.inspect_sweep(0)
print(transmon.Ej)
print(transmon.ng)

transmon.plot_transmon(ax, 5, x_range=1.5, remove_ng=True, fill_between=True)

plt.show()
[10.]
-0.5
../_images/examples_Transmon_7_1.png

Anharmonicity

[7]:
fig = plt.figure(figsize=(8, 4), constrained_layout=True)
ax = fig.add_subplot(121)

Ej_times_Ec = 5.0**2
Ej_over_Ec = np.linspace(1.0, 5.0, 101)**2

Ej_sweep = np.sqrt(Ej_times_Ec * Ej_over_Ec)
Ec_sweep = np.sqrt(Ej_times_Ec / Ej_over_Ec)

transmon.set_parameters(ng=0.0)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Ee = transmon.E_sweep

transmon.set_parameters(ng=0.5)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Eo = transmon.E_sweep

ax.axhline(np.sqrt(Ej_times_Ec), color="grey", ls="--")

for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec), Ee[i + 1, :] - Ee[i, :], transmon.colors[i])
    ax.plot(np.sqrt(Ej_over_Ec), Eo[i + 1, :] - Eo[i, :], transmon.colors[i])

ax.set_xlim(1, 5)
ax.set_xlabel(r"$\sqrt{E_J / E_C}$")
ax.set_ylabel(r"$\hbar \omega_{i,i+1}$  (GHz)")

ax = fig.add_subplot(122)
for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec), Ee[i + 1, :] - Ee[i, :] - np.sqrt(Ej_times_Ec), transmon.colors[i])
    ax.plot(np.sqrt(Ej_over_Ec), Eo[i + 1, :] - Eo[i, :] - np.sqrt(Ej_times_Ec), transmon.colors[i])

ax.set_xlim(2, 5)
ax.set_ylim(-1.75, 0)
ax.set_xlabel(r"$\sqrt{E_J / E_C}$")
ax.set_ylabel(r"$\hbar \omega_{i,i+1} - \sqrt{E_J E_C}$  (GHz)")

plt.show()
../_images/examples_Transmon_9_0.png

Charge dispersion

[8]:
fig = plt.figure()
ax = fig.add_subplot(111)

Ej_times_Ec = 5.0**2
Ej_over_Ec = np.linspace(0.1, 4.0, 101)**2

Ej_sweep = np.sqrt(Ej_times_Ec * Ej_over_Ec)
Ec_sweep = np.sqrt(Ej_times_Ec / Ej_over_Ec)

transmon.set_parameters(ng=0.0)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Ee = transmon.E_sweep

transmon.set_parameters(ng=0.5)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Eo = transmon.E_sweep

for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec), 1e3 * np.abs(Ee[i, :] - Eo[i, :]))

e = transmon.charge_dispersion_approx(Ej_over_Ec, 5)
for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec)[20 + 10 * i:], 1e3 * e[i, 20 + 10 * i:] * np.sqrt(Ej_times_Ec), "k--")

ax.set_yscale("log")
ax.set_ylim(1e-6, 5e5)

ax.set_xlabel(r"$\sqrt{E_J / E_C}$")
ax.set_ylabel(r"$\epsilon$  (MHz)")

axt = ax.twinx()
axt.set_yscale("log")
axt.set_ylim(1e-6 / (1e3 * np.sqrt(Ej_times_Ec)), 5e3 / (1e3 * np.sqrt(Ej_times_Ec)))
axt.set_ylabel(r"$\epsilon / \sqrt{E_J E_C}$")

plt.show()
../_images/examples_Transmon_11_0.png

Convergence

[9]:
fig = plt.figure()
ax = fig.add_subplot(111)

Ej_times_Ec = 5.0**2
Ej_over_Ec = 10
transmon.set_parameters(Ec=np.sqrt(Ej_times_Ec / Ej_over_Ec), Ej=np.sqrt(Ej_times_Ec * Ej_over_Ec), ng=0.0)
transmon.convergence_sweep(40)
transmon.plot_convergence_sweep(ax, 5)

ax.set_yscale("log")
ax.set_ylim(bottom=1e-8)

plt.show()
../_images/examples_Transmon_13_0.png

Matrix elements

[10]:
fig = plt.figure()
ax = fig.add_subplot(111)

Ej_times_Ec = 5.0**2
Ej_over_Ec = 4
transmon.set_parameters(Ec=np.sqrt(Ej_times_Ec / Ej_over_Ec),
                        Ej=np.sqrt(Ej_times_Ec * Ej_over_Ec), ng=0.0, N=31)
transmon.sweep_offset_charge(np.linspace(0.0, 0.5, 51))
transmon.substract_groundstate_energy_sweep()

flux_dm, charge_dm = transmon.calc_dipole_moments_sweep(0, 1)

ax.plot(transmon.par_sweep, flux_dm, color="C0")
ax.set_ylabel(r"")
ax.set_xlabel("$n_g$ (2e)")
ax.set_ylabel(r"$|\langle \psi_m|\phi| \psi_n\rangle |$ ($\Phi_0$)")

axt = ax.twinx()
axt.plot(transmon.par_sweep, charge_dm, color="C3")
axt.set_ylabel(r"$|\langle \psi_m|q| \psi_n\rangle |$ ($2e$)")


plt.show()
../_images/examples_Transmon_15_0.png
[11]:
fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, projection="3d")

transmon.plot_dipole_to_various_states_sweep(ax, 0, np.arange(10), dipole="flux")

ax.set_box_aspect(aspect=None, zoom=0.8)

ax.set_xlabel("$n_g$ (2e)")

plt.show()
../_images/examples_Transmon_16_0.png
[12]:
fig = plt.figure(figsize=(10, 4))
ax = fig.add_subplot(111)

sin_mel = transmon.calc_sin_phi_over_two_sweep(0, 1)
ax.plot(transmon.par_sweep, sin_mel)

ax.set_xlabel("$n_g$ (2e)")
ax.set_ylabel(r"$|\langle \psi_m|sin(\varphi / 2)| \psi_n\rangle |$")

plt.show()
../_images/examples_Transmon_17_0.png

Josephson harmonics

[13]:
C = 25.0e-15
Ej_1 = 10.0
Ej_2 = -1.0
N = 51

transmon.set_parameters(C=C, Ej=[Ej_1, Ej_2], N=N)
print(transmon.__repr__())
C = 2.5000e-14
Ec = 6.1985e+00
Ej = [1.0000e+01,-1.0000e+00]
ℏω = 7.8730e+00
Ej / Ec = 1.2702e+00

[14]:
fig = plt.figure()
ax = fig.add_subplot(111)

transmon.set_parameters(ng=0.0)
transmon.diagonalize_hamiltonian()
transmon.plot_transmon(ax, 5, x_range=1.5, remove_ng=True, fill_between=True)

E_approx = transmon.energies_first_order_approx()
for i in range(3):
    ax.plot((-0.75, 0.75), (E_approx[i], E_approx[i]), color="grey", ls="--", zorder=-1)

plt.show()
../_images/examples_Transmon_20_0.png
[15]:
fig = plt.figure()
ax = fig.add_subplot(111)

Ej_times_Ec = 5.0**2
Ej_over_Ec = np.linspace(1.0, 3.0, 101)**2

Ej_sweep = np.sqrt(Ej_times_Ec * Ej_over_Ec)
Ec_sweep = np.sqrt(Ej_times_Ec / Ej_over_Ec)

transmon.set_parameters(ng=0.0)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": np.vstack((Ej_sweep, - 0.1 * Ej_sweep)).T})
Ee = transmon.E_sweep

transmon.set_parameters(ng=0.5)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": np.vstack((Ej_sweep, - 0.1 * Ej_sweep)).T})
Eo = transmon.E_sweep

for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec), 1e3 * np.abs(Ee[i, :] - Eo[i, :]), color=transmon.colors[i], ls="--")

# comparison with no harmonics
transmon.set_parameters(ng=0.0)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Ee = transmon.E_sweep

transmon.set_parameters(ng=0.5)
transmon.sweep_parameter({"Ec": Ec_sweep, "Ej": Ej_sweep})
Eo = transmon.E_sweep

for i in range(5):
    ax.plot(np.sqrt(Ej_over_Ec), 1e3 * np.abs(Ee[i, :] - Eo[i, :]), color=transmon.colors[i], ls="-")

ax.set_yscale("log")
ax.set_ylim(1e-1, 1e4)

ax.set_xlabel(r"$\sqrt{E_J / E_C}$")
ax.set_ylabel(r"$\epsilon$  (MHz)")

plt.show()
../_images/examples_Transmon_21_0.png

Transmon losses

[16]:
# work in progress

More…

  • get creative with the code and adapt it to your needs