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
@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_ω(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_ω()
        return w * (
            self.linear_ops["a_dag"] @ self.linear_ops["a"]
            + 0.5 * self.linear_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."""
        phi_b = self.linear_ops["phi"]
        H_nl = self.get_H_nonlinear(phi_b)
        H = self.get_H_linear() + H_nl
        return H

    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
111
112
113
114
115
116
def get_H_full(self):
    """Return full H in linear basis."""
    phi_b = self.linear_ops["phi"]
    H_nl = self.get_H_nonlinear(phi_b)
    H = self.get_H_linear() + H_nl
    return H

get_H_linear()

Return linear terms in H.

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

get_H_nonlinear(phi_op)

Return nonlinear terms in H.

Source code in jaxquantum/devices/superconducting/ats.py
 99
100
101
102
103
104
105
106
107
108
109
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_ω()

Get frequency of linear terms.

Source code in jaxquantum/devices/superconducting/ats.py
41
42
43
def get_linear_ω(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
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
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