Skip to content

ats

ATS.

ATS

Bases: FluxDevice

ATS Device.

Source code in jaxquantum/devices/superconducting/ats.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
@struct.dataclass
class ATS(FluxDevice):
    """
    ATS Device.
    """

    def common_ops(self):
        """Written in the linear basis."""
        ops = {}

        N = self.N_pre_diag
        ops["id"] = identity(N)
        ops["a"] = destroy(N)
        ops["a_dag"] = create(N)
        ops["phi"] = self.phi_zpf() * (ops["a"] + ops["a_dag"])
        ops["n"] = 1j * self.n_zpf() * (ops["a_dag"] - ops["a"])
        return ops

    def phi_zpf(self):
        """Return Phase ZPF."""
        return (2 * self.params["Ec"] / self.params["El"]) ** (0.25)

    def n_zpf(self):
        """Return Charge ZPF."""
        return (self.params["El"] / (32 * self.params["Ec"])) ** (0.25)

    def get_linear_frequency(self):
        """Get frequency of linear terms."""
        return jnp.sqrt(8 * self.params["El"] * self.params["Ec"])

    def get_H_linear(self):
        """Return linear terms in H."""
        w = self.get_linear_frequency()
        ops = self.linear_ops
        return w * (
            ops["a_dag"] @ ops["a"]
            + 0.5 * ops["id"]
        )

    @staticmethod
    def get_H_nonlinear_static(phi_op, Ej, dEj, Ej2, phi_sum, phi_delta):
        cos_phi_op = cosm(phi_op)
        sin_phi_op = sinm(phi_op)

        cos_2phi_op = cos_phi_op @ cos_phi_op - sin_phi_op @ sin_phi_op
        sin_2phi_op = 2 * cos_phi_op @ sin_phi_op

        H_nl_Ej = (
            -2
            * Ej
            * (
                cos_phi_op * jnp.cos(2 * jnp.pi * phi_delta)
                - sin_phi_op * jnp.sin(2 * jnp.pi * phi_delta)
            )
            * jnp.cos(2 * jnp.pi * phi_sum)
        )
        H_nl_dEj = (
            2
            * dEj
            * (
                sin_phi_op * jnp.cos(2 * jnp.pi * phi_delta)
                + cos_phi_op * jnp.sin(2 * jnp.pi * phi_delta)
            )
            * jnp.sin(2 * jnp.pi * phi_sum)
        )
        H_nl_Ej2 = (
            2
            * Ej2
            * (
                cos_2phi_op * jnp.cos(2 * 2 * jnp.pi * phi_delta)
                - sin_2phi_op * jnp.sin(2 * 2 * jnp.pi * phi_delta)
            )
            * jnp.cos(2 * 2 * jnp.pi * phi_sum)
        )

        H_nl = H_nl_Ej + H_nl_dEj + H_nl_Ej2

        # id_op = jqt.identity_like(phi_op)
        # phi_delta_ext_op = self.params["phi_delta_ext"] * id_op
        # H_nl_old = - 2 * Ej * jqt.cosm(phi_op + 2 * jnp.pi * phi_delta_ext_op) * jnp.cos(2 * jnp.pi * self.params["phi_sum_ext"])
        # H_nl_old += 2 * dEj * jqt.sinm(phi_op + 2 * jnp.pi * phi_delta_ext_op) * jnp.sin(2 * jnp.pi * self.params["phi_sum_ext"])
        # H_nl_old += 2 * Ej2 * jqt.cosm(2*phi_op + 2 * 2 * jnp.pi * phi_delta_ext_op) * jnp.cos(2 * 2 * jnp.pi * self.params["phi_sum_ext"])

        return H_nl

    def get_H_nonlinear(self, phi_op):
        """Return nonlinear terms in H."""

        Ej = self.params["Ej"]
        dEj = self.params["dEj"]
        Ej2 = self.params["Ej2"]

        phi_sum = self.params["phi_sum_ext"]
        phi_delta = self.params["phi_delta_ext"]

        return ATS.get_H_nonlinear_static(phi_op, Ej, dEj, Ej2, phi_sum, phi_delta)

    def get_H_full(self):
        """Return full H in linear basis."""
        ops = self.linear_ops
        linear = self.get_linear_frequency() * (
            ops["a_dag"] @ ops["a"] + 0.5 * ops["id"]
        )
        return linear + self.get_H_nonlinear(ops["phi"])

    def potential(self, phi):
        """Return potential energy for a given phi."""

        phi_delta_ext = self.params["phi_delta_ext"]
        phi_sum_ext = self.params["phi_sum_ext"]

        V = 0.5 * self.params["El"] * (2 * jnp.pi * phi) ** 2
        V += (
            -2
            * self.params["Ej"]
            * jnp.cos(2 * jnp.pi * (phi + phi_delta_ext))
            * jnp.cos(2 * jnp.pi * phi_sum_ext)
        )
        V += (
            2
            * self.params["dEj"]
            * jnp.sin(2 * jnp.pi * (phi + phi_delta_ext))
            * jnp.sin(2 * jnp.pi * phi_sum_ext)
        )
        V += (
            2
            * self.params["Ej2"]
            * jnp.cos(2 * 2 * jnp.pi * (phi + phi_delta_ext))
            * jnp.cos(2 * 2 * jnp.pi * phi_sum_ext)
        )

        return V

common_ops()

Written in the linear basis.

Source code in jaxquantum/devices/superconducting/ats.py
21
22
23
24
25
26
27
28
29
30
31
def common_ops(self):
    """Written in the linear basis."""
    ops = {}

    N = self.N_pre_diag
    ops["id"] = identity(N)
    ops["a"] = destroy(N)
    ops["a_dag"] = create(N)
    ops["phi"] = self.phi_zpf() * (ops["a"] + ops["a_dag"])
    ops["n"] = 1j * self.n_zpf() * (ops["a_dag"] - ops["a"])
    return ops

get_H_full()

Return full H in linear basis.

Source code in jaxquantum/devices/superconducting/ats.py
112
113
114
115
116
117
118
def get_H_full(self):
    """Return full H in linear basis."""
    ops = self.linear_ops
    linear = self.get_linear_frequency() * (
        ops["a_dag"] @ ops["a"] + 0.5 * ops["id"]
    )
    return linear + self.get_H_nonlinear(ops["phi"])

get_H_linear()

Return linear terms in H.

Source code in jaxquantum/devices/superconducting/ats.py
45
46
47
48
49
50
51
52
def get_H_linear(self):
    """Return linear terms in H."""
    w = self.get_linear_frequency()
    ops = self.linear_ops
    return w * (
        ops["a_dag"] @ ops["a"]
        + 0.5 * ops["id"]
    )

get_H_nonlinear(phi_op)

Return nonlinear terms in H.

Source code in jaxquantum/devices/superconducting/ats.py
100
101
102
103
104
105
106
107
108
109
110
def get_H_nonlinear(self, phi_op):
    """Return nonlinear terms in H."""

    Ej = self.params["Ej"]
    dEj = self.params["dEj"]
    Ej2 = self.params["Ej2"]

    phi_sum = self.params["phi_sum_ext"]
    phi_delta = self.params["phi_delta_ext"]

    return ATS.get_H_nonlinear_static(phi_op, Ej, dEj, Ej2, phi_sum, phi_delta)

get_linear_frequency()

Get frequency of linear terms.

Source code in jaxquantum/devices/superconducting/ats.py
41
42
43
def get_linear_frequency(self):
    """Get frequency of linear terms."""
    return jnp.sqrt(8 * self.params["El"] * self.params["Ec"])

n_zpf()

Return Charge ZPF.

Source code in jaxquantum/devices/superconducting/ats.py
37
38
39
def n_zpf(self):
    """Return Charge ZPF."""
    return (self.params["El"] / (32 * self.params["Ec"])) ** (0.25)

phi_zpf()

Return Phase ZPF.

Source code in jaxquantum/devices/superconducting/ats.py
33
34
35
def phi_zpf(self):
    """Return Phase ZPF."""
    return (2 * self.params["Ec"] / self.params["El"]) ** (0.25)

potential(phi)

Return potential energy for a given phi.

Source code in jaxquantum/devices/superconducting/ats.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
def potential(self, phi):
    """Return potential energy for a given phi."""

    phi_delta_ext = self.params["phi_delta_ext"]
    phi_sum_ext = self.params["phi_sum_ext"]

    V = 0.5 * self.params["El"] * (2 * jnp.pi * phi) ** 2
    V += (
        -2
        * self.params["Ej"]
        * jnp.cos(2 * jnp.pi * (phi + phi_delta_ext))
        * jnp.cos(2 * jnp.pi * phi_sum_ext)
    )
    V += (
        2
        * self.params["dEj"]
        * jnp.sin(2 * jnp.pi * (phi + phi_delta_ext))
        * jnp.sin(2 * jnp.pi * phi_sum_ext)
    )
    V += (
        2
        * self.params["Ej2"]
        * jnp.cos(2 * 2 * jnp.pi * (phi + phi_delta_ext))
        * jnp.cos(2 * 2 * jnp.pi * phi_sum_ext)
    )

    return V