PhilippAumann / circuitq

Toolbox for the simulation and analysis of superconducting circuits.
MIT License
39 stars 8 forks source link

Equivalent circuits have different Hamiltonians? #7

Open lukeburns opened 2 years ago

lukeburns commented 2 years ago

I expected Hamiltonians to be invariant under changing the order in which parallel edges are added, but this appears not to be the case.

Is this a change in coordinates somehow, or a bug?

graph.add_edge(0,1, element = 'L')
graph.add_edge(0,1, element = 'J')

circuit = cq.CircuitQ(graph, ground_nodes=[0, 1])
print(circuit.h)

yields

-E_{J010}*cos(\tilde{\Phi}_{010}/\Phi_{o})

While

graph.add_edge(0,1, element = 'J')
graph.add_edge(0,1, element = 'L')

circuit = cq.CircuitQ(graph, ground_nodes=[0, 1])
print(circuit.h)

yields what looks something like a small angle approximation (?) of the above Hamiltonian

-E_{J010} + \tilde{\Phi}_{010}**2/(2*L_{010})
PhilippAumann commented 2 years ago

Hi, thank you for opening this issue!

The Hamiltonian should be invariant up to a choice of gauge. The circuit you are looking into does have a superconducting loop with an associated loop flux \tilde{\Phi}_{010}, as it is a linear inductance with a Josephson junction in parallel. The construction of the Hamiltonian follows the method of nodes, which involves choosing a spanning tree of the graph. Depending on the choice of this spanning tree, the loop flux will either be associated with the edge corresponding to the linear inductance or the edge corresponding to the Josephson junction. A choice of spanning tree can be related to setting a gauge for the form of the Hamiltonian. That's why you get two different expressions: as for the first case, the loop flux appears in the argument of the cosine, while it appears in the argument of the parabola for the second case.

To further understand why the Hamiltonian looks like this, let me point you to the keyword argument ground_nodes in your initialisation of CircuitQ. This keyword sets all specified nodes to ground, which leads to $\Phi, q = 0 $ for those nodes. So by setting ground_nodes=[0, 1], any difference in potential between node 0 and node 1 is lifted. That corresponds to short-circuiting those nodes which basically bridges the elements you defined. That's also why there are all variables $\Phi$ and $q $ missing in the Hamiltonian (up to the loop flux).

If you initalize the circuit as

graph = nx.MultiGraph()
graph.add_edge(0,1, element = 'L')
graph.add_edge(0,1, element = 'J')
circuit = cq.CircuitQ(graph)

the Hamiltonian reads

$$H = - E{J010} \cos{\left(\frac{\Phi{1}}{\Phi{o}} \right)} +\frac{(\Phi{1} + \tilde{\Phi})^2}{2 L{010}} + \frac{0.5 q{1}^{2}}{Cp_{01}} $$

The node 0 has been set to ground and the node variable $\Phi_1$ and $q_1$ are the conjugate variable pair to describe the 1-dimensional dynamics. Switching L and J in the graph construction would lead to

$$H = - E{J010} \cos{\left(\frac{\Phi{1} + \tilde{\Phi}}{\Phi{o}} \right)} + \frac{\Phi{1}^{2}}{2 L{010}} + \frac{0.5 q{1}^{2}}{Cp_{01}} $$

which is the same Hamiltonian up to a choice of gauge. To put it in other words: The physical interpretation should be invariant under a unitary transformation of the Hamiltonian. One can show that those two Hamiltonians are related by a unitary transformation which generates a translation by $\tilde{\Phi}$ and should look something like $U=e^{-i \tilde{\Phi} q_1}$, where $q_1$ is related to the derivative in the flux-basis.