source: util/src/PrepareStoneWalesDefects.py.in@ 8f9a8e

Last change on this file since 8f9a8e was e1a46d, checked in by Frederik Heber <heber@…>, 16 years ago

All of my python script put into ESPACK and adapted with @PYTHON@ and so on.

  • Property mode set to 100755
File size: 6.3 KB
Line 
1#!@PYTHON@
2#
3# Removes random atoms from a TREMOLO data file
4
5import sys, random, math, re
6
7# check arguments
8if len(sys.argv) < 5:
9 print "Usage: "+sys.argv[0]+" <datafile> <NoDefects> <OffsetElement> <OffsetXYZ> <BondDistance>"
10 sys.exit(1)
11
12input = open(sys.argv[1], "r")
13output = open(sys.argv[1]+".defect", "w")
14defectcount=int(sys.argv[2])
15OffsetElement=int(sys.argv[3])
16OffsetXYZ=int(sys.argv[4])
17DISTANCE=float(sys.argv[5])
18THRESHOLD=.4
19CUTOFF=DISTANCE+THRESHOLD
20
21# 1. parse lines into array
22lines=[]
23comments=[]
24nr=0
25for line in input:
26 if "#" in line:
27 comments.append(line)
28 continue
29 lines.append(line.split())
30nr=len(lines)
31input.close()
32print "I have scanned "+str(nr)+" lines in "+sys.argv[1]+" with "+str(len(comments))+" comments."
33
34# 2a. parse atoms coordinates into list and find bounding box
35max=[ 0., 0., 0. ]
36min=[ 0., 0., 0. ]
37AllAtoms=[]
38
39for n in range(len(lines)):
40 atom=lines[n]
41 #print"reading atom"
42 for i in range(3):
43 #print float(atom[i+1])
44 if float(atom[i+OffsetXYZ]) < min[i]:
45 min[i] = float(atom[i+1])
46 if float(atom[i+OffsetXYZ]) > max[i]:
47 max[i] = float(atom[i+OffsetXYZ])
48 AllAtoms.append([n, atom[OffsetElement], float(atom[OffsetXYZ]), float(atom[OffsetXYZ+1]), float(atom[OffsetXYZ+2])])
49print "Found Box bounds [%f,%f]x[%f,%f]x[%f,%f]." % (min[0],max[0],min[1],max[1],min[2],max[2])
50
51# 2b. get number of linked cells
52cells_x=int(math.ceil((max[0]-min[0])/CUTOFF))
53cells_y=int(math.ceil((max[1]-min[1])/CUTOFF))
54cells_z=int(math.ceil((max[2]-min[2])/CUTOFF))
55print "Number of cells in each axis direction (%f,%f,%f)." % (cells_x, cells_y, cells_z)
56
57# 2c. create 3 dim array to fit in box, each cell has size CUTOFF Ang
58cell=[]
59for i in range(cells_x):
60 cell.append([])
61 for j in range(cells_y):
62 cell[i].append([])
63 for k in range(cells_z):
64 cell[i][j].append([0])
65
66# 2d. parse every atom into appropriate cell
67n=0
68for atom in AllAtoms:
69 x=int(math.floor((atom[2]-min[0])/CUTOFF))
70 y=int(math.floor((atom[3]-min[1])/CUTOFF))
71 z=int(math.floor((atom[4]-min[2])/CUTOFF))
72 cell[x][y][z][0] +=1
73 cell[x][y][z].append(atom[0]) # append index to AllAtoms list
74 n=n+1
75print str(n)+" of "+str(len(AllAtoms))+" atoms were incarcerated."
76
77# 2e. go through every cell, check neighbours
78atom1=[0,0.,0.,0.]
79atom2=[0,0.,0.,0.]
80v=0
81NumBonds=0
82Bonds=[]
83for i in range(cells_x):
84 for j in range(cells_y):
85 for k in range(cells_z):
86 v=cell[i][j][k][0]
87 #go through every atom in cell
88 for l in range(1, v+1):
89 atom1=cell[i][j][k][l]
90 # go through cell and all lower neighbours
91 for e in range(i-1,i+2):
92 #if on border continue periodic
93 if e>=cells_x or e<0:
94 #e=e-cells_x
95 continue
96 for r in range(j-1,j+2):
97 #if on border continue periodic
98 if r>=cells_y or r<0:
99 #r=r-cells_y
100 continue
101 for t in range(k-1,k+2):
102 #if on border continue periodic
103 if t>=cells_z or t<0:
104 #t=t-cells_z
105 continue
106 #efficiency in linked cell: ommit four boxes in middle layer
107 #if (i==e and r==j+1):
108 # continue
109 #if (i==e and r==j+1 and t==k+1):
110 # continue
111 w=cell[e][r][t][0]
112 #go through all atoms in cell
113 for m in range(1, w+1):
114 atom2=cell[e][r][t][m]
115 #when in same cell: ommit identical particles
116 if (AllAtoms[atom1][0]>=AllAtoms[atom2][0]):
117 continue
118 dist=0
119 for h in range(3):
120 dist += (AllAtoms[atom1][2+h] - AllAtoms[atom2][2+h])*(AllAtoms[atom1][2+h] - AllAtoms[atom2][2+h])
121 dist=math.sqrt(dist)
122
123 # add bond
124 if (dist >= (DISTANCE-THRESHOLD)) and (dist <= (DISTANCE+THRESHOLD)):
125 Bonds.append([atom1, atom2])
126 NumBonds+=1
127print str(NumBonds)+" bonds with partners distanced within ["+str(DISTANCE-THRESHOLD)+","+str(DISTANCE+THRESHOLD)+"] angstroem were found."
128
129# 3. check whether we have sufficient bonds and choose desired number
130if NumBonds < defectcount:
131 print "Not enough bonds for the desired number of defects."
132 sys.exit(1)
133
134# 4. flip random but unique bonds by 90 degrees
135vector1=[0., 0., 0.]
136vector2=[0., 0., 0.]
137for n in range(defectcount):
138 # 4a. determine random bond and its bonding partners
139 atom3=-1
140 while atom3==-1: # pick a unique bond
141 i=random.randrange(0,NumBonds)
142 atom1=Bonds[i][0]
143 atom2=Bonds[i][1]
144 atom3=-1
145 if (atom1 == -1) or (atom2 == -1):
146 continue
147 # 4b. obtain a third atom to describe the plane fully
148 for j in range(NumBonds):
149 if ((Bonds[j][0] != atom2) and (Bonds[j][1] == atom1)) or ((Bonds[j][0] != atom1) and (Bonds[j][1] == atom2)):
150 atom3=Bonds[j][0]
151 break
152 if ((Bonds[j][1] != atom2) and (Bonds[j][0] == atom1)) or ((Bonds[j][1] != atom1) and (Bonds[j][0] == atom2)):
153 atom3=Bonds[j][1]
154 break
155 if (atom3 == -1):
156 continue
157 print "Flipping bond "+str(i)+"."
158 Bonds[i][0]=-1
159 Bonds[i][1]=-1
160 # 4c. determine in-plane vectors and orthonormalize
161 for i in range(3):
162 vector1[i]=AllAtoms[atom1][2+i]
163 vector2[i]=AllAtoms[atom1][2+i]
164 for i in range(3):
165 vector1[i]-=AllAtoms[atom2][2+i]
166 vector2[i]-=AllAtoms[atom3][2+i]
167 BondNorm=0
168 for i in range(3):
169 BondNorm+=vector1[i]*vector1[i]
170 BondNorm=math.sqrt(BondNorm)
171 for i in range(3):
172 vector1[i]/=BondNorm
173 norm=0
174 for i in range(3):
175 norm+=vector1[i]*vector2[i]
176 for i in range(3):
177 vector2[i]-=norm*vector1[i]
178 norm=0
179 for i in range(3):
180 norm+=vector2[i]*vector2[i]
181 norm=math.sqrt(norm)
182 for i in range(3):
183 vector2[i]/=norm
184 vector4=[0., 0, 0.]
185 for i in range(3):
186 vector4[i]=(AllAtoms[atom1][2+i]+AllAtoms[atom2][2+i])/2.
187 vector2[i]*=BondNorm/2.
188
189 # 4b. rotate the bonding nuclei and store in array lines!
190 for i in range(3):
191 lines[atom1][OffsetXYZ+i]="%e" % (vector4[i]+vector2[i])
192 lines[atom2][OffsetXYZ+i]="%e" % (vector4[i]-vector2[i])
193
194# 5. store AllAtoms to file
195for line in comments:
196 output.write("%s" % (line))
197for line in lines:
198 for n in range(len(line)):
199 output.write("%s\t" % (line[n]))
200 output.write("\n")
201output.close()
202
203# 6. exit
204print "All done."
205
206sys.exit(0)
Note: See TracBrowser for help on using the repository browser.