-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathquantum_dot.py
105 lines (73 loc) · 2.26 KB
/
quantum_dot.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
"""
quantum_dot.py numerically computes the ground state energy and
eigenfunction of a hemispherical quantum dot using FEniCS with inverse
iteration
"""
import dolfin as df
import numpy as np
if __name__ == '__main__':
# Computational domain radius
r_dom = 2
# Minimum computational domain height
z_dom_min = -1
# Maximum computational domain height
z_dom_max = 2
# Number of cells in the radial direction
nr = 200
# Number of cells in the radial direction
nz = 200
mesh = df.RectangleMesh(0,z_dom_min,r_dom,z_dom_max,nr,nz)
# Define interior of quantum dot r^2+z^2<1 and z>0
class QuantumDot(df.SubDomain):
def inside(self,x,on_boundary):
return df.between(x[0]**2+x[1]**2,(0,1)) and df.between(x[1],(0,1))
quantumDot = QuantumDot()
domains = df.CellFunction("size_t",mesh)
domains.set_all(0)
quantumDot.mark(domains,1)
V = df.FunctionSpace(mesh,"CG",1)
u = df.TrialFunction(V)
v = df.TestFunction(V)
drdz = df.Measure("dx")[domains]
r = df.Expression("x[0]")
# Confining potential
potential = df.Constant(100)
# Partial derivatives of trial and test functions
u_r = u.dx(0)
v_r = v.dx(0)
u_z = u.dx(1)
v_z = v.dx(1)
# Initial guess of ground state is 1 inside dot, 0 outside dot
psi0 = v*r*drdz(1)
Psi0 = df.PETScVector()
df.assemble(psi0,tensor=Psi0)
# Hamiltonian and mass matrix forms
h = (u_r*v_r+u_z*v_z)*r*(drdz(0)+drdz(1))+potential*r*u*v*r*drdz(0)
m = (u*v*r)*(drdz(0)+drdz(1))
# Mass matrix
M = df.PETScMatrix()
df.assemble(m,tensor=M)
# Hamiltonian matrix
H = df.PETScMatrix()
df.assemble(h,tensor=H)
# Solution
psi = df.Function(V)
solver = df.PETScLUSolver(H)
solver.parameters['symmetric'] = True
solver.solve(psi.vector(),Psi0)
q = psi.vector()
# Do inverse iteration
for k in range(5):
Mq = M*q
qHq = q.inner(H*q)
qMq = q.inner(Mq)
# Rayleigh quotient
E = qHq/qMq
print(E)
q /= np.sqrt(qMq)
solver.solve(q,Mq)
Mq = M*q
q /= np.sqrt(q.inner(Mq))
psi.vector()[:] = q
df.plot(psi,title="Ground State")
df.interactive()