-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzvSim.py
301 lines (247 loc) · 7.33 KB
/
zvSim.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/usr/bin/python
# -*- encoding: UTF-8 -*-
'''z(V) Modeling and Simulation
List of Classes: -none-
List of Functions:
quickRun
scqZV
rtcZV
'''
# built-in modules
import sys
sys.path.append('/home/alex/Dropbox/ampPy')
# authored modules
import rtc
import ampNum as an
# third-party modules
from scipy import *
from scipy.optimize import brenth
from scipy.integrate import quad
from pylab import *
#===============================================================================
def main(*args):
pass
# END main
#===============================================================================
def quickRun():
V = linspace(0.5, 4.5, 200)
params = {}
Z = rtcZV(V, 10.0, 24, **params)
f = open('quickRun results.csv', 'w')
for i in range(0,len(V)):
f.write('{0:0.8f}, {1:0.8f}\n'.format(V[i], Z[i]))
f.close()
figure()
plot(V, Z)
xlabel('Gap Bias (V)')
ylabel('z(V) (V)')
title('Simulated cc-STS Results, z')
grid(True)
figure()
plot(V, an.deriv(V, Z))
xlabel('Gap Bias (V)')
ylabel('dz/dV(V) (V)')
title('Simulated cc-STS Reults, dz/dV')
grid(True)
show()
# END quickRun
#===============================================================================
def scqZV(V, I, T, **params):
# dkargs: Default values for keyword arguments
dparams = {
'phi': 5.0, 'tipR': 1.0, 'rhot': 1.0, 'rhoMax': 1.0E-3, 'E0': 2.5,
'w': 0.5, 'rho0': 1.0E-3
}
# Handle keyword arguments
for k in dparams.keys():
# Set all missing keyword arguments to their default values
if k not in params.keys():
params[k] = dparams[k]
elif type(params[k]).__name__ != type(dparams[k]).__name__:
raise TypeError(
'Keyword argument "{0}" should be {1}'.format(
k, type(dparams[k]).__name__
)
)
# END for
# cE: conversion factor for energy
cE = 27.211 #eV/Hartree
# cL: conversion factor for length
cL = 0.0529 #nm/Bohr Radii
# cI: conversion factor for current
cI = 6.62361782E9 #pA/auI
# cDOS: conversion factor for DOS
cDOS = cL**3 * cE #(eV*nm^3)/(Hartree*BohrRadii^3)
# convert input current from pA to a.u.
I /= cI
# convert input voltage from V to Hartree
V = V/cE
# Set up physical parameters
# phi: apparent tunneling barrier height in eV (-> a.u.)
phi = params['phi'] / cE
# A: area of the tunneling junction in nm^2 (-> a.u.)
A = pi*(params['tipR']/cL)**2
# rhot: constant value approximation for DOS of tip in 1/eV/nm^3
# (-> a.u.)
rhot = params['rhot'] * cDOS
# Sample DOS parameters
rhoMax = params['rhoMax'] * cDOS
E0 = params['E0'] / cE
w = params['w'] / cE
rho0 = params['rho0'] * cDOS
# rhosF: DOS function consisting of a flat background and a single
# gaussian peak
rhosF = lambda E: rhoMax*exp( -log(16.0)*((E-E0)/w)**2 ) + rho0
# TF: Transmission function
# square barrier approximation
if T == 'sqr':
TF = lambda z,v,E: exp( -z * sqrt( 8*(phi + 0.5*v - E) ) )
# trapezoid barrier approximation
elif T == 'trap':
TF = lambda z,v,E: exp(
-sqrt(32.0/9.0) * z * ((phi+v-E)**1.5 - (phi-E)**1.5) / v
)
else:
print '**transmission function label not reconized!**'
raise
# tunCurrF: Tunneling current functions
def tunCurrF(z, v):
integralVal = quad(lambda E: rhosF(E)*TF(z,v,E), 0, v)[0]
return A*0.5*pi*rhot*integralVal
# END tunCurr
Z = zeros(len(V))
for i, v in enumerate(V):
if i == 0:
z1 = 0.001/cL
z2 = 0.5/cL
else:
z1 = Z[i-1]
z2 = z1 + 0.05/cL
try:
Z[i] = brenth(lambda z: tunCurrF(z, v)-I, z1, z2)
except ValueError:
print 'V[{0}] = {1:0.3f}V'.format(i, v*cE)
print '(z1 = {0:0.5f}nm, I-10 = {1:0.5e}pA)'.format(
z1*cL, (tunCurrF(z1, v)-I)*cI
)
print '(z2 = {0:0.5f}nm, I-10 = {1:0.5e}pA)'.format(
z2*cL, (tunCurrF(z2, v)-I)*cI
)
quit()
# END for
return Z*cL
# END scqZV
#===============================================================================
def rtcZV(V, I, K, **params):
# dkargs: Default values for keyword arguments
dparams = {
'phi': 5.0, 'tipR': 1.0, 'rhot': 1.0, 'rhoMax': 1.0E-3, 'E0': 2.5,
'w': 0.5, 'rho0': 1.0E-3
}
# Handle keyword arguments
for k in dparams.keys():
# Set all missing keyword arguments to their default values
if k not in params.keys():
params[k] = dparams[k]
elif type(params[k]).__name__ != type(dparams[k]).__name__:
raise TypeError(
'Keyword argument "{0}" should be {1}'.format(
k, type(dparams[k]).__name__
)
)
# END for
# cE: conversion factor for energy
cE = 27.211 #eV/Hartree
# cL: conversion factor for length
cL = 0.0529 #nm/Bohr Radii
# cI: conversion factor for current
cI = 6.62361782E9 #pA/auI
# cDOS: conversion factor for DOS
cDOS = cL**3 * cE #(eV*nm^3)/(Hartree*BohrRadii^3)
# number of points
N = len(V)
# convert input current from pA to a.u.
I /= cI
# convert input voltage from V to Hartree
V = V/cE
# Set up physical parameters
# phi: apparent tunneling barrier height in eV (-> a.u.)
phi = params['phi'] / cE
# A: area of the tunneling junction in nm^2 (-> a.u.)
A = pi*(params['tipR']/cL)**2
# rhot: constant value approximation for DOS of tip in 1/eV/nm^3
# (-> a.u.)
rhot = params['rhot'] * cDOS
# Sample DOS parameters
rhoMax = params['rhoMax'] * cDOS
E0 = params['E0'] / cE
w = params['w'] / cE
rho0 = params['rho0'] * cDOS
# rhosF: DOS function consisting of a flat background and a single
# gaussian peak
rhosF = lambda E: rhoMax*exp( -log(16.0)*((E-E0)/w)**2 ) + rho0
# TF: Transmission function, square barrier approximation
TF = lambda z,E: exp( -z * sqrt( 8*(phi + 0.5*V[0] - E) ) )
# tunCurrF: Tunneling current functions
def tunCurrF(z):
integralVal = quad(lambda E: rhosF(E)*TF(z,E), 0, V[0])[0]
return A*0.5*pi*rhot*integralVal
# Initial z value
z0 = brenth(lambda z: tunCurrF(z)-I, 0.2/cL, 0.3/cL)
# Z: empty vector for storing z values
Z = zeros(N)
Z[0] = z0
# Set up diff eq prefactors
# Cst: ... for the "rhos*T" term
Cst = pi * A * rhot / (I * sqrt(32*phi))
# Cz: ... for the "z" term
Cz = 1/(4.0 * phi)
# pre-loop computation
Q = zeros( (K+1,K+1) )
for k in range(1,K):
for j in range(0,k):
Q[j,k] = 1.0 - float(j)/float(k)
# z(V)-solve loop
# set up loop variables
# taylor coeff array of unitary constant
c = rtc.const(K)
# rv: vector containing taylor coefficients of v
rv = zeros(K+1)
rv[1] = 1.0
# rz: vector containing taylor coefficients of z
rz = zeros(K+1)
# iteratively solve for Z across V, starting at V[1]
for i in range(1,N):
# h: step size
h = V[i] - V[i-1]
# previous V value
rv[0] = V[i-1]
# previous Z value
rz[0] = Z[i-1]
# W1: working variable 1, taylor coeff array
W1 = rtc.sqrt( 8*(phi*c - 0.5*rv), approx='lin' )
# rhos: sample DOS, taylor coeff array
rhos = rhoMax*rtc.gauss(rv, x0=E0, w=w) + rho0*c
W2 = zeros(K+1)
T = zeros(K+1)
# iteratively solve for all orders of taylor coefficients for z
for k in range(0, K):
W2[k] = rtc.prod(-rz, W1, k)
# T = e^W2
if k == 0:
T[0] = exp(W2[0])
else:
for j in range(0,k):
T[k] += Q[j,k] * W2[k-j] * T[j]
# z' = Cst*rhos*T - Cz*z
rz[k+1] = ( Cst*rtc.prod(rhos, T, k) - Cz*rz[k] )/(k+1)
# build up z at the next V point as a Taylor approximation of the
# function out from the previous points
for k in range(0,K+1):
Z[i] += rz[k]*(h**k)
# END z(V)-solve loop
return Z*cL
# END rtcZV
#===============================================================================
if __name__ == "__main__":
quickRun()