Commit ac9564cc authored by Christian Schneider's avatar Christian Schneider
Browse files

Update JJObject.py

parent 2d347041
''' '''
Created on Sep 18, 2014 Created on Sep 18, 2014
@author: Seyed Iman Mirzaei @author: Seyed Iman Mirzaei
''' '''
#import numpy as np #import numpy as np
import numpy as np import numpy as np
import scipy.optimize as opt import scipy.optimize as opt
print('JJObject v1.0.0') print('JJObject v1.0.0')
class junction(): class junction():
version='1.0.0' version='1.0.0'
def __init__(self, Tc, T, Area, RnUnit, def __init__(self, Tc, T, Area, RnUnit,
CjUnit, Cground): CjUnit, Cground):
#def __init__(self, Tc=1.23, T=20e-3, Area=4e-13, RnUnit=1300e-12, #def __init__(self, Tc=1.23, T=20e-3, Area=4e-13, RnUnit=1300e-12,
# CjUnit=50e-3, Cground=30e-18): # CjUnit=50e-3, Cground=30e-18):
# Defining physical constants # Defining physical constants
self.ec_ = 1.602176565e-19 # elementary charge (C) self.ec_ = 1.602176565e-19 # elementary charge (C)
self.c_ = 299792458 # speed of light (m.s^-1) self.c_ = 299792458 # speed of light (m.s^-1)
self.eps0_ = 8.854187817e-12 # electric constant (F.m^-1) self.eps0_ = 8.854187817e-12 # electric constant (F.m^-1)
self.mu0_ = 4*np.pi*1e-7 # magnetic constant (N.A^-2) self.mu0_ = 4*np.pi*1e-7 # magnetic constant (N.A^-2)
self.h_ = 6.62606957e-34 # planck constant (J.s) self.h_ = 6.62606957e-34 # planck constant (J.s)
self.hbar_ = self.h_/(2*np.pi) # reduced planck constant (J.s) self.hbar_ = self.h_/(2*np.pi) # reduced planck constant (J.s)
self.kb_ = 1.3806488e-23 # Boltzman coefficient (J.K^-1) self.kb_ = 1.3806488e-23 # Boltzman coefficient (J.K^-1)
self.Phi0_ = self.h_/(2*self.ec_) # magnetic flux quanta (Wb) self.Phi0_ = self.h_/(2*self.ec_) # magnetic flux quanta (Wb)
# Defining junction constants from parameters passed to the object # Defining junction constants from parameters passed to the object
self.Tc = Tc # critical temperature in kelvin self.Tc = Tc # critical temperature in kelvin
self.T = T # junction temperature in kelvin self.T = T # junction temperature in kelvin
self.Area = Area # junction area (m^2) self.Area = Area # junction area (m^2)
self.RnUnit = RnUnit # normal state resistance of the junction per unit area (ohm) self.RnUnit = RnUnit # normal state resistance of the junction per unit area (ohm)
self.CjUnit = CjUnit # junction capacitance per unit area (Farads) self.CjUnit = CjUnit # junction capacitance per unit area (Farads)
self.Cground = Cground self.Cground = Cground
# Calculating junction properties # Calculating junction properties
self.update() self.update()
def update(self, Tc=None, T=None, Area=None, RnUnit=None, CjUnit=None, Cground=None): def update(self, Tc=None, T=None, Area=None, RnUnit=None, CjUnit=None, Cground=None):
if not Tc is None : if not Tc is None :
self.Tc = Tc self.Tc = Tc
if not T is None : if not T is None :
self.T = T self.T = T
if not Area is None : if not Area is None :
self.Area = Area self.Area = Area
if not RnUnit is None : if not RnUnit is None :
self.RnUnit = RnUnit self.RnUnit = RnUnit
if not CjUnit is None : if not CjUnit is None :
self.CjUnit = CjUnit self.CjUnit = CjUnit
if not Cground is None : if not Cground is None :
self.Cground = Cground self.Cground = Cground
self.Delta0 = self.calcDelta0(self.Tc) self.Delta0 = self.calcDelta0(self.Tc)
self.Delta = self.calcDelta(self.T, self.Tc, self.Delta0) self.Delta = self.calcDelta(self.T, self.Tc, self.Delta0)
self.Rn = self.calcRn(self.Area, self.RnUnit) self.Rn = self.calcRn(self.Area, self.RnUnit)
self.Cj = self.calcCj(self.Area, self.CjUnit) self.Cj = self.calcCj(self.Area, self.CjUnit)
self.Ic = self.calcIc(self.Rn,self.Delta,self.T) self.Ic = self.calcIc(self.Rn,self.Delta,self.T)
self.Ej = self.calcEj(self.Ic) self.Ej = self.calcEj(self.Ic)
self.Ec = self.calcEc(self.Cj) self.Ec = self.calcEc(self.Cj)
# in the following case, the junction current is assumed to be a thousand # in the following case, the junction current is assumed to be a thousand
# times smaller than the critical current # times smaller than the critical current
self.Lj = self.calcLj_lowCurr(self.Ic, self.Ic*1e-3) self.Lj = self.calcLj_lowCurr(self.Ic, self.Ic*1e-3)
self.F0 = self.calcF0(self.Lj, self.Cj) self.F0 = self.calcF0(self.Lj, self.Cj)
def calcDelta0(self,Tc): def calcDelta0(self,Tc):
''' This function calculates the zero kelvin gap value based on BCS theory''' ''' This function calculates the zero kelvin gap value based on BCS theory'''
return 1.764*self.kb_*Tc # gap value in Joules return 1.764*self.kb_*Tc # gap value in Joules
def calcDelta(self,T,Tc,d0): def calcDelta(self,T,Tc,d0):
''' This function calculates the finite-temperature gap based on a simplified equation that is more valid around 0 and Tc''' ''' This function calculates the finite-temperature gap based on a simplified equation that is more valid around 0 and Tc'''
return d0*np.tanh((np.pi/1.764)*np.sqrt(0.95333*((Tc/T)-1))) # gap value in Joules return d0*np.tanh((np.pi/1.764)*np.sqrt(0.95333*((Tc/T)-1))) # gap value in Joules
def calcRn(self,Area,RnUnit): def calcRn(self,Area,RnUnit):
return RnUnit/Area return RnUnit/Area
def calcCj(self,Area,CjUnit): def calcCj(self,Area,CjUnit):
return CjUnit*Area return CjUnit*Area
def calcIc(self,Rn,Delta,T): def calcIc(self,Rn,Delta,T):
'''This function calculates the junction critical current based on Ambegaokar-Baratoff relation [Ambegaokar1963] '''This function calculates the junction critical current based on Ambegaokar-Baratoff relation [Ambegaokar1963]
''' '''
return (np.pi*Delta/(2*self.ec_*Rn))*np.tanh(Delta/(2*self.kb_*T)) return (np.pi*Delta/(2*self.ec_*Rn))*np.tanh(Delta/(2*self.kb_*T))
def calcEj(self,Ic): def calcEj(self,Ic):
return self.h_*Ic/(4*self.ec_*np.pi) return self.h_*Ic/(4*self.ec_*np.pi)
def calcEc(self,Cj): def calcEc(self,Cj):
return self.ec_**2/(2*Cj) return self.ec_**2/(2*Cj)
def calcLj_lowCurr(self,Ic,I): def calcLj_lowCurr(self,Ic,I):
return self.Phi0_/(2*np.pi*Ic*np.sqrt(1-(I/Ic)**2)) return self.Phi0_/(2*np.pi*Ic*np.sqrt(1-(I/Ic)**2))
def calcF0(self,Lj,Cj): def calcF0(self,Lj,Cj):
return 1/(2*np.pi*np.sqrt(Lj*Cj)) return 1/(2*np.pi*np.sqrt(Lj*Cj))
def junctionInfo(self,PrintInfo=True): def junctionInfo(self,PrintInfo=True):
self.update() self.update()
txt = ('\n\nJunction Information: \n' + txt = ('\n\nJunction Information: \n' +
'\n=================================================================' + '\n=================================================================' +
'\n* F0 = ' + '%0.2f' % (self.F0/1e9) + ' GHz Plasma frequency ' + '\n* F0 = ' + '%0.2f' % (self.F0/1e9) + ' GHz Plasma frequency ' +
'\n* Delta('+str(self.T)+'K) = ' + '%0.2f' % (self.Delta/(self.h_*1e9)) + ' GHz Gap value' '\n* Delta('+str(self.T)+'K) = ' + '%0.2f' % (self.Delta/(self.h_*1e9)) + ' GHz Gap value'
'\n* ic(' + str(self.T) + 'K) = ' + '%0.3f' % (self.Ic*1e-6/self.Area) + ' uA/um^2 Critical current density' '\n* ic(' + str(self.T) + 'K) = ' + '%0.3f' % (self.Ic*1e-6/self.Area) + ' uA/um^2 Critical current density'
'\n* Ic(' + str(self.T) + 'K) = ' + '%0.2f' % (self.Ic*1e9) + ' nA Critical current' '\n* Ic(' + str(self.T) + 'K) = ' + '%0.2f' % (self.Ic*1e9) + ' nA Critical current'
'\n*----------------------------------------------------------------' '\n*----------------------------------------------------------------'
'\n* Cj = ' + '%0.3f' % (self.Cj*1e15) + ' fF' '\n* Cj = ' + '%0.3f' % (self.Cj*1e15) + ' fF'
'\n* Lj = ' + '%0.3f' % (self.Lj*1e9) + ' nH' '\n* Lj = ' + '%0.3f' % (self.Lj*1e9) + ' nH'
'\n* Rjn = ' + '%0.3f' % (self.Rn/1e3) + ' kOhm' '\n* Rjn = ' + '%0.3f' % (self.Rn/1e3) + ' kOhm'
'\n*----------------------------------------------------------------' '\n*----------------------------------------------------------------'
'\n* Ej = ' + '%0.3f' % (self.Ej/(self.h_*1e9)) + ' GHz' '\n* Ej = ' + '%0.3f' % (self.Ej/(self.h_*1e9)) + ' GHz'
'\n* Ec = ' + '%0.3f' % (self.Ec/(self.h_*1e9)) + ' GHz' '\n* Ec = ' + '%0.3f' % (self.Ec/(self.h_*1e9)) + ' GHz'
'\n* Ej/Ec = ' + '%0.3f' % (self.Ej/self.Ec) + '\n* Ej/Ec = ' + '%0.3f' % (self.Ej/self.Ec) +
'\n================================================================= \n\n') '\n================================================================= \n\n')
if PrintInfo is True: if PrintInfo is True:
print(txt) print(txt)
return txt return txt
class array(): class array():
def __init__(self, junction, Cs, N): def __init__(self, junction, Cs, N):
self.h_ = 6.62606957e-34 # planck constant (J.s) self.h_ = 6.62606957e-34 # planck constant (J.s)
self.kb_ = 1.3806488e-23 # Boltzman coefficient (J.K^-1) self.kb_ = 1.3806488e-23 # Boltzman coefficient (J.K^-1)
self.j = junction self.j = junction
self.Cs = Cs self.Cs = Cs
self.N = N self.N = N
self.update() self.update()
def update(self, junction = None, N = None, Cs = None): def update(self, junction = None, N = None, Cs = None):
if not junction is None : if not junction is None :
self.j = junction self.j = junction
if not N is None : if not N is None :
self.N = N self.N = N
if not Cs is None : if not Cs is None :
self.Cs = Cs self.Cs = Cs
self.slipRate = self.calcSlipRate(self.j.Ej,self.j.Ec,self.N) self.slipRate = self.calcSlipRate(self.j.Ej,self.j.Ec,self.N)
self.unloadedModes = self.calcModesUnloaded(self.j.F0, np.arange(1,np.floor(self.N/2)), self.N, self.j.Cj, self.j.Cground) self.unloadedModes = self.calcModesUnloaded(self.j.F0, np.arange(1,np.floor(self.N/2)), self.N, self.j.Cj, self.j.Cground)
self.loadedModes = self.calcModesLoaded(self.j.F0, np.arange(1,np.floor(self.N/2)), self.N, self.j.Cj, self.j.Cground,self.Cs,self.j.Ec,self.j.Ej) self.loadedModes = self.calcModesLoaded(self.j.F0, np.arange(1,np.floor(self.N/2)), self.N, self.j.Cj, self.j.Cground,self.Cs,self.j.Ec,self.j.Ej)
self.thermalPop = self.calcThermalPop(self.slipRate, self.j.T) self.thermalPop = self.calcThermalPop(self.slipRate, self.j.T)
def calcSlipRate(self,Ej,Ec,N): def calcSlipRate(self,Ej,Ec,N):
return ((1/self.h_)*N*16 return ((1/self.h_)*N*16
*np.sqrt((Ej*Ec/np.pi)) *np.sqrt((Ej*Ec/np.pi))
*(Ej/(2*Ec))**0.25 *(Ej/(2*Ec))**0.25
*np.exp(-np.sqrt(8*Ej/Ec))) *np.exp(-np.sqrt(8*Ej/Ec)))
def calcModesUnloaded(self,f0,n,N,Cj,C0): def calcModesUnloaded(self,f0,n,N,Cj,C0):
return f0*np.sqrt((1-np.cos(np.pi*n/N))/(1-np.cos(np.pi*n/N)+C0/(2*Cj))) return f0*np.sqrt((1-np.cos(np.pi*n/N))/(1-np.cos(np.pi*n/N)+C0/(2*Cj)))
def calcModesLoaded(self,f0,n_vec,N,C_j,C_0,C_s,E_c,E_j): def calcModesLoaded(self,f0,n_vec,N,C_j,C_0,C_s,E_c,E_j):
#eq_even = lambda omega_l: -1020.0*np.sqrt(2)*C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))) - np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) #eq_even = lambda omega_l: -1020.0*np.sqrt(2)*C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))) - np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))))
#eq_odd = lambda omega_l: -np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) + 0.000490196078431373*np.sqrt(2)/(C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) #eq_odd = lambda omega_l: -np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) + 0.000490196078431373*np.sqrt(2)/(C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))))
sol = np.array([]) sol = np.array([])
eps = 1e2 eps = 1e2
for n in n_vec: n_vec = np.int_(n_vec)
for n in n_vec:
if n%2==0: # even numbers
#eq = lambda w_l_num: eq_even_num(nn,N_num,C0_num,Cj_num,Cs_num,w0_num,Ec_num,Ej_num,w_l_num) if n%2==0: # even numbers
eq = lambda omega_l: -1020.0*np.sqrt(2)*C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))) - np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) #eq = lambda w_l_num: eq_even_num(nn,N_num,C0_num,Cj_num,Cs_num,w0_num,Ec_num,Ej_num,w_l_num)
sol = np.append(sol,opt.ridder(eq,self.unloadedModes[n-1]*(1-1/n)+eps,self.unloadedModes[n-1]-eps)) eq = lambda omega_l: -1020.0*np.sqrt(2)*C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))) - np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))))
else: sol = np.append(sol,opt.ridder(eq,self.unloadedModes[n-1]*(1-1/n)+eps,self.unloadedModes[n-1]-eps))
#eq = lambda w_l_num: eq_odd_num(nn,N_num,C0_num,Cj_num,Cs_num,w0_num,Ec_num,Ej_num,w_l_num) else:
eq = lambda omega_l: -np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) + 0.000490196078431373*np.sqrt(2)/(C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) #eq = lambda w_l_num: eq_odd_num(nn,N_num,C0_num,Cj_num,Cs_num,w0_num,Ec_num,Ej_num,w_l_num)
if n==1: eq = lambda omega_l: -np.tan(np.pi*n*omega_l/(2*f0*np.sqrt((-np.cos(np.pi*n/N) + 1)/(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1)))) + 0.000490196078431373*np.sqrt(2)/(C_s*omega_l*np.sqrt(E_c/(E_j*(-np.cos(np.pi*n/N) + 1)*(C_0/(2*C_j) - np.cos(np.pi*n/N) + 1))))
sol = np.append(sol,opt.ridder(eq,eps,self.unloadedModes[n-1]-eps)) if n==1:
else: sol = np.append(sol,opt.ridder(eq,eps,self.unloadedModes[n-1]-eps))
sol = np.append(sol,opt.ridder(eq,self.unloadedModes[n-1]*(1-2/n)+eps,self.unloadedModes[n-1]-eps)) else:
sol = np.append(sol,opt.ridder(eq,self.unloadedModes[n-1]*(1-2/n)+eps,self.unloadedModes[n-1]-eps))
return sol
return sol
def calcThermalPop(self,slipRate,T):
return np.exp(-2*slipRate*self.h_/(self.kb_*T))/(1 + np.exp(-2*slipRate*self.h_/(self.kb_*T)))*100 def calcThermalPop(self,slipRate,T):
return np.exp(-2*slipRate*self.h_/(self.kb_*T))/(1 + np.exp(-2*slipRate*self.h_/(self.kb_*T)))*100
def arrayInfo(self,PrintInfo=True):
self.update() def arrayInfo(self,PrintInfo=True):
txt =('\n\nArray Information: \n' + self.update()
'\n=================================================================' + txt =('\n\nArray Information: \n' +
'\n* Cs = ' + '%0.3f' % (self.Cs*1e15) + 'fF' + '\n=================================================================' +
'\n* Cj/C0 = ' + '%0.3f' % (self.j.Cj/self.j.Cground) + '\n* Cs = ' + '%0.3f' % (self.Cs*1e15) + 'fF' +
'\n* Lj_array = ' + '%0.3f' % (1e9*self.N*self.j.Lj) + ' nH' + '\n* Cj/C0 = ' + '%0.3f' % (self.j.Cj/self.j.Cground) +
'\n* Ej_array = ' + '%0.3f' % (1e-9*self.j.Ej/(self.h_*self.N)) + ' GHz' + '\n* Lj_array = ' + '%0.3f' % (1e9*self.N*self.j.Lj) + ' nH' +
'\n* First unloaded mode = ' + '%0.3f' % (1e-9*self.unloadedModes[0]) + ' GHz (K=1)' + '\n* Ej_array = ' + '%0.3f' % (1e-9*self.j.Ej/(self.h_*self.N)) + ' GHz' +
'\n* First loaded mode = ' + '%0.3f' % (1e-9*self.loadedModes[0]) + ' GHz (K=1)' + '\n* First unloaded mode = ' + '%0.3f' % (1e-9*self.unloadedModes[0]) + ' GHz (K=1)' +
'\n* Phase slipRate = ' + '%0.2e' % (self.slipRate) + ' Hz' + '\n* First loaded mode = ' + '%0.3f' % (1e-9*self.loadedModes[0]) + ' GHz (K=1)' +
'\n* Qubit thermal population = ' + '%0.2f' % (self.thermalPop) + ' %' + '\n* Phase slipRate = ' + '%0.2e' % (self.slipRate) + ' Hz' +
'\n================================================================= \n\n' '\n* Qubit thermal population = ' + '%0.2f' % (self.thermalPop) + ' %' +
) '\n================================================================= \n\n'
if PrintInfo is True: )
print(txt) if PrintInfo is True:
print(txt)
return txt
return txt
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment