Extra features and tips

Regroup external fluxes

The Circuit instance generates a spanning tree, by default, for all the superconducting loops present in the circuit. In case the user prefers to use a different configuration of loops, the user can provide the list of branches with which external fluxes are grouped. Once, the closure branches are set, spanning tree is given by the set of all branches of the Circuit which do not contain the closure branches, thereby defining a custom spanning tree.

[2]:
zero_pi.branches
[2]:
[Branch(JJ, 1, 2, index: 0),
 Branch(JJ, 3, 4, index: 1),
 Branch(L, 2, 3, index: 2),
 Branch(L, 4, 1, index: 3),
 Branch(C, 1, 3, index: 4),
 Branch(C, 2, 4, index: 5)]
[3]:
zero_pi.configure(closure_branches=[zero_pi.branches[3]])
zero_pi.sym_external_fluxes()
[3]:
{Φ1: (Branch(L, 4, 1, index: 3),
  [Branch(JJ, 1, 2, index: 0),
   Branch(L, 4, 1, index: 3),
   Branch(JJ, 3, 4, index: 1),
   Branch(L, 2, 3, index: 2)])}

Time dependent flux grouping

When the external flux in a loop is time-dependent, merely replacing the static external fluxes with the corresponding time-dependent fluxes is typically inaccurate. The use_dynamic_flux_grouping option, when enabled, ensures a consistent treatment of time-dependent external fluxes using the irrotational gauge as described in You et al.,. In this allocation, time-dependent fluxes can be incorporated only into the potential term, avoiding inaccuracies that arise from ignoring terms with the time-derivative of the external flux in the kinetic energy that arise in other allocations. To use this flux allocation, set the option use_dynamic_flux_grouping in the Circuit definition or the configure method of the instance.

[4]:
zero_pi = scq.Circuit(zp_yaml, from_file=False, use_dynamic_flux_grouping=True)
zero_pi.sym_external_fluxes()
[4]:
{Φ1: (Branch(JJ, 3, 4, index: 1),
  [Branch(C, 1, 3, index: 4),
   Branch(L, 4, 1, index: 3),
   Branch(JJ, 3, 4, index: 1)]),
 Φ2: (Branch(L, 2, 3, index: 2),
  [Branch(JJ, 1, 2, index: 0),
   Branch(C, 1, 3, index: 4),
   Branch(L, 2, 3, index: 2)]),
 Φ3: (Branch(C, 2, 4, index: 5),
  [Branch(JJ, 1, 2, index: 0),
   Branch(L, 4, 1, index: 3),
   Branch(C, 2, 4, index: 5)])}

Note that external flux for loops including a capacitor are also included. The external flux in the capacitive loops will not effect the eigenvalue calculation as fluxes are considered to be static. When fluxes are dynamic, it is important to choose the loops and the corresponding external fluxes carefully by setting the closure branches (which sets the apropriate spanning tree) using the configure method.

Customize variable transformations

It is possible to carry out variable transformations with a user-defined transformation matrix. For example, if we want to work with a more commonly seen set of variables for zero-pi circuit:

[ ]:
zero_pi = scq.Circuit(zp_yaml, from_file=False, ext_basis="harmonic")
[34]:
trans_mat = np.array([[ -1,  -1,  1,  1],
                       [ 1,  1,  1,  1],
                       [ 1,  -1, -1,  1],
                       [ -1,  1,  -1,  1]])*0.5
zero_pi.configure(transformation_matrix=trans_mat)
zero_pi.variable_transformation()
[34]:
$\displaystyle \left[ φ_{1} = 0.5 θ_{3} + 0.5 θ_{4} - 0.5 θ_{1} - 0.5 θ_{2}, \ φ_{2} = 0.5 θ_{1} + 0.5 θ_{2} + 0.5 θ_{3} + 0.5 θ_{4}, \ φ_{3} = 0.5 θ_{1} + 0.5 θ_{4} - 0.5 θ_{2} - 0.5 θ_{3}, \ φ_{4} = 0.5 θ_{2} + 0.5 θ_{4} - 0.5 θ_{1} - 0.5 θ_{3}\right]$
[35]:
zero_pi.sym_hamiltonian()
[35]:
$\displaystyle \left(40.0 Q_{2}^{2} + 0.03996 n_{1}^{2} + 0.03996 n_{g1}^{2} + 0.04 Q_{3}^{2} + 0.07992 n_{1} n_{g1}\right) - \left(- 0.008 θ_{2}^{2} - 0.008 θ_{3}^{2} + EJ \cos{\left(θ_{1} + θ_{2} \right)} + EJ \cos{\left((2πΦ_{1}) + θ_{2} - 1.0 θ_{1} \right)}\right)$

Higher harmonics in Josephson junctions

In Circuit module, it is possible to define a Josephson junction with higher harmonics in the following way

[7]:
circ_input = """
branches:
- [JJ3, 0, 1, 21nA, 2nA, EJ3=0.2nA, 0.2]
"""

The branch definition - [JJ3, 0, 1, 21nA, 2nA, EJ3=0.2nA, 0.2] in the input file is a list with the following entries:

  • branch type:

    • JJ<n> for a Josephson junction with n harmonics,

  • initial node index: \(i\)

  • final node index: \(f\)

  • branch parameters:

    • EJn junction energies for each order from 1..n.

    • ECJ junction capacitance

[8]:
circ = scq.Circuit(circ_input, from_file=False)
circ
$H=\left(0.8 n_{1}^{2} + 0.8 n_{g1}^{2} + 1.6 n_{1} n_{g1}\right) - \left(0.993367 \cos{\left(2 θ_{1} \right)} + 10.430354 \cos{\left(θ_{1} \right)} + EJ_{3} \cos{\left(3 θ_{1} \right)}\right)$
Operators (flux, charge) - cutoff: Discrete Charge Basis: $(θ1, n1) - 5$,
Symbolic parameters (symbol, default value): $(EJ3, 0.09933670215533513)$,
Offset charges (symbol, default value): $(ng1, 0.0)$,
[8]:
Circuit_2

Options for automatic variable transformation

  • After the periodic, frozen and free variables are identified, the transformation matrix is completed by adding on a set of linearly-independent vectors. This heuristic method for generating the transformation matrix may not always provide the “ideal” or expected choice of variables.

  • As an alternative, missing column vectors in the transformation matrix may be filled by suitable canonical basis vectors (drawn from the identity matrix). This choice is made by setting basis_completion="canonical" when creating the Circuit object. (The default is "heuristic".)

Handling large circuits

  • For large circuits, the Hilbert space dimension grows exponentially with cutoffs. Numerical diagonalization is therefore challenging for large cutoffs, both in terms of runtime and memory. It is recommended to start diagonalization with small cutoffs, and gradually increase them as needed. This applies to both the direct and hierarchical diagonalization methods.

  • For hierarchical diagonalization: as diagonalization for systems with three or more variables takes much longer than for smaller systems, it is recommended to try and group less than three nodes for each subsystem, and build a hierarchy of subsystems.

  • Note that convergence of the eigenergies for large circuits can differ significantly according to the variable transformation used. It is advisable to (i) try changing the basis_completion option, (ii) define a custom transformation matrix, or (iii) add/remove the reference ground node in the YAML description of the circuit.