forked from golddoushi/mcsolver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lattice.py
148 lines (134 loc) · 4.88 KB
/
Lattice.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
import numpy as np
import matplotlib.pyplot as plt
class Orbital:
'''
represent the orbital, it is linked to many other orbitals
'''
def __init__(self,id,spin=1.,x=0.,y=0.,z=0.):
self.id=id
self.linkedOrb=[]
self.linkStrength=[]
self.spin=spin
self.inBlock=False
#use to plot on screen
self.x=x
self.y=y
self.z=z
def addLinking(self,targetOrb,strength):
self.linkedOrb.append(targetOrb)
self.linkStrength.append(strength)
def classifyTheLinking(self):
initialType=-1
self.classStrength=[]
self.linkedOrbType=[]
for linkStrength in self.linkStrength:
findType=False
for itype, StrengthType in enumerate(self.classStrength):
if abs(linkStrength-StrengthType)<0.0001:
self.linkedOrbType.append(itype)
findType=True
break
if not findType:
initialType+=1
self.linkedOrbType.append(initialType)
self.classStrength.append(linkStrength)
#print(self.classStrength,self.linkedOrbType)
self.totLinkingTypes=initialType+1
def getCorrEnergy(self,corrList=[]):
corr=0.
for targetOrb, bondStrengh in zip(self.linkedOrb,self.linkStrength):
excluded=True
for corrOrb in corrList:
if targetOrb.id==corrOrb.id:
excluded=False
break
if excluded:
continue
corr+=self.spin*targetOrb.spin*bondStrengh
return corr
def getCorrEnergyDirect(self):
corr=0.
for targetOrb, bondStrengh in zip(self.linkedOrb,self.linkStrength):
corr+=self.spin*targetOrb.spin*bondStrengh
return corr
def getCorrEnergyWithBlock(self):
corr=0.
for targetOrb, bondStrengh in zip(self.linkedOrb,self.linkStrength):
if targetOrb.inBlock:
corr+=self.spin*targetOrb.spin*bondStrengh
return corr
class Bond:
'''
represent the bond
'''
def __init__(self,source,target,overLat,strength):
self.source=source
self.target=target
self.overLat=overLat
self.strength=strength
def establishLattice(Lx=1,Ly=1,Lz=1,norb=1,Lmatrix=np.array([[1,0,0],[0,1,0],[0,0,1]]),bmatrix=[np.array([0.,0.,0.])]):
'''
create a Lx X Ly X Lz lattice, and create norb orbitals
for each cell
'''
# pre-checking if bmatrix is not consistent with norb
if len(bmatrix)<norb:
print('Error: when establish lattice list, we find there is no enough bshift for each orbital')
exit()
# now let us begin
lattice_flatten=[]
lattice=[]
id=0
for x in range(Lx):
lattice_x=[]
for y in range(Ly):
lattice_y=[]
for z in range(Lz):
lattice_z=[]
for o in range(norb):
pos=np.dot(np.array([x,y,z])+bmatrix[o],Lmatrix)
orbital=Orbital(id,x=pos[0],y=pos[1],z=pos[2])
lattice_z.append(orbital)
lattice_flatten.append(orbital)
id+=1
lattice_y.append(lattice_z)
lattice_x.append(lattice_y)
lattice.append(lattice_x)
return lattice, lattice_flatten
def establishLinking(lattice,bondList):
Lx=len(lattice)
Ly=len(lattice[0])
Lz=len(lattice[0][0])
Lo=len(lattice[0][0][0])
# uncode every orbitals
for x in range(Lx):
for y in range(Ly):
for z in range(Lz):
for o in range(Lo):
# start linking
sourceOrb=lattice[x][y][z][o]
for bond in bondList:
if o==bond.source:
targetOrb=lattice[(x+bond.overLat[0])%Lx][(y+bond.overLat[1])%Ly][(z+bond.overLat[2])%Lz][bond.target]
sourceOrb.addLinking(targetOrb,bond.strength)
targetOrb.addLinking(sourceOrb,bond.strength)
# after process
for x in range(Lx):
for y in range(Ly):
for z in range(Lz):
for o in range(Lo):
lattice[x][y][z][o].classifyTheLinking()
def plotLattice(lattice):
'''
uncode the lattice pack and print each orbital on screen
'''
plt.figure()
for x in lattice:
for y in x:
for z in y:
for o in z:
plt.scatter(o.x,o.y,color='blue')
plt.annotate(o.id,(o.x,o.y),size=10.5)
for target in o.linkedSite:
plt.plot([o.x,target.x],[o.y,target.y],color='red')
plt.show()